Three questions a tool call has to answer

Every time a model calls a tool, three separate questions get answered, usually without anyone in the room noticing that there were three. What tools exist right now. What each one actually does. And whether this particular caller, with this particular credential, is allowed to do that particular thing. Treat those as one blended question — “can the model use this tool” — and the failure modes documented below become invisible, because each of the three is secured, if it is secured at all, by a completely different mechanism.

This article is about the layer that answers those three questions for real, deployed systems: the Model Context Protocol (MCP), the OAuth-based authorization scheme grafted onto it, and the handful of adjacent protocols that solve neighbouring problems. It separates what is actually specified from what is merely observed to happen in practice, what is observed to happen in practice from what has already been broken by named, dated attacks, and all of that from the forward-looking part — three scenarios for where this machinery sits by 2035, each stated so that it can be shown wrong.

What MCP actually specifies: discovery, description, invocation

MCP frames the problem as a message protocol between three roles: a host application that a user interacts with, a client inside that host that manages one connection, and a server that exposes tools, data resources, and prompt templates over JSON-RPC 2.0 [1]. The specification explicitly draws the analogy to the Language Server Protocol — a prior case of standardizing how one category of application (editors) talks to many independent providers (language analyzers) — and applies the same shape to how AI applications talk to context and tool providers [1].

ADVERTISEMENT

Discovery and invocation are two distinct JSON-RPC methods, and the distinction matters more than it looks. A client sends tools/list and gets back a paginated array of tool objects, each with a name, a description, and an inputSchema written in JSON Schema; the server is required to return that list deterministically so that clients can cache it, and may vary the list by what the caller’s credentials actually permit [2]. Only once a tool has been selected does the client send a separate tools/call request naming that tool and supplying arguments that must validate against its declared schema [2]. Nothing in this exchange is exotic — it is a directory lookup followed by a remote procedure call — and that ordinariness is exactly why the next section matters: the directory entries are themselves adversarial input.

A software package tray paused under a barcode scanner beam on an intake counter, an accept lane glowing green ahead of it and a reject bin with amber tape standing to the side
Figure 1. What a package claims to do is read here before it is trusted anywhere else — the check that never runs a second time once the tray moves on.Image prompt and art direction by Brecht Corbeel; generation pending.

The specification’s own text does not pretend this is fully solved. It states plainly that tools represent arbitrary code execution and must be treated with corresponding caution, that hosts must obtain a user’s explicit consent before invoking any tool, and — in a warning easy to skim past — that “descriptions of tool behavior such as annotations should be considered untrusted, unless obtained from a trusted server” [2] [1]. That single sentence is the entire security model for tool descriptions, and it is a disclosure, not a guarantee: the protocol tells implementers what to distrust, it does not make the distrust automatic.

The description problem: a schema is a claim, not a fact

A description field exists to tell a model what a tool does, in natural language, so the model can decide when to call it. That field is also, by construction, text the model reads and can act on — which means a tool’s own self-description is a channel for instructions, indistinguishable in kind from a user’s prompt, arriving from whoever controls the server.

Invariant Labs demonstrated the consequence directly and disclosed it on April 1, 2025: a “tool poisoning attack” embeds hidden directives inside a tool’s description — often set off with tags like <IMPORTANT> that a chat UI never renders but a model reads in full — instructing the model to take actions the user never approved. Their published proof-of-concept tricked a coding assistant into leaking a local configuration file and SSH keys through the arguments of an ordinary-looking add tool, and demonstrated a related technique they call tool shadowing, where instructions from one connected server rewrite how the model behaves toward a second, otherwise trustworthy server it is also connected to [8]. They also named a “rug pull” pattern: a server can change a tool’s description after a user has already approved it once, so consent granted to version one silently covers whatever version two now says [8].

Follow-on academic work generalizes the finding rather than merely repeating it. A 2026 threat-modeling paper applies STRIDE and DREAD analysis across the five components of an MCP deployment — host and client, the model itself, the server, any external data store, and the authorization server — and identifies 57 distinct threats, concluding that tool poisoning specifically is the most prevalent and most impactful client-side vulnerability in the set, scoring in the critical range under DREAD [9]. Tested against seven major MCP clients, the paper finds most rely on the user reading a description before approving a tool, with little or no static validation of what that description actually contains — which is precisely the assumption tool poisoning defeats, since the dangerous half of the description was never shown to the user in the first place [9].

ADVERTISEMENT

Read the specification’s warning against this evidence and its limits become exact. “Consider annotations untrusted unless from a trusted server” correctly identifies the threat model. It does not specify how a client establishes that a server is trusted, and it does not require any client to check. Both are left, for now, as an integration decision made separately by every implementer — which is the gap the next section is about.

A dual-control key-ceremony console with one smart card fully seated in its slot and a second card still short of its own slot, the shared unlock indicator between them still dark
Figure 2. One credential is never enough to decide a grant this large — the panel stays dark until a second, independent hand has agreed.Image prompt and art direction by Brecht Corbeel; generation pending.

From a consent dialogue to a bounded grant

The oldest fix for “the model might misuse this” is a modal dialogue: show the user what is about to happen, wait for a click. That pattern is exactly what the MCP specification requires as a baseline — a human in the loop with the ability to deny a tool call [2] — and exactly what tool poisoning is built to slip past, because the dialogue shows what the client chooses to render, not the full description the model actually read.

MCP’s authorization specification addresses a narrower but more tractable question: not “did the user understand this,” but “what is this bearer token actually good for.” It defines an HTTP-transport authorization flow built on OAuth 2.1, in which an MCP server acts as a resource server, a client acts as an OAuth client, and a separate authorization server issues access tokens scoped to that specific server’s resource identifier [3]. Three details make this a genuinely capability-scoped model rather than an ambient-trust one. Tokens are bound to a specific server URI as an audience, per RFC 8707’s resource-indicator mechanism, so a token stolen from one server cannot be replayed against another [3]. Servers can challenge a request with the exact scope it is missing via a WWW-Authenticate header, and clients are expected to request only that scope rather than everything the user might ever need, following what the specification calls a step-up flow [3]. And issuer values in the authorization response are validated against what was recorded before the redirect, closing a known mix-up attack in which a malicious authorization server answers on behalf of a legitimate one [3].

That architecture is a specific case of a more general primitive already standardized outside MCP. RFC 9396 defines authorization_details, an OAuth 2.0 extension letting a client request structured, fine-grained permissions — its own example is the difference between “read access to a profile” and “transfer 45 euros to a named merchant” — instead of the flat, coarse strings that scope provides on its own [7]. MCP’s step-up scoping is a narrower instance of the same idea: authorization as a set of bounded, named permissions rather than a single yes/no grant. The dual-control key-ceremony rig — two independent credentials, neither sufficient alone, both required before a shared grant activates — is the physical form of the same principle: no single presented credential should be sufficient to authorize an action whose cost, if wrong, is large.

harm(scope)  =  p(misuse)blast_radius(scope) \text{harm}(\text{scope}) \;=\; p(\text{misuse}) \cdot \text{blast\_radius}(\text{scope})

None of this is optional dressing. It is the formal reason “least privilege” is the specification’s own stated design goal for scope selection [3]: for a fixed probability of a tool being tricked into acting, the damage a poisoned tool call can do is bounded by how much the token it is running under can actually reach. Widen the scope and the expected harm of exactly the same attack widens with it, even though the attack itself did not get any more sophisticated.

A code-signing press with its stamping head caught mid-descent just above a clamped software package, not yet making contact, a row of already-signed packages waiting to the side
Figure 3. A signature fixes a package to the hands that made it — but only for the instant after the press has actually come down, never before.Image prompt and art direction by Brecht Corbeel; generation pending.

Registries, packages, and the layer beneath the protocol

Everything above assumes the server you connect to is the server you think it is, running the code its maintainer published. That assumption has already failed in ways unrelated to prompt injection, purely as ordinary software-supply-chain compromise.

ADVERTISEMENT

In September 2025, the npm package postmark-mcp — an MCP server wrapping the Postmark email API — was modified so that outgoing email traffic silently carried a blind copy to an address outside the maintainer’s control; the tampered versions were live for roughly ten days before removal, and because an MCP server routinely handles password resets, tokens, and other secrets that travel by email, the exposure was not cosmetic [10]. That incident targeted an MCP server directly, but MCP tooling was also swept up in supply-chain compromises that had nothing to do with MCP at all: a separate September 2025 compromise of widely used npm packages including debug and chalk — dependencies collectively downloaded more than two billion times a week — put a meaningful share of npm-based MCP servers at indirect risk purely because the official MCP TypeScript SDK depends on packages from the same ecosystem [11]. Most JavaScript MCP servers are invoked through npx, which fetches and executes a package with the same system access as the user running it — so a compromised transitive dependency is not a theoretical risk model, it is a direct path to arbitrary local execution [11].

Nothing in the MCP specification currently requires a signed, verifiable link between a published server package and the identity that built it — that guarantee, where it exists at all today, comes from general package-ecosystem provenance tooling, not from MCP itself. The gap between “this package’s description says it does X” and “this package is cryptographically provable to be the code its named author actually published” is presently closed, if it is closed at all, by registry reputation and by how quickly a compromise gets noticed and pulled — ten days, in the postmark-mcp case [10].

A rack-mounted hardware security module drawn part-way out of its rack on rails, its tamper-evident foil seal half-peeled back from one edge and not yet fully removed
Figure 4. The seal is meant to make a quiet opening loud — and it is only doing its job right at the instant it is still half-attached.Image prompt and art direction by Brecht Corbeel; generation pending.

Neighbouring protocols, not competing rankings

MCP is frequently discussed as though it were the only way a model reaches a tool, which understates both how the field is organized and how narrow MCP’s own claim actually is. It is worth being precise about what each neighbouring mechanism actually specifies, since they solve different problems rather than the same problem twice.

OpenAI’s function-calling interface, as currently documented, describes tools to a model as JSON-Schema objects attached directly to a single API request: a name, a description, a parameter schema, and an optional strict mode that constrains generation so that arguments are guaranteed to validate against the schema [5]. The model returns structured function_call entries with a call ID and arguments; the calling application executes the function itself and returns the result in a following turn, optionally issuing several such calls in parallel within one turn [5]. This is a vendor-specific request format, not a network protocol — there is no separate transport, no independent server role, and no cross-session discovery mechanism; the tool list is whatever the calling application attaches to that request.

Google’s Agent2Agent protocol (A2A) sits at a different layer entirely. It targets agent-to-agent interoperability rather than model-to-tool integration: independently built agents exchange JSON-RPC 2.0 messages over HTTP, advertise their capabilities through a published “Agent Card,” and collaborate on long-running tasks while keeping their own internal memory and tooling opaque to one another [6]. A2A’s own documentation is explicit that it complements MCP rather than replacing it — MCP is the mechanism an individual agent might use to reach a database or an API; A2A is the mechanism by which two such agents, each with their own private toolset, negotiate a shared task [6]. Governance also differs by design: A2A was contributed to the Linux Foundation as an Apache-2.0 project from a broad initial partner base, structurally similar to where MCP has since arrived by a different route, described next [6].

None of this supports a ranking. A tool-calling format embedded in one vendor’s API, a standalone protocol for reaching many independent tool servers, and a protocol for two whole agents to negotiate with each other are not substitutable, and a claim that any one of them is “better” without specifying better at what would be comparing incomparable things.

A governance signal: MCP leaves single-vendor hands

In December 2025, Anthropic transferred MCP’s stewardship to a newly formed Agentic AI Foundation under the Linux Foundation, co-founded alongside Block and OpenAI, with Google, Microsoft, AWS, Cloudflare, and Bloomberg named as supporting members [4]. Anthropic’s own announcement frames the move explicitly as keeping the protocol “neutral, open, and community-driven” rather than controlled by the vendor that originated it, and reports scale that had by then made single-vendor control awkward regardless of intent: more than 97 million monthly SDK downloads, over 10,000 public MCP servers, and first-class client support already shipped inside ChatGPT, Cursor, Gemini, Microsoft Copilot, and Visual Studio Code — a list that notably includes MCP’s originator’s own direct competitors [4].

That last detail is the fact worth sitting with, because it is a fact rather than an inference: a protocol adopted natively by its author’s competitors, while still under that author’s sole governance, is an arrangement institutional participants have reasons beyond altruism to want changed. A shared specification only pays off once enough independent parties are using the same one — a dynamic economists have long formalized informally as a network externality, where a network’s value scales not with the number of participants but with the number of pairs of participants able to interoperate:

V(n)n(n1) V(n) \propto n(n-1)

This is a coarse model — it treats every pair as equally valuable and compatibility as all-or-nothing, both of which are false in practice, where a server built to one draft of the spec may or may not interoperate cleanly with a client built to another. But even in its coarse form it explains why a widely adopted specification under single-vendor control becomes a standing liability for every other adopter, and why transferring it to neutral governance is a rational response to exactly the adoption numbers Anthropic itself disclosed — not a symbolic gesture layered on top of them.

A wall-mounted board of small hanging capability tags with one tag caught mid-lift off its hook, the empty hook beside it still swinging slightly
Figure 5. A grant that is not renewed here simply stops existing — the moment a tag actually leaves its hook is the only record that it ever did.Image prompt and art direction by Brecht Corbeel; generation pending.

Three scenarios for 2035, and what would prove each one wrong

Everything above is fact and analysis, dated to what is documented as of August 2026. What follows is explicitly a different kind of claim: dated, falsifiable scenarios, none of which should be read as a forecast of what will definitely happen. Horizon for all three: year-end 2035.

Scenario one — schema convergence without transport convergence. By 2035, the JSON-Schema shape of a tool description (name, description, inputSchema) becomes a de facto lingua franca that most tool-serving systems emit in some form, even where the surrounding transport, authentication, and session model never converge on one protocol. Assumptions: the network-externality logic above continues to favor one shared description format over many incompatible ones; JSON Schema itself does not get displaced by a materially better alternative. Indicators to watch: competing agent frameworks adding native import/export of MCP-shaped tool schemas without adopting MCP’s transport; the same pattern in reverse, where MCP servers get thin wrappers exposing their tool list as OpenAI-style function definitions; standards bodies documenting schema-level compatibility as a distinct, separately tracked property from full protocol compatibility. Disconfirmed if, by 2035, describing a tool’s inputs still requires materially different schema shapes across major providers, and cross-provider tool integration still routes primarily through custom, provider-specific adapters rather than a shared description shape.

Scenario two — capability-scoped tokens become the default, not the exception. By 2035, a majority of production tool-calling deployments authorize each call against a token whose scope was negotiated for that specific operation — in the shape RFC 9396 and MCP’s step-up authorization flow already define — rather than a single broad grant approved once at connection time. Assumptions: the tool-poisoning and rug-pull findings already disclosed continue to be reproducible against new servers, keeping pressure on implementers; scoped-token issuance becomes cheap and standard enough that developers do not routinely bypass it for convenience, the way broad OAuth scopes are routinely over-requested today. Indicators to watch: MCP client conformance reports that track step-up scope usage as a measured field, not merely a specification recommendation; published incident postmortems that name “over-broad scope” rather than “no consent dialogue” as the root cause once dialogue-based consent is already standard; RFC-9396-style structured authorization appearing as a checked box in enterprise AI-procurement security questionnaires. Disconfirmed if, by 2035, the dominant authorization pattern in production tool-calling systems is still a single broad grant approved once, with per-operation scoping remaining a minority practice used mainly by security-conscious outliers rather than the default.

Scenario three — package provenance replaces registry reputation as the trust signal. By 2035, installing a tool server carries a cryptographically verifiable, machine-checked link between the published package and the identity that built it — the way code-signing already works in mature software ecosystems — as a default rather than an opt-in feature that only careful teams enable. Assumptions: the rate of supply-chain incidents like postmark-mcp and the September 2025 npm compromise continues or worsens rather than being absorbed by registries without a structural fix; the cost of adding verifiable provenance to a publishing pipeline continues to fall faster than the cost of the incidents it would have prevented. Indicators to watch: major package registries making signed provenance the default publish path rather than an optional flag; MCP server directories displaying provenance status as a first-class, checkable field rather than an unread footnote; a measurable drop in the time-to-detection for a compromised package, from the roughly ten days observed in the postmark-mcp case toward something closer to automatic. Disconfirmed if, by 2035, installing a tool server from a public registry still relies chiefly on registry reputation and after-the-fact reports rather than a checkable cryptographic link to a known publisher, and incidents of the postmark-mcp kind are still being discovered primarily by outside researchers rather than by the registry’s own verification.

Each of these is a bet about which of two already-visible pressures wins, not a claim that either pressure will vanish. Fragmentation has its own advocates, precisely because a single shared schema also becomes a single shared attack surface; ambient consent has its own advocates, because scoped tokens add real friction to legitimate, low-risk calls; registry reputation has persisted this long because provenance tooling has a real adoption cost. None of the three scenarios claims otherwise — each states the condition under which it, specifically, would be wrong.

What this is, plainly, right now

As of August 2026, a tool call is secured, where it is secured at all, by three mechanisms that do not share an enforcement point: a discovery list the server controls and can vary per credential, a natural-language description the model reads as instructions and that at least one disclosed attack class already weaponizes, and an authorization layer capable of fine-grained scoping that most deployments have not yet been shown to actually use at that granularity. The protocol specifications are explicit about the gap between what they require and what they cannot enforce — “hosts must obtain explicit user consent,” stated as a should, is not the same claim as “hosts do obtain it,” and the disclosed attacks exist precisely in that space. Whether that gap narrows by capability-scoped tokens, cryptographic provenance, and converging schemas, or persists as a permanent tax on tool-calling systems, is exactly what the three scenarios above are staked on — and each one says, in advance, what would have to be true for it to have been the wrong bet.