The MCP server author’s checklist

The MCP server author's checklist

Thirty-four parts is a lot to hold in your head while you build. So this last part folds the series into one page: a checklist to keep beside a pull request, each item linked to the part that explains it, the seven ideas I’d keep, and what I’m watching next.

This is part 35 of my series on what a Model Context Protocol (MCP) server does under the 2026-07-28 specification, and the last, after part 34’s reference architecture. The facts are as I read them in October 2026.

In brief

  1. An MCP server in 2026 is a small, well-defined platform, not a list of tools: five layers, from its protocol duties to its extensions.
  2. A MUST, SHOULD, MUST NOT or SHOULD NOT in the checklist is the specification’s word; the other checks are practice I recommend, across eight areas from the protocol core to compatibility.
  3. Deprecations run on more than one clock. Roots, sampling and logging can go no earlier than the first revision on or after 2027-07-28, the HTTP with Server-Sent Events (HTTP+SSE) transport sooner, and Dynamic Client Registration gives way to Client ID Metadata Documents.
  4. Extensions sit on top of a core that works everywhere, and your telemetry shows which of them your users’ hosts support.

The series on one page

An MCP server in 2026 describes itself through server/discover and handles every request on its own terms, reading the protocol version, capabilities and identity from _meta, and trace context when the client sends it. It tells clients how long they can cache what it says, asks for missing input with Multi Round-Trip Requests (MRTR) without holding a connection open, reports progress, and stops when told to.

When it uses authorization over HTTP, it validates every token as an OAuth resource server and never forwards one. It offers tools to the model, resources to the application and prompts to the user, and where both sides agree it goes further: it renders interfaces, runs long jobs and ships whole workflows as verified skills.

Protocol duties discover, instructions, stateless _meta, caching, transports → Server features tools, resources, prompts, completion; Server features tools, resources, prompts, completion → Interaction patterns MRTR, elicitation, progress / cancel, subscriptions; Interaction patterns MRTR, elicitation, progress / cancel, subscriptions → Security and operations OAuth resource server, OpenTelemetry, threat model, versioning; Security and operations OAuth resource server, OpenTelemetry, threat model, versioning → Extensions Apps, Tasks, Skills, Auth, ExperimentalProtocol dutiesdiscover, instructions, stateless _meta,caching, transportsServer featurestools, resources, prompts, completionInteraction patternsMRTR, elicitation, progress / cancel,subscriptionsSecurity and operationsOAuth resource server, OpenTelemetry,threat model, versioningExtensionsApps, Tasks, Skills, Auth, Experimental

Each band covers a run of parts, top to bottom: parts 3 to 7, parts 8 to 12, parts 13 to 17, parts 18 to 22 and parts 23 to 29. Part 1 and part 2 set the scene, and parts 30 to 34 put it together.

The checklist

Here is my guide’s checklist, condensed. The marks in capitals are the specification’s words. The unmarked checks are practice I recommend, though some are the specification’s rules too; the part in the last column has the detail.

Protocol core

CheckPart
Implement server/discover with supportedVersions, capabilities, ttlMs and cacheScope (MUST), and the optional instructionsPart 3
Read protocolVersion and clientCapabilities from _meta on every request, and never cache them per connection (MUST)Part 5
Return -32021 (MUST, with status 400 on HTTP) when the operation needs a capability the request didn’t declare, and -32022 for a protocol version you can’t servePart 3, part 5
Identify the server with serverInfo in each result’s _meta (SHOULD), and log clientInfoPart 3
Set resultType on every result (MUST)Part 5
Add ttlMs and cacheScope to complete results of server/discover, the four list methods and resources/read (MUST), and none to an input_required result; use private when a list varies by callerPart 6
Return lists in a deterministic order (SHOULD, for tools), and paginate with opaque cursorsPart 6
Write server instructions: purpose, boundaries, how the tools fit together and constraints, in under about 2,000 charactersPart 4

Transport

CheckPart
On standard input and output (stdio): only protocol messages on stdout, logs on stderr, credentials from the environmentPart 7
On HTTP: require and verify MCP-Protocol-Version and Mcp-Method on every request, and Mcp-Name on tools/call, prompts/get and resources/read; return -32020 on a mismatchPart 7
On HTTP: no Mcp-Session-Id, no GET endpoint, no resumability assumptionsPart 7, part 2
Use x-mcp-header only on non-sensitive primitive parameters (SHOULD NOT on sensitive ones)Part 7
A local HTTP server binds to localhost and validates OriginPart 7

Features

CheckPart
Tools: valid names (1 to 128 characters from A-Z a-z 0-9 _ - .), an inputSchema that is never null, honest annotationsPart 8
Tools: outputSchema and structuredContent where useful, plus readable content (SHOULD)Part 8
Tools: isError: true with an actionable message for execution failures, JSON-RPC 2.0 errors only for protocol failuresPart 9
Tools: output sizes within host limits, using summaries and resource_linksPart 9
Resources: -32602 for not found (MUST), never an empty contents for a missing resource (MUST NOT), path sanitization (MUST)Part 10
Prompts: validated arguments (MUST), free text between clear markers, arguments designed as identifiersPart 11
Completion for prompt and template arguments whose values can be listedPart 11
Lists don’t vary per connection (MUST NOT), but may vary by authorizationPart 8

Interaction patterns

CheckPart
MRTR for all server-to-client input (MUST), and only on tools/call, resources/read and prompts/getPart 13
Protect the integrity of requestState (MUST, when it influences logic), and bind the principal, an expiry and a digest of the request inside the sealPart 14
Request only the input types the client declared (MUST NOT otherwise)Part 13, part 15
No side effects before the final input roundPart 14
A non-interactive path for every elicitation, for when no user can answerPart 15
Progress: values that increase (MUST), nothing after completion (MUST), rate-limited (SHOULD)Part 16
Cancellation: an HTTP disconnect is a cancel (MUST), notifications/cancelled honoured on stdio, cancellation passed on to the calls your tool makesPart 16
subscriptions/listen: acknowledgement first (MUST), only acknowledged types (MUST NOT otherwise), subscriptionId on every message (MUST), a graceful close (SHOULD)Part 17

Security

CheckPart
Validate inputs, enforce access control, rate-limit and sanitize outputs (MUST)Part 9, part 21
An HTTP server that uses authorization: Protected Resource Metadata (MUST), and 401 and 403 challenges that name the scope (SHOULD)Part 18, part 19
Validate the token’s audience (MUST), and never accept or forward a token issued for anything else (MUST NOT)Part 18, part 19
On-behalf-of or token exchange for downstream callsPart 19
Minimal scopes_supported, one complete step-up challenge (SHOULD), scope hierarchies respected (MUST)Part 19
Handles and task IDs with high entropy, authorized on every callPart 5, part 26
Factual tool descriptions and instructions, with nothing that reads like an injectionPart 4, part 21
Untrusted third-party content marked as data, never as instructionsPart 21

Operations

CheckPart
Continue traceparent, tracestate and baggage from _meta when the client sends them, and propagate them downstreamPart 20
Never use baggage for authorization or tenancyPart 20
Metrics: latency per tool, isError rate, protocol errors by code, input_required rate, disconnects, output size, calls by clientPart 20
Logging moved off the deprecated notifications/message to stderr or OpenTelemetryPart 20, part 22
Idle timeouts on intermediaries sized for long calls and listen streamsPart 7, part 16
Idempotency keys on write toolsPart 9

Extensions

CheckPart
Declare extensions in server/discover, and check each request’s declarations before using onePart 23
MCP Apps: ui:// and text/html;profile=mcp-app, minimal Content Security Policy (CSP) domains, an explicit prefersBorder, app-only tools through visibility, and meaningful text content always (MUST)Part 24, part 25
Tasks: durable creation before acknowledging (MUST), failed only for JSON-RPC errors (MUST NOT otherwise), unique inputRequests keys, Mcp-Name routing honoured, a durable storePart 26
Skills: frontmatter name matching the directory name (MUST), complete manifests with exact-byte digests (MUST), skills/get for every skill (MUST), no more than 512 files or 16 MiB per skill (SHOULD NOT exceed), no secretsPart 27
Authorization extensions: validate the Identity Assertion JSON Web Token (JWT) Authorization Grant (ID-JAG) under enterprise-managed authorization, and prefer JWT bearer assertions for client credentialsPart 28
Vendor _meta keys used only as enhancementsPart 29

Compatibility

CheckPart
Serve both the stateless era and the legacy handshake era, until your telemetry says otherwisePart 22
Plan the removal of roots, sampling and logging: the earliest is the first revision released on or after 2027-07-28Part 22
Plan it for HTTP+SSE too, which can go sooner: three months after the feature-lifecycle Specification Enhancement Proposal (SEP-2596) reaches FinalPart 22
Move from Dynamic Client Registration to Client ID Metadata DocumentsPart 19, part 22
Test in at least three hosts, including one text-only hostPart 25, part 31
Re-check the host support matrix every quarterPart 31

Those dates come from the registry of deprecated features. Under SEP-2596, twelve months is the usual floor, but a feature that presents an active security risk can go after at least 90 days. When a window closes, the feature only becomes eligible for removal; taking it out is the core maintainers’ decision.

Hosts can ask for more than the specification, such as shorter tool names and required annotations; my rulebook of what each AI host requires lists them. For testing in both protocol eras, my review of MCP testing tools covers the options, from the official conformance suite to the MCP Inspector.

Seven ideas to keep

  1. Stateless by default, stateful by design. There are no sessions, so handles, tasks and listen streams are deliberate choices with a durable store behind them.
  2. Control determines the primitive. The model decides on tools, the application on resources and the user on prompts (part 12). Server instructions sit beside all three, though whether they reach the model is the host’s choice.
  3. Ask, don’t block. MRTR turns “wait for the user” into “return and retry”. Protect requestState, and do nothing irreversible before the last input round.
  4. Two audiences for every result. content for the model and text-only hosts, structuredContent for programs and apps. Under the MCP Apps convention, structuredContent stays out of the model’s context, so write content that stands on its own. Hosts differ, though: Claude Code and its Agent software development kit (SDK) pass structuredContent to the model in place of the text blocks, and ChatGPT lets the model see it.
  5. Security lives in the server. Annotations, instructions and descriptions are hints. Validation, authorization, audience checks and rate limits are what protect you.
  6. Extensions are negotiated per request and degrade gracefully. Build the core so it works everywhere, then add MCP Apps, Tasks and Skills where hosts support them.
  7. Your telemetry is your support matrix. clientInfo and the capabilities each request declares show what your users’ hosts can really do.

What to watch next

What I’m watching, as of October 2026:

  • Tasks moving into the core. SEP-2663, the Tasks extension, states the intent to promote it once it stabilizes and is widely adopted (part 26).
  • Skills adoption. The specification is final, and the official SDKs are catching up: all four, for Go, TypeScript, Python and C#, have open pull requests, and the Go SDK’s already passes the conformance suite (part 27). Hosts will decide how fast servers can rely on it.
  • Interceptors. A standard policy layer for validation, redaction and audit would change how enterprises deploy MCP. The proposal, SEP-2624, is still open (part 29).
  • Host adoption of 2026-07-28. The removal clock for roots, sampling and logging is running, and part 31 shows where each host stands.
  • Enterprise identity. Enterprise-Managed Authorization in mainstream hosts and identity providers would remove most of the consent friction in corporate rollouts (part 28).

The protocol has grown from a way to give models tools into a full contract between AI applications and the systems they work with. I think the servers that do well will be the ones that treat that contract carefully: honest descriptions, strict validation, graceful degradation and good observability. Thank you for reading along. I hope the series makes your next server a little easier to build.

Method and caveats

  • Built from my guide’s checklist and conclusion, and written against the 2026-07-28 specification. Product facts are as of October 2026.
  • The MUST, SHOULD, MUST NOT and SHOULD NOT marks are my guide’s, plus five that its own chapters or the specification set: -32021, prompt validation, x-mcp-header, progress rate limits and content in MCP Apps.
  • Where the specification is more precise than my notes (the deprecation windows and Dynamic Client Registration, caching hints, Mcp-Name, -32021, optional authorization, trace context and instructions), this article follows the specification.
  • Where the hosts’ docs and the extensions’ records are newer (structuredContent in hosts, the SDKs’ Skills work, the Interceptors proposal), it follows them, as checked on 8 October 2026.