--- id: general/mcp-server-guide name: MCP Server Development Guide version: 1.0.0 ecosystem: multi type: guide time_sensitivity: evergreen source: verified confidence: high maintainer: Anthropic last_updated: 2026-03-19 --- ## Overview MCP (Model Context Protocol) is an open protocol by Anthropic for connecting AI assistants to external tools, data sources, and services. An MCP Server exposes **Tools** (callable functions), **Resources** (data/files), and **Prompts** (reusable templates) to any MCP-compatible client (Claude Desktop, Cursor, etc.). ## Core Concepts - **Tools**: Functions the LLM can call (e.g., search_web, query_db) - **Resources**: Files or data the LLM can read (e.g., file://, db://) - **Prompts**: Reusable prompt templates with parameters - **Transport**: stdio (local) or HTTP+SSE (remote) ## Minimal MCP Server (TypeScript) ```typescript 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-mcp-server', version: '1.0.0', }) // Register a Tool server.tool( 'get_weather', 'Get current weather for a city', { city: z.string().describe('City name') }, async ({ city }) => { // Your implementation here const weather = await fetchWeather(city) return { content: [{ type: 'text', text: `Weather in ${city}: ${weather.description}, ${weather.temp}°C` }], } } ) // Register a Resource server.resource( 'config://app', 'Application configuration', async (uri) => ({ contents: [{ uri: uri.href, text: JSON.stringify({ version: '1.0' }), mimeType: 'application/json' }], }) ) // Start server const transport = new StdioServerTransport() await server.connect(transport) ``` ## Tool with Multiple Parameters ```typescript server.tool( 'search_database', 'Search records in the database', { query: z.string().describe('Search query'), limit: z.number().optional().default(10).describe('Max results'), table: z.enum(['users', 'products', 'orders']).describe('Table to search'), }, async ({ query, limit, table }) => { const results = await db.search(table, query, limit) return { content: [{ type: 'text', text: JSON.stringify(results, null, 2), }], } } ) ``` ## Claude Desktop Config Add to `~/Library/Application Support/Claude/claude_desktop_config.json`: ```json { "mcpServers": { "my-server": { "command": "node", "args": ["/path/to/your/server/dist/index.js"], "env": { "API_KEY": "your-api-key" } } } } ``` ## HTTP Transport (Remote Server) ```typescript import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js' import express from 'express' const app = express() app.use(express.json()) app.post('/mcp', async (req, res) => { const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined }) await server.connect(transport) await transport.handleRequest(req, res, req.body) }) app.listen(3000) ``` ## Error Handling ```typescript server.tool('risky_op', 'Might fail', { id: z.string() }, async ({ id }) => { try { const result = await riskyOperation(id) return { content: [{ type: 'text', text: result }] } } catch (err) { return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true, } } }) ``` ## Installation ```bash npm install @modelcontextprotocol/sdk zod ``` ## Reference - [MCP Specification](https://modelcontextprotocol.io) - [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) - [MCP Servers examples](https://github.com/modelcontextprotocol/servers)