Антон Ларичев

Введение
MCP сервер — это способ дать AI-ассистенту доступ к данным и инструментам вашего проекта через стандартизированный протокол. Model Context Protocol (MCP) был создан компанией Anthropic как открытый стандарт, и сегодня его поддерживают Claude, Cursor, VS Code и десятки других AI-инструментов. Если вы хотите, чтобы ваш AI-помощник не просто генерировал код, а работал с вашей базой данных, API и файлами — MCP сервер решает именно эту задачу.
В этой статье разберём архитектуру Model Context Protocol, создадим MCP сервер на TypeScript с нуля и подключим его к AI-ассистенту. Всё с рабочими примерами кода, которые можно сразу использовать в своём проекте.
Как устроен Model Context Protocol
MCP работает по клиент-серверной модели. MCP-клиент — это AI-приложение (Claude Desktop, Cursor, JetBrains AI Assistant), а MCP-сервер — ваша программа, которая предоставляет данные и инструменты.
Общение между клиентом и сервером происходит через JSON-RPC 2.0. Протокол определяет три типа сущностей, которые сервер может предоставить:
- Tools — функции, которые AI может вызывать. Например, запрос к API, запись в базу данных, отправка уведомления
- Resources — данные для чтения. Конфигурации, документы, состояние системы
- Prompts — шаблоны взаимодействия. Готовые инструкции для типовых сценариев
Какой транспорт выбрать для MCP сервера
MCP поддерживает два основных транспорта:
STDIO — сервер запускается как дочерний процесс, обмен данными через stdin/stdout. Подходит для локальной разработки и CLI-инструментов.
Streamable HTTP — сервер работает как HTTP-эндпоинт. Подходит для удалённого доступа, когда MCP сервер развёрнут на сервере или в облаке.
Для большинства проектов начинайте со STDIO — он проще в настройке и отладке.
Как создать MCP сервер на TypeScript
Установим зависимости и настроим проект:
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx
Настроим TypeScript в tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist",
"strict": true
}
}
Теперь создадим сам MCP сервер. В файле src/index.ts:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Создаём экземпляр MCP сервера
const server = new McpServer({
name: "my-project-server",
version: "1.0.0",
});
// Регистрируем инструмент для поиска пользователей
server.tool(
"find-user",
"Найти пользователя по email или ID",
{
query: z.string().describe("Email или ID пользователя"),
},
async ({ query }) => {
// Здесь ваша логика поиска — запрос к БД, API и т.д.
const user = await findUserInDatabase(query);
return {
content: [
{
type: "text",
text: JSON.stringify(user, null, 2),
},
],
};
}
);
// Регистрируем ресурс — конфигурация проекта
server.resource("project-config", "config://main", async (uri) => ({
contents: [
{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify({
environment: process.env.NODE_ENV,
version: "2.1.0",
features: ["auth", "notifications", "analytics"],
}),
},
],
}));
// Запускаем сервер через STDIO транспорт
const transport = new StdioServerTransport();
await server.connect(transport);
Обратите внимание: валидация входных параметров инструментов выполняется через Zod-схемы. SDK автоматически проверяет данные от AI-клиента и возвращает понятные ошибки.
Как подключить MCP сервер к Claude Desktop
После создания сервера его нужно зарегистрировать в AI-клиенте. Для Claude Desktop откройте файл конфигурации claude_desktop_config.json:
{
"mcpServers": {
"my-project": {
"command": "npx",
"args": ["tsx", "/path/to/my-mcp-server/src/index.ts"],
"env": {
"DATABASE_URL": "postgresql://localhost:5432/mydb"
}
}
}
}
Для Cursor конфигурация аналогична — файл .cursor/mcp.json в корне проекта:
{
"mcpServers": {
"my-project": {
"command": "npx",
"args": ["tsx", "src/index.ts"],
"cwd": "/path/to/my-mcp-server"
}
}
}
После перезапуска клиента AI-ассистент увидит ваши инструменты и ресурсы. Попросите его «найти пользователя с email test@example.com» — и он вызовет ваш tool find-user.
Практический пример: MCP сервер для работы с задачами
Разберём более реалистичный сценарий — MCP сервер для управления задачами проекта:
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: "task-manager",
version: "1.0.0",
});
// Инструмент: создать задачу
server.tool(
"create-task",
"Создать новую задачу в проекте",
{
title: z.string().describe("Название задачи"),
priority: z.enum(["low", "medium", "high"]).describe("Приоритет"),
assignee: z.string().optional().describe("Исполнитель"),
},
async ({ title, priority, assignee }) => {
const task = await db.tasks.create({
data: { title, priority, assignee, status: "open" },
});
return {
content: [{ type: "text", text: `Задача #${task.id} создана: ${title}` }],
};
}
);
// Инструмент: получить статистику по задачам
server.tool(
"task-stats",
"Показать статистику задач по статусам и приоритетам",
{},
async () => {
const stats = await db.tasks.groupBy({
by: ["status", "priority"],
_count: true,
});
return {
content: [{ type: "text", text: JSON.stringify(stats, null, 2) }],
};
}
);
// Ресурс: список открытых задач
server.resource("open-tasks", "tasks://open", async (uri) => {
const tasks = await db.tasks.findMany({
where: { status: "open" },
orderBy: { priority: "desc" },
});
return {
contents: [
{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify(tasks, null, 2),
},
],
};
});
const transport = new StdioServerTransport();
await server.connect(transport);
Теперь AI-ассистент может создавать задачи, просматривать статистику и читать список открытых задач — всё через типизированный интерфейс с валидацией.
Отладка MCP сервера с Inspector
Для отладки используйте MCP Inspector — визуальный инструмент, который показывает каждое JSON-RPC сообщение между клиентом и сервером:
npx @modelcontextprotocol/inspector npx tsx src/index.ts
Inspector откроется в браузере и покажет список доступных tools, resources и prompts. Вы можете вызывать инструменты вручную, видеть запросы и ответы, проверять ошибки валидации.
Частые ошибки при создании MCP сервера
Сервер не отвечает после подключения. Проверьте, что вы не пишете в stdout напрямую. MCP использует stdout для JSON-RPC — любой console.log сломает протокол. Используйте console.error для отладочного вывода.
AI-ассистент не видит инструменты. Убедитесь, что описания tools понятные и конкретные. AI принимает решение о вызове инструмента на основе его описания. «Работа с данными» — плохо, «Найти пользователя по email или ID в базе PostgreSQL» — хорошо.
Ошибки типизации в параметрах. Всегда добавляйте .describe() к каждому полю Zod-схемы. Без описания AI-клиент не сможет правильно заполнить параметры.
Таймауты при длительных операциях. Если ваш инструмент выполняет долгую операцию, используйте прогресс-токены SDK для отправки промежуточных статусов клиенту.
Заключение
MCP сервер — это мост между AI-ассистентом и вашим проектом. Model Context Protocol стандартизирует этот мост: один раз написали сервер — и он работает с Claude, Cursor, VS Code и любым другим клиентом, поддерживающим протокол. TypeScript SDK делает создание MCP сервера задачей на один вечер: определите tools и resources, подключите транспорт, зарегистрируйте в конфиге клиента. Начните с одного-двух инструментов для самой частой задачи в вашем проекте — и вы быстро увидите, как AI-ассистент становится полезнее, когда у него есть доступ к реальным данным.






Комментарии
0