DEV Community

The Daily Agent
The Daily Agent

Posted on

How to Build Your First MCP Server in 10 Minutes

You keep hearing about MCP servers but every tutorial throws you into multi-agent swarms and complex architectures. Here's the simplest possible MCP server -- one file, one tool, fully runnable in 10 minutes.

The Code

Create a new project and install the SDK:

mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
Enter fullscreen mode Exit fullscreen mode

Create server.ts:

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: "weather-server",
  version: "1.0.0",
});

server.registerTool(
  "get-weather",
  {
    title: "Get Weather",
    description: "Get current weather for a city",
    inputSchema: z.object({
      city: z.string().describe("City name"),
    }),
  },
  async ({ city }) => {
    const res = await fetch(
      `https://wttr.in/${encodeURIComponent(city)}?format=j1`
    );
    const data = await res.json();
    const current = data.current_condition[0];

    return {
      content: [
        {
          type: "text",
          text: `${city}: ${current.temp_C}°C, ${current.weatherDesc[0].value}`,
        },
      ],
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Weather MCP server running on stdio");
Enter fullscreen mode Exit fullscreen mode

That's it. 30 lines. A fully functional MCP server.

What's Happening

Lines 1-3 import the three things every MCP server needs: McpServer to create the server instance, StdioServerTransport for the communication layer, and zod for input validation.

Lines 5-8 create your server with a name and version. These show up when AI clients discover your server.

Lines 10-31 register a single tool called get-weather. The inputSchema uses Zod to define and validate what the tool expects -- a city name as a string. The handler function fetches real weather data from wttr.in (a free API, no key needed) and returns it as a text content block.

Lines 33-35 wire up the stdio transport and start the server. Stdio means the AI client launches your server as a child process and communicates over stdin/stdout. This is how Claude Desktop, Cursor, and most local MCP clients work.

Connect It to Claude Desktop

Add this to your Claude Desktop config file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "weather": {
      "command": "npx",
      "args": ["tsx", "/full/path/to/my-mcp-server/server.ts"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart Claude Desktop. Ask it "What's the weather in Tokyo?" and it will call your get-weather tool.

Test It Without a Client

You can also test directly from the terminal using the MCP Inspector:

npx @modelcontextprotocol/inspector npx tsx server.ts
Enter fullscreen mode Exit fullscreen mode

This opens a web UI where you can browse your server's tools and call them manually -- useful for debugging before connecting to an AI client.

What to Build Next

Now that you have a working server, swap the weather API for anything:

  • Database queries: Register a tool that runs read-only SQL against your dev database
  • Internal APIs: Wrap your company's REST endpoints as MCP tools
  • File operations: Let AI assistants read/search your project files

Each new tool is just another server.registerTool() call with a schema and a handler. The MCP SDK handles discovery, validation, and communication automatically.

The full TypeScript SDK has examples for HTTP transports, authentication, streaming, and multi-tool servers at github.com/modelcontextprotocol/typescript-sdk.


This is part of the AI Agent Quick Tips series -- short, code-first tutorials for developers building with AI tools.

Top comments (0)