Skip to main content
Build Your Own MCP Server: Step-by-Step with TypeScript
Back to Blog
AI Connectors April 3, 2026 Updated: September 30, 2026 8 min readby Matthias Meyer

Build Your Own MCP Server: Step-by-Step with TypeScript

A local MCP server with the official TypeScript SDK v2: Node.js, ESM, one tool, stdio and client configuration. With a verified code example.

On this page▾

An MCP server exposes tools with clearly described inputs to an AI application. Start with a local function. Move to a remote interface once the tool and client work together.

This guide follows the stable version 2 of the official TypeScript SDK and protocol revision 2026-07-28, as of September 30, 2026. Older tutorials using @modelcontextprotocol/sdk and session transports belong to SDK v1. Do not mix the two APIs.

Create a project with Node.js 20 or later#

mkdir mein-mcp-server
cd mein-mcp-server
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/server@2 zod@4 tsx
mkdir src

type=module is required because the SDK uses ES modules. Here tsx runs TypeScript directly, so there is no tsc build or assumed dist/index.js. Shipping JavaScript instead requires a suitable build configuration; tsc --init alone does not establish that output path.

Register a tool#

Save this as src/index.ts:

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

serveStdio(() => {
  const server = new McpServer({ name: "mein-server", version: "1.0.0" });

  server.registerTool(
    "add_numbers",
    {
      description: "Add two numbers and return their sum",
      inputSchema: z.object({ a: z.number(), b: z.number() })
    },
    async ({ a, b }) => ({
      content: [{ type: "text", text: String(a + b) }]
    })
  );

  return server;
});

The schema validates both numbers. The description tells the assistant when the tool is useful. serveStdio handles communication over the process's standard streams. Run npx tsx src/index.ts to start it; waiting for input without printing a greeting is normal.

Connect a local client#

Claude Desktop's local configuration is at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS and %APPDATA%\Claude\claude_desktop_config.json on Windows. Use absolute paths for the installed tsx executable and your source file:

{
  "mcpServers": {
    "mein-server": {
      "command": "/absolute/path/to/node_modules/.bin/tsx",
      "args": ["/absolute/path/to/mein-mcp-server/src/index.ts"]
    }
  }
}

On Windows, adjust the executable path to your installation too. Restart the client and check that add_numbers is available. Ask the assistant to add two numbers with that tool, then check both the answer and the actual tool call.

Claude Code can register the same local process:

claude mcp add mein-server -- /absolute/path/to/node_modules/.bin/tsx /absolute/path/to/mein-mcp-server/src/index.ts

Before production#

With stdio, do not print debugging output to stdout: that stream is for protocol messages. Send local logs to stderr. Limit inputs, handle expected failures clearly and return tool errors appropriately. External services need timeouts and, where relevant, rate limits.

The addition example has no external service dependencies and changes no data. Tools that write files or call external APIs require actual permissions, secret management and checks on side effects. Local transport does not guarantee the server sends no data over the network.

Serve it remotely over HTTP#

Use the SDK-v2 HTTP guidance and a complete integration for your runtime rather than an old session example. Revision 2026-07-28 uses per-request metadata; protocol sessions and the separate GET stream are not part of that revision.

Check origin validation, authentication and permissions. Local HTTP tests should listen on localhost only. A reachable endpoint alone is not a secure production integration. Also check which revision the intended client supports.

Sources: SDK-v2 quickstart, MCP transports, stdio, stdio versus HTTP.

Matthias Meyer

Matthias Meyer

Founder & AI Director

Founder & AI Director at StudioMeyer. Has been building websites and AI systems for 10+ years. Living on Mallorca since 2011, running an AI and web design studio there: web design, AI connectors, AI systems and custom-trained models, plus three self-serve MCP servers.

Update history

  • Rebuilt the MCP tutorial around SDK v2; compiled and executed the TypeScript example through stdio.
MCPTutorialTypeScriptsdkserverbuild
Model Context Protocol

Three more posts from the same topic cluster that show how the picture fits together:

Cluster overview: MCP vs REST API vs WebMCP: When to Use Which Protocol