Зачем нужен MCP: Function Calling, Plugins и стена интеграций
LLM сильны в рассуждениях, но слабы в исполнении. Первым исправлением стал OpenAI Function Calling (июнь 2023): задаёте JSON-схемы, модель эмитит структурированные вызовы, ваш код их выполняет. Работало — но только внутри API OpenAI. Каждой другой модели нужен отдельный адаптер.
ChatGPT Plugins (март 2023) попробовали модель маркетплейса: каждый plugin — bespoke REST-обёртка со своим manifest. Discovery централизован в store OpenAI, а не в runtime агента. Когда Anthropic выпустил Tool Use, а LangChain популяризировал agent frameworks, в индустрии оказалось три несовместимых tool schema и ни одного переносимого server layer.
Эра Function Calling: схемы per-vendor. GPT, Claude и Gemini ожидают разные формы сообщений. Смена модели → переписывание tool bridge.
Эра Plugins: централизованный discovery в одном store, не в runtime агента. Нет стандарта для Resources или Prompts — только callable endpoints.
Эра фреймворков: LangChain Tools, CrewAI tools и IDE-specific hooks каждый определяет свои tool objects. Определения не переносятся между Cursor, VS Code и Claude Desktop.
Стоимость N×M: N AI-клиентов × M бэкендов = N×M интеграций. Enterprise CRM-команды поддерживают параллельные adapter layers для каждого LLM-вендора.
Ответ MCP (ноябрь 2024): Anthropic open-source единый протокол — JSON-RPC 2.0 через STDIO или HTTP — где Servers self-describe Tools, Resources и Prompts. Пишете один раз; Cursor, Claude Desktop, ChatGPT, Gemini и VS Code подключаются без переписывания.
Design rationale Anthropic похож на USB-C: стандартизировать порт, а не каждый кабель. MCP не заменяет REST API — он оборачивает их в uniform discovery и invocation layer, чтобы AI-клиенты перестали заботиться о вендоре или фреймворке на другой стороне. К Q2 2026 governance перешла в Linux Foundation AAIF; OpenAI, Google и Microsoft ship native MCP client support.
Function Calling решил «как одна модель вызывает одну функцию?». MCP решает «как любой AI-клиент обнаруживает и вызывает любой tool server?» — вопрос, с которым сталкивается каждый agent stack в 2026.
Архитектура MCP: Client/Server, три capability и lifecycle транспорта
MCP работает на JSON-RPC 2.0 с bidirectional messaging. Host (Cursor, Claude Desktop) встраивает один или несколько MCP Clients. Каждый Client поддерживает 1:1 session с MCP Server, который мостит к реальным системам.
Servers expose три типа capability: Tools (исполняемые действия с side effects), Resources (read-only данные с URI-идентификаторами) и Prompts (переиспользуемые template strings, которые client может pre-fill). Core RPC methods: tools/list, tools/call, resources/list, resources/read, prompts/list и prompts/get.
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "query_database",
"arguments": { "sql": "SELECT id, email FROM users LIMIT 10" }
},
"id": 42
}
STDIO transport: Host spawn Server как subprocess; сообщения идут через stdin/stdout. Нулевые сетевые зависимости, сильная process isolation, идеально для local dev. Lifecycle: spawn → initialize handshake → capability negotiation → persistent session → subprocess exit при disconnect.
HTTP + SSE / streamable-http: Server работает как long-lived HTTP service. Client открывает SSE stream для server-push events; tool calls идут через POST. Позволяет remote deploy, team-shared servers, horizontal scaling — но требует session affinity для SSE и proper auth на edge. Спека 2026 добавляет streamable-http как рекомендуемый remote transport, заменяя legacy SSE-only patterns.
| Измерение | OpenAI Function Calling | LangChain Tools | MCP |
|---|---|---|---|
| Область | Только OpenAI API | Python agent frameworks | Любой MCP Host (Cursor, Claude, ChatGPT, VS Code) |
| Discovery | Статический: dev хардкодит function list в API call | Статический: tools регистрируются в Python при startup | Динамический: tools/list при init session |
| Self-description | JSON Schema в API payload | Pydantic / dict schemas в коде | JSON Schema от Server; то же для Resources и Prompts |
| Доступ к данным | Нет стандартного read-only layer | Custom retrievers per framework | Resources с URI scheme (file://, db://) |
| Переиспользуемые шаблоны | Только system prompts | PromptTemplate objects | Prompts capability с argument schemas |
| Транспорт | HTTPS к OpenAI | In-process Python calls | STDIO subprocess или HTTP streamable remote |
| Переносимость | Vendor-locked | Framework-locked | Server один раз; любой client подключается |
Dev setup и реализация: FastMCP, Tools, Resources и Prompts
Выберите SDK stack: Python с mcp + FastMCP для fastest iteration или TypeScript с @modelcontextprotocol/sdk для Node-native HTTP servers. Рекомендуемая структура проекта:
my-mcp-server/
pyproject.toml
src/
server.py # FastMCP entry
tools/ # tool modules
resources/ # resource handlers
prompts/ # prompt templates
tests/
test_tools.py
Dockerfile
Установка: pip install mcp или npm install @modelcontextprotocol/sdk. Отладка через MCP Inspector (npx @modelcontextprotocol/inspector) — подключается к STDIO или HTTP endpoints и показывает live tools/list. Подключение в Cursor: Settings → MCP → add server config; Claude Desktop — через claude_desktop_config.json.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("hello-mcp")
@mcp.tool()
def greet(name: str) -> str:
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run()
Tools с Pydantic input: FastMCP derives JSON Schema из type hints и Pydantic models автоматически. Ниже — пять практичных tools: calculator, file I/O, HTTP fetch, DB query и time с async support и structured error returns.
import asyncio
import httpx
from datetime import datetime, timezone
from pathlib import Path
from pydantic import BaseModel, Field
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("utility-server")
class CalcInput(BaseModel):
expression: str = Field(description="Math expression e.g. 2 + 3 * 4")
@mcp.tool()
def calculate(input: CalcInput) -> str:
try:
allowed = set("0123456789+-*/(). ")
if not all(c in allowed for c in input.expression):
return "Error: invalid characters in expression"
return str(eval(input.expression, {"__builtins__": {}}, {}))
except Exception as e:
return f"Error: {e}"
@mcp.tool()
def read_file(path: str) -> str:
try:
target = Path(path).resolve()
if not target.is_file():
return f"Error: {path} is not a file"
return target.read_text(encoding="utf-8", errors="replace")[:50000]
except Exception as e:
return f"Error: {e}"
@mcp.tool()
async def http_get(url: str) -> str:
try:
async with httpx.AsyncClient(timeout=15.0) as client:
resp = await client.get(url)
return resp.text[:10000]
except Exception as e:
return f"Error: {e}"
@mcp.tool()
async def db_query(sql: str) -> str:
try:
import aiosqlite
async with aiosqlite.connect("app.db") as db:
cursor = await db.execute(sql)
rows = await cursor.fetchall()
return str(rows[:100])
except Exception as e:
return f"Error: {e}"
@mcp.tool()
def current_time(tz: str = "UTC") -> str:
return datetime.now(timezone.utc).isoformat()
Resources: статические URI map к fixed files; dynamic URI принимают parameters. Filesystem resource server expose project docs, которые agent читает без tool side effects.
from mcp.server.fastmcp import FastMCP
from pathlib import Path
mcp = FastMCP("fs-resources")
DOCS = Path("./docs")
@mcp.resource("docs://index")
def docs_index() -> str:
files = [f.name for f in DOCS.glob("*.md")]
return "\n".join(files)
@mcp.resource("docs://{filename}")
def read_doc(filename: str) -> str:
path = DOCS / filename
if not path.exists():
return f"Error: {filename} not found"
return path.read_text(encoding="utf-8")
Prompts: переиспользуемые templates с argument slots. Code-review prompt pre-fills context, чтобы agent следовал checklist review вашей команды.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("review-prompts")
@mcp.prompt()
def code_review(file_path: str, language: str) -> str:
return f"""Review {file_path} ({language}) for:
1. Security vulnerabilities (injection, auth bypass)
2. Performance bottlenecks
3. Error handling gaps
4. Test coverage holes
Provide severity-rated findings with fix suggestions."""
Snippet конфигурации Cursor: добавьте в .cursor/mcp.json — {"mcpServers": {"utility": {"command": "python", "args": ["src/server.py"]}}}. Claude Desktop использует ту же форму в claude_desktop_config.json.
HTTP-транспорт, отладка и шестишаговый runbook MCP Server
Streamable HTTP transport — default 2026 для remote MCP Servers. Запуск FastMCP: mcp.run(transport="streamable-http") или TypeScript SDK StreamableHTTPServerTransport. Security на edge:
Bearer tokens: валидируйте Authorization: Bearer <token> на каждом request. Ротация tokens через env vars, никогда не хардкодите.
API keys: принимайте header X-API-Key для simpler client configs. Map keys к per-tenant rate limits.
CORS: ограничьте Access-Control-Allow-Origin known Host origins. Wildcard * на production MCP endpoints — частая misconfiguration.
Rate limiting: cap requests per key на reverse proxy (nginx, Cloudflare) или in-app middleware. MCP tool calls могут триггерить expensive downstream APIs.
Workflow отладки: сначала MCP Inspector, затем client logs, затем unit tests. Inspector показывает raw JSON-RPC, schema validation errors и timing per call.
import pytest
from server import calculate, CalcInput
def test_calculate_valid():
result = calculate(CalcInput(expression="2 + 3"))
assert result == "5"
def test_calculate_invalid_chars():
result = calculate(CalcInput(expression="import os"))
assert result.startswith("Error:")
| Симптом ошибки | Вероятная причина | Исправление |
|---|---|---|
| Server не в списке Cursor | Неверный path или command в config | Проверьте command/args в mcp.json; subprocess стартует без import errors |
| tools/list возвращает пусто | Decorators не зарегистрированы до run() | Import tool modules в entry point server.py |
| HTTP connection refused | Неверный port или transport mismatch | Сопоставьте client transport с server mode (STDIO vs streamable-http) |
| CORS error в browser client | Missing или overly strict headers | Добавьте allowed origins; credentials только когда нужно |
| Tool call timeout | Sync blocking в async context | Используйте async def tools или asyncio.to_thread для I/O |
| Invalid JSON Schema rejected | Pydantic model без Field descriptions | Добавьте Field(description=...) для agent-readable params |
Шестишаговый runbook от assessment до production-ready MCP Server:
Карта интеграций: перечислите external systems (DB, Git, Slack, internal APIs). Посчитайте текущие per-model adapters и estimate rewrite cost при смене vendor.
Выбор SDK и transport: Python FastMCP для STDIO prototyping; добавьте streamable-http, когда teammates нужен remote access. TypeScript, если stack — Node.
Реализация capabilities: начните с 2–3 Tools, одной Resource URI scheme, одного Prompt template. Валидируйте schemas в MCP Inspector до wiring clients.
Подключение clients: добавьте server в Cursor mcp.json и Claude Desktop config. Подтвердите tools/list при start session — без hard-coded tool arrays в prompts.
Test и hardening: unit tests per tool, integration tests через Inspector, structured error strings вместо raw tracebacks к LLM.
Deploy 24/7 host: Dockerize, push в Railway/Render/Cloud Run или dedicated VPS. Для Apple Silicon inference и Xcode CI на том же узле — облачный Mac Mini вместо Linux VPS.
Production-деплой, capstone-проект, экосистема и цифры
Production paths: package через Docker (python:3.12-slim base, non-root user, health check на HTTP port). Варианты платформ:
Railway / Render: push container, env vars для API keys, expose HTTP port. Хорошо для team-shared dev/staging servers.
AWS Lambda: работает только для stateless tool calls — избегайте для persistent SSE sessions. API Gateway + short-lived handlers.
Google Cloud Run: scales HTTP streamable servers; min instances = 1 для session warmth.
VPS / bare metal: полный контроль для long-running agents, local embeddings и multi-server stacks на одном host.
Monitoring: export request latency и tool-call counters в Prometheus; exceptions в Sentry с MCP method name tags. Pin SDK versions в pyproject.toml / package.json и tag Docker images per release — MCP spec revisions 2026 всё ещё ship breaking transport changes.
Capstone: personal knowledge base MCP. Combine ChromaDB vector store, embedding model (local Ollama или API) и semantic search tool:
import chromadb
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("knowledge-base")
client = chromadb.PersistentClient(path="./chroma_data")
collection = client.get_or_create_collection("notes")
@mcp.tool()
def semantic_search(query: str, n: int = 5) -> str:
results = collection.query(query_texts=[query], n_results=n)
docs = results.get("documents", [[]])[0]
return "\n---\n".join(docs) if docs else "No matches found."
@mcp.tool()
def ingest_note(text: str, source: str) -> str:
collection.add(documents=[text], metadatas=[{"source": source}], ids=[source])
return f"Indexed: {source}"
Экосистемные servers для изучения в 2026: mcp-server-filesystem (official reference), GitHub MCP (repo/PR/issue ops), Brave Search MCP (web retrieval), Postgres MCP (SQL с schema introspection), Slack MCP (channel messaging). Тренды H2 2026: OAuth 2.1 standardized auth, unified server registries, multi-tenant hosted MCP marketplaces и Agent-to-Agent (A2A) orchestration над tool layer MCP.
10 000+ community servers: число MCP servers превысило десять тысяч к середине 2026 — каждый новый server мгновенно достигает каждого compatible client.
Снижение затрат на интеграцию на 38–55%: enterprise-команды сообщают о 38–55% меньших расходах на AI-интеграцию после консолидации adapters за MCP Servers (industry survey average, 2025–2026).
~1000 exposed unauthorized servers: security scans в начале 2026 нашли примерно тысячу MCP endpoints в публичном интернете без auth — никогда не деплойте production Servers без Bearer tokens, API keys и network isolation.
Важно: Linux VPS nodes не запускают Xcode builds или Apple Silicon-optimized local embedding models. Laptop STDIO sessions умирают при sleep. AWS Lambda не держит persistent MCP SSE sessions. Каждый shortcut отдаёт то, что нужно production agents.
Командам, которые запускают MCP Servers рядом с Cursor agents, ChromaDB ingestion и iOS CI на одном always-on узле, аренда облачного Mac Mini у MESHLAUNCH обычно лучший production host: dedicated Apple Silicon, без sleep disconnects, гибкая оплата день/неделя/месяц и стабильный дом для tool definitions как portable team assets вместо per-developer laptop configs. Спеки узлов — на странице цен; SSH и сеть — в центре помощи.
Python FastMCP быстрее всего для прототипирования: decorator-based tools, автоматическая JSON Schema из type hints и однострочный STDIO launch. TypeScript @modelcontextprotocol/sdk подходит командам на Node.js или HTTP streamable servers на Express. Оба SDK официальные — выбирайте язык, на котором команда поставляет код. Спеки узлов — на странице цен.
Да. STDIO servers работают как subprocess на любом macOS host. HTTP streamable servers нуждаются в persistent process и stable network — bare-metal облачный Mac Mini даёт Apple Silicon для local embedding inference, Xcode CI на том же узле и отсутствие sleep ноутбука, который рвёт stateful MCP sessions.
Сначала запустите MCP Inspector против endpoint сервера, проверьте что tools/list возвращает ожидаемые schemas, затем смотрите логи MCP в Cursor. Частые причины: mismatched transport mode, invalid JSON Schema, subprocess crash при import или CORS, блокирующий HTTP servers. SSH tunnel и настройка портов — в центре помощи.