{"slug": "microservices-were-built-for-programs-agents-need-capabilities", "title": "Microservices Were Built for Programs. Agents Need Capabilities.", "summary": "Ikanos, an open-source capability runtime published as the naftiko/ikanos Docker Hub image, argues that exposing microservices one-to-one as MCP tools forces AI agents to re-make five decisions — granularity, formats, payload size, credentials and side effects — on every request. The runtime deploys as a Kubernetes Deployment behind a Service with /health/live, /health/ready and /metrics control endpoints, and lets a single spec file declare aggregates, per-service auth (basic, apikey, bearer, digest, oauth2), output formats (JSON, XML, Avro, Protobuf, CSV, YAML) and flow semantics (safe, idempotent, cacheable) that the engine converts into MCP hints. The project's stated conclusion is that microservices remain the right backend but the wrong unit of exposure for agents, since only declared fields leave the engine and unexposed endpoints become tools the agent cannot call.", "body_md": "Microservices were designed for **deterministic clients**. A developer reads the contract, writes the call sequence, handles the auth, picks the fields that matter — once.\n\nAn agent decides all of that at runtime, pays for every byte it reads, and retries when unsure. Expose your services one-to-one as MCP tools and every decision the developer made once, the model now makes on every request. **The services are fine. The unit of exposure is wrong.**\n\n## Same container infrastructure as your microservices\n\nThis is not a new tier of infrastructure. A running Ikanos capability uses the same container infrastructure as your microservices: the [`naftiko/ikanos`](https://hub.docker.com/r/naftiko/ikanos) image from Docker Hub serving one spec file, deployed in your Kubernetes cluster as a `Deployment` behind a `Service`.\n\nIt scales like any `Deployment`, sits behind your gateway, and a control port exposes `/health/live`, `/health/ready` and `/metrics` for your probes and Prometheus. Your platform team operates it with the tools it already has. What differs is the contract: it is declared for an agent, not coded for a program.\n\n## Five decisions the agent should not be making\n\n**1. Granularity.** `POST /orders`, `GET /users/{id}/payment-methods`, `POST /inventory/reserve` are each correct; none of them is “fulfil this order”. An Ikanos aggregate composes them in `steps` — `call` and `lookup` — and exposes the flow as one tool.\n\n**2. Formats.** The legacy service returns XML, the partner feed CSV. Each consumed operation declares its `outputRawFormat` (JSON, XML, Avro, Protobuf, CSV, YAML and more); the engine parses it and the agent only sees JSON.\n\n**3. Payload size.** Responses carry database keys, trace IDs and audit fields. A capability maps only the fields it declares; everything else never leaves the engine.\n\n**4. Credentials.** Auth is declared per consumed service (`basic`, `apikey`, `bearer`, `digest`, `oauth2`) with values resolved from `binds` at runtime. The model sees a tool name and its inputs, never a secret.\n\n**5. Side effects.** An unsure agent retries, which is harmless for `GET` and costly for `POST`. Flows declare `semantics` (`safe`, `idempotent`, `cacheable`) and the engine derives MCP hints from them. Endpoints you don’t expose are tools the agent can’t call; rate limiting stays [in your gateway](https://naftiko.io/blog/you-have-apigee-now-your-ai-agents-need-to-use-it/).\n\n## One file, five answers\n\nTrimmed from step 9 of the Shipyard tutorial:\n\n```\ncapability:\n  consumes:\n  - namespace: registry                  # JSON, bearer\n    type: http\n    baseUri: \"https://registry.internal\"\n    authentication: { type: bearer, token: \"{{REGISTRY_TOKEN}}\" }\n  - namespace: legacy                    # XML, API key\n    type: http\n    baseUri: \"https://dockyard.internal\"\n    authentication: { type: apikey, key: X-Dock-Key, placement: header, value: \"{{DOCKYARD_API_KEY}}\" }\n\n  aggregates:\n  - namespace: crew-resolver\n    flows:\n      resolve-crew-for-ship:\n        semantics: { safe: true, idempotent: true, cacheable: true }\n        steps:\n          get-ship:  { type: call, call: registry.get-ship, with: { imo_number: \"{{imo}}\" } }\n          list-crew: { type: call, call: registry.list-crew }\n          resolve-crew:\n            type: lookup\n            index: list-crew\n            match: crewId\n            lookupValue: \"$.get-ship.assignedCrew\"\n            outputParameters: [ fullName, role ]\n        mappings:\n        - { target: name, value: \"$.get-ship.vessel_name\" }\n        - { target: crew, value: \"$.resolve-crew\" }\n\n  exposes:\n  - type: mcp\n    namespace: shipyard-tools\n    tools:\n      get-ship-with-crew:\n        description: \"Get ship details with resolved crew names\"\n        ref: crew-resolver.resolve-crew-for-ship\n```\n\nTwo services, two auth schemes, one goal-shaped tool. None of the services changed.\n\n## The takeaway\n\n- Microservices are the right way to build the backend, and the wrong unit to hand an agent.\n- Capabilities run on the same container infrastructure: one container, one spec, in the cluster you already run.\n- Make the five decisions once, in a reviewable spec, and expose the result as MCP, REST or a skill.", "url": "https://wpnews.pro/news/microservices-were-built-for-programs-agents-need-capabilities", "canonical_source": "https://naftiko.io/blog/microservices-were-built-for-programs-agents-need-capabilities/", "published_at": "2026-10-04 00:00:00+00:00", "updated_at": "2026-10-04 19:12:54.318035+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-tools", "developer-tools", "ai-infrastructure"], "entities": ["Ikanos", "naftiko/ikanos", "Docker Hub", "Kubernetes", "Prometheus", "MCP", "Shipyard"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/microservices-were-built-for-programs-agents-need-capabilities", "markdown": "https://wpnews.pro/news/microservices-were-built-for-programs-agents-need-capabilities.md", "text": "https://wpnews.pro/news/microservices-were-built-for-programs-agents-need-capabilities.txt", "jsonld": "https://wpnews.pro/news/microservices-were-built-for-programs-agents-need-capabilities.jsonld"}}