Aller au contenu
apim.one

The blog

Exposing your APIs to agents

The MCP protocol, the identity of the agent, the difference between discovering a tool and having the right to invoke it, and what per token billing changes.

Agents consume APIs differently from applications. They read a catalogue of tools instead of documentation. They chain dozens of calls for a single task. And they act on behalf of someone without being that someone. These differences shift governance, not just the technology.

What MCP changes

The MCP protocol describes tools: a name, a natural language description, an input schema. The agent reads that catalogue and decides on its own what to call. The contract is no longer read by a developer at integration time, it is read by a machine on every task.

Direct and often missed consequence: the description becomes an interface. An approximate description produces approximate calls. The same requirements as for a quality OpenAPI contract, real examples, error semantics, usage limits, become here conditions for the thing to work at all rather than editorial courtesies.

There is no new contract to produce: the work is on the descriptions, not on the interfaces. Azure API Management generates the MCP tools from the APIs the instance already manages, and AgentCore at AWS from a supplied OpenAPI specification, provided each operation carries an identifier. The agent then goes through the same governance as any other consumer.

And since the 28 July 2026 revision, the protocol has no session. No handshake, no session identifier: every request describes itself. An intermediary therefore rules on what it sees go past, instead of trusting state it does not hold.

A server can even ask for certain tool parameters to be mirrored into HTTP headers (Mcp-Param-*). A gateway then routes, and applies its rules, without opening the body of the request. Provided no sensitive parameter goes in there: those headers are visible to every intermediary. The protocol has been rewritten in part to make that platform work possible.

Two identities, not one

An agent acts on behalf of a user. So two things have to be known on every call: which agent, and for whom.

Confusing the two produces the two symmetrical failures. With a single agent identity, the audit trail loses the user and authorisation decisions can no longer depend on them. Simply forwarding the user's token gives the agent all their scopes, and a compromised agent becomes the user.

This is not a consultancy best practice, it is an obligation of the standard. The MCP authorisation specification forbids the server from accepting or transiting a token that was not issued for it. It mandates audience validation. And it requires the client to state the target resource, per RFC 8707, even when the authorisation server cannot read it.

The 28 July 2026 revision hardened the rest. It mandates validation of the issuer of the authorisation response (RFC 9207), against mix-up attacks. And it deprecates dynamic client registration, in favour of a client_id that is a URL pointing at a metadata document.

The mechanics are those of ordinary call chaining, described in access: the token exchange of RFC 8693. The agent obtains a token intended for the target API, with reduced scopes, that preserves the original identity.

Discovering is not invoking

Those two identities are not enough if they are established only once. An agent can see a tool in the catalogue and be refused its use: the decision is re-evaluated on every call, never once and for all at discovery.

The reason is specific to agents: the catalogue is read at the start of the task, the invocation comes several steps later, in a context that has changed. Treating discovery as an authorisation freezes rights for the whole session, which is exactly what per call authorisation is there to fix.

In practice that makes two distinct decisions, in the same place, on different data. MCP does in fact separate them into two methods. On tools/list, the gateway filters the catalogue according to the identity asking for it: a tool an agent will never be able to invoke has no business being there, because a visible tool is a tool it will try.

The specification allows this explicitly: the list may vary according to the authorisation presented on the request. It must not vary according to the connection. The reason fits in one sentence: credentials are per call input, not session state.

On tools/call, it decides on what the list did not carry: the scopes of the exchanged token, the identity of the original user, the actual parameters of the call. Hence the only rule that counts: authorisation applies to the data requested, not to the tool. An agent allowed to view one customer file is not allowed to view them all. That decision cannot be taken at discovery, since the file identifier does not exist yet.

Bursts change the quotas

That leaves the most mundane difference, and the most expensive: volume. An agent task routinely produces several dozen calls where a screen produced one.

Count in cost, not in calls, as soon as what sits downstream is a model: the cost depends on the tokens consumed, and two calls can differ by a factor of a thousand. Recent gateways can count in tokens and attribute the spend to the consuming team.

Limit the task, not just the call. A per call quota is no protection against an agent loop. The useful limit applies to the task or to the session.

Keep a usable log. Which agent, for which user, which tool, what cost. Without it, the first invoice comes as a surprise and nobody can say which task produced it.

An API response becomes a command input

This is the risk most specific to agents, and the one no API security checklist covers. An agent reads the responses it receives and treats them as context. And a response often contains text written by a third party: a customer name, a comment, the free text field of a form. That text can carry instructions, and the agent has no way of telling data from an instruction.

The scenario is in no way theoretical: an attacker with no access at all to your platform places the payload in a field your API returns, and waits for an agent to read it. The trust boundary therefore moves from the caller to the content returned, and that is new.

Three measures sit at gateway level, and they are worth more than trust in the client. Explicitly marking the fields that contain untrusted text, so the agent can treat them as data. Capping the size and the number of items returned per call, because exfiltration goes through large responses. And above all, never making a sensitive operation depend on the chain of steps the agent alone decided: that is the point of the confirmation below.

What must not be exposed

The natural reflex is to expose the whole catalogue, since generation is automatic. That is a mistake on two counts.

Too broad a catalogue degrades the behaviour of the agent: more tools, more bad choices, and an ambiguous description between two neighbouring tools produces wrong calls. A chosen subset works better than an exhaustive catalogue.

And every irreversible operation has to go through a human confirmation. MCP provides annotations to signal that a tool is read only or destructive. But these are hints aimed at the client, not a security boundary. The specification says so itself: a client must treat an annotation as untrusted unless it comes from a trusted server.

The protocol can now interrupt a call to ask for input, but it is still the client that displays it and decides to ask. So the confirmation belongs upstream, in the gateway, where it is not optional. An agent that can delete, debit or notify third parties must not be able to do it alone.

Where to start

Three read-only APIs, well described, exposed to a single agent, with a log of invocations and a per task quota. That scope takes a few days and reveals what no documentation says: the real quality of your contract descriptions. It is in fact the best argument for investing in contracts, far more convincing than discovery for humans, because the failure is immediate and visible.

Published in July 2026, revised in August 2026.

On the same subject