Turning Point Academy · MCP Engineering

Your first MCP server in TypeScript — Commented code

Curso MCP Engineering · M2


Complete reference guide for the lesson m2 · TypeScript server with the official SDK. It's meant to be read top to bottom and to copy each block in order: first you set up the project, then you write index.ts explained line by line, and finally you run it and connect it to Claude Code. Don't worry if you've never written TypeScript: we define each term as it comes up.


Step 0 — The minimum vocabulary


Step 1 — Start the project

# Create the project folder and enter it
mkdir mi-servidor-mcp
cd mi-servidor-mcp

# Start a Node project with no questions (-y = "yes to everything")
npm init -y

npm init -y creates a package.json file: your project's "record", where Node notes the name, the version and —most important for us— the list of dependencies.


Step 2 — Enable modern modules (import/export)

Open package.json and add the line "type": "module". This tells Node that you're going to use import (the modern syntax) instead of require (the old one). The official SDK uses import, so this step is mandatory.

{
  "name": "mi-servidor-mcp",
  "version": "1.0.0",
  "type": "module"
}

Step 3 — Install dependencies

# The official MCP SDK + Zod (to validate the tools' data)
npm install @modelcontextprotocol/sdk zod

# Optional: only if you're going to read environment variables (keys, tokens, etc.)
npm install dotenv

npm install downloads the libraries into the node_modules folder and notes them in your package.json. The SDK brings everything needed to speak MCP; Zod validates the inputs.


Step 4 — The complete server (index.ts)

Create an index.ts file with this content. Below we explain it block by block.

// ─────────────────────────────────────────────────────────────
// index.ts — Your first MCP server in TypeScript
// ─────────────────────────────────────────────────────────────

// We import the pieces from the official SDK.
// McpServer: the class that represents your server.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// StdioServerTransport: the "pipe" (stdio) through which the host and the server talk.
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// z (Zod): describes and validates what data each tool receives.
import { z } from "zod";

// 1) We create the server.
//    name and version identify it to the host (Claude, an IDE, etc.).
const server = new McpServer({
  name: "demo",
  version: "1.0.0",
});

// 2) We register a tool with server.tool(name, schema, handler):
//    - name   : how the model calls the tool ("suma").
//    - schema : what it receives, described with Zod ({ a, b } are two numbers).
//    - handler: the async function that runs and RETURNS the result.
//
//    The result ALWAYS has the shape { content: [ ... ] }.
//    Here we return a text block with the sum.
server.tool(
  "suma",
  { a: z.number(), b: z.number() },
  async ({ a, b }) => ({
    content: [{ type: "text", text: String(a + b) }],
  })
);

// 3) We open the stdio transport and connect the server.
//    After connect(), the server stays LISTENING for messages.
const transport = new StdioServerTransport();
await server.connect(transport);

What each block does

Notice the pattern: create the server → register tools → connect a transport. That's the skeleton of any MCP server in TypeScript.

Step 5 — Run the server

# tsx runs TypeScript directly, without compiling by hand.
# npx downloads and runs it on the fly.
npx tsx index.ts

You won't see output on screen: the server stays waiting over stdio. That's normal. Close it with Ctrl+C.


Step 6 — Register the server in Claude Code

# Use the ABSOLUTE PATH to your index.ts.
claude mcp add demo -- npx tsx /ruta/absoluta/a/index.ts

# Check that it was registered:
claude mcp list

The absolute path matters: Claude starts your server from any folder, so a relative path (like ./index.ts) might not be found. On macOS/Linux an absolute path starts with /; on Windows, with something like C:\.


Step 7 — Test it

Inside Claude Code, ask something like:

Use the "suma" tool from the demo server to add 21 and 21.

You should see Claude invoke your tool and answer 42.


Common errors (and how to fix them)

The pattern you take away

Create the server → register tools → connect a transport. That's the skeleton of any MCP server in TypeScript; the rest are variations on the same scheme.