What to require from an MCP server vendor: a buyer’s checklist

What to require from an MCP server vendor: a buyer's checklist. A blueprint drawing of a tall sheet with a column of check boxes standing beside a small server module.

A vendor’s demo of a Model Context Protocol (MCP) server will show you an AI assistant calling its tools. That part always works in a demo. What I’d want to know before signing is everything the demo doesn’t show: whether the server works without sessions, what it does with a token, how it behaves when a user cancels, and what evidence the vendor has that any of it holds. The 2026 specification is precise about most of this, which makes it a good basis for a list of requirements.

This is part 1 of a short series for the people who buy, approve and govern MCP servers rather than build them. It draws on the same facts as my series for builders, under the 2026-07-28 specification, as I read them in October 2026, and leaves the detail to that series. MUST, SHOULD and MUST NOT in capitals are the specification’s words; where something is my advice, I say so.

MCP is an open standard that lets AI applications discover and use external tools, data and prompt templates through one common interface. The AI application you use is the host. It creates one client for each server it connects to, and the model never talks to a server directly.

In brief

  1. A compliant server is much more than a list of tools. It describes itself, handles every request without a session, tells clients how long they may cache its answers, asks for missing input without blocking, and follows the transport rules. Most of these are MUSTs, so you can require each one by name.
  2. The security requirements can be written down. A server that uses authorization is an OAuth 2.1 resource server: it validates every token, including who the token was issued for, and never forwards one. Every server MUST validate its inputs, rate-limit calls and sanitize its outputs.
  3. Operations have requirements of their own: trace context continued when the client sends it, logging moved off a deprecated channel, and a short list of metrics the vendor should be able to show you.
  4. Ask for evidence rather than assurances: the official conformance suite, tests against clients from both protocol eras, and tests in at least three hosts, one of them text-only.
  5. My advice: put the questions in writing and ask for the answers in writing. The table at the end is meant to be forwarded.

The protocol duties every server owes

The duties start with where a server sits. Your people talk to a host, the host’s runtime holds the conversation and the approvals, and a client inside the host carries requests to the server, which reaches your systems. A server can be a local process on a laptop, over standard input and output (stdio), or a remote service over Streamable HTTP in front of your application programming interfaces (APIs) and databases.

Host application: Host runtime conversation, approvals, UI, LLM, MCP client, one per server; Host runtime conversation, approvals, UI – LLM; Host runtime conversation, approvals, UI – MCP client, one per server; User – Host runtime conversation, approvals, UI; MCP client, one per server → MCP server local over stdio, or remote over Streamable HTTP: JSON-RPC; MCP server local over stdio, or remote over Streamable HTTP → Your systems APIs, databases, filesHost applicationUserHost runtimeconversation, approvals, UILLMMCP client, one per serverMCP serverlocal over stdio, or remote over Streamable HTTPYour systemsAPIs, databases, filesJSON-RPC

The 2026-07-28 revision made the protocol stateless: there is no handshake, no session and no way for a server to send a request to the client. That changes what you can require of a server. Here are the duties I’d put on the list, with the question each one turns into.

DutyWhat the specification saysWhat to ask
DiscoveryEvery server MUST implement server/discover, which advertises its protocol versions, capabilities and identityWhich protocol revisions does the server advertise?
Stateless requestsThere are no sessions. The server reads the protocol version and the client’s capabilities from each request, and every result carries a resultType (MUST)Can any instance serve any request? Where does state that outlives a request live?
Caching hintsComplete results of discovery, the list methods and resource reads MUST carry ttlMs and cacheScope (caching)What may be cached, for how long, and is anything cached across users that shouldn’t be?
TransportOver Streamable HTTP, MCP-Protocol-Version and Mcp-Method go on every request and Mcp-Name on tool calls, prompt requests and resource reads (MUST); a header that disagrees with the body is an errorCan our gateway apply policy per tool from those headers?
Asking for inputA server that needs more input returns an input_required result and the client retries with the answers (Multi Round-Trip Requests, MRTR, the one way a server may ask); the state it hands back MUST be protected when it influences logicDoes the server do anything irreversible before the user’s last answer?
CancellationOn HTTP, a dropped connection is a cancellation (MUST)What happens to work in flight when a user cancels?
InstructionsOptional: a paragraph of guidance the host may give the modelCan we read the instructions and every tool description before we connect?

Two of the smaller rules are worth a line each. A server SHOULD return its tools in a deterministic order, which keeps the hosts’ caches warm. And work that takes minutes rather than seconds belongs in the Tasks extension, where the server returns a task handle and the client polls, so nothing has to stay connected; under 2026-07-28 a dropped stream cancels the request and there is no resuming it.

Security you can write into the contract

Authorization is OPTIONAL in the specification, so the first question is whether the server uses it at all. When it does, the rule depends on the transport: an HTTP-based server SHOULD follow the MCP authorization specification, and a local stdio server SHOULD NOT, taking its credentials from the environment instead. A remote server that uses authorization is an OAuth 2.1 resource server. It accepts and validates tokens; it doesn’t issue them. Its duties:

  • It MUST publish Protected Resource Metadata (Request for Comments, or RFC, 9728), the document that tells clients which authorization server issues its tokens and which scopes it supports.
  • It MUST validate every token and check that the token was issued specifically for this server as its audience (RFC 8707), and return 401 for an invalid or expired one.
  • It MUST only accept tokens valid for its own resources, and MUST NOT accept or transit any other token. When it calls a downstream API for the user, it gets a separate token for that API, through an on-behalf-of or token-exchange flow. Your token never travels on.
  • It SHOULD name the scope the request needs in its 401 and 403 challenges, and when a valid token lacks a scope it SHOULD list every scope the operation needs in one challenge, so the client asks once. It MUST respect scope hierarchies.

Beyond authorization, the specification sets a baseline for every server. It MUST validate all tool inputs, implement access controls, rate-limit tool invocations, sanitize tool outputs, validate resource addresses and sanitize file paths, validate prompt inputs and outputs, treat the state it hands back in a round trip as attacker-controlled, and, under the Tasks extension, generate unguessable task IDs and authorize every task-related request.

My own additions are about text, because everything the model reads can steer it. Tool descriptions and instructions should be factual, with nothing that reads like “always use this server”; hosts and reviewers distrust that. Read tools should be separate from write tools, so a host can approve reads quietly and confirm writes. And no secret belongs in a skill, an instruction or a parameter mirrored into a header.

Put together, the controls form layers around every call, and a vendor should be able to say what sits at each one:

tools/call → Edge WAF, rate limits, Mcp-Method / Mcp-Name policy; Edge WAF, rate limits, Mcp-Method / Mcp-Name policy → Authentication token signature, issuer, audience, expiry; Authentication token signature, issuer, audience, expiry → Authorization scopes, per-tool policy, handle ownership; Authorization scopes, per-tool policy, handle ownership → Input validation schema, ranges, allowlists, path sanitizing; Input validation schema, ranges, allowlists, path sanitizing → Execution least-privilege delegated credentials, timeouts, quotas; Execution least-privilege delegated credentials, timeouts, quotas → Output size caps, sanitization, untrusted-content marking; Output size caps, sanitization, untrusted-content marking → Audit trace, log caller, tool, arguments hash, outcome; Audit trace, log caller, tool, arguments hash, outcome → Resulttools/callEdgeWAF, rate limits,Mcp-Method / Mcp-Name policyAuthenticationtoken signature, issuer,audience, expiryAuthorizationscopes, per-tool policy,handle ownershipInput validationschema, ranges, allowlists,path sanitizingExecutionleast-privilege delegated credentials,timeouts, quotasOutputsize caps, sanitization,untrusted-content markingAudittrace, log caller, tool,arguments hash, outcomeResult

Operations and evidence

A server you can’t observe is a server you can’t support. When a client sends OpenTelemetry trace context in a request (traceparent, tracestate and baggage, standardized by SEP-414), the server continues the trace and passes it on to everything it calls, so one trace runs from your assistant to your data. That’s a convention rather than a MUST, and one caveat goes with it: baggage comes from the client and must never decide authorization or which tenant’s data is read. MCP’s own logging channel is deprecated, so logs belong on stderr for a local server or in OpenTelemetry for a remote one.

These are the metrics I’d ask a vendor to show, and why:

SignalWhy you’d ask for it
Latency per method and tool, at the median and the tailsSlow tools hit the hosts’ timeouts before anyone notices
Error rate per tool, split into tool errors and protocol errorsTool errors show the model misusing a tool or a backend failing; a spike in protocol errors often means a schema change broke clients
Rate of input_required results per toolA high rate suggests the tool doesn’t ask for what it needs
Cancellations and client disconnectsStreams cut by intermediaries show up here first
Output size per toolHosts cap what a tool may return
Calls by client name and versionWhich hosts use the server, and where host-specific bugs live

For evidence, I’d ask what the vendor’s build pipeline checks before a release. MCP has artifacts of its own, from tool schemas to skill files, and each has rules a machine can test:

Source repo code, skills, UI, prompts → Lint and validate tool schemas, names, header rules, skill front matter; Lint and validate tool schemas, names, header rules, skill front matter → Build bundle the UI, normalize skill bytes, compute digests; Build bundle the UI, normalize skill bytes, compute digests → Test conformance suite, fake-host integration test, both protocol eras; Test conformance suite, fake-host integration test, both protocol eras → Package container image or package; Package container image or package → Deploy blue/green, statelessSource repocode, skills, UI, promptsLint and validatetool schemas, names,header rules, skill front matterBuildbundle the UI,normalize skill bytes,compute digestsTestconformance suite,fake-host integration test,both protocol erasPackagecontainer image or packageDeployblue/green, stateless

The tests I’d want named are the official MCP conformance suite, which my review of MCP testing tools records as carrying per-revision requirement sets for 2025-11-25 and 2026-07-28; an integration test against a fake host that records every message; and tests against one client from each protocol era. Beyond those, my advice is to require tests in at least three hosts, one of them text-only, because a tool whose answer is only useful as an interactive interface isn’t finished.

Both eras matter because hosts adopt protocol revisions at very different speeds. A server that only speaks 2026-07-28 will look broken in any host that hasn’t caught up, and a server that only speaks the older handshake can’t serve the hosts that have. The clean approach, which several software development kits (SDKs) take, is to decide the era per request. Ask which era each of your hosts speaks; as of October 2026, Claude Code is the only one of the seven hosts I compared that is confirmed to use 2026-07-28.

The questions, on one page

Here is the list I’d send. The last column says whether the basis is the specification or my advice.

#QuestionA good answerBasis
1Which protocol revisions does the server serve?Both the handshake era and the stateless era, decided per request, with server/discover implementedMUST for discovery; the rest my advice
2Where does state live between requests?Nowhere in the connection: explicit handles in a shared store, checked against the caller on every callThe specification removed sessions
3Does the server use authorization, and as what?Over HTTP, as an OAuth 2.1 resource server that publishes Protected Resource Metadata; locally, credentials from the environmentSHOULD, SHOULD NOT and MUST
4What does the server do with our tokens?Validates signature, issuer, audience and expiry; forwards none; gets a separate token for each downstream APIMUST and MUST NOT
5Which scopes does it ask for?The smallest set that works, then step-up, naming every missing scope in one challengeSHOULD
6What is validated and limited?All inputs, resource paths and prompt arguments; rate limits per caller; output sizes capped and outputs sanitizedMUST
7Can we read every tool description and the instructions before we connect?Yes; they’re factual, versioned, and changes are announcedMy advice
8Does the server do anything irreversible before the user’s last answer?NoMy advice
9What happens when a user cancels or a connection drops?A dropped HTTP connection cancels the request; long work runs as a task that survives itMUST; the Tasks extension
10How is the server observed?It continues our trace context, exposes the metrics above, and logs off the deprecated channelA convention; my advice
11Which tests does it pass?The official conformance suite for both revisions, a fake-host integration test, and tests in three hosts including a text-only oneMy advice
12Which deprecated features does it still use?A named list, with the date each one may be removed, and none adopted sinceThe specification’s feature lifecycle

Method and caveats

  • Built from my guide to MCP servers, written against the 2026-07-28 specification, and reframed for the people who buy and approve servers. The builder series carries the detail behind each row; product facts are as of October 2026.
  • The MUST, SHOULD and MUST NOT marks are the specification’s. The questions, the “good answers”, the metrics and the three-host test are my advice.
  • Everything here is framed from the specification. It describes no particular vendor, product or deployment.