Model Context Protocol (MCP) — это открытый стандарт от Anthropic, который позволяет AI-моделям подключаться к внешним инструментам, источникам данных и сервисам структурированным и безопасным способом. Вместо того чтобы встраивать интеграции непосредственно в каждое AI-приложение, MCP предоставляет универсальный интерфейс: хост (Claude Desktop, Cursor, VS Code, Claude Code) говорит на MCP, и любой MCP-сервер подключается мгновенно.
Создать собственный MCP-сервер на удивление просто, как только вы разберётесь в архитектуре. В этом туториале мы построим полноценный MCP-сервер с нуля на TypeScript с использованием официального @modelcontextprotocol/sdk. К концу у вас будет сервер, который можно использовать локально, делиться с командой или опубликовать на npm для обнаружения в каталоге Mindaxis.
Архитектура MCP
Прежде чем писать код, стоит разобраться в трёх ключевых компонентах экосистемы MCP:
- Хост — AI-приложение (Claude Desktop, Cursor, VS Code, Claude Code). Хост запускает серверы и взаимодействует с ними.
- Сервер — ваш код. Он предоставляет инструменты, ресурсы и промпты, которые хост может вызывать.
- Транспорт — способ передачи сообщений между хостом и сервером. Самый распространённый —
stdio(стандартный ввод/вывод), хотя HTTP с Server-Sent Events тоже поддерживается.
MCP-сервер — это долгоживущий процесс. Хост запускает его, обменивается JSON-RPC 2.0 сообщениями через stdio, а сервер отвечает на запросы возможностей. Когда пользователь закрывает AI-приложение, хост завершает работу сервера.
Три примитива
Каждый MCP-сервер предоставляет комбинацию трёх примитивов:
- Инструменты (Tools) — вызываемые функции. AI может вызвать инструмент с аргументами и получить результат:
search_codebase(query),run_sql(query),send_slack_message(channel, text). - Ресурсы (Resources) — читаемые источники данных с URI и содержимым: файлы, записи БД, снимки страниц.
- Промпты (Prompts) — переиспользуемые шаблоны промптов с аргументами, которые хост может показывать в интерфейсе.
Инициализация проекта
Требования
- Node.js 18 и выше
- npm или pnpm
- Знание TypeScript
Создание проекта
mkdir my-mcp-server
cd my-mcp-server
npm init -y
Установите зависимости:
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx
Создайте tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Обновите package.json:
{
"name": "my-mcp-server",
"version": "1.0.0",
"type": "module",
"bin": {
"my-mcp-server": "./dist/index.js"
},
"scripts": {
"build": "tsc",
"dev": "tsx src/index.ts",
"start": "node dist/index.js"
}
}
Написание MCP-сервера
Создайте src/index.ts. Мы построим простой, но практичный сервер — менеджер текстовых заметок, который позволяет AI создавать, перечислять, читать и удалять заметки на диске.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import fs from "fs/promises";
import path from "path";
const NOTES_DIR = path.join(process.env.HOME ?? ".", ".mcp-notes");
await fs.mkdir(NOTES_DIR, { recursive: true });
const server = new McpServer({
name: "notes-manager",
version: "1.0.0",
});
Определение инструментов
server.tool(
"create_note",
"Создать новую текстовую заметку",
{
title: z.string().describe("Заголовок заметки"),
content: z.string().describe("Содержимое заметки"),
},
async ({ title, content }) => {
const filename = title.toLowerCase().replace(/s+/g, "-") + ".txt";
const filepath = path.join(NOTES_DIR, filename);
await fs.writeFile(filepath, content, "utf-8");
return {
content: [{ type: "text", text: `Заметка создана: ${filename}` }],
};
}
);
server.tool(
"list_notes",
"Получить список всех заметок",
{},
async () => {
const files = await fs.readdir(NOTES_DIR);
const notes = files.filter((f) => f.endsWith(".txt"));
return {
content: [{ type: "text", text: notes.length > 0 ? notes.join("\n") : "Заметок нет." }],
};
}
);
Запуск сервера
const transport = new StdioServerTransport();
await server.connect(transport);
Тестирование с MCP Inspector
MCP Inspector — самый быстрый способ проверить работу сервера перед интеграцией с AI-хостом:
npx @modelcontextprotocol/inspector tsx src/index.ts
Откроется локальный веб-интерфейс, где можно:
- Просмотреть все инструменты, ресурсы и промпты
- Вызвать инструменты с произвольными аргументами и посмотреть JSON-RPC ответы
- Прочитать ресурсы напрямую
- Изучить полный лог сообщений
Интеграция с AI-хостами
Claude Desktop
Добавьте сервер в ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"notes-manager": {
"command": "node",
"args": ["/абсолютный/путь/к/dist/index.js"]
}
}
}
Cursor IDE
Отредактируйте ~/.cursor/mcp.json:
{
"mcpServers": {
"notes-manager": {
"command": "node",
"args": ["/абсолютный/путь/к/dist/index.js"]
}
}
}
Claude Code
claude mcp add notes-manager node /абсолютный/путь/к/dist/index.js
Безопасная работа с секретами
Никогда не хардкодьте API-ключи. Используйте переменные окружения:
const apiKey = process.env.MY_SERVICE_API_KEY;
if (!apiKey) {
throw new Error("MY_SERVICE_API_KEY не задан");
}
Конструктор Mindaxis автоматически генерирует правильные шаблоны переменных окружения для каждого AI-хоста.
Обработка ошибок
MCP-инструменты должны возвращать структурированные ошибки, а не бросать исключения:
server.tool("risky_op", "...", { input: z.string() }, async ({ input }) => {
try {
const result = await riskyOperation(input);
return { content: [{ type: "text", text: result }] };
} catch (err) {
return {
content: [{ type: "text", text: `Ошибка: ${err instanceof Error ? err.message : "Неизвестная ошибка"}` }],
isError: true,
};
}
});
Публикация на npm
Когда сервер готов, опубликуйте его на npm:
npm run build
npm publish --access public
После публикации другие разработчики смогут использовать ваш сервер через npx без глобальной установки. Также добавьте его в каталог Mindaxis, чтобы сообщество могло его найти.
Типичные ошибки
- Относительные пути в конфигах — всегда используйте абсолютные пути
- Забыли собрать проект — после изменений всегда запускайте
npm run build - Запись в stdout в stdio-сервере — никогда не используйте
console.log, толькоconsole.error - Отсутствие валидации входных данных — всегда проверяйте входные данные с Zod
Что строить дальше
Идеи для практичных MCP-серверов:
- Сервер запросов к БД — read-only SQL к PostgreSQL или SQLite
- Интеграция с GitHub — поиск issues, создание PR, чтение файлов
- Поиск по документации — индексация внутренней документации с семантическим поиском
- Автоматизация браузера — скриншоты и взаимодействие со страницами через Playwright
Просмотрите полный каталог существующих MCP-серверов, чтобы найти вдохновение. Если вы создали что-то полезное, добавьте сервер в каталог Mindaxis.
