MCP Server с нуля: пошагово к AI tool calling capability
LLM может быть умным сколько угодно — без прямого доступа к БД, API и файлам он изолирован. AI tool calling определяет, дотянется ли Agent до реального мира. MCP (Model Context Protocol) — open-source стандарт от Anthropic: Claude, Cursor и другие клиенты единообразно discover и invoke ваш Server. Гайд для backend / AI devs с базой Python или TypeScript: протокол, setup, три capability (Tools / Resources / Prompts), remote HTTP deploy, debugging и production.
После прочтения ответите на три вопроса: ① чем MCP принципиально отличается от Function Calling и LangChain Tools; ② как зарегистрировать tools, resources и prompt templates через official SDK; ③ как упаковать personal knowledge base в production-ready MCP Server и спросить в Cursor: «Что я записывал про MCP на прошлой неделе?»
01 Что такое MCP? Принципы протокола, коммуникация и сравнение
Tool calling прошёл три поколения: Function Calling (vendor-specific format) → Plugins (platform lock-in) → MCP (open protocol standard). Core motivation Anthropic: JSON-RPC spec унифицирует discover / describe / invoke external capabilities — конец кошмару N models × M tools custom integration.
- Pain point: модели не имеют доступа к external tools и realtime data — нет query DB, call API, file ops.
- Scenario: нужно, чтобы Claude / GPT query database, hit REST API, read/write local Markdown — это и expose MCP Server.
- Value promise: после статьи — самостоятельно develop и deploy production-ready MCP Server.
Архитектурно MCP Client (Claude Desktop, Cursor и др.) и MCP Server (ваш код) общаются bidirectional JSON-RPC; Server стыкуется с external systems:
- Tools: функции, вызываемые AI (search, calc, DB query)
- Resources: ресурсы для чтения AI (files, URL, data streams)
- Prompts: predefined prompt templates с parameter injection
Коммуникация на JSON-RPC 2.0. Transport: stdio (local subprocess, минимальная latency) и HTTP + SSE / Streamable HTTP (remote service, multi-client). Lifecycle: init handshake → capability negotiation → request/response → shutdown.
| Dimension | MCP | OpenAI Function Calling | LangChain Tools |
|---|---|---|---|
| Standardization | Open protocol standard | Vendor proprietary | Framework-bound |
| Transport | stdio / HTTP | HTTP | HTTP |
| Cross-model | Да | Нет | Частично |
| Resources / Prompts | Native support | Не поддерживается | Не поддерживается |
| Ecosystem | Быстрый рост (10 000+ Server) | Зрелый | Зрелый |
Further reading: Почему MCP становится HTTP эпохи AI; official spec — modelcontextprotocol.io.
02 Dev environment: выбор языка, dependencies и project structure
Python (рекомендуем новичкам): official SDK mcp, FastMCP decorators — минимальный boilerplate. TypeScript (frontend / full-stack): official SDK @modelcontextprotocol/sdk. Основной track — Python, TypeScript для сравнения.
Python environment
python -m venv .venv
source .venv/bin/activate
pip install mcp
TypeScript environment (reference)
npm init -y
npm install @modelcontextprotocol/sdk
Recommended project structure:
my-mcp-server/
├── server.py Main entry point
├── tools/
│ ├── __init__.py
│ ├── calculator.py
│ └── web_search.py
├── resources/
│ └── file_reader.py
├── prompts/
│ └── templates.py
├── tests/
│ └── test_tools.py
├── pyproject.toml
└── README.md
Debug toolkit (три must-have):
- MCP Inspector: official debug UI — visual test Tools / Resources / Prompts
- Claude Desktop: edit
claude_desktop_config.jsonдля local integration - Cursor MCP config: Settings → MCP → add stdio launch command
03 Hello World: минимальный MCP Server и подключение Cursor
FastMCP — десять строк до первого working Server:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("my-first-server")
@mcp.tool()
def say_hello(name: str) -> str:
"""Приветствует указанного человека"""
return f"Hello, {name}! Это ваш первый MCP tool."
if __name__ == "__main__":
mcp.run()
Run и verify:
python server.py
Or via MCP Inspector
npx @modelcontextprotocol/inspector python server.py
Cursor integration — 6 steps:
- Confirm Python path: в venv
which python— записать absolute path. - Open Cursor MCP settings: Settings → Features → MCP Servers.
- Add stdio Server: command = Python path, args = absolute path к
server.py. - Restart Cursor: MCP config применится.
- Verify tool list: в Agent mode проверить
say_hello. - Trigger call: попросить AI «использовать say_hello для приветствия JEXCLOUD» — confirm correct response.
Claude Desktop аналогично: edit ~/Library/Application Support/Claude/claude_desktop_config.json, register под mcpServers.
04 Tools development: param types, пять практических tools и async mode
Tool contract: function signature = documentation — param types, return type, docstring конвертируются MCP в JSON Schema для AI. Naming: snake_case; errors — structured info, не raw exceptions.
Complex params через Pydantic:
from pydantic import BaseModel, Field
class SearchInput(BaseModel):
query: str = Field(description="Поисковый запрос")
max_results: int = Field(default=5, description="Макс. число результатов")
language: str = Field(default="ru", description="Язык результатов")
@mcp.tool()
def web_search(input: SearchInput) -> list[dict]:
"""Выполняет web search, возвращает список результатов"""
...
Пять практических tools — training checklist:
- Calculator: safe eval math expressions (
ast.literal_evalanti-injection) - File read/write: read / write только в whitelist directory
- HTTP requests: GET / POST с unified timeout и retry
- DB query: read-only SQL + parameterized anti-injection
- Time tools: current time, timezone convert, ISO 8601 format
IO-heavy tools — async:
import httpx
@mcp.tool()
async def fetch_url(url: str) -> str:
"""Получает содержимое указанного URL"""
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=30.0)
return response.text
Error handling best practice: timeouts, permission check (path whitelist / API Key), return {"error": "...", "code": "..."} для AI self-correction.
05 Resources: URI addressing, static/dynamic resources, filesystem
Resource vs Tool: Resource — data provider (read-only), Tool — action executor (write, side effects). Addressing: URI schemes file://, http://, custom://.
Static resource
@mcp.resource("config://app-settings")
def get_app_settings() -> str:
return json.dumps({"version": "1.0", "env": "production"})
Dynamic resource (with params)
@mcp.resource("user://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
user = db.query_user(user_id)
return json.dumps(user)
Resource types:
- Text:
text/plain,application/json - Binary: images, PDF (Base64 или blob URI)
- Streaming: realtime logs, market feed (resource subscription)
Filesystem resource server: list directory → read file by path → optional watchfiles для change detection и resource update notifications.
06 Prompts: reusable templates и multi-turn scenarios
MCP Prompt — predefined prompt fragment, AI client reuse напрямую; dynamic parameter injection для team prompt consistency и maintainability.
from mcp.types import PromptMessage, TextContent
@mcp.prompt()
def code_review_prompt(language: str, code: str) -> list[PromptMessage]:
"""Шаблон prompt для code review"""
return [
PromptMessage(
role="user",
content=TextContent(
type="text",
text=f"Проверьте следующий {language} код..."
)
)
]
Multi-turn templates mix user и assistant roles. Typical scenarios: interview simulation (assistant asks, user answers), debug assistant (assistant guides troubleshooting steps).
07 HTTP transport: remote MCP Server и security hardening
| Feature | stdio | HTTP + SSE |
|---|---|---|
| Deploy | Local process | Remote server |
| Latency | Minimal | Network-dependent |
| Multi-client | Not supported | Supported |
| Use case | Local tools | SaaS / team sharing |
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("remote-server", transport="streamable-http")
if __name__ == "__main__":
mcp.run(host="0.0.0.0", port=8000)
Production stack: Bearer Token auth, API Key middleware, CORS whitelist, rate limiting (e.g. slowapi). Remote Server — team-shared DB queries, internal API gateway и т.д.
08 Debugging и tests: MCP Inspector, unit tests, common errors
MCP Inspector workflow: launch Inspector → connect stdio command → test tools/call in UI → inspect JSON-RPC request/response logs → simulate timeout и permission denied.
import pytest
from mcp.client.session import ClientSession
from mcp.client.stdio import StdioServerParameters, stdio_client
@pytest.mark.asyncio
async def test_calculator_tool():
server_params = StdioServerParameters(command="python", args=["server.py"])
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool("calculate", {"expression": "2 + 2"})
assert result.content[0].text == "4"
| Error | Cause | Fix |
|---|---|---|
| Tool не появляется в AI | Wrong config path | Check absolute command / args paths in config.json |
| JSON serialization fail | Unsupported return type | Convert to string or dict |
| Timeout disconnect | Tool too slow | Switch to async + timeout control |
| Permission denied | Restricted file path | Configure allowed directory whitelist |
09 Production deploy: Docker, cloud и observability
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "server.py"]
Deploy options:
- Railway / Render: one-click deploy, personal projects
- AWS Lambda / Google Cloud Run: serverless, pay-per-invocation
- Self-hosted VPS: Nginx reverse proxy + TLS + Bearer Token
Observability trio: structured request logs, Prometheus tool-call metrics, Sentry error alerts; expose /health. Version management: declare MCP protocol version, backward-compatible tool upgrades, capability negotiation против client crashes.
- MCP Python SDK: github.com/modelcontextprotocol/python-sdk
- MCP TypeScript SDK: github.com/modelcontextprotocol/typescript-sdk
- MCP Inspector: github.com/modelcontextprotocol/inspector
10 Hands-on: personal knowledge base MCP Server
Requirements: AI search local Markdown notes, semantic retrieval, create/update notes.
Tech stack:
- Vector DB: ChromaDB или Qdrant (lightweight local)
- Embedding model:
text-embedding-3-small(OpenAI) или localnomic-embed-text - File watch:
watchfilesincremental index rebuild
Core modules:
index_notestool: scan notes dir, chunk + embed → vector DBsemantic_searchtool: query → top-k relevant chunkswrite_notetool: create / append Markdown filesnotes://{path}resource: full note text by URI
Demo: в Cursor спросить «Что я записывал про MCP на прошлой неделе?» → AI calls semantic_search → returns relevant chunks + synthesized answer. Shortest path private knowledge → Agent workflow.
11 MCP ecosystem outlook, learning path и production host
Recommended community Servers:
mcp-server-filesystem: filesystem opsmcp-server-github: GitHub repo opsmcp-server-brave-search: web searchmcp-server-postgres: DB queriesmcp-server-slack: Slack messages
2026 ecosystem trends: Cursor, Claude Desktop, VS Code, OpenAI, Google Gemini — native или planned MCP support; MCP Marketplace accelerates Server distribution; enterprise security (OAuth 2.1, audit logs) на roadmap.
Next learning path: deep-read MCP spec → publish first public Server → explore MCP + Agent orchestration → contribute PRs to open-source ecosystem.
- Protocol version: 2024-11-05 initial release; с 2025 Streamable HTTP replaces pure SSE as recommended remote transport
- Ecosystem scale: к 2026 community MCP Servers — более 10 000
- SDK maintainers: Anthropic open source + Linux Foundation AAIF governance; Python / TypeScript official SDKs — weekly updates
MCP — standard protocol для AI tooling. Master Server development = любой LLM может вызывать ваши business systems. Что упакуете в MCP tool первым? Делитесь сценарием в комментариях.
Hidden cost production MCP Server — host stability: laptop lid close kills STDIO subprocess; home broadband jitter breaks HTTP long connections; shared VPS без macOS sandbox и TCC permissions. Для 24/7 knowledge base indexing, remote HTTP MCP или Cursor Agent CI — JEXCLOUD multi-region bare-metal Mac: dedicated Apple Silicon, fixed public IP, 120s provisioning, flexible monthly rental. Лучше чем «local hack + constant reconnect». Nodes и pricing: JEXCLOUD pricing; deploy questions: help center.