MCP in Depth: build MCP servers in TypeScript · Part 1 of 9
What is MCP? Model Context Protocol explained
The video for this part is on its way to the channel. The written lesson comes first so you can start now.
Every AI app that wants to touch your files, your database or your tickets used to need its own custom integration. MCP is the attempt to replace that with one shared plug. If you want the comparison with regular APIs first, read MCP vs API: what is the difference?.
The three roles#
- Host: the AI app a person uses, for example a desktop chat app, a terminal agent or an IDE.
- Client: a connection manager inside the host. The host creates one client per server.
- Server: a small program that offers capabilities. It can run on your machine or remotely.
A server can offer tools (the model calls them), resources (the app reads them as context) and prompts (the user picks them). This part uses tools only.
Set up#
You need Node.js 20 or newer. Create a folder and install the SDK, zod for the input schema, and tsx to run TypeScript directly:
mkdir repopilot && cd repopilot
npm init -y
npm pkg set type=module
npm i @modelcontextprotocol/sdk zod
npm i -D tsx typescriptYour first server#
One tool, add. It is deliberately boring so the protocol is the only new thing:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({ name: "repopilot", version: "0.1.0" });
server.registerTool(
"add",
{
description: "Add two numbers.",
inputSchema: { a: z.number(), b: z.number() },
},
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
}),
);
await server.connect(new StdioServerTransport());Save it as server.ts. Three things worth noticing:
- The description is for the model. It is the only thing telling it when to use the tool.
- The input schema is zod. The SDK turns it into JSON Schema and validates every call for you.
- The result is a list of content blocks, not a bare value.
Run it in the Inspector#
Do not wire a server into an AI app before you have seen it work alone. The MCP Inspector is a small web UI that acts as a client:
npx @modelcontextprotocol/inspector npx tsx server.tsOpen the URL it prints, connect, open the Tools tab, run add with a = 2 and b = 3. You should get 5.
The stdio rule. With stdio, stdout is the protocol. A stray
console.logbreaks the connection in confusing ways. Log withconsole.error, which goes to stderr.
Register it in an AI app#
In Claude Code, one command registers a local stdio server:
claude mcp add repopilot -- npx tsx /absolute/path/to/server.tsOther apps take the same command and arguments in their MCP settings file. Ask the app to add two numbers and watch it pick your tool.
What you learned#
- MCP has three roles: host, client and server.
- A tool is a name, a description for the model, an input schema and a handler.
- stdio servers must keep stdout clean.
- Test with the Inspector before connecting an app.
Next up: real tools for RepoPilot, starting with git_log and git_diff.
Frequently asked questions
What does MCP stand for?
Model Context Protocol.
What is the difference between an MCP host, client and server?
The host is the AI app the user talks to. It creates one client per server connection. The server is the program that offers tools, resources and prompts.
Why must an MCP stdio server never print to stdout?
With the stdio transport, stdout carries the protocol messages. Anything else written there corrupts the stream. Log to stderr with console.error instead.
Prefer plain text? Read this page as Markdown.