Lesson 11 Why TypeScript for Production MCP
Theme:

Why TypeScript for Production MCP

Lesson 11 · MCP Servers · ~10 min read

The pivot

Modules 1–4 built PKB in Python because Python is the fastest path from zero to “I have a working MCP tool I can call from Claude Desktop”. The SDK is mature, the syntax is light, the iteration loop is short. For learning MCP, Python wins and it is not close.

For shipping MCP to other people, the calculus changes. Once the server has to run somewhere other than your laptop, has to accept connections from someone other than you, or has to survive a security review written by someone other than yourself, every hidden cost that Python papered over starts to show up on the bill: image size, cold start, edge-runtime support, transport features the SDK shipped first elsewhere.

This lesson is the bridge. It writes no code. It establishes the trade-off honestly and gives the reader explicit permission to choose Python and stop the course here if the use-case is personal — or to commit to the TypeScript half of the course if the goal is to ship to other humans on the public internet.

The 2026 MCP ecosystem

A snapshot of what the ecosystem actually looks like in 2026: the majority of public, remote, internet-facing MCP servers are written in TypeScript. Not because TypeScript is a better language — that argument is older than this course and unwinnable — but because four concrete forces line up the same direction.

  1. SDK feature velocity. The TypeScript SDK ships new transport features first. HTTP+SSE, Streamable HTTP, the session-resumability prototype, the middleware shape for auth/rate-limit/audit — all landed in TS before reaching the Python SDK. If today’s recommended pattern matters today, TS gets it first.
  2. Container ergonomics. Node, Bun, and Deno containers are smaller and start faster than equivalent Python containers. For a registry or autoscaler cycling pods, that compounds into real pull-time and bandwidth-bill differences (see the next section for the numbers).
  3. Edge-runtime support. The JavaScript/TypeScript edge-runtime ecosystem — Cloudflare Workers, Vercel Functions, Deno Deploy, Fly.io machines, AWS Lambda@Edge — treats Node as a first-class citizen. Python on those same platforms is at best a second-class citizen and at worst not supported. If you want your MCP server geographically close to the user without operating your own globe of servers, the edge platforms are it, and the edge platforms speak Node.
  4. Author pool. The humans writing public MCP servers overlap heavily with the existing web-API developer base — people who already write TypeScript-on-Node every day. Picking the language that matches your contributor pool is free. Picking the language that doesn’t costs you reviews and pull-requests.

Python keeps two strongholds. The first is local-only servers: a Claude-Desktop-only personal tool, an editor plugin, an internal team helper that never leaves a laptop. The second is AI-research servers that wrap heavy scientific dependencies — PyTorch, transformers, scikit-learn, NumPy with custom C-kernels. Porting those tools to TS would either mean shelling out to a Python subprocess per call (slow and ugly) or re-implementing the math (years of work for no user-visible win). PKB-the-Python-version is genuinely useful for the rest of your life as a local notes assistant; PKB-the-TS-version is what you push to a domain other people can hit.

Performance and deploy ergonomics

Two numbers, both back-of-envelope but both reproducible on a modern laptop:

These ratios flip in two cases. First, if your tools do heavy CPU work — embedding generation, image processing, vector math — the per-call runtime cost dwarfs cold-start and image size, and language choice matters less than tool design. Second, if you deploy as a long-running process with no autoscale (a VM, a single pod pinned to one node), cold-start is paid once at boot and never again; the steady-state cost is what matters. The decision rule is therefore narrow but sharp: edge-style HTTP MCP with scale-to-zero → TypeScript; long-running personal process → Python.

The SDK feature lead

As of 2026, the TypeScript SDK ships transport features roughly two quarters ahead of the Python SDK:

Python catches up — usually within a release or two — but if you want today’s recommended pattern today, the TS SDK is the path. None of this is permanent. It reflects the protocol authors’ shipping cadence at the time of writing, and the gap could close (or invert) over time. Reassess each year before making this call from memory.

When to stay in Python

Stay in Python when

If none of those apply and you are building a server other people will connect to over the internet, the rest of Module 5 is for you.

What we carry over

Conceptually, the TS port preserves every shape from the Python half of the course. Nothing you learned in Modules 1–4 is wasted; the names and packages change but the patterns do not:

What is new in TS-land

Things that have no Python counterpart in our course so far and that will bite you the first time you meet them:

Common pitfalls

Five pitfalls before you write a line of TS

  1. Porting your Python server to TS first and then asking whether you needed to. Port last, decide first. Run the decision memo from the lab before you run npm init.
  2. Treating Zod as “TypeScript with extra steps”. Runtime validation is the whole point; the TS types you get for free are a bonus, not the reason you added the dependency.
  3. Forgetting "type": "module" in package.json. You will get opaque ESM/CJS errors at import time that look unrelated to the missing field. Set it before you write the first import.
  4. Skipping the .js extension on local imports under ESM. The tsc build will succeed; Node will throw “module not found” at runtime. Write ./tools.js even when the file on disk is tools.ts.
  5. Choosing TS for a single-user laptop server “because the lesson said so”. Re-read the When to stay in Python section. The lesson does not say so; the lesson says think.

References