Building an MCP server used to mean wrestling with sessions, sticky routing and streams held open like a bad phone call. That is over. The 2026-07-28 specification made MCP fully stateless, and the practical result is that your first server can be an ordinary HTTP handler.

This is the walkthrough I wish someone had handed me. Not the hello-world you can get anywhere. The decisions that actually determine whether this thing survives contact with real users.

Step 1: Check Whether You Need to Build At All

The registry passed roughly 2,000 server entries within months of launching. Before you write a line of code, search it. Someone has probably wrapped the system you are about to wrap.

Build your own when the system is internal, when the existing server asks for more permission than you want to grant, or when you need a narrow tool surface rather than a hundred generic endpoints. That last reason is underrated. A server exposing five well-named tools beats one exposing eighty.

Step 2: Pick Your SDK and Transport

Four Tier 1 SDKs speak the current spec: TypeScript, Python, Go and C#. Rust is in beta. Pick whatever your team already deploys, because the operational story matters more than the language.

Transport is simpler than it sounds. Use stdio if the server runs as a local subprocess next to a desktop client. Use Streamable HTTP for anything remote. With the stateless core, that HTTP server needs no session store and no sticky sessions, so a plain serverless function is now enough.

Step 3: Design the Tools, Not the API

A rack of hand tools, each one hung in its own place
Photo: 1lenore / CC BY 2.0, via Flickr.

This is where most first servers go wrong. People map one tool per REST endpoint and hand the model a menu of forty verbs. The model then picks the wrong one, confidently.

Write tools the way you would write instructions for a competent new hire. Name them for the outcome, not the endpoint. Describe when NOT to use them. Return errors the model can act on, so customer not found, try search_customers first beats a bare 404.

Keep It Read-Only for Two Weeks

Ship the read path first. Watch what the model reaches for when nobody is supervising. You will discover your tool descriptions were ambiguous in ways no code review catches, and you will discover it without anyone deleting a record.

Step 4: Wire Up Auth Properly

For remote servers, MCP uses OAuth 2.1. Two changes matter right now. Authorization servers should return the iss parameter per RFC 9207 and clients must validate it before redeeming a code. And Dynamic Client Registration is deprecated in favour of Client ID Metadata Documents, with removal slated after summer 2027.

If you are starting fresh, start on CIMD. Do not build something you will have to unbuild.

Step 5: Make It Observable Before You Make It Fast

The new spec puts method and tool names in the Mcp-Method and Mcp-Name headers, so your gateway can route, rate limit and record tool-level metrics without parsing JSON bodies. Use that on day one.

Log every call with the tool name, the arguments, the caller and the outcome. MCP still has no standardised audit trail, so if you do not log it, nobody does.

What to Skip on Your First Build

  • Long-running Tasks. They moved into an extension. Great feature, wrong week.
  • Deprecated primitives. Roots, Sampling and Logging are on a twelve-month offramp. Do not adopt them now.
  • Clever caching. Set sensible ttlMs hints on your list responses and move on.
  • Every tool you can imagine. Five good tools beat fifty mediocre ones, every time.

Conclusion

A useful first MCP server is small, read-only, well described and heavily logged. It exposes a handful of tools your team already understands and nothing else. Ship that in a week, run it for a fortnight, and let real usage tell you what to add. The teams that struggle are the ones who tried to build the complete server before anyone had used the simple one.

Frequently Asked Questions

Do I need to rewrite an MCP server built in 2025?

Eventually, yes, particularly if you relied on session identifiers. You have a twelve-month deprecation window, and you can run a stateless route beside the old one while you migrate.

Can an MCP server run on serverless?

Now it can, comfortably. That was the whole point of the stateless rewrite. Any request can land on any instance behind a plain load balancer.

How do I handle state my tools genuinely need?

Mint an explicit handle from a tool and have the model pass it back as an argument. Visible state beats state hidden in the transport, because the model can see and thread it.

Is it safe to publish my server to the public registry?

Only after a security review. Remember that a registry entry is a distribution channel, and your tool descriptions become an attack surface the moment strangers can install them.

Leave a Reply

Your email address will not be published. Required fields are marked *