AI DevelopmentPlaybook12 min readPublished October 31, 2026

Three documents · eleven mistakes · no audit claims

MCP Server Design Mistakes the Spec Itself Warns About

The Model Context Protocol specification, its security best-practices page and Anthropic's guide to writing tools each name design choices that break servers. Most are not exotic attacks. They are shortcuts that feel reasonable the first time: forwarding a token, publishing every scope, trusting a handle, returning the whole record. This post lists eleven, with the rule each one breaks and the fix the source gives.

DA
Digital Applied Team
Senior strategists · Published October 31, 2026
PublishedOct 31, 2026
Read time12 min
SourcesMCP spec · Anthropic · OWASP
Spec revision read
2026-07-28·
the current revision as of November 5, 2026
Server-side MUSTs at the core
6·
more MUSTs bind clients; the rest are SHOULD or vendor advice
Features deprecated in July
5·
old tutorials still recommend some of them
Servers we tested for this
0·
documentation only, as read on November 5

The Model Context Protocol, the open standard most AI agents now use to call external tools, is specific about how a server should not be built. Its specification, revised on July 28, 2026, carries MUST and MUST NOT rules for tokens, scopes, consent and state. Its security best-practices page names the anti-patterns behind those rules. And Anthropic's engineering guide to writing tools for agents covers the mistakes the spec does not police: tool surfaces that confuse the model rather than the attacker.

This post is a reading of those three documents, plus the OWASP MCP Top 10 project as a cross-reference, organised by mistake rather than by section. It is deliberately not a security hardening guide; our MCP server security best practices guide covers the controls to deploy. This one is about the design decisions that make those controls necessary or impossible, taken at the point where a developer chooses how tokens flow, what a scope means, and what a tool returns.

One scope note before the list. Everything here is what the documents say, read on November 5, 2026. We have not tested any server, and we do not claim to know how often any of these mistakes occurs in the wild.

Key takeaways
  1. 01
    Six of the mistakes break a server-side MUST in the spec.Token passthrough, missing audience validation, treating a handle as authentication, proxies without per-client consent, unvalidated inputs and unsanitised outputs are all spelled out as MUST or MUST NOT. Others break a MUST on the client side or for structured output; the rest break a SHOULD or Anthropic's guidance.
  2. 02
    The July 2026 revision changed what the mistakes are.The 2026-07-28 spec went stateless: no session ID, no initialize handshake. Session-hijacking advice is replaced by state-handle hijacking, and Dynamic Client Registration, Roots, Sampling, Logging and the HTTP+SSE transport are deprecated.
  3. 03
    Scope design is where consent fails quietly.Among the security page's listed mistakes are publishing every scope in scopes_supported, using wildcard or omnibus scopes, and trusting a token's claimed scopes without server-side checks. Clients that receive no scope challenge ask for everything.
  4. 04
    Tool errors belong in results, not in the protocol.The tools page separates input-validation and business-logic failures, returned as results with isError set so the model can correct itself, from protocol errors for unknown tools and malformed requests. Anthropic's guide adds: make the error text actionable.
  5. 05
    The spec cannot enforce most of this.Its own overview says MCP cannot enforce these principles at the protocol level and that implementors should build consent and authorization flows into their applications. The rules are a checklist, not a guardrail.

01 — The SourcesWhere the rules come from.

Three documents carry the weight, and they have different authority. The MCP specification is normative: its MUST and SHOULD keywords have their RFC meanings, and the current revision is 2026-07-28. The security best-practices page is informational but names specific anti-patterns and the rule each one violates. Anthropic's guide to writing effective tools for agents, published September 11, 2025, is vendor advice about usability rather than a standard.

The spec's own framing sets the tone. Its overview states that tools "represent arbitrary code execution and must be treated with appropriate caution", that hosts must obtain explicit user consent before invoking any tool, and that tool annotations "should be considered untrusted, unless obtained from a trusted server". The tools page adds that there "SHOULD always be a human in the loop with the ability to deny tool invocations". Those three sentences explain why most of what follows is phrased as a server obligation: the host is expected to distrust you.

Sources as read on November 5, 2026. The security best-practices page was served from the draft path and references both the 2026-07-28 behaviour and earlier protocol versions.
DocumentStatusWhat it governs here
MCP specification, 2026-07-28Normative, current revisionAuthorization, tools, tool-list and error semantics
Security best practicesInformational, draft pathNamed anti-patterns: passthrough, confused deputy, scope minimisation, state handles, local servers, SSRF
Anthropic, writing tools for agentsVendor guidance, Sep 11, 2025Tool count, naming, response shape, error text, parameters
OWASP MCP Top 10Project page, marked betaRisk categories used as a cross-reference only

02 — AuthorizationTokens that were never yours.

The first mistake is the one the security page calls an anti-pattern by name: token passthrough. A server receives an access token from the client, does not check who the token was issued to, and forwards it to the downstream API it wraps. It is tempting because it works on the first try and removes a whole OAuth flow. The authorization spec forbids it twice over. Servers "MUST validate that access tokens were issued specifically for them as the intended audience", and servers "MUST NOT accept or transit any other tokens".

Why the rule is absolute is in the page's list of consequences. A passed-through token lets the caller bypass whatever rate limits and validation the downstream API expected the server to apply. It breaks the audit trail, because the downstream service sees a token and not the server that should have been accountable for the call. And a stolen token can use the server "as a proxy for data exfiltration", in the page's words, since nothing in the chain checks that the token and the server were meant for each other.

The fix is mechanical: check the audience claim against your own identifier, which the spec ties to RFC 8707 resource indicators, and obtain a separate downstream token for the API you wrap rather than reusing the one you were handed. The second mistake hides inside the fix. A server that validates the audience but then puts the token in a URL query string has broken another MUST NOT; tokens travel in headers only.

03 — Least PrivilegeScopes that cover everything.

Scope design is where good intentions produce the broadest tokens. The security page asks servers to implement what it calls a progressive, least-privilege scope model: a minimal initial set, with elevation granted per operation through a targeted challenge in the WWW-Authenticate header. The authorization spec backs it: on insufficient scope a server responds 403 with an insufficient_scope error and should list every scope the operation needs in one challenge, so the client does not loop.

The page then lists the mistakes it sees, and they are worth reproducing because each is a default someone will reach for.

Mistake · scopes_supported
Publishing every possible scope in metadata
Allscopes

The spec nuance that makes this costly: when a server issues no scope challenge, clients fall back to requesting everything in scopes_supported. Over-publishing therefore widens what every client asks for on day one.

Security best practices · scope minimisation
Mistake · omnibus scopes
Wildcard or full-access scopes
*all

The page names *, all and full-access as the pattern to avoid. Its stated consequence is an expanded blast radius: one stolen broad token reaches unrelated tools and resources.

Security best practices · scope minimisation
Mistake · trusting claims
Treating a token's claimed scopes as sufficient
0checks

A scope in a token is a claim, not an authorization decision. The page lists treating claimed scopes as sufficient without server-side logic as a mistake, and asks for elevation events to be logged with correlation IDs.

Security best practices · scope minimisation
Consequence the page names
Consent abandonment
Declineddialogs

Users decline consent screens that list excessive scopes. The page lists this beside audit noise and blast radius: a scope model that asks for too much loses the consent it needed.

Security best practices · scope minimisation

The example that makes this concrete is a CRM connector. A read-only baseline scope lets the model search and read; the first tool that writes a record triggers a challenge for the write scope, the user sees exactly which privilege is being added, and the elevation is logged. The failure case is the same connector shipped with a single crm:full scope because it was faster to build, where the first prompt-injected tool call has every privilege the user ever granted.

04 — StateA handle is a name, not a login.

This mistake is new, because the protocol it applies to is new. The 2026-07-28 revision made MCP stateless: per its changelog there is no session identifier and no initialize handshake. Servers that need continuity across calls mint a handle, such as a cart ID or a workflow ID, and the model passes it back as a tool argument. The mistake is to treat the handle as proof that the caller owns the state it names.

The security page is explicit: servers "MUST NOT treat possession of a state handle as authentication". The tools page puts the same idea in plain words, that a handle is a name, not a capability. The consequence the page gives is direct: an attacker who guesses or obtains the handle can access or modify another user's state. The fix has three parts. Generate handles with a secure random generator so they cannot be guessed. Bind each handle server-side to the authenticated user, which the page illustrates as keying stored state by user ID and handle together, with the user ID taken from the verified token rather than supplied by the client. And expire them, returning a tool error on an unknown or expired handle so the model can recreate the state rather than fail silently.

The failure case is the sequential ID. A server that numbers carts 1001, 1002, 1003 and checks nothing else has given every caller a way to read every cart by counting. It is a classic web-application bug, re-created because the stateless protocol moved state into tool arguments and nobody re-read the rule.

05 — ConsentOne client ID for everyone.

Many MCP servers are thin proxies in front of a third-party API, and the convenient way to build one is to register a single OAuth client with that API, let any MCP client register dynamically, and rely on the third party's consent cookie to remember that the user already approved the proxy. The security page describes this as the confused deputy problem, and its consequence: malicious clients can obtain authorization codes without proper user consent and then impersonate the user, because the third party sees only the proxy's static client ID and skips the consent screen.

The rule is a MUST: proxy servers "MUST implement per-client consent and proper security controls". The page then specifies the consent screen the proxy must own itself. It names the requesting MCP client, shows the specific third-party scopes, shows the registered redirect URI, and carries CSRF and anti-framing protection. Redirect URIs are matched by exact string, never by pattern or wildcard. The OAuth state value is single-use, short-lived, and not set until after the user approves. Consent cookies, if used, carry the __Host- prefix with Secure, HttpOnly and SameSite=Lax.

A related mistake is older advice. Dynamic Client Registration was the default way for clients to introduce themselves, and the 2026-07-28 changelog deprecates it in favour of Client ID Metadata Documents, keeping it only for backwards compatibility. A tutorial written in 2025 will still tell you to enable it. The spec also notes the limit of the replacement: a metadata document proves control of a domain but cannot prove which local process is listening on a localhost redirect URI, which is why the per-client consent screen matters even after the migration.

Mix-up attacks, for client authors
Two more MUSTs apply to anyone writing the client side of the flow. The client must record the authorization server's issuer before redirecting and validate the iss parameter in the response, per RFC 9207, before sending the code anywhere; the page notes that PKCE alone does not prevent this attack because the client would send its verifier to the attacker's token endpoint. And clients must only open http and https URLs, must reject javascript, data, file and vbscript schemes, and must not use a shell to open them.

06 — Tool SemanticsThe tool contract, and the error that belongs in the result.

The tools page carries four server obligations in one list, all MUST: validate all tool inputs, implement proper access controls, rate limit tool invocations, and sanitise tool outputs. The mistakes are the omissions. A server that trusts the model to send well-formed arguments has no input validation. A server with no per-caller rate limit lets a looping agent run a bill or a denial of service. A server that returns raw downstream content has no output sanitisation. On the client side, the spec asks hosts to show tool inputs to the user before calling a server, to avoid malicious or accidental data exfiltration.

Structured output is the part most servers skip. When a tool declares an output schema, the spec says servers "MUST provide structured results that conform to this schema". Declaring the schema and then returning free text under it is a contract violation that clients are entitled to reject.

The subtler mistake is where errors go. The spec splits them. Input-validation and business-logic failures are results with isError set to true, so the model can read the message and correct itself. Protocol errors are reserved for unknown tools and malformed requests. A server that raises a protocol error when a date is out of range has taken the one failure the model could have fixed and turned it into one it cannot see. The router below is how we read the spec's split.

An argument is missing, malformed or out of range
Return a result with isError: true and a message that says which field and what would be valid. The model retries.
Tool result
The call is valid but the operation cannot proceed
Same route: a tool result with isError and the reason, such as a handle that expired or a record that no longer exists.
Tool result
The tool name does not exist on this server
A protocol error. The request was malformed at the protocol level and the model cannot fix it by changing arguments.
Protocol error
The caller lacks the scope the tool needs
An HTTP 403 with insufficient_scope and the full list of required scopes in one WWW-Authenticate challenge, so the client can elevate once.
HTTP challenge

07 — UsabilityToo many tools, too little signal.

The spec polices safety. Anthropic's guide polices whether the model can use the server at all, and its mistakes are the ones a security review never flags. The guide's thesis is that a tool is an interface for a model, not a wrapper around an endpoint, and that the design question is what a new colleague would need to be told. Five patterns from it, each with the spec detail that agrees.

Too many tools
Overlapping tools that mirror your API
Consolidate

Anthropic's guide says too many or overlapping tools can distract agents from efficient strategies, and gives the example of one schedule_event tool that finds availability and books, instead of separate list and create tools. The spec adds that tools/list should return a deterministic order, which improves prompt cache hit rates.

Anthropic guidance
Unclear boundaries
Names that collide across servers
Namespace

The guide recommends grouping related tools under common prefixes, such as asana_search beside jira_search. The spec agrees from the other side: aggregators should prefix tool names with a server identifier to disambiguate. Names should be 1 to 128 characters of letters, digits, underscore, hyphen and dot.

Anthropic guidance · spec
Noisy responses
Returning the whole record
High signal only

Return only high-signal information and leave out low-level technical identifiers, the guide says; it suggests a response_format parameter with concise and detailed options. Unbounded outputs need pagination, range selection, filtering or truncation with sensible defaults.

Anthropic guidance
Opaque errors
Tracebacks and error codes
Actionable text

The guide asks you to prompt-engineer error responses so they state a specific, actionable improvement, rather than returning opaque codes or stack traces. The spec's isError route is the mechanism; the guide is about what the message says.

Anthropic guidance · spec
Vague parameters
A parameter called user
user_id

The guide's example is literal: a parameter named user_id over one named user. Describe each tool as you would to a new hire. One spec caution on parameters: do not mark sensitive ones for header transport, because header values are visible to network intermediaries.

Anthropic guidance · spec

The failure case for this whole section is a server that exposes forty endpoint-shaped tools, each returning full JSON, each named after the REST route. It passes every security check in the sections above and the model still picks the wrong tool, pages through irrelevant fields and gives up on the third error. Our MCP server build tutorial walks through the opposite shape; the MCP Inspector workflow is how you see what the model sees.

08 — Trust BoundariesLocal servers, one-click installs and untrusted descriptions.

Two more mistakes sit at the edge of the server's own code. The first is a local server that listens on HTTP. The security page says servers meant to run locally should use the stdio transport, which limits access to the MCP client that launched them, or else protect an HTTP listener with an authorization token or a Unix socket. Its stated risks for local servers are arbitrary code execution, data exfiltration by compromised JavaScript (DNS rebinding is the named attack on a server left running on localhost), and irrecoverable data loss. Clients with one-click local setup must show the exact command they will run, without truncation, and obtain consent before executing it.

The second is trust in the other direction. The spec says clients "MUST consider tool annotations to be untrusted unless they come from trusted servers". A server author who relies on a readOnlyHint annotation to persuade the host to skip confirmation has built on a claim the host is required to ignore. OWASP's MCP Top 10 lists the attack this guards against as tool poisoning, which it defines as "an adversary compromises the tools, plugins, or their outputs". The documented cases are in our MCP security incident ledger, and one scored 9.0 under CVSS 3.1 (6.4 under 4.0) with no public fix documented, which we covered in our Context7 CVE report.

The honest limit of the list is the one the spec states about itself: it cannot enforce these principles at the protocol level. Only one party in the chain, the host, is in a position to deny a tool call, and the spec asks for that human in the loop with a SHOULD. Everything above is therefore a design obligation the server author either meets or does not, and nothing in the wire format will tell them which. If you want that checked before a server ships, it is part of what our AI transformation engagements cover.

09 — ConclusionThe spec wrote the review; nobody is required to run it.

The finding, October 31, 2026

Check the six MUSTs before shipping, re-read the July 2026 changelog before trusting a tutorial, and design the tool surface for the model, not the endpoint.

Eleven design mistakes, all named in public documents. Six break a server-side MUST in the Model Context Protocol specification: forwarding tokens not issued to the server, skipping audience validation, treating a state handle as authentication, fronting a third-party API without per-client consent, and leaving inputs unvalidated or outputs unsanitised. Most of the others break a SHOULD, such as progressive scopes and stdio for local servers, or Anthropic's usability guidance on tool count, naming, responses and errors.

The 2026-07-28 revision matters because it moved the targets. Stateless operation turned session hijacking into handle hijacking, and five features that older tutorials still teach, including Dynamic Client Registration and the HTTP+SSE transport, are now deprecated with a twelve-month window. A server built from a 2025 guide can be correct for a protocol that no longer exists.

What the documents cannot do is run the review for you. The spec says so. Treat the MUSTs as a release gate, the SHOULDs as the next sprint, and the tool-surface guidance as the difference between a server the model can use and one it merely can call.

Ship a server the spec would pass

A MUST in the spec is a release gate.

We review MCP servers against the current specification and Anthropic's tool guidance before they ship: token flow, scope model, state handling, consent screens and the tool surface the model actually sees.

Free consultationExpert guidanceTailored solutions
What we work on

MCP server design reviews

  • →Authorization flow review against the 2026-07-28 spec
  • →Scope models that elevate per operation
  • →State handle design for the stateless protocol
  • →Tool surface design and error text for the model
  • →Deprecation sweeps for pre-July patterns
FAQ · MCP server design

The questions we get every week.

Token passthrough is accepting an access token from an MCP client without verifying it was issued to your server, then forwarding it to the downstream API. The MCP authorization specification says servers MUST validate that tokens were issued specifically for them as the intended audience and MUST NOT accept or transit any other tokens. The security best-practices page calls it an anti-pattern and lists the consequences: bypassed rate limits and validation, a broken audit trail, and a stolen token usable through the server as a proxy for data exfiltration. The fix is audience validation plus a separate downstream token.
Digital Applied newsletter

Deep dives on AI, marketing and development.

Practical guides and fresh insights by email. No recycled takes.

Related dispatches

Continue exploring MCP server design.

AI Development

1,000 Public MCP Servers Checked: 55% Complete a Handshake

We sent an unauthenticated initialize to 1,000 remote MCP servers sampled from the official registry on Nov 5, 2026: 55% answered, 34% asked for credentials.

November 5, 2026 · 13 minRead
AI Development

MCP Adoption Statistics 2026: Registry, SDK and CVE Data

MCP adoption statistics for 2026: official registry counts, npm and PyPI SDK downloads, platform support, enterprise survey results and NVD vulnerability data.

April 20, 2026 · 11 minRead
AI Development

The MCP Security Incident Ledger: 27 Dated Entries

A dated ledger of 27 MCP security entries — 25 incidents plus 2 protocol revisions — April 2025 to August 2026: component, defect class, route, patch status.

August 24, 2026 · 15 minRead
AI Development

CrewAI Quietly Fixed an SSRF Gap Agent Fetch Tools Can Share

CrewAI 1.15.17 pins SSRF checks to every redirect hop and the resolved peer IP. The same pattern can sit in any agent tool that fetches a model-supplied URL.

August 20, 2026 · 18 minRead
AI Development

Agentic AI RBAC: Design Patterns + Implementation 2026

Role-based access control for agentic AI — six design patterns, per-tool scoping, per-tenant isolation, attribute-based extensions. Implementation included.

May 9, 2026 · 13 minRead
AI Development

AI Agent Marketplaces 2026: Discovery and Distribution

AI agent marketplace landscape — Claude Skills, GPT Store, MCP Hubs, Hugging Face Spaces, Replit Agent Market. Distribution strategy for agency builds.

April 16, 2026 · 16 minRead
Google Search

See more Digital Applied analysis in your Google results by adding us as a preferred source.

Add as a preferred source