Back to Learn
beginner15 min

Your First MCP Server

Build a working MCP server from scratch in 5 steps.

Prerequisites
  • Node.js 18+ installed
  • Basic TypeScript/JavaScript knowledge
  • A code editor (VS Code recommended)
1
Create Project
Initialize a new Node.js project

Create a new directory and initialize a Node.js project:

Terminal
mkdir my-mcp-server
cd my-mcp-server
npm init -y

Update your package.json to use ES modules:

package.json
{
  "name": "my-mcp-server",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.0.0",
    "zod": "^3.22.0"
  }
}
We use "type": "module" to enable ES module imports, which is required by the MCP SDK.
2
Install Dependencies
Add MCP SDK and Zod for validation
3
Create Server
Write the basic server code
4
Add a Tool
Define your first MCP tool
5
Test It
Run and test your MCP server
Bonus: Adding More Tools
Expand your server with multiple tools

Here's an example with three tools - a greeter, calculator, and random number generator:

index.js (expanded)
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: "my-first-server",
  version: "1.0.0",
});

// Tool 1: Greeting
server.tool(
  "greet",
  "Say hello to someone",
  { name: z.string() },
  async ({ name }) => ({
    content: [{ type: "text", text: `Hello, ${name}!` }],
  })
);

// Tool 2: Calculator
server.tool(
  "calculate",
  "Perform basic math",
  {
    operation: z.enum(["add", "subtract", "multiply", "divide"]),
    a: z.number(),
    b: z.number(),
  },
  async ({ operation, a, b }) => {
    let result: number;
    switch (operation) {
      case "add": result = a + b; break;
      case "subtract": result = a - b; break;
      case "multiply": result = a * b; break;
      case "divide": result = b !== 0 ? a / b : NaN; break;
    }
    return {
      content: [{ type: "text", text: `Result: ${result}` }],
    };
  }
);

// Tool 3: Random number
server.tool(
  "random",
  "Generate a random number",
  {
    min: z.number().default(1),
    max: z.number().default(100),
  },
  async ({ min, max }) => ({
    content: [{
      type: "text",
      text: `Random number: ${Math.floor(Math.random() * (max - min + 1)) + min}`,
    }],
  })
);

const transport = new StdioServerTransport();
await server.connect(transport);
Try It Yourself
Experiment with the code in our interactive playground

Modify the code below and use the "Test Tools" tab to simulate tool calls:

MCP Server Playground

Edit the code and test your tools

Loading...