В прошлый раз разобрали зачем нужен MCP и какую проблему он решает. Сегодня смотрим что там внутри и как написать свой сервер с нуля.
Три участника: Host, Client, Server
Любая MCP-система состоит из трёх частей.
MCP Host = это приложение, в котором живёт AI-агент. Например Claude Desktop, Cursor. Хост запускает всё и управляет соединениями.
MCP Client = живёт внутри хоста и общается с сервером один-к-одному. Один клиент = одно соединение с одним сервером.
Клиент это посредник: передаёт запросы от агента и возвращает ответы обратно.
MCP Server = лёгкая программа/сервер, которую пишете вы. Она подключается к вашим данным (БД, API, файлы) и отдаёт их агенту.
Что умеет отдавать сервер : три примитива
Сервер может отдавать три вещи.
Tools = функции, которые AI вызывает сам. Запрос в базу, отправка письма, вызов API. Аналог POST-эндпоинта: что-то выполняется и возвращается результат.
Resources = данные, которые AI читает в контекст. Файл, строки из таблицы, содержимое документа. Аналог GET-эндпоинта: просто читаем, не меняем.
Prompts = готовые шаблоны для типовых задач. Стандартные заготовленные шаблоны для ваших целей.
Для большинства практических задач достаточно Tools. Их используем чаще всего.
Пишем свой MCP-сервер на TypeScript
Используем официальный SDK от Anthropic
@modelcontextprotocol/sdk.Пример: сервер с одним тулом, который возвращает данные по проекту из условной базы.
// Создаём сервер с именем и версией
const server = new McpServer({
name: “vash-server",
version: "3.2.2",
});
// Регистрируем тул функцию, которую сможет вызвать AI
server.tool(
"get_project_data", // имя тула
"Получить данные по проекту за период", // описание для AI
{
project_name: z.string().describe("Название проекта"),
month: z.string().describe("Месяц в формате YYYY-MM"),
},
async ({ project_name, month }) => {
// Здесь ваша реальная логика: запрос в БД, вызов API и т.д.
const data = await fetchFromDatabase(project_name, month);
return {
content: [{ type: "text", text: JSON.stringify(data) }],
};
}
);
Что тут происходит: создаём сервер, описываем тул с параметрами через Zod-схему (AI сам разберётся какие параметры передавать), внутри пишем любую логику.
И дальше подключаемся например к Claude desktop
{
"mcpServers": {
"vash-server": {
"command": "node",
"args": ["/путь/до/вашего/server.js"]
}
}
}Теперь можно писать в чат: "выдай данные по проекту Альфа за январь 2025" и Claude сам вызовет ваш сервер.