MCP Server Quickstart Guide
Build, run, and connect your first Model Context Protocol server in Node.js and TypeScript in under five minutes.
Quick Answer / TL;DR
The fastest way to connect a local AI agent such as Claude Desktop or Cursor to a custom tool is the stdio transport in the official Model Context Protocol SDK: define a tool schema, register list and call handlers, then point the client config at the compiled server.
Key Takeaways
- A minimal MCP server needs only a tool schema and two request handlers: list tools and call tool.
- Validate every tool argument with a schema library such as Zod before executing it.
- Test locally with the MCP Inspector before wiring the server into Claude Desktop or Cursor.
Prerequisites
Install Node.js 18 or higher, and have Claude Desktop or Cursor IDE available to test the finished server.
Basic familiarity with TypeScript and npm is enough to follow this guide end to end.
Initialize the project
Create a new directory, initialize a Node.js project, and install the official SDK along with Zod for input validation.
mkdir my-first-mcp-server
cd my-first-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node
npx tsc --initDefine the tool server
A minimal server declares its name and capabilities, registers a list-tools handler that describes each tool's JSON Schema, and registers a call-tool handler that validates arguments with Zod before executing.
Always validate tool inputs with a schema library. The MCP SDK requires strict JSON Schema definitions for every tool to prevent malformed or malicious requests from reaching your execution logic.
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
const server = new Server(
{ name: "my-first-mcp-server", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
const WeatherSchema = z.object({
location: z.string().describe("The city and state, e.g., 'Mumbai, IN'"),
});
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "get_current_weather",
description: "Get the current weather for a specific location.",
inputSchema: {
type: "object",
properties: { location: { type: "string", description: "The city and state" } },
required: ["location"],
},
},
],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
if (name === "get_current_weather") {
const parsed = WeatherSchema.parse(args);
const mockWeather = { location: parsed.location, temperature: "28C", condition: "Partly Cloudy" };
return { content: [{ type: "text", text: JSON.stringify(mockWeather, null, 2) }] };
}
throw new Error(`Tool ${name} not found`);
});
const transport = new StdioServerTransport();
await server.connect(transport);Compile, test, and connect to Claude Desktop
Compile the TypeScript output, then verify the server responds correctly with the MCP Inspector before wiring it into any client.
To use the server in Claude Desktop, add it to claude_desktop_config.json (in Library/Application Support/Claude on Mac, or %APPDATA%/Claude on Windows) using an absolute path to the compiled entry point, then restart Claude Desktop.
npx tsc
npx @modelcontextprotocol/inspector node dist/index.jsMCP Server Quickstart Guide FAQs
Direct answers for developers, operators, and Indian teams evaluating MCP.