Building a Production MCP Server: The Guide I Wish I Had
Most MCP tutorials stop at hello-world. Then you try to run one on the open internet with real auth, real load, and real attackers, and every assumption breaks. Here are the five design decisions that actually decide whether your server survives production.

Key takeaways
- MCP went from a handful of experimental servers at its November 2024 launch to over 10,000 active public MCP servers and more than 97 million monthly SDK downloads by the end of 2025.
- As of the November 25, 2025 spec, every internet-facing MCP server must implement OAuth 2.1 with PKCE (S256) and act as a resource server only, never issuing its own tokens or showing login pages.
- The MCPSecBench study found that over 85% of tested attacks compromised at least one major MCP platform across 17 attack types, while existing defenses blocked them at an average rate under 30%.
- Tool-poisoning prompt injection reached attack success rates as high as 72.8% across 20 different LLM agents and produced two 2025 CVEs, CVE-2025-54136 (MCPoison) and CVE-2025-54135 (CurXecute).
- The 2026-07-28 spec release candidate makes MCP stateless at the protocol layer by removing the initialize handshake and Mcp-Session-Id header, so servers scale horizontally with no sticky sessions or shared session store.
The MCP hello-world is a lie of omission. You wire up a server, expose a get_weathertool, point Claude or Cursor at it, watch it call the tool, and feel like you understand the protocol. You don't. You understand the demo. The demo runs on your laptop, talks to one client over a pipe, trusts everything, and never sees a second user.
Production is a different animal. Now the server is on the open internet. Real users authenticate against it. It gets scaled behind a load balancer. And, this is the part nobody tells you, attackers are specifically hunting MCP servers, because a server the model trusts is a server the model will do damage on your behalf. This piece assumes you already know what MCP is. If you don't, start with the intro. What follows is the ops deep-dive: the five design decisions that decide whether your server survives contact with real traffic.
The scale is not hypothetical. MCP went from a handful of experimental servers at its November 2024 launch to over 10,000 active public servers and more than 97 million monthly SDK downloads a year later.1 Every major AI vendor is on it. OpenAI adopted MCP in March 2025 across its Agents SDK, Responses API, and ChatGPT desktop. Google DeepMind confirmed Gemini support in April 2025. Microsoft co-developed the official C# SDK. And on December 9, 2025, Anthropic handed the whole thing to the Linux Foundation's new Agentic AI Foundation, so it is now vendor-neutral rather than one company's protocol.2 The upshot for you: MCP is now stable infrastructure worth building on properly, not a bet that might get abandoned.
Decision 1: Pick Streamable HTTP, and don't reach for the old SSE transport
There are two supported transports, and only two. stdio is for local servers that run as a subprocess of the client, talking over standard input and output. It's perfect for a server that lives on the same machine as the agent. If your server is remote, which any production server is, you want Streamable HTTP.
This is where people trip. If you learned MCP in early 2025, you learned the HTTP+SSE transport, a two-endpoint design with a long-lived server-sent-events stream. That got deprecated in the 2025-03-26 spec and replaced by Streamable HTTP, which folds everything onto a single endpoint and only opens a stream when a response actually needs one.3Half the “why does my MCP server behave weirdly behind a proxy” threads I've read trace back to someone implementing the dead transport. Don't. Build against Streamable HTTP from the first commit.
Heads up
Decision 2: Be a resource server, and nothing more
This is the decision people get most wrong, because the instinct is to build auth into the server. Resist it. As of the June 2025 spec update, an MCP server is classified as an OAuth 2.1 resource server only. It validates tokens. It does not issue them, does not show a login page, and does not store credentials.4Token issuance is somebody else's job, specifically a separate authorization server.
“The MCP server never issues tokens, never shows a login page, and never stores a credential. If yours does any of those, you built an auth server by accident.”
Concretely, as of the November 25, 2025 revision, any internet-accessible MCP server must implement OAuth 2.1 with PKCE using S256.5 The mechanics come down to a few RFCs doing specific jobs:
- The server implements RFC 9728 Protected Resource Metadata, a discovery document that tells clients which authorization server to go get a token from.
- When a request arrives without a valid token, the server returns HTTP 401 with a WWW-Authenticate headerpointing at that metadata. That's the whole handshake from the server's side.
- Clients implement RFC 8707 Resource Indicatorsto bind a token to your specific server, so a token minted for one server can't be replayed against another. This is the fix for token reuse, and it's a real attack, not a theoretical one.
The November 2025 spec also cleaned up the client side. It replaced Dynamic Client Registration with URL-based Client ID Metadata Documents (SEP-991) as the recommended default, added machine-to-machine client-credentials auth (SEP-1046) for the agent-talking-to-agent case, and added enterprise IdP cross-app access controls (SEP-990).1If you're selling into companies, that last one is what lets their identity provider actually govern your server.
Why this matters
Decision 3: Assume tool poisoning, because the numbers are brutal
Here's the part that should keep you up at night. The single most important security concept in MCP is tool poisoning: a form of indirect prompt injection where malicious instructions are hidden in tool metadata. The model reads a tool's description or schema and treats the hidden text as instructions. The attacker never talks to the model directly. They just poison something the model is going to read.
This produced two CVEs in 2025 alone: MCPoison (CVE-2025-54136) and CurXecute (CVE-2025-54135).6And it's not just proofs of concept. In a real mid-2025 incident, a Supabase Cursor agent running with service-role access exfiltrated integration tokens after an attacker embedded SQL in a support ticket. The agent read the ticket, the ticket carried instructions, and the agent had the permissions to act on them.6
The MCPSecBench study is the sobering one. Across 17 attack types, over 85% of tested attacks compromised at least one major platform, Claude Desktop, OpenAI, or Cursor, while existing protection mechanisms blocked attacks at an average rate under 30%.7 A separate study measured prompt-injection-with-tool-poisoning success rates as high as 72.8% across 20 different LLM agents.7 Read those together and the conclusion is uncomfortable: the platform is not going to save you, and the model is not going to save you. Your server design has to.
What that means in practice, on the server you control:
- Scope every tool to least privilege. The Supabase incident happened because the agent had service-role access. A tool should hold the narrowest permission that lets it do its one job, so a successful injection buys the attacker as little as possible.
- Treat tool descriptions and returned data as untrusted. Anything a tool returns can carry an injection payload aimed at the next model turn. Sanitize and constrain what you hand back, don't just pipe raw third-party content into the context.
- Pin and review tool definitions.MCPoison was fundamentally about tool metadata changing out from under a user who already approved it. Version your tool definitions and don't let them mutate silently.
Takeaway
The mental model that keeps you safe: an MCP tool is a way for text you don't control to trigger actions with permissions you do control. Every design choice should shrink the gap between those two things.
Decision 4: Design for the stateless future that's already arriving
If you're building today, build with one eye on the 2026-07-28 spec, published as a release candidate ahead of the final July 28, 2026 release. It's the largest revision since launch, and the headline change is that MCP goes stateless at the protocol layer. It removes the initialize handshake and the Mcp-Session-Id header, so servers no longer need sticky routing or a shared session store to scale.8
This is a bigger deal operationally than it sounds. Under the old model, a session lived somewhere, and every request in that session had to come back to the instance that held it, or you needed a shared store all instances could read. That's sticky sessions, and sticky sessions fight everything you want in production: clean autoscaling, safe rolling deploys, serverless. Strip the session out and an MCP server becomes a boring stateless service. You get Kubernetes HPA with no affinity rules, serverless viability, and rolling deploys that don't drop anyone mid-session.8
The same release adds the plumbing a serious service wants: full JSON Schema 2020-12 validation, cache-control hints via ttlMs and cacheScope, W3C Trace Context propagation so your MCP calls show up in OpenTelemetry traces, and required Mcp-Method and Mcp-Name routing headers so a proxy can route without parsing the body.8That trace-context piece is the one I'd flag: it means you can finally see an agent's tool calls inside the same distributed trace as the rest of your stack, instead of them being a black box.
Context
Decision 5: Use the production primitives instead of hand-rolling them
The last decision is about not reinventing wheels the spec now ships. The November 2025 update added primitives aimed squarely at real workloads, and the most useful is Tasks(SEP-1686). A tool that kicks off something slow, a report build, a data migration, a long agent run, shouldn't block a request until it finishes. Tasks give you a first-class way to track a long-running multi-step operation through working, input_required, completed, failed, and cancelled states.1Before this, everyone bolted on their own job-status hack. Now it's in the protocol.
Two more worth knowing. Sampling with Tools (SEP-1577) lets the server run its own agent loop, calling back into the model, which turns a server from a passive tool bag into something that can actually orchestrate. And URL Mode Elicitation (SEP-1036) gives you browser-based OAuth credential collection, so when a tool needs the user to authorize a third-party service, you can hand off to a real browser flow instead of trying to smuggle credentials through the chat.
The through-line across all five decisions is the same. MCP grew up fast. The protocol went from a demo toy to something OpenAI, Google, Microsoft, and the Linux Foundation all stand behind, and the spec grew the auth model, the security posture, the scaling story, and the production primitives to match. The servers that break in production are the ones still built like the hello-world: trusting, stateful, and issuing their own tokens. The ones that survive treat the server as a stateless, least-privilege resource server that assumes it's under attack. That's not paranoia. Given a sub-30% defense rate, it's just the job.
Sources and further reading
- 1.PrimaryOne Year of MCP: November 2025 Spec Release. blog.modelcontextprotocol.io
- 2.PrimaryDonating the Model Context Protocol and establishing the Agentic AI Foundation. anthropic.com
- 3.PrimaryModel Context Protocol: transports (Streamable HTTP). modelcontextprotocol.io
- 4.ReportingModel Context Protocol Spec Updates from June 2025. auth0.com
- 5.PrimaryAuthorization (2025-11-25 spec). modelcontextprotocol.io
- 6.ReportingMCP Tool Poisoning (CVE-2025-54136): A Structural Vulnerability in Agent Context. truefoundry.com
- 7.PrimaryMCPSecBench: A Systematic Security Benchmark for Model Context Protocols. arxiv.org
- 8.ReportingThe 2026-07-28 MCP Specification Release Candidate. blog.modelcontextprotocol.io
Frequently asked questions
- Which transport should a production MCP server use?
- Use Streamable HTTP, which became the standard remote transport in the 2025-03-26 spec and replaced the deprecated HTTP+SSE transport. The two supported transports today are stdio, meant for local servers running as a subprocess of the client, and Streamable HTTP, meant for anything remote. If your server is reachable over the network, Streamable HTTP is the answer.
- Does an MCP server issue its own auth tokens?
- No. As of the June 2025 and November 25, 2025 spec updates, an MCP server is an OAuth 2.1 resource server only. It never issues tokens, never shows login pages, and never stores credentials. Token issuance belongs to a separate authorization server. The MCP server validates the token it receives, implements RFC 9728 Protected Resource Metadata, and returns HTTP 401 with a WWW-Authenticate header when a token is missing or invalid.
- What is tool poisoning in MCP?
- Tool poisoning is a form of indirect prompt injection where malicious instructions are hidden inside tool metadata, like a tool description or schema, so the model reads them as instructions. It produced two 2025 CVEs, MCPoison (CVE-2025-54136) and CurXecute (CVE-2025-54135). In one real mid-2025 incident, a Supabase Cursor agent running with service-role access exfiltrated integration tokens after an attacker embedded SQL in a support ticket.
- How do you scale an MCP server horizontally?
- Under the 2026-07-28 spec release candidate you scale it like any other stateless service, with no sticky routing. That release makes MCP stateless at the protocol layer by removing the initialize handshake and the Mcp-Session-Id header, so servers no longer need a shared session store or session affinity. That unlocks Kubernetes HPA without affinity rules, serverless deployment, and safe rolling deploys.
- Is MCP controlled by a single company?
- No. On December 9, 2025, Anthropic donated MCP to the Linux Foundation’s new Agentic AI Foundation (AAIF), making the protocol vendor-neutral. The AAIF was co-founded by Anthropic, Block, and OpenAI, with Google, Microsoft, AWS, Cloudflare, and Bloomberg as supporting organizations. Before that, OpenAI adopted MCP in March 2025 and Google DeepMind confirmed Gemini support in April 2025.
- What production features did the November 2025 spec add?
- It added Tasks (SEP-1686) for tracking long-running multi-step operations through working, input_required, completed, failed, and cancelled states. It also added server-side agent loops via Sampling with Tools (SEP-1577) and browser-based OAuth credential collection via URL Mode Elicitation (SEP-1036). On the auth side it replaced Dynamic Client Registration with URL-based Client ID Metadata Documents and added machine-to-machine client-credentials auth.
Written by
Tech Talk News Editorial
Computer engineering background. Writes about software, AI, markets, and real estate, and the places where the three meet.
More about the author