The MCP server author's checklist A 35-part series on the Model Context Protocol (MCP) server specification dated 2026-07-28 concludes with a consolidated author's checklist covering eight areas, from the protocol core to compatibility, with each item linked to the part that explains it. The checklist marks specification-mandated requirements in capitals — including implementing `server/discover` with `supportedVersions`, `capabilities`, `ttlMs` and `cacheScope` (MUST), reading `protocolVersion` and `clientCapabilities` from `_meta` on every request without caching them per connection (MUST), and setting `resultType` on every result (MUST) — while unmarked items are the author's recommended practice. The author notes that deprecations run on more than one clock: Roots, sampling and logging can be removed 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. 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 https://pournasserian.com/writing/mcp-2026-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 https://modelcontextprotocol.io/specification/2026-07-28/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 https://modelcontextprotocol.io/specification/2026-07-28/basic/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. Each band covers a run of parts, top to bottom: parts 3 to 7 https://pournasserian.com/writing/mcp-2026-server-discover , parts 8 to 12 https://pournasserian.com/writing/mcp-2026-tool-definitions , parts 13 to 17 https://pournasserian.com/writing/mcp-2026-multi-round-trip-requests , parts 18 to 22 https://pournasserian.com/writing/mcp-2026-oauth-resource-server and parts 23 to 29 https://pournasserian.com/writing/mcp-2026-extensions . Part 1 https://pournasserian.com/writing/mcp-2026-what-a-server-does and part 2 https://pournasserian.com/writing/mcp-2026-what-changed set the scene, and parts 30 to 34 https://pournasserian.com/writing/mcp-2026-end-to-end 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 | Check | Part | |---|---| | Implement server/discover with supportedVersions , capabilities , ttlMs and cacheScope MUST , and the optional instructions | Part 3 https://pournasserian.com/writing/mcp-2026-server-discover | | Read protocolVersion and clientCapabilities from meta on every request, and never cache them per connection MUST | Part 5 https://pournasserian.com/writing/mcp-2026-stateless-requests | | Return -32021 https://modelcontextprotocol.io/specification/2026-07-28/basic/index 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 serve | Part 3 https://pournasserian.com/writing/mcp-2026-server-discover , part 5 https://pournasserian.com/writing/mcp-2026-stateless-requests | | Identify the server with serverInfo in each result’s meta SHOULD , and log clientInfo | Part 3 https://pournasserian.com/writing/mcp-2026-server-discover | | Set resultType on every result MUST | Part 5 https://pournasserian.com/writing/mcp-2026-stateless-requests | | Add ttlMs and cacheScope to complete results https://modelcontextprotocol.io/specification/2026-07-28/server/utilities/caching 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 caller | Part 6 https://pournasserian.com/writing/mcp-2026-caching-and-pagination | | Return lists in a deterministic order SHOULD, for tools , and paginate with opaque cursors | Part 6 https://pournasserian.com/writing/mcp-2026-caching-and-pagination | | Write server instructions: purpose, boundaries, how the tools fit together and constraints, in under about 2,000 characters | Part 4 https://pournasserian.com/writing/mcp-2026-server-instructions | Transport | Check | Part | |---|---| | On standard input and output stdio : only protocol messages on stdout, logs on stderr, credentials from the environment | Part 7 https://pournasserian.com/writing/mcp-2026-transports | | On HTTP: require and verify MCP-Protocol-Version and Mcp-Method https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http on every request, and Mcp-Name on tools/call , prompts/get and resources/read ; return -32020 on a mismatch | Part 7 https://pournasserian.com/writing/mcp-2026-transports | | On HTTP: no Mcp-Session-Id , no GET endpoint, no resumability assumptions | Part 7 https://pournasserian.com/writing/mcp-2026-transports , part 2 https://pournasserian.com/writing/mcp-2026-what-changed | | Use x-mcp-header only on non-sensitive primitive parameters SHOULD NOT on sensitive ones | Part 7 https://pournasserian.com/writing/mcp-2026-transports | | A local HTTP server binds to localhost and validates Origin | Part 7 https://pournasserian.com/writing/mcp-2026-transports | Features | Check | Part | |---|---| | Tools: valid names 1 to 128 characters from A-Z a-z 0-9 - . , an inputSchema that is never null, honest annotations | Part 8 https://pournasserian.com/writing/mcp-2026-tool-definitions | | Tools: outputSchema and structuredContent where useful, plus readable content SHOULD | Part 8 https://pournasserian.com/writing/mcp-2026-tool-definitions | | Tools: isError: true with an actionable message for execution failures, JSON-RPC 2.0 errors only for protocol failures | Part 9 https://pournasserian.com/writing/mcp-2026-tool-errors-and-design | | Tools: output sizes within host limits, using summaries and resource link s | Part 9 https://pournasserian.com/writing/mcp-2026-tool-errors-and-design | | Resources: -32602 for not found MUST , never an empty contents for a missing resource MUST NOT , path sanitization MUST | Part 10 https://pournasserian.com/writing/mcp-2026-resources | | Prompts: validated arguments MUST , free text between clear markers, arguments designed as identifiers | Part 11 https://pournasserian.com/writing/mcp-2026-prompts | | Completion for prompt and template arguments whose values can be listed | Part 11 https://pournasserian.com/writing/mcp-2026-prompts | | Lists don’t vary per connection MUST NOT , but may vary by authorization | Part 8 https://pournasserian.com/writing/mcp-2026-tool-definitions | Interaction patterns | Check | Part | |---|---| | MRTR for all server-to-client input MUST , and only on tools/call , resources/read and prompts/get | Part 13 https://pournasserian.com/writing/mcp-2026-multi-round-trip-requests | | Protect the integrity of requestState MUST, when it influences logic , and bind the principal, an expiry and a digest of the request inside the seal | Part 14 https://pournasserian.com/writing/mcp-2026-request-state | | Request only the input types the client declared MUST NOT otherwise | Part 13 https://pournasserian.com/writing/mcp-2026-multi-round-trip-requests , part 15 https://pournasserian.com/writing/mcp-2026-elicitation | | No side effects before the final input round | Part 14 https://pournasserian.com/writing/mcp-2026-request-state | | A non-interactive path for every elicitation, for when no user can answer | Part 15 https://pournasserian.com/writing/mcp-2026-elicitation | | Progress: values that increase MUST , nothing after completion MUST , rate-limited SHOULD | Part 16 https://pournasserian.com/writing/mcp-2026-progress-and-cancellation | | Cancellation: an HTTP disconnect is a cancel MUST , notifications/cancelled honoured on stdio, cancellation passed on to the calls your tool makes | Part 16 https://pournasserian.com/writing/mcp-2026-progress-and-cancellation | | subscriptions/listen : acknowledgement first MUST , only acknowledged types MUST NOT otherwise , subscriptionId on every message MUST , a graceful close SHOULD | Part 17 https://pournasserian.com/writing/mcp-2026-subscriptions-listen | Security | Check | Part | |---|---| | Validate inputs, enforce access control, rate-limit and sanitize outputs MUST | Part 9 https://pournasserian.com/writing/mcp-2026-tool-errors-and-design , part 21 https://pournasserian.com/writing/mcp-2026-threat-model | | An HTTP server that uses authorization: Protected Resource Metadata MUST , and 401 and 403 challenges that name the scope SHOULD | Part 18 https://pournasserian.com/writing/mcp-2026-oauth-resource-server , part 19 https://pournasserian.com/writing/mcp-2026-oauth-step-up-and-entra | | Validate the token’s audience MUST , and never accept or forward a token issued for anything else MUST NOT | Part 18 https://pournasserian.com/writing/mcp-2026-oauth-resource-server , part 19 https://pournasserian.com/writing/mcp-2026-oauth-step-up-and-entra | | On-behalf-of or token exchange for downstream calls | Part 19 https://pournasserian.com/writing/mcp-2026-oauth-step-up-and-entra | | Minimal scopes supported , one complete step-up challenge SHOULD , scope hierarchies respected MUST | Part 19 https://pournasserian.com/writing/mcp-2026-oauth-step-up-and-entra | | Handles and task IDs with high entropy, authorized on every call | Part 5 https://pournasserian.com/writing/mcp-2026-stateless-requests , part 26 https://pournasserian.com/writing/mcp-2026-tasks | | Factual tool descriptions and instructions, with nothing that reads like an injection | Part 4 https://pournasserian.com/writing/mcp-2026-server-instructions , part 21 https://pournasserian.com/writing/mcp-2026-threat-model | | Untrusted third-party content marked as data, never as instructions | Part 21 https://pournasserian.com/writing/mcp-2026-threat-model | Operations | Check | Part | |---|---| | Continue traceparent , tracestate and baggage from meta when the client sends them, and propagate them downstream | Part 20 https://pournasserian.com/writing/mcp-2026-opentelemetry | | Never use baggage for authorization or tenancy | Part 20 https://pournasserian.com/writing/mcp-2026-opentelemetry | | Metrics: latency per tool, isError rate, protocol errors by code, input required rate, disconnects, output size, calls by client | Part 20 https://pournasserian.com/writing/mcp-2026-opentelemetry | | Logging moved off the deprecated notifications/message to stderr or OpenTelemetry | Part 20 https://pournasserian.com/writing/mcp-2026-opentelemetry , part 22 https://pournasserian.com/writing/mcp-2026-migration-two-eras | | Idle timeouts on intermediaries sized for long calls and listen streams | Part 7 https://pournasserian.com/writing/mcp-2026-transports , part 16 https://pournasserian.com/writing/mcp-2026-progress-and-cancellation | | Idempotency keys on write tools | Part 9 https://pournasserian.com/writing/mcp-2026-tool-errors-and-design | Extensions | Check | Part | |---|---| | Declare extensions in server/discover , and check each request’s declarations before using one | Part 23 https://pournasserian.com/writing/mcp-2026-extensions | | 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 https://pournasserian.com/writing/mcp-2026-apps , part 25 https://pournasserian.com/writing/mcp-2026-apps-building | | Tasks: durable creation before acknowledging MUST , failed only for JSON-RPC errors MUST NOT otherwise , unique inputRequests keys, Mcp-Name routing honoured, a durable store | Part 26 https://pournasserian.com/writing/mcp-2026-tasks | | 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 secrets | Part 27 https://pournasserian.com/writing/mcp-2026-skills | | 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 credentials | Part 28 https://pournasserian.com/writing/mcp-2026-enterprise-auth | | Vendor meta keys used only as enhancements | Part 29 https://pournasserian.com/writing/mcp-2026-experimental-extensions | Compatibility | Check | Part | |---|---| | Serve both the stateless era and the legacy handshake era, until your telemetry says otherwise | Part 22 https://pournasserian.com/writing/mcp-2026-migration-two-eras | | Plan the removal of roots, sampling and logging: the earliest is the first revision released on or after 2027-07-28 | Part 22 https://pournasserian.com/writing/mcp-2026-migration-two-eras | | Plan it for HTTP+SSE too, which can go sooner: three months after the feature-lifecycle Specification Enhancement Proposal SEP-2596 reaches Final | Part 22 https://pournasserian.com/writing/mcp-2026-migration-two-eras | | Move from Dynamic Client Registration to Client ID Metadata Documents | Part 19 https://pournasserian.com/writing/mcp-2026-oauth-step-up-and-entra , part 22 https://pournasserian.com/writing/mcp-2026-migration-two-eras | | Test in at least three hosts, including one text-only host | Part 25 https://pournasserian.com/writing/mcp-2026-apps-building , part 31 https://pournasserian.com/writing/mcp-2026-host-support | | Re-check the host support matrix every quarter | Part 31 https://pournasserian.com/writing/mcp-2026-host-support | Those dates come from the registry of deprecated features https://modelcontextprotocol.io/specification/2026-07-28/deprecated . 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 https://pournasserian.com/writing/what-ai-hosts-require-of-an-mcp-server lists them. For testing in both protocol eras, my review of MCP testing tools https://pournasserian.com/writing/mcp-server-testing-tools-2026 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 https://pournasserian.com/writing/mcp-2026-choosing-a-primitive . 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 https://code.claude.com/docs/en/agent-sdk/custom-tools 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 https://modelcontextprotocol.io/seps/2663-tasks-extension , the Tasks extension, states the intent to promote it once it stabilizes and is widely adopted part 26 https://pournasserian.com/writing/mcp-2026-tasks . - 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 https://github.com/modelcontextprotocol/ext-skills/blob/main/docs/implementations.md , and the Go SDK’s already passes the conformance suite part 27 https://pournasserian.com/writing/mcp-2026-skills . 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 https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2624 , is still open part 29 https://pournasserian.com/writing/mcp-2026-experimental-extensions . - Host adoption of 2026-07-28. The removal clock for roots, sampling and logging is running, and part 31 https://pournasserian.com/writing/mcp-2026-host-support 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 https://pournasserian.com/writing/mcp-2026-enterprise-auth . 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.