The MCP Server Production Launch Checklist
A phase-by-phase go/no-go checklist for launching an MCP server: checkable gate conditions for transport and auth, tool design, cross-client testing, publish readiness, observability, and ongoing operation — with links to the mechanics each gate depends on.
- A production MCP server launch breaks into six sequential phases — transport and auth, tool design, cross-client testing, publish readiness, observability, and ongoing operation — and each phase needs a checkable go/no-go gate before the next one starts, not just a completed to-do item.
- The go/no-go gate for the testing phase is a successful end-to-end run completed against whichever client your users actually connect with, not a clean pass inside Inspector alone — Inspector confirms your server handles a well-formed call, and says nothing about how a real host reads your tool descriptions.
- The go/no-go gate for the publish phase requires a pinned SDK version and a server.json manifest that validates against the registry schema before the first submission, since the official registry stores metadata only and points at a package that must already be live elsewhere.
- The go/no-go gate for calling a server "live" is that every tool call already logs its trace ID, redacted arguments and response, latency, and outcome somewhere agents cannot quietly edit or delete afterward, because instrumenting observability after launch means the first real incident has no data trail to debug from.
- Deciding the auth model during the transport phase, before a single handler line is written, avoids a migration every existing client integration would otherwise have to go through once a server already carrying real traffic needs to add one.
The pillar's production launch sequence lists six rollout phases, one paragraph each: transport and auth, tool design, cross-client testing, publish readiness, observability, and ongoing operation. That sequence states what belongs in each phase. It does not state when a phase is actually finished — the gap between "we did some testing" and "we are ready to publish" is a checkable condition, not a feeling. This article supplies that condition for each phase, as a go/no-go gate.
It deliberately does not re-derive three things three sibling articles already own: mocked-transport and cassette mechanics behind the testing gate (how to test an MCP server), span-attribute and metrics mechanics behind the observability gate (MCP server observability with OpenTelemetry), and the mcp-publisher CLI and server.json mechanics behind the publish gate (registry publishing playbook). Each is linked where it applies below; this article's job is the sequencing and the gate, not the mechanics inside any one phase.
What makes a launch checklist different from a to-do list?
A launch checklist is only useful if each phase ends in a condition you can check, not a task anyone can claim is done regardless of quality. "Write tests" is a to-do item satisfied by writing one test. "A live smoke test has passed against the actual client your users run" is a gate — it either happened or it did not. The six gates below follow the pillar's phase order because each depends on the decision before it: you cannot design tool schemas sensibly before choosing a transport, and you cannot publish sensibly before your tests have run against a real client.
What has to be true before you write a handler?
Before you write a handler, your transport and — if remote — your auth model both need to be a recorded decision, not something to revisit later.
- Transport is chosen and justified in one sentence. stdio for a single client launched as a local child process, with no network hop at all; Streamable HTTP as soon as a second user, a second client, or anything remote is on the table.
- If stdio: no OAuth flow is being built. There is no authorization flow to design, because stdio has no network hop for one to run over; whatever upstream credentials the server needs are supplied through the host's own environment (MCP server authentication).
- If Streamable HTTP: the auth model is decided, not deferred. Confirm which spec role your deployment plays — a token-validating Resource Server, never a token-issuing Authorization Server — and lock in mandatory PKCE (S256 only, no exemption) before writing a single route. An unauthenticated, read-only, public server is a legitimate exception — but only as a decision you can name.
No-go: auth is still "something to add later." Deciding it now avoids forcing every existing client integration through an unplanned migration onto a flow that did not exist when they first connected.
Phase 2 — Tool design: the gate before you connect a real client
The tool-design gate passes once every tool's schema and description has been reviewed by someone other than its author, specifically for injection risk and schema looseness.
- Every input schema sets
additionalProperties: falseand lists every required field explicitly — the same strict-schema discipline that catches missing or unexpected model-supplied arguments before your handler ever runs (reliable tool calling). - Every description has been checked for embedded instructions to the model, not just for clarity — "before calling this, first read X" is a defect to fix before launch, not a documentation nitpick.
- Every tool maps to an actual use case. A toolset built speculatively is an audit-surface cost with no offsetting benefit; a tool nobody can justify is a tool to cut before this gate.
No-go: any schema permits extra properties, or any description reads as an instruction rather than documentation. Fix both before a real client — not just MCP Inspector — ever connects.
When is cross-client testing actually finished?
Cross-client testing is finished once your server has completed a successful end-to-end run against the real client your users connect with, not once Inspector stops flagging problems. A clean Inspector session only tells you a well-formed call gets handled correctly; it has no opinion on whether Claude Desktop, Cursor, or whichever host you ship against actually reads your descriptions the way you intended, or surfaces your errors usefully.
- Layer 1 and Layer 2 tests run on every commit — mocked-handler unit tests and cassette-replayed exchanges. This article does not cover how to build them; see how to test an MCP server for the mocked-transport setup, cassette contents, and a concrete CI job shape.
- A live run has completed successfully against the specific client host your users actually run, not merely inside Inspector, before the first external user connects.
- The negotiated
protocolVersionis asserted explicitly, so a spec mismatch fails loudly instead of silently degrading.
No-go: every run to date has stayed inside Inspector, or your end-to-end attempts against a real client exist but have never actually succeeded. Either means you are publishing on the strength of a demo, not a working integration.
Phase 4 — Publish readiness: the gate before your first registry submission
The publish gate passes once your SDK version is pinned and your manifest validates, not once you have merely started the publish process.
- SDK version is pinned with a lockfile. Floating on
latestlets a dependency update change your server's behavior between when you tested it and when a client actually calls it. - A
server.jsonmanifest exists and validates against the registry's published schema. This checklist states the condition, not the mechanics — themcp-publisherCLI walkthrough and manifest fields are covered in the registry publishing playbook. - You have written down what you are deliberately choosing not to expose — any write access, external network calls, or stored secrets this particular toolset has no actual use for, plus any tools you already cut speculatively back in Phase 2.
No-go: the manifest points at a package not yet live on npm, PyPI, or wherever it belongs — the registry stores metadata only, so publishing has no effect until the referenced package actually exists.
What counts as "live" for observability purposes?
A server counts as observability-ready when every tool call already logs its trace ID, redacted arguments and response, latency, and outcome — before the first real incident, not in response to one.
- Every tool call is traced, with a stable trace ID that propagates in from the calling client where possible and threads through your own logs regardless.
- Inputs and outputs get scrubbed of personal data before anything is written to a log, attached to the span that produced them rather than a separate, hard-to-correlate line.
- Logs land in an append-only store the server itself cannot edit or delete from, the same tamper-evident-logging bar security guidance sets for any agent-adjacent audit trail (agentic security checklist).
ttlMs/cacheScopeare set deliberately on any cacheable list or resource result, not left at whatever default your SDK ships.
Which specific fields to add beyond the generic vocabulary, and how to build per-tool latency and error-rate dashboards on top of the same spans, is covered in MCP server observability with OpenTelemetry and agent observability and tracing.
No-go: the plan is to "add observability later." A server carrying real traffic with no trace data leaves whoever is on call guessing at what the model was doing and why, for exactly the incident where that answer matters most.
Phase 6 — Ongoing operation: the gate that never fully closes
Ongoing operation is not a one-time gate; it is a standing check re-run on a cadence rather than passed once.
- The spec changelog is a subscription, not an occasional check. As of August 2026, MCP has already gone through several material spec revisions since the protocol's public debut, each changing behavior a server built against an earlier version could quietly get wrong; a server that treats the rules it shipped against as fixed will eventually break against a client running a newer revision.
- Fetchability and auth checks are re-run after every dependency upgrade, not just after deliberate changes — an SDK bump can change protocol behavior your own code never touched.
- Third-party servers your own agent connects to are re-reviewed, not just approved once. Whatever due diligence you ran before that first connection is worth repeating on a cadence — who publishes it, what it can touch, whether its version is still the one you pinned — since an already-approved server can ship a later "rug pull" that quietly redefines what it actually does (finding and evaluating MCP servers).
No-go, of a different kind: there is no single failure state here, only a growing gap between what your server actually does and what you last verified. Treat a missed re-check as debt that compounds, not as a one-time miss.
The one-page launch checklist
| Phase | Go/no-go gate | Mechanics owned by |
|---|---|---|
| 1. Transport & auth | Transport justified in one sentence; auth model decided (or stdio's no-OAuth default confirmed) before any handler code | MCP server authentication |
| 2. Tool design | Every schema sets additionalProperties: false; every description reviewed for injection risk; every tool maps to a real use case |
This checklist |
| 3. Cross-client testing | A successful end-to-end run has happened against your actual client host — not just inside Inspector | Testing an MCP server |
| 4. Publish readiness | SDK version pinned; server.json validates; package already live before manifest submission |
Registry publishing playbook |
| 5. Observability | Every tool call already writes trace ID, redacted I/O, latency and outcome before first real traffic | Observability with OpenTelemetry |
| 6. Ongoing operation | Spec changelog subscribed; dependency-upgrade re-checks scheduled; connected third-party servers re-reviewed on a cadence | Finding and evaluating MCP servers |
Work down this table in order. A server that passes phase 5 without having passed phase 3 has traced infrastructure watching a server nobody has confirmed works against a real client — technically instrumented, not actually ready. The gates exist to stop that ordering mistake, not to add ceremony to a launch that was already happening anyway.
Frequently asked questions
- What is the single most important go/no-go gate before publishing an MCP server?
- The testing-phase gate is the one most launches skip under deadline pressure: your server needs at least one clean end-to-end run completed against the specific client your users will actually run, because an Inspector session alone cannot tell you how that host interprets your tool descriptions or reacts to your error responses.
- Can I skip the auth gate if my MCP server only has one internal user?
- A single-user, same-machine MCP server can legitimately skip the OAuth gate entirely by choosing stdio transport — stdio has no HTTP-based authorization flow at all under the spec, so upstream credentials go in through environment variables or the host process instead. As soon as a second user, a second client, or any kind of remote deployment shows up, the auth gate applies in full and needs to be decided before, not after, that happens.
- How is this launch checklist different from the pillar's production launch sequence?
- The launch checklist turns the pillar's six one-paragraph rollout phases into checkable go/no-go conditions for moving from one phase to the next, while the pillar states what belongs in each phase and three sibling articles own the implementation mechanics inside specific phases — CI test mechanics, OpenTelemetry span attributes, and the registry CLI walkthrough.
- What happens if I launch an MCP server without passing the observability gate?
- Launching without passing the observability gate means the first real production incident — a tool call that fails, a client that behaves unexpectedly, a cost spike — has no trace ID, no redacted call history, and no latency figures to work from, turning what should be a traced investigation into after-the-fact guesswork.