Blog

Agents Undid Twenty Years of API Curation. Put It Back with Capabilities.

Jerome Louvel ·August 17, 2026
Table of contents

Large APIs are not new. Stripe, Salesforce and Jira have each exposed hundreds of endpoints for years, and nobody wrote blog posts about endpoint bloat. Yet point an agent at a couple of vendor MCP servers and the tool count is the first thing anyone complains about.

The catalogs did not get worse. We removed the step that used to handle them.

REST already solved this, at design time

There was always a curation step. It just ran early, and a human performed it.

A developer read the docs once, decided the feature needed exactly these three endpoints, and wrote those three call sites. The other four hundred cost nothing at runtime, because the selection was already made and frozen into code. It was reviewed in a pull request. It behaved identically on every execution. And when a regulator asked which systems the service could reach, you answered by reading the source.

Pointing an agent at a generic tool catalog deletes that step. The selection is no longer made once, by a developer, at design time — it is remade on every turn, at runtime, by a probabilistic model reasoning over tool descriptions. That trade is worse on three counts:

  • Inefficient. A decision made once is re-derived per request, and the whole catalog must be re-read into context to make it.
  • Costly. You pay tokens to re-litigate a settled question, then pay again for every mis-selection and its retry.
  • Impossible to trust. The same request can resolve to a different tool tomorrow, and the choice exists only inside an inference — you cannot diff it, certify it, or prove which operations a workflow can reach.

The third is the one that stops deployments. “Which systems can this touch?” was a code-reading question; when tool selection lives in a model, you answer it by watching production.

What the protocol did and did not change

The obvious objection: isn’t MCP fixing this? It is fixing the plumbing, which is the easier half.

MCP versions its protocol by date, and 2026-07-28 is current. It removed the initialize handshake and the session header — and read the replacements with a composition layer in mind, because they are nearly a specification for one. Protocol version, identity and capabilities ride in _meta on every request, so any request can land on any instance and an intermediary can fan calls across upstream servers without owning affinity. Mcp-Method and Mcp-Name let a gateway dispatch, authorise and meter at the edge without parsing the body. And server/discover plus the ttlMs / cacheScope metadata on list results lets an aggregator cache an upstream’s capability map instead of re-negotiating per call.

So composing MCP servers no longer requires dropping to lower-level REST for structural reasons. That is a real change — and orthogonal to the problem above. A cheaper way to reach two hundred tools does not tell your agent which four it should see. If anything it makes the gap more visible, because the plumbing excuse is gone.

It also added an obligation. State did not disappear with the session header — it moved. What used to hide in transport metadata is now an explicit handle the model threads from call to call: a basket_id, a run_id, a cursor. A model asked to carry correlation identifiers across turns will occasionally drop one, and every dropped identifier is a retry you pay for twice. Something above the vendor servers has to hold that coherence — either a layer you control, or your prompt.

Why MCP is still the better upstream

None of that makes REST the answer for agents. MCP has one structural advantage, and it is a design-time one, which is why it belongs here: with REST the machine-readable contract is a separate artifact. You must know an OpenAPI document exists, find its URL, match its version to the deployment you are actually calling, and hope someone regenerated it after the last change. Nothing in an HTTP response tells you it drifted.

With MCP the description is in the protocol. tools/list is a live call against the running server, so the contract cannot drift from the implementation — it is the implementation answering. Version mismatches are protocol errors rather than client-side heuristics, and agent affordances like readOnly and idempotent hints come back with the tools; in REST that guidance lives in prose docs, vendor extensions, or nowhere. So REST stays the execution truth for systems that already speak it, MCP is the agent-facing layer, and a curated surface between them decides what crosses.

The curation nobody else can do for you

A provider MCP server is scoped to a provider’s product — the right scope for the vendor, the wrong scope for your agent, because the unit of match is the use case, not the API. Four decisions stay yours no matter how good the upstream servers get:

  • Elevation — turning low-level operations into task-shaped tools.
  • Filtering — exposing only the subset this agent, this tenant and this policy allow.
  • Aggregation — fusing several systems into one coherent contract.
  • Orchestration — running multi-step sequences deterministically, off the model’s critical path.

Every one is a decision a developer used to make while writing call sites. None are protocol gaps, which is why a better protocol does not retire them.

Two things get offered as the fix, and both deserve a straight answer. The first is dynamic tool discovery: stop putting two hundred schemas in context, let the agent search for the one it needs. That helps the token bill, but the selection still happens at runtime, in the model — and search needs a query, which means the agent must already know your surface’s vocabulary to ask for the right thing. As the earlier post on retrieval put it: retrieval doesn’t remove curation, it relocates it.

The second is Agent Skills, and here the answer is partly yes: they do recover part of the step. A skill carries procedural knowledge a tool list never conveys, and its allowed-tools frontmatter is a pre-approved list of tool names — a selection made in advance, by a person, in a file you can diff.

It is still not the whole property. A skill advises which tools to prefer; the exposed surface determines which exist — so with two hundred tools still underneath, the boundary is a suggestion the model can wander past, not a wall. And a skill maintained apart from its surface drifts: rename a tool and it does not fail, it silently misdirects. Skills narrow and inform the choice; only the surface bounds it. The two belong in one artifact.

Writing the decision down

A restored design-time choice needs an artifact. That is the argument from Five Fragmented Specs, One Ikanos Capability.

An Ikanos capability puts three answers in one declarative file: consumes (which upstream systems, under which credentials), aggregates (how calls compose into flows), and exposes (what the downstream surface offers). Because there is no control flow, a reviewer can enumerate the whole surface by reading it — restoring the property REST had and agents lost: the reachable operations are knowable before anything runs.

That also closes the skill gap. A skill declared here draws its tools from sibling adapters in the same document rather than naming them from a distance, so guidance and boundary are versioned together and reviewed in one diff. You keep the procedural knowledge; it can no longer drift from the surface it describes.

The transport independence is a bonus this year made concrete. The YAML never mentioned sessions or headers, so adopting a stateless revision was an engine concern: 2026-07-28 support is in the engine today, and no capability file changed to get it.

Two jobs, one model

This shows up as two jobs usually discussed as rival strategies. They are two tiers of the same artifact.

Give a system an MCP front door it never had. Most of an enterprise’s estate — legacy SaaS predating the protocol, the homegrown CRM, the claims engine — has a good HTTP API, no MCP server, and no vendor coming to write one. A capability consuming that API and projecting a faithful MCP surface originates the server. That is a source capability: thin domain logic, strong upstream governance, close to a one-to-one projection. The point is reach.

Give one agent the few tools its use case needs. That surface is a task, not a system. It draws on several upstreams — source capabilities you originated, vendor MCP servers, raw APIs — and fuses them into a handful of task-shaped tools with policy and sequencing applied. That is an applied capability: AI-facing intent is explicit, and the MCP and skill surfaces are the centre of gravity rather than a passthrough.

They compose. An applied capability does not re-declare the plumbing beneath it; the spec’s imports mechanism (from, import, as) reuses another file’s consumes, aggregates or exposes blocks by name, so credentials and operation shapes are written once, in the capability that owns them.

That splits the work the way organisations are shaped. The team that owns a system publishes its source capability once — they know the API’s quirks, auth and rate limits. The team that owns an agent assembles an applied capability from whatever source capabilities and vendor servers exist — they know the use case, the policy, and which four tools the model should see. Neither blocks the other, and since both tiers are the same kind of file, one review, lint and engine upgrade covers both.

Where Ikanos actually stands

Worth stating precisely if you are planning against it: Ikanos serves 2026-07-28 on the exposure side — the curated surface your agent talks to is protocol-current today. On the consumption side it ships a single HTTP client adapter, which covers the majority case, since most of the estate this argument is about has an HTTP API and no MCP server at all.

You can also reach an MCP endpoint from a capability today — an MCP call is HTTP with a JSON-RPC body, and _meta is just fields you declare — but you are hand-writing what a native client would do: no automatic tools/list discovery, no capability negotiation, no generated mapping from an upstream tool schema into a consumed operation.

So a native consumes: type: mcp adapter is a candidate roadmap item, and the stateless revision moved it up the list. It would turn “consume three vendor servers, expose four curated tools” into a declaration instead of a transcription — the natural sibling of the gRPC and SQL client adapters already proposed, and the shape a stateless protocol now rewards. Notably it changes nothing about the spec: another consumes type under the same consumes / aggregates / exposes model, which is a fair sign the model was drawn at the right level.

The takeaway

For twenty years someone decided at design time which handful of operations a piece of software could reach. That decision was cheap to make, easy to review, and identical on every run.

Agents did not make it harder. They moved it to runtime and handed it to a probabilistic model — which is where the token cost, the latency and the lost auditability come from.

Ubiquitous MCP servers lower the cost of reaching a system. They do not decide what your agent should be allowed to do with it. As the protocol layer commoditises, the durable advantage belongs to whoever puts that decision back where it was: made once, written down, reviewed, and versioned.

Further reading

Subscribe to the Naftiko Manifest

Want to learn more and stay up to date on the latest from Naftiko? Get new posts, releases, and signals from the capability fleet in your inbox.