§05.06

How to Build an MCP Server in TypeScript

Write a one-tool MCP server with the official TypeScript SDK, serve it over stdio, and call it from Claude Code. Copy-paste.

published 06 Sept 2026 checked against docs 06 Sept 2026 4 min in MCP Markdown

On this page5 sections
  1. 1. Set up the project
  2. 2. Write the server
  3. 3. One rule about output
  4. 4. Run and connect it
  5. 5. Call it

The official TypeScript SDK turns a function into an MCP tool. This builds one that any MCP client can call over stdio.

1. Set up the project

mkdir wordcount && cd wordcount
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/server zod

type=module matters — the SDK is ESM. @modelcontextprotocol/server is the v2 server package; it replaces the older monolithic @modelcontextprotocol/sdk package, so ignore v1 snippets that import from there.

2. Write the server

server.ts:

import { McpServer } from "@modelcontextprotocol/server";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import * as z from "zod";

serveStdio(() => {
  const server = new McpServer(
    { name: "wordcount", version: "1.0.0" },
    { capabilities: { tools: {} } }
  );

  server.registerTool(
    "word_count",
    {
      description: "Count the words in a piece of text.",
      inputSchema: z.object({ text: z.string() }),
    },
    async ({ text }) => ({
      content: [{ type: "text", text: String(text.trim().split(/\s+/).length) }],
    })
  );

  return server;
});

serveStdio takes a factory that builds the server for each connection — it replaces the older new StdioServerTransport() plus server.connect(transport) wiring. The zod schema is the tool’s input contract, and the description is what the model reads when deciding whether to call it.

3. One rule about output

stdout is the JSON-RPC channel. The client parses every line of it as a protocol message, so a stray console.log corrupts the stream and the server looks broken. Log with console.error instead.

4. Run and connect it

Node 24 runs .ts files directly in an ESM project, so there’s no build step:

node server.ts

It will sit there waiting for a client on stdin — that’s correct. Stop it with Ctrl+C and hand the same command to Claude Code, with an absolute path:

claude mcp add wordcount -- node C:\path\to\server.ts
claude mcp add wordcount -- node /path/to/server.ts

On older Node versions that can’t strip types, compile to JavaScript first and point the command at the compiled file instead. Restart Claude Code, then check it loaded:

claude mcp list

5. Call it

Use the word_count tool to count the words in the first paragraph of README.md.

Next: build the same server in Python, the best MCP servers to start with, or generate the claude mcp add command with the MCP config generator.

← All MCP plates · Search all guides

↑↓ move↵ openalt+↵ copy first command

Keyboard

⌘/ctrl+K or /
Search all guides
alt+↵
In search: copy the guide's first command
j / k
Move through a list of guides
c
On a guide: copy its first command
t
Toggle light / dark
?
This list