Alejandro Rioja.
AI Agents

Как Создать Первый MCP-Сервер: Практическое Руководство

Alejandro Rioja
Alejandro Rioja
5 мин чтения
TL;DR

MCP (Model Context Protocol) — это способ предоставить Claude структурированный доступ к внешним инструментам и данным — базам данных, файлам, API — не перегружая контекстное окно. Сервер проще, чем кажется: установите SDK, определите инструменты как JSON-схему, реализуйте обработчики, подключитесь через stdio. Менее чем за 30 минут Claude сможет вызывать ваши кастомные инструменты.

Бесплатная рассылка

Каждую среду. 28 400+ читателей. Никакой воды.

Содержание

Обновлено июнь 2026.

TL;DR: MCP (Model Context Protocol) — это способ предоставить Claude структурированный доступ к внешним инструментам и данным — базам данных, файлам, API — не перегружая контекстное окно. Сервер проще, чем кажется: установите SDK, определите инструменты как JSON-схему, реализуйте обработчики, подключитесь через stdio. Менее чем за 30 минут Claude сможет вызывать ваши кастомные инструменты.

[Взгляд оператора] Я регулярно подключаю новые инструменты к своим агентам, и MCP стал стандартным способом делать это чисто. Как только сервер построен, любой совместимый клиент — Claude Desktop, Claude Code, любое приложение на Anthropic SDK — может его использовать без изменений в вызывающем коде. В этом ценность: создайте один раз, используйте везде.

Что такое MCP на самом деле

Model Context Protocol — открытый протокол, стандартизирующий подключение ИИ-моделей к внешнему контексту и инструментам. Представьте его как стандарт USB-C для ИИ-интеграций: раньше каждое приложение, желавшее подключить Claude к базе данных или API, изобретало собственные решения. Теперь создаёте один MCP-сервер, и любой совместимый хост может его использовать.

MCP определяет три вещи, которые сервер может предоставить:

Для большинства операторских случаев вы создаёте серверы инструментов. Ресурсы и промпты — позже, когда основное заработает.

Архитектура клиент-серверная, где клиент (Claude Desktop, Claude Code, ваше приложение) всем управляет. Сервер пассивен — просто слушает запросы вызовов инструментов и возвращает результаты.

Три части каждого MCP-сервера

Каждый MCP-сервер имеет одинаковую структуру:

  1. Объект сервера — объявляет имя, версию и возможности сервера (инструменты, ресурсы, промпты)
  2. Определения инструментов — список инструментов с именами, описаниями и JSON-схемами для входных данных
  3. Обработчики запросов — функции, запускаемые при вызове Claude инструмента

Всё. Для начала не нужны база данных, HTTP-стек и слой авторизации. Минимальный сервер — менее 30 строк TypeScript.

Предварительные требования (2 минуты)

Для запуска MCP-сервера Anthropic API-ключ не нужен. Ключ живёт в клиенте (Claude Desktop), не в сервере.

Шаг 1: Настройка проекта (3 минуты)

bash
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript tsx @types/node

Добавьте в package.json:

json
{
  "type": "module",
  "scripts": {
    "build": "tsc",
    "dev": "tsx src/index.ts"
  }
}

Создайте tsconfig.json:

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "strict": true
  },
  "include": ["src/**/*"]
}

Шаг 2: Написать минимальный сервер (5 минут)

Создайте src/index.ts:

typescript
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

const server = new Server(
  { name: "my-mcp-server", version: "1.0.0" },
  { capabilities: { tools: {} } }
);

// Объявить инструменты сервера
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "get_word_count",
      description: "Подсчитывает слова в блоке текста.",
      inputSchema: {
        type: "object",
        properties: {
          text: {
            type: "string",
            description: "Текст для подсчёта слов",
          },
        },
        required: ["text"],
      },
    },
  ],
}));

// Обработка вызовов инструментов от клиента
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  if (name === "get_word_count") {
    const { text } = args as { text: string };
    const count = text.trim().split(/\s+/).filter(Boolean).length;
    return {
      content: [{ type: "text", text: `Количество слов: ${count}` }],
    };
  }

  throw new Error(`Неизвестный инструмент: ${name}`);
});

// Подключиться через stdio — так Claude Desktop общается с сервером
const transport = new StdioServerTransport();
await server.connect(transport);

Это полный сервер. Регистрирует один инструмент (get_word_count) и реализует его. Структура — главное.

Шаг 3: Сборка и регистрация в Claude Desktop (5 минут)

Скомпилируйте TypeScript:

bash
npm run build

Зарегистрируйте в конфигурационном файле Claude Desktop.

На macOS: ~/Library/Application Support/Claude/claude_desktop_config.json На Windows: %APPDATA%\Claude\claude_desktop_config.json

Если файл не существует, создайте его:

json
{
  "mcpServers": {
    "my-mcp-server": {
      "command": "node",
      "args": ["/абсолютный/путь/к/my-mcp-server/build/index.js"]
    }
  }
}

Используйте абсолютный путь. Перезапустите Claude Desktop после сохранения. В поле ввода сообщения появится значок молотка (🔨) — Claude обнаружил ваши инструменты.

Шаг 4: Создание полезного инструмента

Подсчёт слов — для иллюстрации. Вот более полезный инструмент: чтение файлов из директории проекта, что я использую для агентов инъекции контекста, суммирующих кодовые базы, changelogs или конфигурационные файлы.

typescript
import { readFileSync, readdirSync } from "fs";
import { join, extname } from "path";

const ALLOWED_EXTENSIONS = [".md", ".txt", ".ts", ".json", ".yaml"];
const PROJECT_DIR = process.env.PROJECT_DIR ?? process.cwd();

Логика та же: определите инструменты с точными JSON-схемами, реализуйте обработчики, валидируйте входные данные для предотвращения path traversal, возвращайте текст клиенту.

Ошибки, которые я совершил (чтобы вы не повторяли)

Путь должен быть абсолютным. Относительные пути в конфигурации Claude Desktop разрешаются неожиданным образом. Всегда используйте полный путь /home/user/....

Stdio означает никакого console.log в сервере. Claude Desktop общается с сервером через stdin/stdout. Debug console.log повреждает JSON-RPC поток. Логируйте в stderr:

typescript
process.stderr.write(`Дебаг: ${message}\n`);

Перезапускайте Claude Desktop после каждого изменения конфига. MCP-серверы загружаются при запуске. Отредактированный файл конфига ничего не делает до перезапуска приложения.

Описания инструментов — это продукт. Claude решает, вызывать ли инструмент, исходя из поля description. Расплывчатое описание — Claude не знает, когда его использовать. Точное — Claude берёт его в нужный момент. Тратьте больше времени на описания, чем на реализацию.

Как я использую MCP-серверы в продакшне

Паттерн stdio отлично подходит для Claude Desktop и Claude Code (локально). Для production-агентов — 30+ на Cloudflare Workers — напрямую использую tool-use API Anthropic SDK, поскольку мне нужна гибкость маршрутизации к Haiku vs Sonnet по шагам.

Паттерны, которые реально использую:

  1. Локальный dev-инструментарий — MCP-серверы для Claude Code, экспонирующие проектоспецифичные инструменты
  2. Инъекция контекста — MCP-серверы, предзагружающие релевантные документы без ручного копирования
  3. Мост прототип-к-API — сначала строю MCP (быстрее итерировать), затем переношу логику в SDK tool-use для продакшна

Что строить дальше

Как только структура сервера понята, полезные инструменты — те, что дают Claude доступ к внешнему контексту:

Часто задаваемые вопросы

Нужен ли API-ключ Anthropic для создания MCP-сервера?

Нет. MCP-сервер не вызывает API Anthropic. Он лишь отвечает на запросы вызовов инструментов от клиента. API-ключ находится в клиенте, не в сервере.

Может ли MCP-сервер вызывать внешние API?

Да — обработчик просто асинхронный TypeScript-код. Получайте данные от погодного API, запрашивайте БД, пишите в файл. Сервер не интересуется, что делает обработчик внутри.

В чём разница между транспортами stdio и HTTP?

Stdio — для локальных серверов на одной машине с Claude Desktop или Claude Code. HTTP с SSE — для удалённых серверов, развёртываемых как веб-сервис. Начните со stdio; проще отлаживать.

Как Claude знает, когда вызывать мой инструмент?

Claude решает на основе поля description инструмента и контекста разговора. Если Claude продолжает игнорировать инструмент, уточните описание.

Читать дальше

Получайте ИИ-руководство на почту

Каждую среду. 28 400+ читателей. Никакой воды.

↵ — все результаты esc esc — закрыть