Intermediate·Concept·2 min read

Build a Local TypeScript MCP Server

Practice this question

Project setup

Shell
mkdir order-mcp && cd order-mcp
npm init -y
npm install @modelcontextprotocol/server zod
npm install -D typescript tsx @types/node
JSON
{
  "scripts": {
    "dev": "tsx src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js"
  },
  "type": "module"
}

Folder structure

Example
src/
  domain/order.ts
  services/order-service.ts
  tools/register-order-tools.ts
  index.ts
tests/
  order-tool.test.ts

Minimal runnable server

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

const orders = new Map([
  ["ORD-101", { id: "ORD-101", status: "shipped" }],
]);

const server = new McpServer({ name: "order-learning-server", version: "1.0.0" });

server.registerTool(
  "orders.lookup",
  {
    description: "Look up one mock order by ID",
    inputSchema: z.object({ orderId: z.string().regex(/^ORD-\d+$/) }),
    outputSchema: z.object({ id: z.string(), status: z.string() }),
  },
  async ({ orderId }) => {
    const order = orders.get(orderId);
    if (!order) {
      return { content: [{ type: "text", text: "Order not found" }], isError: true };
    }
    return {
      content: [{ type: "text", text: JSON.stringify(order) }],
      structuredContent: order,
    };
  },
);

const transport = new StdioServerTransport();
await server.connect(transport);

What each part does

  • McpServer manages high-level registrations.
  • The Zod schema validates untrusted arguments.
  • The handler can call an existing service or data layer.
  • The transport carries protocol messages.
  • connect attaches the server to the stdio channel.

Expected behavior

The Inspector or client will list the tools and allow the user to select orders.lookup. A valid ID returns a structured order, a malformed ID fails schema validation, and a missing order returns a tool error.

Adapted from 20_MCP_SERVER.md · “8. Build a Local TypeScript MCP Server”. Code examples are study fragments. Difficulty and core labels are editorial estimates; version-specific behavior should be checked against your project.