Skip to main content
RapidDev - Software Development Agency
mcp-tutorial

How to install the MCP TypeScript SDK

Install the MCP TypeScript SDK with npm install @modelcontextprotocol/sdk zod, then create a minimal McpServer with stdio transport. The SDK provides the McpServer class for defining tools, resources, and prompts, StdioServerTransport for local communication, and uses Zod for input validation. A working server skeleton is under 20 lines of code.

What you'll learn

  • How to install the MCP TypeScript SDK and its dependencies
  • How to scaffold a minimal MCP server project with TypeScript
  • How to create a McpServer instance with stdio transport
  • How to configure TypeScript and package.json for MCP development
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner7 min read10 minNode.js 18+, TypeScript 5+, npm or yarn or pnpmMarch 2026RapidDev Engineering Team
TL;DR

Install the MCP TypeScript SDK with npm install @modelcontextprotocol/sdk zod, then create a minimal McpServer with stdio transport. The SDK provides the McpServer class for defining tools, resources, and prompts, StdioServerTransport for local communication, and uses Zod for input validation. A working server skeleton is under 20 lines of code.

Setting Up the MCP TypeScript SDK

The TypeScript SDK (@modelcontextprotocol/sdk) is the primary way to build MCP servers. It provides a high-level McpServer class that handles protocol negotiation, capability registration, and message routing. Combined with Zod for schema validation, you get type-safe tool definitions with minimal boilerplate. This tutorial walks you through installation, project setup, and creating your first server skeleton.

Prerequisites

  • Node.js 18 or later installed (check with node --version)
  • npm, yarn, or pnpm package manager
  • A code editor (VS Code, Cursor, or similar)
  • Basic familiarity with TypeScript and npm

Step-by-step guide

1

Create a new project directory and initialize npm

Create a fresh directory for your MCP server project. Initialize it with npm init to create a package.json. Use the -y flag to accept defaults — you can edit the package.json later. This gives you a clean project to install the SDK into.

typescript
1mkdir my-mcp-server
2cd my-mcp-server
3npm init -y

Expected result: A new directory with a package.json file ready for dependency installation.

2

Install the MCP SDK and Zod

Install @modelcontextprotocol/sdk as your main dependency and zod for input schema validation. The SDK includes the McpServer class, transport implementations, and all MCP protocol types. Zod is used to define and validate tool input schemas — the SDK integrates with Zod natively.

typescript
1npm install @modelcontextprotocol/sdk zod

Expected result: Both packages appear in your package.json dependencies. You should see @modelcontextprotocol/sdk and zod in node_modules.

3

Install TypeScript and tsx for development

Install TypeScript for type checking and tsx as a dev dependency for running TypeScript files directly without a separate build step. tsx is a fast TypeScript executor that works out of the box with ESM imports, which the MCP SDK uses.

typescript
1npm install -D typescript tsx @types/node
2npx tsc --init

Expected result: A tsconfig.json file is created. TypeScript and tsx are available in your project.

4

Configure TypeScript for ESM and MCP SDK compatibility

The MCP SDK uses ESM (ECMAScript modules) with .js extensions in import paths. Update your tsconfig.json to use NodeNext module resolution, which handles ESM correctly. Also set the target to ES2022 or later for top-level await support, which MCP servers commonly use.

typescript
1// tsconfig.json
2{
3 "compilerOptions": {
4 "target": "ES2022",
5 "module": "NodeNext",
6 "moduleResolution": "NodeNext",
7 "outDir": "./dist",
8 "rootDir": "./src",
9 "strict": true,
10 "esModuleInterop": true,
11 "skipLibCheck": true,
12 "forceConsistentCasingInFileNames": true
13 },
14 "include": ["src/**/*"]
15}

Expected result: TypeScript is configured for ESM modules with proper resolution for MCP SDK imports.

5

Update package.json for ESM and add scripts

Add "type": "module" to package.json so Node.js treats .js files as ESM. Add scripts for development (using tsx for direct TypeScript execution) and production (compile then run). Also add a "bin" entry if you plan to publish to npm later.

typescript
1// Add these fields to package.json:
2{
3 "type": "module",
4 "scripts": {
5 "dev": "tsx src/index.ts",
6 "build": "tsc",
7 "start": "node dist/index.js"
8 },
9 "bin": {
10 "my-mcp-server": "dist/index.js"
11 }
12}

Expected result: package.json is configured for ESM with dev, build, and start scripts.

6

Create a minimal MCP server skeleton

Create src/index.ts with a minimal MCP server. Import McpServer and StdioServerTransport from the SDK. Create a server instance with a name and version, define one example tool using Zod for input validation, and connect via stdio transport. This is the foundation you will build on — every MCP server starts with this structure.

typescript
1// src/index.ts
2import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4import { z } from "zod";
5
6const server = new McpServer({
7 name: "my-mcp-server",
8 version: "1.0.0",
9});
10
11// Example tool — replace with your own
12server.tool(
13 "hello",
14 "Greet someone by name",
15 { name: z.string().describe("Name of the person to greet") },
16 async ({ name }) => ({
17 content: [{ type: "text", text: `Hello, ${name}!` }],
18 })
19);
20
21// Connect via stdio transport
22const transport = new StdioServerTransport();
23await server.connect(transport);
24console.error("Server started");

Expected result: Running npm run dev starts the server process. It waits for JSON-RPC messages on stdin (you will not see visible output — that is normal for stdio servers).

Complete working example

src/index.ts
1#!/usr/bin/env node
2
3import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5import { z } from "zod";
6
7// Create the MCP server
8const server = new McpServer({
9 name: "my-mcp-server",
10 version: "1.0.0",
11});
12
13// Define a tool with Zod input validation
14server.tool(
15 "hello",
16 "Greet someone by name",
17 { name: z.string().describe("Name of the person to greet") },
18 async ({ name }) => ({
19 content: [
20 {
21 type: "text",
22 text: `Hello, ${name}! This response comes from an MCP server.`,
23 },
24 ],
25 })
26);
27
28// Define a tool with multiple parameters
29server.tool(
30 "calculate",
31 "Perform basic arithmetic",
32 {
33 a: z.number().describe("First number"),
34 b: z.number().describe("Second number"),
35 operation: z.enum(["add", "subtract", "multiply", "divide"]),
36 },
37 async ({ a, b, operation }) => {
38 let result: number;
39 switch (operation) {
40 case "add": result = a + b; break;
41 case "subtract": result = a - b; break;
42 case "multiply": result = a * b; break;
43 case "divide":
44 if (b === 0) {
45 return {
46 content: [{ type: "text", text: "Error: Division by zero" }],
47 isError: true,
48 };
49 }
50 result = a / b;
51 break;
52 }
53 return {
54 content: [{ type: "text", text: `${a} ${operation} ${b} = ${result}` }],
55 };
56 }
57);
58
59// Connect via stdio
60const transport = new StdioServerTransport();
61await server.connect(transport);
62console.error("my-mcp-server started successfully");

Common mistakes when installing the MCP TypeScript SDK

Why it's a problem: Forgetting "type": "module" in package.json

How to avoid: The MCP SDK uses ESM imports with .js extensions. Without "type": "module", Node.js treats files as CommonJS and import statements fail. Add "type": "module" to package.json.

Why it's a problem: Using .ts extensions in import paths

How to avoid: TypeScript with NodeNext resolution requires .js extensions in import paths, even for .ts source files. Write import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" — note the .js extension.

Why it's a problem: Using console.log instead of console.error

How to avoid: Stdio transport uses stdout for JSON-RPC messages. console.log writes to stdout and corrupts the protocol stream. Always use console.error for debugging and logging.

Why it's a problem: Not adding Zod descriptions to parameters

How to avoid: Without .describe() on Zod schemas, the AI model sees parameters without context. Always add descriptions: z.string().describe("Search query keywords") so the model knows what values to pass.

Best practices

  • Always use Zod .describe() on every tool parameter to help the AI model understand what values to provide
  • Use tsx for development (fast, no build step) and tsc + node for production
  • Add #!/usr/bin/env node as the first line of your entry file if you plan to publish to npm as a CLI tool
  • Log to stderr only (console.error) — stdout is reserved for MCP protocol messages in stdio servers
  • Pin your @modelcontextprotocol/sdk version in package.json to avoid unexpected breaking changes
  • Set "strict": true in tsconfig.json for maximum type safety in tool handlers
  • Keep your server entry point clean — extract tool implementations into separate files as the server grows
  • Test your server with MCP Inspector before connecting it to Claude Desktop or Cursor

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

Show me how to set up a new MCP server project with TypeScript. Include the npm install commands, tsconfig.json configuration, package.json setup for ESM, and a minimal server with one tool using the @modelcontextprotocol/sdk and Zod for input validation.

MCP Prompt

Create an MCP server project from scratch. I need the complete setup: package.json with ESM, tsconfig.json, and an src/index.ts file with a McpServer that has two tools using Zod schemas. Include the correct import paths with .js extensions.

Frequently asked questions

What Node.js version do I need for the MCP SDK?

Node.js 18 or later is required. The SDK uses ESM, top-level await, and modern JavaScript features that are not available in older Node.js versions. Node.js 20 LTS or 22 LTS is recommended.

Can I use JavaScript instead of TypeScript?

Yes. The MCP SDK works with plain JavaScript. However, TypeScript is strongly recommended because Zod schemas provide type inference for tool handler parameters, giving you autocomplete and compile-time error checking.

Why does the MCP SDK use .js extensions in import paths?

The SDK is published as ESM. TypeScript's NodeNext module resolution requires explicit file extensions that match the compiled output. Since .ts files compile to .js, you use .js extensions in imports even when the source is TypeScript.

Can I use yarn or pnpm instead of npm?

Yes. yarn add @modelcontextprotocol/sdk zod or pnpm add @modelcontextprotocol/sdk zod work identically. The SDK has no npm-specific dependencies.

Do I need to install Zod separately?

Yes. While the MCP SDK depends on Zod internally, you need it as a direct dependency to define tool input schemas in your code. Install it explicitly: npm install zod.

How do I run the server once it is built?

For development, use npx tsx src/index.ts. For production, compile with npx tsc and run with node dist/index.js. MCP hosts like Claude Desktop and Cursor will launch the server process automatically based on your configuration.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.