Как написать свой MCP-сервер
Минимальный сервер собирается за полчаса. Ниже — рабочие примеры на TypeScript и Python: один tool, который умножает два числа. Дальше масштабируется на любые задачи.
1. Выбираем транспорт
Если сервер запускается локально и нужен одному клиенту — берите stdio. Если будет общий и доступен по сети — HTTP + SSE. В этом гайде stdio: он проще и безопаснее (нет открытого порта).
2. TypeScript: минимальный сервер
Создаём проект:
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript tsx @types/nodeФайл src/index.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: "my-mcp-server",
version: "0.1.0",
});
// Объявляем один tool: умножение
server.tool(
"multiply",
"Умножает два числа",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a * b) }],
}),
);
const transport = new StdioServerTransport();
await server.connect(transport);Запуск: npx tsx src/index.ts. Сервер сразу слушает stdin и ждёт MCP-сообщений.
3. Python: то же самое
pip install mcpfrom mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-mcp-server")
@mcp.tool()
def multiply(a: float, b: float) -> float:
"""Умножает два числа."""
return a * b
if __name__ == "__main__":
mcp.run()Запуск: python server.py. Декоратор @mcp.tool() сам подхватит сигнатуру функции и сгенерирует JSON Schema для модели.
4. Подключаем к Claude Desktop
Открываем конфиг Claude Desktop:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"my-mcp": {
"command": "npx",
"args": ["tsx", "/абсолютный/путь/к/src/index.ts"]
}
}
}Перезапускаем Claude Desktop — в нижней панели чата появится иконка-молния, и multiply будет виден среди доступных инструментов.
5. Дальше — что обычно добавляют
- Resources — выгрузка содержимого по URI (файл, ответ от API, запись в БД).
- Prompts — параметризуемые шаблоны, которые пользователь выбирает в UI.
- Logging — пишите в
stderr(stdio транспорт занимаетstdoutпод протокол). - Авторизация — для HTTP-серверов поддерживаются OAuth-флоу; для локальных stdio пользователь сам прописывает токены через переменные окружения.
Типичные грабли
- print() в stdio-сервере ломает протокол. stdout целиком уходит на MCP-сообщения. Любые логи — только в stderr.
- Слишком общие tools. Модели проще выбрать
db.query_users, чемdb.execute: явные узкие функции дают предсказуемое поведение. - Тяжёлые операции без стриминга. Если tool работает секундами — используйте прогресс-нотификации, иначе host-приложение будет казаться зависшим.
Спецификация: modelcontextprotocol.io. Готовые серверы и каталог → список MCP-серверов.