Module 4: MCP Server in TypeScript
Module 4: MCP Server in TypeScript
Module 4: MCP Server in TypeScript
Capsule description
You've reached Phase 2. Modules 1-3 built your vocabulary and mental model: you know what MCP is, how the Host-Client-Server architecture works, and what Resources, Tools, and Prompts are. You even built a minimal server with the 3 primitives. But that server was a prototype — code in a single file, without structure, without robust validation, without transport configuration.
Now you're going to build a real MCP server.
TypeScript isn't an arbitrary choice — it's the language of the MCP ecosystem. Most open source MCP servers are written in TypeScript. The official TypeScript SDK (@modelcontextprotocol/sdk) is the most mature. Anthropic's official documentation uses TypeScript as a reference. If you look at the MCP server repositories on GitHub, TypeScript dominates by a wide margin. Starting with TypeScript means you can read, understand, and contribute to most of the ecosystem from day one.
This module is the densest of Phase 2, and it's intentional. The patterns you learn here — project setup, Zod schemas, error handling, transports — repeat in Python (module 5), in MCP Apps (module 6), and in the capstone project (module 8). Mastering the MCP server in TypeScript is mastering the fundamentals that apply to any language.
Where are we?
Context within the guide
Phase 1: MCP Fundamentals (Modules 1-3)
✅ Module 1: What MCP is and why it matters
✅ Module 2: Host-Client-Server Architecture
✅ Module 3: Three Primitives — Resources, Tools, Prompts
Phase 2: Build MCP Servers (Modules 4-6)
→ Module 4: MCP Server in TypeScript (YOU ARE HERE)
○ Module 5: MCP Server in Python
○ Module 6: MCP Apps and Interactive UI
Phase 3: Production (Modules 7-8)
○ Module 7: Testing, Debugging, and Integration
○ Module 8: Project — Real MCP Server
What you already know
From the previous modules you bring:
- The M×N vs M+N mental model — why a standard protocol is necessary
- The Host-Client-Server architecture — how the pieces connect
- The 3 primitives — Resources (data), Tools (actions), Prompts (templates)
- A minimal MCP server — 1 resource, 1 tool, 1 prompt working in Claude Code
- Experience with the basic SDK —
McpServer,StdioServerTransport,zfrom Zod
What's missing
Your server from module 3 was a monolithic file. It didn't have a real project structure. The Zod schemas were basic. You didn't explore dynamic resources or URI templates. And you only used stdio as a transport. In this module you're going to close those gaps.
Why TypeScript dominates the MCP ecosystem
The numbers
If you explore the MCP server repositories on GitHub, the pattern is clear:
Distribution of open source MCP servers (approximate):
├── TypeScript/JavaScript ~65%
├── Python ~25%
├── Go ~5%
├── Rust ~3%
└── Others ~2%
It's not accidental. There are technical and ecosystem reasons:
1. The SDK was born in TypeScript
The TypeScript @modelcontextprotocol/sdk was the first official SDK. It has the most complete API surface, the most detailed documentation, and the most polished reference examples. When Anthropic builds a new official MCP server, it does so in TypeScript first.
2. Zod as the validation standard
Zod is the validation library the SDK uses to define tool schemas. It's not a wrapper over JSON Schema — it's a typed validation library that generates JSON Schema automatically. This means:
// With Zod: typed definition + validation + JSON Schema, all in one
{
filePath: z.string().describe("Path of the file"),
content: z.string().min(1).describe("Content"),
overwrite: z.boolean().default(false),
}
// Equivalent in manual JSON Schema:
{
"type": "object",
"properties": {
"filePath": { "type": "string", "description": "Path of the file" },
"content": { "type": "string", "minLength": 1, "description": "Content" },
"overwrite": { "type": "boolean", "default": false }
},
"required": ["filePath", "content"]
}
Zod is more concise, more readable, and gives you runtime validation for free. You'll see this in detail in capsule 03.
3. The Node.js ecosystem is the natural match
MCP servers need filesystem access, process execution, networking. Node.js has mature APIs for all of this. Also, many integrations an MCP server needs (GitHub API, Slack API, database clients) have first-class SDKs in JavaScript/TypeScript.
4. TypeScript strict mode catches errors before runtime
When you use strict: true in your tsconfig.json, TypeScript catches a whole category of errors that in JavaScript or Python only appear when the code runs:
// ❌ TypeScript strict mode detects it at compile time
function processResult(result: ToolResult) {
console.log(result.content[0].text.toUpperCase());
// ^^^^ Error: 'text' is possibly undefined
}
// ✅ The fix is explicit
function processResult(result: ToolResult) {
const text = result.content[0]?.text;
if (text) {
console.log(text.toUpperCase());
}
}
In an MCP server, where inputs come from a language model and outputs go to a protocol with a strict format, this level of type safety prevents real bugs.
Comparison: TypeScript vs Python for MCP servers
| Aspect | TypeScript SDK | Python SDK |
|---|---|---|
| Maturity | More mature, more complete API | Mature, evolving API |
| Validation | Zod (typed + runtime) | Pydantic / type hints |
| Style | Methods: server.tool() | Decorators: @server.tool() |
| Concurrency | Native event loop (Node.js) | asyncio |
| Ecosystem | More reference MCP servers | More ML/AI libraries |
| Community | Dominant in MCP servers | Dominant in AI/ML apps |
| Setup | npm + tsconfig | pip + venv |
| Error handling | try/catch + isError | try/except + raise |
The choice isn't "one is better than the other" — it's "which fits your use case better." For MCP servers, TypeScript has the edge because of the ecosystem. For integrating with ML pipelines, Python has the edge. You'll learn both.
What the community says
If you review the most popular MCP server repositories, the pattern is clear:
- Filesystem Server (Anthropic) → TypeScript
- GitHub Server (Anthropic) → TypeScript
- Slack Server (Anthropic) → TypeScript
- PostgreSQL Server (community) → TypeScript
- Brave Search Server (community) → TypeScript
Anthropic's official servers are all in TypeScript. The most maintained community servers tend to be in TypeScript. This doesn't mean Python is worse — it means that when you look for examples, documentation, or servers to study, TypeScript will be your first resource.
The Zod factor
Zod deserves special mention because it's more than a validation library — it's the runtime type system of the MCP ecosystem in TypeScript. When you define a Zod schema for a tool:
- TypeScript infers the handler's types automatically
- The SDK generates JSON Schema for the MCP protocol
- Validation happens at runtime before your code runs
- Validation errors are automatically formatted for the model
This means a single Zod schema solves three problems: typing, validation, and protocol documentation. In Python, you need to combine type hints (typing), Pydantic (validation), and docstrings (documentation) to achieve the same.
It's not that Python is inferior — FastMCP's decorators are elegant and concise. But Zod offers a more integrated experience for the specific case of MCP servers.
Module objective
By the end of this module, you'll be able to:
- ✅ Create an MCP project in TypeScript from scratch — npm init, dependencies, tsconfig, structure
- ✅ Implement multiple tools with Zod schemas that validate inputs automatically
- ✅ Implement static and dynamic resources with URI templates
- ✅ Understand and configure transports — stdio for local development, HTTP/SSE for remote use
- ✅ Handle robust error handling in tools and resources
- ✅ Build a complete MCP server with multiple tools for a real use case
- ✅ Connect your server to Claude Code and verify that it works end-to-end
The jump from module 3 to module 4
So you understand the magnitude of the progress:
Module 3 — Minimal server:
├── 1 file (src/index.ts)
├── 1 resource (static)
├── 1 tool (basic)
├── 1 prompt (simple)
├── Trivial Zod schemas
├── No project structure
├── Only stdio
└── ~150 lines of code
Module 4 — Complete server:
├── Professional project structure
├── Multiple resources (static + templates)
├── Multiple tools (with full validation)
├── Advanced Zod schemas (enums, arrays, nested objects)
├── Robust error handling
├── Transports: stdio + HTTP/SSE + Streamable HTTP
├── Modular and maintainable code
└── ~500+ lines of code
Don't worry about the magnitude — you go step by step. Each capsule adds a piece, and at the end everything fits together.
Module roadmap
| Capsule | Topic | What you'll learn |
|---|---|---|
| 02 | Project and SDK setup | Create a project from scratch: npm, TypeScript, dependencies, structure |
| 03 | Implement Tools | Tools with Zod schemas: basic, complex, with error handling |
| 04 | Implement Resources | Static resources, dynamic ones, URI templates, discovery |
| 05 | Transports: stdio and HTTP | Configure stdio for local, HTTP/SSE for remote, when to use each |
| 06 | Project: TS MCP Server | Complete server with multiple tools for a real use case |
Learning flow
The progression is deliberate:
- Setup (capsule 02) — first things first: a project that compiles and runs. Without this, nothing else works.
- Tools (capsule 03) — the most important primitive. Here you spend 80% of the implementation time of a real MCP server.
- Resources (capsule 04) — contextual data with URI templates. They complement the tools and make your server richer.
- Transports (capsule 05) — how your server communicates with the host. It determines where and how it runs.
- Project (capsule 06) — everything together: a complete MCP server you could use in your real work.
Each capsule is ~40% theory and ~60% practice. You're going to write a lot of code.
Connection to the capstone project (Module 8)
The server you build in capsule 06 of this module is the prototype of the capstone project in Module 8. The patterns are the same:
Module 4 → Module 8:
├── Project setup → Same pattern, more dependencies
├── Zod schemas → Same library, more complex schemas
├── Error handling → Same patterns, more edge cases
├── Resources with templates → Same API, connected to a real DB
├── Tools with validation → Same patterns, more complex operations
└── Transport configuration → Same setup, possible remote deploy
Every decision you make in this module — how you structure your code, how you define your schemas, how you handle errors — you'll use directly in the final project. You're not learning something temporary; you're building habits you'll apply in every MCP server you create.
Prerequisites
For this module you need:
- ✅ Node.js v18+ installed —
node --version - ✅ npm installed —
npm --version - ✅ Claude Code installed and working —
claude --version - ✅ A code editor with TypeScript support (VS Code, Cursor, etc.)
- ✅ Modules 1-3 completed — especially the module 3 mini-project
TypeScript knowledge needed
You don't need to be a TypeScript expert. What you need to know:
// Typed variables
const name: string = "hello";
const count: number = 42;
const items: string[] = ["a", "b"];
// Interfaces / types
interface User {
id: string;
name: string;
email: string;
}
// Async functions
async function getData(): Promise<string> {
const result = await fetch("...");
return result.text();
}
// Imports/exports
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
export function helper() { ... }
If this looks familiar, you're ready. If not, you can learn as you go — the examples are self-explanatory.
Boundaries: what is NOT covered in this module
- ❌ Implementation in Python — That comes in module 5
- ❌ MCP Apps with UI — Covered in module 6
- ❌ Automated testing — Covered in module 7
- ❌ Deploy to production — Covered in module 8
- ❌ Sampling (server-initiated LLM calls) — Advanced feature outside the scope of this guide
- ❌ MCP Roots — A context feature the host can send, mentioned but not implemented
This module is pure construction. You're building the "how to do it in TypeScript" after having understood the "what it can do" in the previous modules.
Signs of success
By the end of this module, you'll know you succeeded if:
- ✅ You can create an MCP project in TypeScript from scratch in less than 5 minutes
- ✅ Your tools have Zod schemas that validate inputs automatically
- ✅ You can implement resources with URI templates that are discovered dynamically
- ✅ You understand when to use stdio vs HTTP/SSE and can configure both
- ✅ You have a functional MCP server with multiple tools connected to Claude Code
- ✅ You feel comfortable reading open source MCP server code in TypeScript
- ✅ You're ready to implement the same in Python (module 5) or scale to the final project (module 8)
Mindset for this module
This module is a workshop. It's not a lecture where you listen passively. The ratio is ~80% code, ~20% explanation. Each concept is demonstrated with runnable code you can copy, compile, and test.
Four principles to get the most out of it:
-
Write the code, don't just read it mentally. The difference between reading code and writing it is enormous. Write each example, compile, run. The compilation errors you find are part of the learning.
-
Test with MCP Inspector before Claude Code. The Inspector gives you immediate and visual feedback. Claude Code is the final destination, but the Inspector is your development tool.
-
Break things on purpose. What happens if you send a string where Zod expects a number? What happens if the resource points to a file that doesn't exist? What happens if the transport doesn't connect? Discovering the failure modes teaches you more than just following the happy path.
-
Read the code of existing servers. When you finish each capsule, open an open source MCP server on GitHub and look for the same patterns. Seeing how other developers implement tools and resources solidifies your understanding.
Frequently asked questions before starting
"Do I need to know TypeScript for this module?"
You need the basics: types, interfaces, async/await, imports. You don't need to know advanced generics, mapped types, or conditional types. The examples are self-explanatory and the focus is on the MCP patterns, not on advanced TypeScript.
"Can I jump straight to module 5 (Python)?"
You can, but I don't recommend it. The concepts are explained in more depth here because TypeScript is the main module. Module 5 assumes you already understand the patterns from this module and focuses on Python's idiomatic differences.
"Is my server from module 3 still useful?"
Yes. In fact, you can use your module 3 server as a reference while you build this module's. You're going to see the same patterns, but more complete and robust.
"How much code am I going to write?"
The capsule 06 project has ~500+ lines distributed across several files. You don't write them all at once — each capsule adds a piece. At the end, everything integrates.
"Do I need an IDE with TypeScript support?"
Highly recommended. VS Code or Cursor with the TypeScript Language Server give you autocompletion, real-time error detection, and code navigation. If you don't use an IDE with TS support, compilation errors are your only feedback — it's slower but it works.
Tools you'll use in this module
| Tool | What you use it for |
|---|---|
| Node.js | Runtime of your MCP server |
| npm | Dependency management |
| TypeScript (tsc) | Compiler — converts .ts to .js |
| @modelcontextprotocol/sdk | Official SDK to create MCP servers |
| Zod | Schema validation for tools |
| MCP Inspector | Visual testing of your server (tools, resources, prompts) |
| Claude Code | The host that consumes your MCP server |
| VS Code / Cursor | Recommended IDE with TypeScript support |
You don't need to install everything now — capsule 02 guides you step by step.
Summary
- This module marks the start of Phase 2: Build MCP Servers
- TypeScript is the dominant language of the MCP ecosystem — the most mature SDK, more reference servers, Zod for validation
- You go from a minimal server (1 file, 3 primitives) to a professional server (project structure, complex schemas, transports)
- The capsules follow an arc: Setup → Tools → Resources → Transports → Project
- The patterns you learn here apply directly to the capstone project in Module 8
- This module is ~80% code — it's a workshop, not a lecture
- TypeScript first isn't an arbitrary preference — it's where the ecosystem, the documentation, and the reference examples are
Additional resources
- MCP TypeScript SDK - Official SDK you'll use throughout the module
- Zod Documentation - Validation library for tool schemas
- TypeScript Handbook - TypeScript reference if you need a refresher
- MCP Specification - Official protocol specification
- MCP Inspector - Visual testing and debugging tool
- Awesome MCP Servers - Directory of community MCP servers (most in TypeScript)
- Node.js fs/promises API - Filesystem API you'll use frequently
- Official MCP Servers (Anthropic) - Reference servers implemented in TypeScript
Next capsule: Project and SDK setup — create an MCP project in TypeScript from scratch, configured and ready to implement tools and resources.