Part 2 Chapter 15 Last verified 2026-06-13 Fresh

MCP: Designing External Capability

How to wire external capability against a least-privilege, capability-negotiated protocol — and design against a known moving target. The host/client/server split and its design-time isolation, the three primitives as three control modes, the OAuth-2.1 authorization posture, and how to build to MCP's stable core while isolating what the announced 2026-07-28 release candidate changes.

Volatility: feature-surface
Tools compared: claude-codecross-tool
On this page
  1. What MCP is, and where its guarantees stop
  2. Three primitives, three control modes
  3. The authorization posture: OAuth 2.1, by design
  4. MCP is mid-transition — and that is the design problem
  5. Governance moved out of Anthropic — which is why dual-layer reading is the honest default
  6. Designing against a moving target
  7. Patterns
  8. Quick reference
  9. Practice

The previous chapter set the discipline for the tools you write yourself; this one is about the tools you reach for across a wire. MCP — the Model Context Protocol — is how an agent connects to external data and tools through a standard interface instead of a bespoke integration each time. The thesis: wire external capability against a least-privilege, capability-negotiated protocol, and treat its security properties as obligations you design to — because the spec is explicit that it “cannot enforce these security principles at the protocol level.” And because MCP is mid-transition, design against a known moving target: build to the stable core, isolate what the release candidate changes.

What MCP is, and where its guarantees stop

MCP is an open protocol whose stated job is the integration problem this volume keeps circling: it “is an open protocol that enables seamless integration between LLM applications and external data sources and tools.” [Official] Specification — Model Context Protocol · Model Context Protocol contributors (2025)T1-official original Structurally it is a JSON-RPC client–host–server model: MCP “follows a client-host-server architecture where each host can run multiple client instances,” [Official] Architecture — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original with each client bound one-to-one to a server. The host runs the model and holds the conversation; each client speaks to exactly one server.

The protocol is capability-negotiated: clients and servers declare which features they support at initialization, and “Both parties must respect declared capabilities throughout the session.” [Official] Architecture — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original Nothing is assumed to be present; everything in play is negotiated up front and honored for the session’s duration. And the architecture carries a least-privilege isolation principle — servers “should not be able to read the whole conversation, nor ‘see into’ other servers.” [Official] Architecture — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original The full conversation stays with the host; a server sees only what is routed to it.

Here is the load-bearing honesty, and it shapes the whole chapter. The spec states plainly that “While MCP itself cannot enforce these security principles at the protocol level,” [Official] Specification — Model Context Protocol · Model Context Protocol contributors (2025)T1-official original the responsibility shifts to implementers to build the consent and authorization flows. Capability negotiation, server isolation, and the auth posture in this chapter are design-time obligations, not runtime guarantees.

Three primitives, three control modes

A server exposes capability through exactly three primitives, and the design payload is that each encodes a different answer to who is in control.

Tools are model-controlled. The model itself decides when to call them: the language model can “discover and invoke tools automatically based on its contextual understanding and the user’s prompts.” [Official] Tools — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original This is the primitive that puts the agent in the driver’s seat — and so it is the one tool-minimization’s whole discipline applies to.

Resources are application-driven. They are URI-addressable read context whose inclusion the host decides, “with host applications determining how to incorporate context based on their needs.” [Official] Resources — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original The model does not reach for a resource; the application places it. Resources can be parameterized — “Resource templates allow servers to expose parameterized resources using” [Official] Resources — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original URI templates — so a single resource definition covers a family of addresses.

Prompts are user-controlled. They are templates surfaced “with the intention of the user being able to explicitly select them for use.” [Official] Prompts — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original The user picks them deliberately (a slash command, say) — neither the model nor the application invokes them autonomously.

The tool primitive also fixes two interface details worth carrying into your own server design. The error model is deliberately split: a tool-execution error is reported inside the result with isError true, and such errors “contain actionable feedback that language models can use to self-correct and retry with adjusted parameters,” [Official] Tools — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original whereas a malformed or unknown-tool request is a JSON-RPC protocol error the model is far less likely to recover from. Return business-logic failures as isError results, not protocol errors, so the model can read the feedback and retry. And tool annotations (readOnly, destructive, and the like) are advisory only: clients must “consider tool annotations to be untrusted unless they come from trusted servers.” [Official] Tools — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original An annotation is a hint, not a permission — which is the design-time-obligation theme again, applied to a single field.

The authorization posture: OAuth 2.1, by design

MCP standardizes its authorization on OAuth 2.1 — it “implements a selected subset of their features to ensure security and interoperability while maintaining simplicity:” [Official] Authorization — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original drawing on the established OAuth specification family rather than inventing a new scheme. On that baseline the spec sets four verified design requirements a remote MCP server or host builds to. Three sit on the OAuth posture; the architectural isolation principle above is the fourth, and together they are what “least-privilege by design” means in MCP.

The three OAuth requirements:

  • Resource indicators (RFC 8707). Clients MUST “implement Resource Indicators for OAuth 2.0 as defined in” [Official] Authorization — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original RFC 8707, binding a token to the canonical URI of the resource it is meant for. A token minted for server A cannot be replayed against server B, because it carries its intended audience.
  • No token passthrough. A server making upstream requests MUST NOT “pass through the token it received from the MCP client.” [Official] Authorization — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original When it needs upstream access it acts as a separate OAuth client with its own token — the client’s token never travels further than the server it was issued for.
  • Mandatory PKCE. Clients MUST implement PKCE, which “helps prevent authorization code interception and injection attacks by requiring clients to create a secret verifier-challenge pair” [Official] Authorization — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original (with the S256 method when capable), so only the original requestor can exchange an authorization code for a token.

There are four key principles in the spec’s overview — user consent and control, data privacy, tool safety, and sampling controls — and the same caveat governs all of them: the protocol asks implementers to honor them; it does not enforce them on the wire. [Official] Specification — Model Context Protocol · Model Context Protocol contributors (2025)T1-official original

MCP is mid-transition — and that is the design problem

The current authoritative revision is 2025-11-25, and it is genuinely current. But MCP is at a dated inflection point, and a responsible design accounts for it rather than pretending the spec is static.

Today the protocol is stateful. The lifecycle opens with an initialize handshake that MUST “be the first interaction between client and server,” [Official] Lifecycle — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original inside which client and server negotiate a protocol version. The transport layer defines two standards — stdio, which clients SHOULD “support stdio whenever possible,” [Official] Transports — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original and Streamable HTTP, where the server MAY “assign a session ID at initialization time” [Official] Transports — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original via an Mcp-Session-Id header the client then echoes on every request. That session ID is the protocol-level session.

The announced 2026-07-28 release candidate prunes much of this toward a stateless core — applying the volume’s subtract-first instinct to the protocol itself. The following are announced for 2026-07-28, not current; recheck each after that date:

  • The initialize/initialized handshake is removed (SEP-2575). [Official] The 2026-07-28 MCP Specification Release Candidate · David Soria Parra and Den Delimarsky (Lead Maintainers)T1-official original
  • The Mcp-Session-Id header and the protocol-level session are removed (SEP-2567). [Official] The 2026-07-28 MCP Specification Release Candidate · David Soria Parra and Den Delimarsky (Lead Maintainers)T1-official original
  • A formal feature-lifecycle policy deprecates Roots, Sampling, and Logging with “at least twelve months between deprecation and the earliest possible removal.” [Official] The 2026-07-28 MCP Specification Release Candidate · David Soria Parra and Den Delimarsky (Lead Maintainers)T1-official original
  • Tasks becomes a server-directed extension and tasks/list “is removed because it can’t be scoped safely without sessions.” [Official] The 2026-07-28 MCP Specification Release Candidate · David Soria Parra and Den Delimarsky (Lead Maintainers)T1-official original (Tasks exists today as an in-core experimental feature, added in the current revision “to enable tracking durable requests with polling and deferred result retrieval.” [Official] Key Changes (Changelog) — MCP Specification 2025-11-25 · Model Context Protocol maintainers (2025)T1-official original )
  • A new MCP Apps extension “lets servers ship interactive HTML interfaces that hosts render in a sandboxed iframe” (SEP-1865). [Official] The 2026-07-28 MCP Specification Release Candidate · David Soria Parra and Den Delimarsky (Lead Maintainers)T1-official original
  • An Extensions framework where “extensions are identified by reverse-DNS IDs, negotiated through an extensions map on client and server capabilities, live in their own ext-* repositories with delegated maintainers, and version independently of the specification” (SEP-2133). [Official] The 2026-07-28 MCP Specification Release Candidate · David Soria Parra and Den Delimarsky (Lead Maintainers)T1-official original

Governance moved out of Anthropic — which is why dual-layer reading is the honest default

The reason “current plus announced-coming” is the right way to hold MCP, rather than a quirk, is that the protocol no longer has a single vendor steering it. In December 2025, “Anthropic is donating the Model Context Protocol to the Linux Foundation,” [Official] Donating the Model Context Protocol and establishing the Agentic AI Foundation · Anthropic (2025)T1-official original establishing the Agentic AI Foundation. The donation came with a continuity assurance: the governance model “will remain unchanged: the project’s maintainers will continue to prioritize community input and transparent decision-making.” [Official] Donating the Model Context Protocol and establishing the Agentic AI Foundation · Anthropic (2025)T1-official original

Development now runs through an open process. The current revision moved to “Formalize Working Groups and Interest Groups in MCP governance” (SEP-1302), [Official] Key Changes (Changelog) — MCP Specification 2025-11-25 · Model Context Protocol maintainers (2025)T1-official original and the 2026 roadmap confirms that “Working and Interest Groups are now the primary vehicle for protocol development.” [Official] The 2026 MCP Roadmap · David Soria Parra (Lead Maintainer) (2026)T1-official original The maintainers are candid about what that means for predictability: “A release-oriented roadmap implies a level of predictability that open-standards work rarely has.” [Official] The 2026 MCP Roadmap · David Soria Parra (Lead Maintainer) (2026)T1-official original

Designing against a moving target

Put the two halves together — a stable conceptual core, a churning transport-and-feature surface — and the design rule writes itself: build to the stable core, isolate what the RC changes behind adapters.

The durable parts are the conceptual ones: the host/client/server architecture Architecture — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original and the three-primitive control model Tools — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original are not what the RC touches. Design your integration’s shape against those and it survives the transition. The parts in motion are the mechanical ones — the transport and lifecycle (the handshake, the session ID) Transports — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original Lifecycle — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original heading toward a stateless core, and Tasks Key Changes (Changelog) — MCP Specification 2025-11-25 · Model Context Protocol maintainers (2025)T1-official original heading out of core into an extension. Wrap exactly those behind a thin adapter so the migration, when it lands, is contained to one seam instead of smeared across the codebase.

MCP's host/client/server split with capability negotiation and the three primitives. The host runs the model and holds the full conversation; each client is bound one-to-one to a server, declaring and respecting negotiated capabilities for the session. Servers do not see into one another. Each server exposes capability through three primitives that encode three control modes: tools (model-controlled), resources (application-driven), prompts (user-controlled). The isolation shown is a design-time obligation the spec asks implementers to honor, not a property the protocol enforces.On the left, a gray 'Host (runs the model)' box containing client A and client B, annotated 'full conversation stays here'. Two double-headed arrows labelled 'capability negotiation' link client A to Server A and client B to Server B (teal boxes) one-to-one, with a dashed line between the servers annotated 'servers do not see into each other'. On the right, three orange primitive boxes branch off a server: tools (model-controlled), resources (app-driven), prompts (user-controlled), annotated 'three primitives = three control modes'.
MCP's host/client/server split with capability negotiation and the three primitives. The host runs the model and holds the full conversation; each client is bound one-to-one to a server, declaring and respecting negotiated capabilities for the session. Servers do not see into one another. Each server exposes capability through three primitives that encode three control modes: tools (model-controlled), resources (application-driven), prompts (user-controlled). The isolation shown is a design-time obligation the spec asks implementers to honor, not a property the protocol enforces.

Patterns

Pick the primitive by control authority. Sketch: map each capability to tool / resource / prompt by who should trigger it. When to use: designing any server’s surface. Tools — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original Mechanics: model-initiated → tool; app-placed read context → resource (template it); user-selected → prompt. Remember: a model-controlled tool hands the model initiative — if the user should decide, that is the wrong primitive.

Design to least-privilege auth. Sketch: OAuth 2.1 with audience-bound tokens, no passthrough, mandatory PKCE. When to use: any remote MCP server. Authorization — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original Mechanics: RFC 8707 resource indicators bind the token; the server uses its own upstream token; PKCE (S256) on every client. Remember: it is the posture you implement, not the threat model — and the protocol does not enforce it for you.

Return self-correctable errors. Sketch: report business-logic failures inside the result, not as protocol errors. When to use: any tool that can fail on bad input. Tools — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original Mechanics: set isError true and include actionable feedback; reserve JSON-RPC errors for malformed/unknown requests. Remember: an isError result is something the model can read and retry; a protocol error usually is not.

Isolate by design, host-side. Sketch: keep the full conversation in the host; route only the relevant slice to each server. When to use: always — especially with multiple servers. Architecture — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original Mechanics: one client per server, capabilities negotiated and respected; no cross-server visibility. Remember: the spec “cannot enforce these security principles at the protocol level” — isolation is your obligation.

Build to the core, wrap the churn. Sketch: design the shape against the stable architecture/primitives; adapter-wrap transport, lifecycle, and Tasks. When to use: any integration meant to outlive the 2026-07-28 RC. The 2026-07-28 MCP Specification Release Candidate · David Soria Parra and Den Delimarsky (Lead Maintainers)T1-official original Mechanics: one seam for the stateful-vs-stateless transition; recheck the RC mechanisms after 2026-07-28. Remember: a diffuse stateful assumption is a migration; an isolated one is a one-file change.

Quick reference

  • What MCP is: an open, JSON-RPC, capability-negotiated client–host–server protocol for connecting agents to external data and tools. Specification — Model Context Protocol · Model Context Protocol contributors (2025)T1-official original Architecture — Model Context Protocol Specification 2025-11-25 · Model Context Protocol contributors (2025)T1-official original
  • The honesty: the spec “cannot enforce these security principles at the protocol level” — isolation, negotiation, and auth are design-time obligations, not runtime guarantees. Specification — Model Context Protocol · Model Context Protocol contributors (2025)T1-official original
  • Three primitives = three control modes: tools (model-controlled), resources (app-driven), prompts (user-controlled) — choose by who holds the trigger. Tools — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original Resources — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original Prompts — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original
  • Tool interface: isError results carry self-correctable feedback (distinct from protocol errors); annotations are untrusted unless the server is. Tools — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original
  • Auth posture (four principles): OAuth 2.1 + RFC 8707 resource indicators + no token passthrough + mandatory PKCE — the posture, not the threat model. Authorization — Model Context Protocol Specification (revision 2025-11-25) · Model Context Protocol contributors (2025)T1-official original
  • Mid-transition: today stateful (initialize handshake, Mcp-Session-Id); the 2026-07-28 RC announces a stateless core, deprecation policy, Tasks-as-extension, MCP Apps, and an Extensions framework — announced, recheck after 2026-07-28. The 2026-07-28 MCP Specification Release Candidate · David Soria Parra and Den Delimarsky (Lead Maintainers)T1-official original
  • Governance: donated to the Linux Foundation (Agentic AI Foundation, Dec 2025); developed through Working Groups — trackable, not vendor-scheduled. Donating the Model Context Protocol and establishing the Agentic AI Foundation · Anthropic (2025)T1-official original The 2026 MCP Roadmap · David Soria Parra (Lead Maintainer) (2026)T1-official original
  • Design rule: build to the stable core; isolate what the RC changes behind an adapter.

Practice

Exercise solutions

Solution ↑ Exercise

The justifying line is the spec’s own: “While MCP itself cannot enforce these security principles at the protocol level,” — the protocol acknowledges it cannot guarantee the consent, isolation, and authorization properties on the wire, and shifts responsibility to the implementer. Once you accept that, you stop assuming the protocol isolates servers or scopes tokens for you and start building those properties yourself: the host must actually keep the full conversation and route only the relevant slice to each server, the server must actually implement audience-bound tokens and no-passthrough, and you treat any “the protocol does X” claim as “I must build X.” Treating the protocol as self-enforcing is the failure mode — it leaves the isolation and auth you assumed were present simply unbuilt.

Solution ↑ Exercise

(a) Fetch the diff → resource. It is URI-addressable read context the application decides to surface (e.g. a template like pr://{id}/diff); the model does not “act,” it reads context the host places. (b) Post an inline review comment → tool. It is an action the agent should take in context based on its understanding of the diff — model-controlled is exactly right. (c) Summarize for the release notes → prompt. The human editor invokes it deliberately; making it a model-controlled tool would hand the model an initiative meant to stay with the user. The assignment is by who holds the trigger (application / model / user), not by whether the payload is text or structured. The OAuth requirement that most directly stops token replay is RFC 8707 resource indicators: they bind the token to the canonical URI of this server as its intended audience, so a token minted here carries an audience that a different internal service will reject — replay fails because the token says who it is for. (No-passthrough is the complementary rule, but it governs the server’s upstream calls rather than replay of the token issued to this server.)

Solution ↑ Exercise

Design the integration’s shape against MCP’s stable conceptual core — the host/client/server architecture and the three-primitive control model — because those are not what the RC touches; an integration whose structure rests on them survives the transition unchanged. Wrap the mechanical, in-motion parts behind a single thin adapter: the transport and lifecycle (the initialize handshake and Mcp-Session-Id session) and Tasks, which are exactly what the stateless core and the Tasks-extension graduation change. With that seam in place, the announced stateless-core change is a one-file swap behind the adapter rather than a stateful assumption you have to chase through the whole codebase. The dual-layer reading is the honest default precisely because MCP is now an open-standards protocol developed through Working Groups rather than a vendor-scheduled product — the maintainers themselves note “a release-oriented roadmap implies a level of predictability that open-standards work rarely has,” so the responsible stance is to hold what is authoritative now and what is announced coming with a recheck date together, and to make the moving parts findable rather than assume a frozen spec.