The Short Answer
Model Context Protocol solves one problem well. It standardizes how an agent discovers and calls tools across systems you do not control, replacing custom integrations with a single interface. It does not solve context economics, tool curation, prompt injection, or authorization, and those are what decide whether your agent works in production. Use MCP at the edges, for third party services and tools other people's agents consume. Inside your own loop, a typed function call is cheaper and more stable.
What MCP Actually Standardizes
An MCP server advertises tools, resources and prompts. A client connects and calls them. That collapses the N by M problem, where every agent needs a bespoke adapter for every system, into one wire format that both OpenAI and Google implement in their own APIs.
It is also the cheapest part of building an agent. Writing an adapter for the GitHub API is a day of work. Deciding which operations your agent should see, keeping similar tools from being confused, and preventing the agent from acting on instructions an attacker planted in an issue body is the rest of the quarter.
MCP has no authorization model of its own beyond OAuth resource server conventions, and it does not verify tool provenance. The official MCP Registry launched in preview on 2025-09-08, and its own launch post states it does not provide data durability guarantees, with moderation by community flagging rather than verification. If a vendor pitches MCP as governance, decline.
The Breaking Change Most MCP Writing Predates
The current protocol revision is 2026-07-28. MCP versions are date strings marking the last date backwards-incompatible changes were made, and the prior revisions were 2024-11-05, 2025-03-26, 2025-06-18 and 2025-11-25. Four breaking revisions in twenty months is your planning assumption.
That latest revision made the protocol stateless. Per the specification changelog, it removed the initialize and notifications/initialized handshake, removed protocol-level sessions along with the Mcp-Session-Id header, and added a mandatory server/discover RPC. Every request now declares its protocol version in the _meta key io.modelcontextprotocol/protocolVersion, and the server accepts or rejects each request independently. Servers needing cross-call state now mint explicit handles passed as ordinary tool arguments.
Gone in the same revision: SSE stream resumability and redelivery, meaning the Last-Event-ID header and event IDs, plus ping and logging/setLevel. The spec says plainly that a broken response stream loses the in-flight request and clients must re-issue it with a new request ID. Roots, Sampling and Logging are formally deprecated with earliest removal at the first revision released on or after 2027-07-28, and OAuth 2.0 Dynamic Client Registration is deprecated in favor of Client ID Metadata Documents.
The rationale in SEP-2567 is caching, not deployment: the mere possibility of session-scoped tools/list forced re-fetches across every subagent and server pair even though almost no servers used the feature, and explicit handles make list endpoints cacheable. The deployment consequences are still yours to absorb, and three of them matter. A sticky-session Streamable HTTP server built against 2025-11-25 needs an infrastructure rewrite, not a version bump. Anything depending on Sampling has a known expiry date and an official migration path to calling an LLM provider API directly. And with resumability gone, a long-running tool call behind a 60-second idle timeout now fails in a way that reads as flakiness, so idempotency keys on every write tool moved from hygiene to requirement.
The Context Bill Nobody Puts in Code Review
Every MCP server you connect pushes all of its tool definitions into the system prompt on every request, before the agent reads the user's message. Anthropic published the numbers for a realistic five server setup in its advanced tool use writeup.
| Server | Approximate definition tokens |
|---|---|
| GitHub | 26,000 |
| Slack | 21,000 |
| Sentry | 3,000 |
| Grafana | 3,000 |
| Splunk | 2,000 |
| Total (58 tools) | around 55,000 |
Anthropic reports 134,000 tokens of tool definitions in its own internal systems before optimization, and its code execution with MCP writeup names the second half of the problem: intermediate result duplication, where a two-hour meeting transcript passing through context twice costs another 50,000 tokens.
This cost is invisible in code review because nobody diffs a system prompt. Teams add servers one at a time, each individually cheap to justify, then find per-request input cost has climbed with no commit to blame. Measure it and treat a new server as a budget request.
How Many Tools Can One Agent Actually Handle
Fewer than you want. Anthropic's documentation states that Claude's ability to pick the right tool degrades past 30 to 50 available tools, and recommends tool search at 10 or more tools, definitions over 10k tokens, or aggregation across multiple MCP servers.
The degradation is not graceful. Research on a deployed enterprise assistant with a 584-tool catalog, published as arXiv 2606.17519, measured routing F1 on under-specified requests dropping 16 to 23 percentage points across the models tested as the catalog scaled from 10 to 110 agents. Even with perfect retrieval the oracle ceiling fell 10 points, because the model confuses similar tools it can see. In production that looks like an agent calling list_issues when the user asked to create one, intermittently, in a way no unit test reproduces. Salesforce AI Research's MCP-Universe benchmark, run against 11 real MCP servers across 6 domains, reports GPT-5 at 43.72% success, Grok-4 at 33.33% and Claude-4.0-Sonnet at 29.44%.
Every fix that works is a mechanism for showing the model fewer MCP tools. Anthropic's Tool Search Tool moved selection accuracy from 49% to 74% on Claude Opus 4 and from 79.5% to 88.1% on Claude Opus 4.5. Programmatic Tool Calling cut token usage on complex research tasks from 43,588 to 27,297. Exposing MCP servers as filesystem-mounted code APIs took one workflow from 150,000 tokens to 2,000. Research published as arXiv 2605.24660 found a learned shortlist policy nearly matched the coverage of showing 50 tools, 90.3% against 90.8%, while showing only 7. The leading MCP optimization is hiding MCP from the model.
One caveat: deferred tools are still sent in full on every request. Deferred loading controls what enters the context window, not what crosses the wire.
MCP or a Typed Function Call: The Decision
| Situation | Build it as |
|---|---|
| Your own service, your own agent, one to one | A typed function call |
| Third party SaaS you do not control | MCP client against their server |
| A tool other people's agents will consume | MCP server you publish |
| Internal API used by three or more agent surfaces | MCP server, scoped tightly |
| Anything touching production writes | Deterministic non-LLM approval step in front |
| Large intermediate payloads between steps | Code execution over mounted APIs, not tool piping |
The rule underneath the table: MCP solves N by M wiring. When N and M are both 1, you are paying a version treadmill for an abstraction that buys you nothing. The common inversion is wrapping an internal API in MCP because it feels modern, then wiring a community server into production data because it was easy.
The Security Failures That Have Already Happened
Invariant Labs demonstrated a working exfiltration against the official GitHub MCP server in May 2025. A prompt injection planted in a public repository issue caused an agent asked to review issues to pull data from the user's private repositories and publish it in a public pull request. Invariant stated that this is not a flaw in the server code but an architectural issue at the agent system level, and that GitHub cannot fix it server-side.
The npm package postmark-mcp shipped fifteen clean versions before 1.0.16 added a single line that BCC'd every outgoing email to an attacker-controlled address. Koi Security, which found it, put the package at roughly 1,500 downloads per week and estimated 300 affected organizations. A semver-minor bump of an MCP package is an unreviewed code execution event.
Compromise also runs toward the client. CVE-2025-6514, an OS command injection in mcp-remote scoring CVSS 9.6, affected versions 0.0.5 through 0.1.15. Per the NVD entry it triggers on connecting to an untrusted MCP server, through crafted input in the authorization_endpoint response URL. Connecting is enough.
A dynamic security assessment published as arXiv 2608.00150 audited 414 internet-facing MCP servers and found 91.8% had no OAuth authentication, plus 687 tool instances exposing unauthenticated shell execution. It also found 41.6% of servers vanished within 72 hours between scans.
Prompt Injection Is Not an MCP Bug
The lethal trifecta framing from Simon Willison names the precondition exactly: access to private data, exposure to untrusted content, and the ability to communicate externally. Any agent with all three can be turned against its owner, whether it reaches its tools through MCP or plain function calling.
What MCP adds is aggravation, not causation. Willison calls it specifically problematic because it encourages mixing and matching tools from different sources, which assembles all three legs by accident. Blaming the protocol invites teams to believe a better guardrail closes the hole. Supabase wraps the SQL results its MCP server returns with instructions telling the model not to follow commands embedded in the data, and its own documentation says that mitigation is not foolproof. The recommendation it leads with is environmental instead: point the MCP server at a development project, not production. Break a leg of the trifecta architecturally or accept the exposure.
Assume the Client Enforces Nothing
The MCP tools specification puts validation, access control, rate limiting and output sanitization on the server as requirements, but puts user confirmation, input display and result validation on the client mostly as recommendations. If your users connect through Claude Desktop, Cursor or ChatGPT, you do not own the enforcement point, and your readOnlyHint annotation is a suggestion an attacker can forge. Design the server to be safe against a client that confirms nothing.
Three server-side rules from the spec's security best practices are non-negotiable. Never accept a token that was not explicitly issued for your MCP server, because token passthrough turns you into a confused deputy and produces downstream audit logs under the wrong identity. Never treat possession of a state handle as authentication: bind handles to the authenticated user, key them as user_id plus handle, and expire them, because with protocol sessions gone those handles now live in model context, transcripts, logs and prompt cache entries. And route any OAuth discovery fetch through an egress proxy blocking private and link-local ranges, since the spec documents SSRF against 169.254.169.254 as a first-class risk and warns against hand-rolling IP validation that attackers defeat with octal, hex and IPv4-mapped IPv6 encodings.
One compliance note: OpenAI's MCP documentation states that its MCP tool is compatible with Zero Data Retention and Data Residency, but that MCP servers are third party services and data sent to them is subject to their retention and residency policies. Confirming that is your job, not the vendor's. Adding a connector does not look like a procurement decision, which is why it bypasses one.
A Production MCP Checklist
- Pin exact server versions, vendor or mirror the artifact, and diff on upgrade.
- Publish the tool definition token count per environment on a dashboard.
- Turn on tool search or deferred loading before you connect another server.
- Cap the tools visible to any single agent well below the 30 to 50 threshold.
- Give every write tool an idempotency key, because agents retry.
- Put OAuth in front of any internet-reachable server, today.
- Validate the audience claim on every inbound token and reject the rest.
- Bind state handles to the authenticated user and re-authorize on every call.
- Point agents at read-only, project-scoped or anonymized data, never production writes.
- Propagate OpenTelemetry trace context through the _meta traceparent key documented in 2026-07-28, and track per-tool call volume, token cost and error rate. If you cannot say which tool burned the most tokens last week, you cannot control spend.
What This Looks Like in Practice
At SASID the pattern that survives production is a small, tightly constrained tool surface rather than a broad one. The cybersecurity platform we built runs a plain-English query engine that has been in production for over six months with zero bad queries, and that record comes from scoping what the model is allowed to express, not from a larger catalog. The same discipline holds in the call center QA system running 100% automated coverage where manual review had never exceeded 5%, and in the customer platform handling more than 30,000 reviews a day across 200+ locations.
Where This Leaves You
Adopt MCP at your edges and price the rest honestly: a breaking revision roughly every year, the token cost of every server you connect, and every third party server treated as unreviewed code holding your credentials. The protocol that makes it easy to add tools is the protocol that makes it easy to wreck your agent's accuracy.
Get a Free Technical Assessment
If you are deciding whether to build an MCP server, migrating one to the 2026-07-28 spec, or working out why an agent that demoed well now picks the wrong tool, we offer a free technical assessment: a 30-minute call about your use case, followed by a written roadmap within 48 hours covering architecture, tool surface, security posture, timeline and cost. There is no obligation, and the roadmap is yours to keep. Book at sasid.ai.