MCP Server с нуля:
полное руководство по разработке вызова AI-инструментов

Если вы разработчик на Python или TypeScript и хотите, чтобы Claude, GPT или Cursor в IDE получали доступ к БД, вызывали API и читали файлы, вы уже упираетесь в базовое ограничение: у LLM нет встроенных «конечностей». Cutoff обучающих данных и отсутствие side-effect операций без внешнего слоя — норма. Это руководство проведёт от пустого репозитория до production-ready MCP Server: реализуем Tools, Resources и Prompts, пройдём stdio и HTTP+SSE, доведём до Docker. После прочтения вы подключите собственный toolchain в Cursor или Claude Desktop. Тарифы узлов — на странице цен NOVAKVM.

Интеграция AI-инструментов прошла три этапа. Function Calling (OpenAI, 2023) дал модели структурированный JSON для вызова функций. Plugins / GPT Actions обернули HTTP-эндпоинты в плагины чата. MCP (Model Context Protocol), открытый Anthropic в ноябре 2024, стандартизирует обнаружение, описание и вызов инструментов — одна реализация Server работает в Claude Desktop, Cursor, VS Code Continue и других host-приложениях.

  • Границы LLM: нет live-данных, нет прямого доступа к ФС и БД — внешние tools закрывают «сенсоры и руки».
  • Фрагментация schema: OpenAI Function Calling, Claude Tool Use и LangChain Agent задают форматы по-разному; смена модели или IDE требует переписывания адаптеров.
  • Отсутствие discovery: REST API не сообщает AI, что умеет; MCP runtime отдаёт актуальный список через tools/list.
  • Сессия и контекст: MCP держит persistent connection для многошаговых Agent workflow; stateless REST хуже цепляет сложные задачи.
  • Безопасность: Server ограничивает write-tools, read-only Resources и предотвращает эскалацию привилегий на прод-данных.

Client-Server JSON-RPC архитектура складывается так:

  • Host: Claude Desktop, Cursor, VS Code — UI для пользователя.
  • MCP Client: встроен в Host, поддерживает сессию 1:1 с каждым Server.
  • MCP Server (ваш код): три примитива — Tools (исполняемые действия), Resources (read-only данные), Prompts (переиспользуемые шаблоны).
  • Транспорт: локально — stdio (stdin/stdout дочернего процесса); удалённо — HTTP + SSE.
  • Протокол: все сообщения — JSON-RPC 2.0: initializetools/listtools/callnotifications/cancelled.
  • Жизненный цикл: handshake → согласование capabilities → steady state → graceful shutdown; Client шлёт ping для keepalive.
MCP vs OpenAI Function Calling vs LangChain Tools
Измерение MCP OpenAI FC LangChain Tools
Стандартизация Открытый протокол, cross-vendor Привязка к OpenAI API Формат внутри фреймворка
Discovery инструментов Runtime tools/list Schema в каждом запросе Статическая регистрация в коде
Resources / Prompts Нативная поддержка Не поддерживается Требуют обёрток
Транспорт stdio / HTTP+SSE HTTPS API Вызовы in-process
IDE-интеграция Cursor, Claude Desktop и др. Экосистема ChatGPT plugins Нужен bridge-слой

MCP решает не вопрос «можно ли вызвать API», а вопрос «как AI единообразно обнаруживает, выбирает и корректно вызывает инструменты» — центральная задача эры Agent.

Официальный стек — два first-class SDK: Python-пакет mcp (FastMCP) и TypeScript @modelcontextprotocol/sdk. Python удобен для прототипов и data/ML; TypeScript — для Node.js и frontend-команд. Ниже — Python FastMCP; структура TypeScript зеркальна.

setup.sh
mkdir my-mcp-server && cd my-mcp-server
python3 -m venv .venv
source .venv/bin/activate
pip install "mcp[cli]" httpx pydantic python-dotenv
npm install -g @modelcontextprotocol/inspector

Рекомендуемая структура проекта:

project-tree
my-mcp-server/
├── server.py
├── tools/
├── resources/
├── prompts/
├── tests/
├── Dockerfile
├── requirements.txt
└── .env

Три инструмента для отладки и подключения к Host:

  • MCP Inspector: официальный визуальный отладчик; перечисляет tools/resources/prompts и позволяет вызывать их вручную.
  • Claude Desktop: правка ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) для регистрации stdio Server.
  • Cursor: Settings → MCP → добавление конфигурации; поддерживаются stdio и удалённые HTTP-эндпоинты.

Минимальный Server на FastMCP с tool say_hello:

server.py
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("hello-server")

@mcp.tool()
def say_hello(name: str) -> str:
    return f"Hello, {name}! MCP Server is running."

if __name__ == "__main__":
    mcp.run()

Проверка через Inspector:

terminal
npx @modelcontextprotocol/inspector python server.py

Откройте UI Inspector в браузере. В панели Tools вызовите say_hello с аргументом {"name": "NOVAKVM"} — должен вернуться greeting.

Конфигурация Claude Desktop (claude_desktop_config.json):

claude_desktop_config.json
{
  "mcpServers": {
    "hello-server": {
      "command": "/path/to/my-mcp-server/.venv/bin/python",
      "args": ["/path/to/my-mcp-server/server.py"]
    }
  }
}

Конфигурация Cursor MCP: создайте .cursor/mcp.json в корне проекта или добавьте эквивалентный JSON в Cursor Settings → MCP. После перезапуска Cursor в Agent mode появится tool say_hello.

В MCP сигнатура функции — документация: имена параметров, type hints и docstring превращаются в JSON Schema для модели. Сложный ввод — через Pydantic:

tools/search.py
from pydantic import BaseModel, Field

class SearchInput(BaseModel):
    query: str = Field(..., description="Ключевые слова поиска")
    limit: int = Field(10, ge=1, le=100, description="Максимум результатов")

@mcp.tool()
async def search_docs(input: SearchInput) -> list[dict]:
    ...

Production Server обычно реализует пять категорий tools:

  • calculator: безопасное вычисление выражений; не используйте голый eval — парсите через ast или специализированную библиотеку.
  • file_read / file_write: ограничение корневой директорией (chroot-подход), защита от path traversal; write — с подтверждением или whitelist расширений.
  • fetch_url: асинхронные HTTP-запросы — пример ниже.
  • db_query: read-only SQL (SELECT) с параметризованными запросами; write — отдельный tool с audit log.
  • get_current_time: ISO 8601 timestamp — модель «знает текущее время».
tools/http.py
import httpx

@mcp.tool()
async def fetch_url(url: str, timeout: int = 30) -> str:
    async with httpx.AsyncClient(timeout=timeout) as client:
        resp = await client.get(url)
        resp.raise_for_status()
        return resp.text[:50000]

Паттерны обработки ошибок:

  • Перехватывайте исключения внутри tool и возвращайте структурированный текст ошибки — Client передаст результат модели для retry или смены стратегии.
  • Timeout и лимит retry для внешних API — защита от бесконечных циклов вызовов модели.
  • API Key и connection string — только из env; не возвращайте секреты в output tool или Resources.
  • Write-tools возвращают summary операции (что изменено, число затронутых строк) для подтверждения пользователю.

Resource vs Tool: Resource — read-only контекст (конфиг, профиль, фрагмент лога); модель читает через resources/read. Tool — исполняемое действие (запрос, запись, HTTP). Resource подходит для информации, которую AI должен видеть, но не менять.

Соглашения по URI scheme:

  • config://app/settings — статический конфиг, регистрируется при старте.
  • user://{id}/profile — динамический шаблон; Client передаёт id, Server генерирует контент.
  • file:// — маппинг локальной ФС (нужен path sandbox).

Resources поддерживают четыре MIME-категории: text/plain, application/json, binary blob (Base64), stream (chunked push для больших файлов).

resources/config.py
@mcp.resource("config://app/settings")
def get_app_settings() -> str:
    return json.dumps({"env": "production", "version": "1.2.0"})

@mcp.resource("user://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
    profile = db.fetch_user(user_id)
    return json.dumps(profile)

Filesystem Resource Server может рекурсивно регистрировать файлы каталога — AI видит структуру проекта и ключевой конфиг при кодинге без отдельного read tool на каждый файл.

MCP Prompt — предопределённый шаблон, который Host перечисляет и инжектирует в контекст диалога. Подходит для code review, postmortem инцидентов, ревью API-дизайна. Prompts принимают placeholder-параметры и поддерживают multi-turn message structure.

prompts/review.py
from mcp.types import PromptMessage, TextContent

@mcp.prompt()
def code_review_prompt(language: str, focus: str = "security") -> list[PromptMessage]:
    return [
        PromptMessage(
            role="user",
            content=TextContent(
                type="text",
                text=f"Проведи {focus}-ревью следующего {language}-кода. Перечисли проблемы и рекомендации:\n\n"
            )
        )
    ]

Multi-turn пример: раунд 1 — роль и ограничения; раунд 2 — placeholder кода; раунд 3 — structured JSON (severity / file / line / suggestion). Команда фиксирует best practices в Prompts — новым участникам не нужно переписывать system prompt.

Сравнение stdio и HTTP + SSE
Измерение stdio HTTP + SSE
Размещение Локальный дочерний процесс Удалённый сервер / контейнер
Сеть Не требуется Доступность по LAN или интернету
Горизонтальное масштабирование Один хост Load balancer + session affinity
Аутентификация Изоляция процесса Bearer Token / API Key
Сценарий Личная разработка, Claude Desktop Командный доступ, 7×24 в облаке

FastMCP поддерживает транспорт streamable-http — переключение одной строкой:

server.py
if __name__ == "__main__":
    mcp.run(transport="streamable-http", host="0.0.0.0", port=8080)

Production HTTP требует дополнительных слоёв:

  • Bearer Token / API Key: проверка заголовка Authorization на reverse proxy или в middleware.
  • CORS: при cross-origin доступе browser Inspector — whitelist доменов-источников.
  • Rate Limiting: throttling по IP или API Key против call storm от модели.
  • TLS: публичный endpoint — только HTTPS; termination через Caddy или Nginx.

Workflow MCP Inspector: после запуска слева — дерево capabilities; панель Tools принимает JSON-параметры; Notifications — push от Server; Logs — stderr. При изменении кода Inspector перезапускает дочерний процесс.

tests/test_tools.py
import pytest
from server import say_hello

def test_say_hello():
    result = say_hello("World")
    assert "Hello, World!" in result

@pytest.mark.asyncio
async def test_fetch_url():
    result = await fetch_url("https://httpbin.org/get")
    assert "origin" in result
Типичные ошибки MCP Server и решения
Симптом Вероятная причина Решение
Tools не отображаются Нет декоратора или сбой старта Server Проверить stderr; переподключить Inspector
Ошибка JSON-сериализации Возврат datetime, Decimal и др. non-JSON типов Явный json.dumps или приведение к str
Timeout вызова Медленный внешний API, нет timeout Timeout в tool; увеличить limit на Client
Permission denied Путь вне sandbox или неверные DB credentials Проверить ALLOWED_PATHS и .env

Шестишаговый production deploy checklist:

  1. Зафиксировать зависимости: pip freeze > requirements.txt; в CI зафиксировать Python и версию mcp SDK против upstream breaking change.
  2. Dockerfile: multi-stage build; финальный образ — только runtime deps; процесс Server от non-root пользователя.
  3. Environment variables: API Key, DB connection string, ALLOWED_PATHS — через secrets management, без hardcode.
  4. Хостинг: Railway / Render для быстрой валидации; AWS Lambda + HTTP adapter для редких вызовов; Cloud Run / VPS для 7×24 always-on.
  5. Мониторинг: structured JSON logs, endpoint /health, Prometheus metrics или Sentry.
  6. Проверка Cursor / Claude: remote URL и Bearer Token в MCP config; вызов tools/list для подтверждения полного списка tools перед rollout.

Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
USER nobody
EXPOSE 8080
CMD ["python", "server.py"]

Выбор платформы хостинга:

  • Railway / Render: deploy по git push; free tier для MVP; учитывайте cold start для SSE long connection.
  • AWS Lambda: оплата за вызов; нужен HTTP-to-stdio adapter; подходит для редких internal tools.
  • Google Cloud Run: container-native autoscaling; для SSE — min-instances ≥ 1.
  • VPS / bare metal: полный контроль сети и диска; когда чувствительные данные не покидают перимeter.

Observability stack:

  • Logging: structlog или python-json-logger; каждый tool call — name, duration_ms, status.
  • Prometheus: метрики mcp_tool_calls_total, mcp_tool_duration_seconds.
  • Sentry: необработанные исключения с tag версии Server для быстрого rollback.

Совместимость версий: ревизия MCP 2025-03-26 ввела Streamable HTTP. Перед deploy сверьте Client (версия Cursor, Claude Desktop) и Server SDK на поддержку одного транспорта. В README укажите минимум, например mcp>=1.2.0.

Итоговый проект — knowledge-base MCP Server: векторы документов в ChromaDB или Qdrant, watchfiles для re-index при изменении каталога, tools search_knowledge и write_note. После подключения в Cursor Agent ищет по внутренней документации команды, а не только по training data.

tools/knowledge.py
@mcp.tool()
async def search_knowledge(query: str, top_k: int = 5) -> list[dict]:
    embedding = await embed(query)
    results = collection.query(query_embeddings=[embedding], n_results=top_k)
    return [{"text": doc, "score": score} for doc, score in zip(...)]

@mcp.tool()
async def write_note(title: str, content: str) -> str:
    doc_id = collection.add(documents=[content], metadatas=[{"title": title}])
    return f"Note saved: {doc_id}"

Community MCP Server для переиспользования:

  • @modelcontextprotocol/server-filesystem — sandbox read/write файлов
  • server-github — issues, PR, code search
  • server-brave-search — live web search
  • server-postgres — read-only SQL
  • server-slack — сообщения каналов и уведомления

Экосистема MCP в 2026:

  • Масштаб: к 2026 году публичных MCP Server — более 10 000; суммарные GitHub Stars org modelcontextprotocol — свыше 50 000.
  • Adoption вендоров: Q1 2026 — нативная поддержка MCP у OpenAI; Q2 — Google Gemini и Microsoft Copilot; governance передан AAIF при Linux Foundation.
  • Стоимость enterprise-интеграции: отраслевые опросы фиксируют снижение затрат на AI toolchain на 38–55% после стандартизации на MCP.

Рекомендуемый learning path:

  1. Изучить официальную спецификацию и JSON-RPC message flow
  2. Собрать Hello World на FastMCP и отладить в Inspector
  3. Реализовать минимум три реальных Tool (файл, HTTP, БД)
  4. Добавить Resources и Prompts — понять различие трёх примитивов
  5. Переключиться на HTTP-транспорт и Docker-deploy в облако
  6. Подключить Cursor и завершить проект knowledge-base или GitHub-интеграции

Публичные источники ниже — для сверки спецификации и SDK; при обновлении upstream ориентируйтесь на ссылки.

Model Context Protocol — официальная спецификация и документация

modelcontextprotocol/python-sdk — Python MCP SDK

modelcontextprotocol/typescript-sdk — TypeScript MCP SDK

modelcontextprotocol/inspector — MCP Inspector

MCP Server на ноутбуке с режимом сна даёт повторяющиеся сбои: обрыв сессии tools/list, истечение OAuth, переполнение диска с порчей vector store, разрыв SSE при смене сети — это влияет на ежедневную разработку сильнее, чем выбор модели. Docker на laptop наследует sleep хоста; free tier PaaS рвёт long connection при cold start; Lambda плохо подходит для always-on SSE.

Если нужны 7×24 MCP toolchain, стабильный SSH и предсказуемая вычислительная мощность Apple Silicon, перенос Cursor Agent и custom Server на выделенный bare metal часто выгоднее: NOVAKVM предлагает multi-region Mac Mini M4 / M4 Pro с гибкими сроками аренды — для Cursor MCP, удалённой разработки в Claude Desktop и co-located vector store. Тарифы — страница цен, заказ — оформить аренду, вопросы по развёртыванию — центр помощи.