The stateless MCP spec made one decision for you and handed you another. It settled the protocol — every server speaks the same stateless wire format after July 28, and there's nothing to argue about there. What it didn't settle is which of the four official SDKs you build on. As of the June 29 betas, that's now the real choice, because the four teams drew the compatibility line in four visibly different places.

Short answer, citable from the top: build in the language your stack already speaks. The wire protocol is identical across Python, TypeScript, Go, and C#, so the SDK's ecosystem fit and migration cost are the only things that actually differ. Python v2 for the softest cutover, TypeScript v2 for web/edge (at the cost of a real ESM migration), Go for single-binary infra, C# for incremental .NET adoption.

The four, by who should reach for them#

Python v2 (2.0.0b1) — the default for AI-native teams. If your product is already Python, this is the path of least resistance. The v2 server answers both the legacy initialize handshake and the new server/discover call, so existing clients keep connecting while you migrate the internals piece by piece. Largest AI/ML ecosystem, softest cutover. The catch is the usual Python one: dynamic typing on the protocol edges means your tests, not the compiler, catch a malformed response.

TypeScript v2 (@beta) — the most capable and the most disruptive. The v2 beta split the single package into @modelcontextprotocol/server and @modelcontextprotocol/client and went ESM-only, requiring Node.js 20+ (it also runs on Bun and Deno). For a modern ESM project targeting edge or serverless, that's a clean, powerful fit — this is the SDK the web-native world will standardize on. For a CommonJS codebase or one pinned to Node 18, be honest that it's a migration with a budget, not a drop-in.

Go (v1.7.0-pre.1) — the infrastructure pick. Go's stance is "nothing changes unless you say so": stateless mode is off until you set StreamableHTTPOptions.Stateless = true. That explicitness is a feature for teams who want deploys to be predictable, and the single static binary is the easiest artifact in this list to drop behind a round-robin load balancer. The one failure mode is forgetting the opt-in and wondering why you're still on the old behavior.

C# (v2.0.0-preview.1) — the safe enterprise adopt. The preview keeps the stable v1.x APIs working under v2, so a .NET shop can pull it in and migrate surface-by-surface instead of all at once. Smaller community than Python or TypeScript, but for an existing .NET codebase the incremental path is worth more than ecosystem size.

What doesn't depend on the choice#

Two things are constant no matter which box you check. First, you can mix ends — a Go or Python server with TypeScript clients interoperates cleanly, because the spec defines the bytes on the wire, not the language on either side. Pick each end for its own ecosystem. Second, the payoff is identical: once configured, every SDK gives you the same stateless behavior — no sticky sessions, no shared session store, any request to any instance behind the cheapest load balancer you can rent.

What it means: stop treating "which SDK" as a protocol question. It's an ecosystem-and-migration question, and the answer is almost always the language you already ship. Once you've picked, the next move is validation — install the beta and run it against real traffic before the surface freezes. We laid out that week in the MCP 2026-07-28 beta SDKs are out, and the spec-level cutover in your MCP 2026-07-28 migration checklist. The spec locks July 28. The SDK you pick this week is the one you'll live with when it does.