The post has been translated automatically. Original language: Russian
Of course, everyone already knows and uses ChatGPT and Claude, but there is a layer below that determines how useful these tools are in real work — and it's called MCP. I'll write briefly for what it is, why it's cool, and how to write your first MCP server in an evening.
The problem that the MCP solves
Imagine: you have Claude or GPT and you want the AI to be able to read files on your server, make queries to your database, check the status of tasks in Jira. Such an assistant wouldn't hurt, would it? How to do it?
Until 2024, there was only one answer — it was necessary to write custom integration for each pair of "model + tool". If you changed the model, rewrite it. We have added a new service — write the adapter again. This is the so—called N×M problem: Multiply N models by M tools, and each combination has its own code.
Before MCP
- Separate code for Claude + DB
- Separate code for GPT + DB
- Separate code for Claude + Jira
- Changed the model, rewrote everything
After the MCP
- One MCP server for the database
- One MCP server for Jira
- Any model connects to any server
- N + M instead of N × M
What is MCP?
MCP (Model Context Protocol) is an open standard that Anthropic released in November 2024. It defines a single communication protocol between the AI application and external tools. The best analogy is USB-C for AI: a single connector that fits almost all devices.
Currently, MCP is supported by Claude, ChatGPT, Cursor, VS Code Copilot and dozens of other tools. The number of SDK downloads is almost 100 million per month. Salesforce, ServiceNow, Workday — all have already released their MCP servers.
Architecture in 2 minutes
There are three roles in the MCP:
The scheme of interaction:
Host: Claude Desktop / Cursor / your application→ manages
Client: MCP Client (inside the host), JSON-RPC
Server: Your MCP server → calls PostgreSQL / API / files
Host is an application in which AI lives (Claude Desktop, Cursor, etc.). It runs a Client that communicates with your MCP server using the JSON-RPC 2.0 protocol. The server, in turn, accesses real data: database, API, file system.
Three MCP Primitives
The MCP server can provide three types of entities:
Tools — Actions that can be called by the model. Writing to the database, sending a request, executing a command.
Resources — Read-only data: files, DATABASE entries, API results. The context for the model.
Prompts — Reusable prompt templates. They help to standardize complex queries.
In practice, 90% of the time you will work with Tools — they are the ones that give the model the opportunity to do something, not just read.
Writing the first MCP server in Python
We use FastMCP, a high—level framework on top of the official SDK. It hides all the JSON-RPC mechanics and allows you to describe tools through decorators, like Flask routes.
Installation
# Install the official SDK (includes FastMCP)
pip install mcp
# Or via uv (recommended)
uv add mcpSimple server: tools for working with PostgreSQL
Let's create an MCP server that gives Claude access to the database to read tables and perform queries.:
# server.py
from mcp.server.fastmcp import FastMCP
import psycopg2
import os
# Initialize the server with the name
mcp = FastMCP("database-assistant")
def get_conn():
return psycopg2.connect(os.environ["DATABASE_URL"])
# Decorator @mcp.tool() — that's the whole MCP
@mcp.tool()
def list_tables() -> list[str]:
"""Show a list of all tables in the database."""
conn = get_conn()
with conn.cursor() as cur:
cur.execute("""
SELECT tablename FROM pg_tables
WHERE schemaname = 'public'
ORDER BY tablename
""")
return [row[0] for row in cur.fetchall()]
@mcp.tool()
def query_table(table: str, limit: int = 10) -> list[dict]:
"""Get the first N rows from the table.
Args:
table: The name of the table
limit: Number of rows (max. 100)
"""
limit = min(limit, 100) # protection against huge samples
conn = get_conn()
with conn.cursor() as cur:
cur.execute(
f"SELECT * FROM {table} LIMIT %s",
(limit,)
)
cols = [desc[0] for desc in cur.description]
return [dict(zip(cols, row)) for row in cur.fetchall()]
# Run via stdio (for Claude Desktop)
if __name__ == "__main__":
mcp.run(transport="stdio")Why docstring is important: FastMCP automatically sends the docstring text to the model as a description of the tool. The more accurate the description, the better the model understands when and how to use this tool. This is literally industrial engineering inside the code.
Connecting to Claude Desktop
Adding the server to the Claude Desktop config (file claude_desktop_config.json):
{
"mcpServers": {
"database-assistant": {
"command": "python",
"args": ["/path/to/server.py"],
"env": {
"DATABASE_URL": "postgresql://user:pass@localhost/mydb"
}
}
}
}After restarting Claude Desktop— the hammer icon will appear in the interface. This means that the tools are connected. Now you can write:
Show all the tables in the database and output the first 5 rows from the users table
→ Claude will call list_tables() himself, then query_table("users", 5)
→ and return the result as readable textReal-world usage examples
Here's what already exists in the MCP server registry and what can be connected in minutes:
GitHub MCP — read issues, PR, commits. Claude writes the code for real tasks from the repository himself.
PostgreSQL MCP is the official server. We give Claude access to the database and ask in Russian.
Filesystem MCP — secure file access. You can ask to analyze the logs or the structure of the project.
Your internal API — any REST endpoint turns into an MCP tool in 20 lines of code.
Transports: stdio vs HTTP
The MCP supports two connection methods:
- The stdio server is started as a child process. Ideal for local tools and Claude Desktop. Just, no ports.
- The streamable HTTP server lives separately and is accessible by URL. For teams and production deployment. In 2026, this is the preferred transport for remote servers.
# HTTP transport for deployment to the server
if __name__ == "__main__":
mcp.run(
transport="streamable-http",
host="0.0.0.0",
port=8000
)
# Configuration for Claude Desktop with remote server:
# "url": "http://localhost:8000/mcp "About security: An MCP server with access to a database is actually an API without authentication by default. For production, be sure to add token authorization and limit the allowed operations. There is no DROP TABLE in the list of available tools.
MCP vs function calling — what is the difference
MCP is often confused with function calling (tool use) in the API. These are different levels:
- Function calling is an API mechanism within a specific model. You describe the functions in the JSON schema for each request.
- The MCP protocol is one level higher. The server announces its tools once, and any MCP-compatible host sees them. Under the hood, MCP uses function calling anyway — but you don't think about it.
In short: The function calling is the motor, the MCP is the connector standard. You can use a motor without a standard, but then you have to solder the wires manually every time.
Result
MCP is a new standard that has been adopted by all major AI players. If you're writing something that integrates with AI, clients will soon ask, "Do you have an MCP server?" just like they're asking about the REST API now.
Конечно все уже знают и используют ChatGPT и Claude, но есть слой ниже, который определяет, насколько эти инструменты полезны в реальной работе — и он называется MCP. Напишу кратко для что это, почему это круто и как написать свой первый MCP-сервер за вечер.
Проблема, которую решает MCP
Представьте: у вас есть Claude или GPT и вы хотите, чтобы ИИ мог читать файлы на вашем сервере, делать запросы к вашей базе данных, проверять статус задач в Jira. Такой помощник не помешает не правда ли? Как это сделать?
До 2024 года ответ был один — надо было написать кастомную интеграцию под каждую пару «модель + инструмент». Поменяли модель — переписывайте. Добавили новый сервис — снова пишите адаптер. Это так называемая N×M проблема: N моделей умножить на M инструментов — и для каждой комбинации свой код.
До MCP
- Отдельный код для Claude + БД
- Отдельный код для GPT + БД
- Отдельный код для Claude + Jira
- Поменяли модель — переписали всё
После MCP
- Один MCP-сервер для БД
- Один MCP-сервер для Jira
- Любая модель подключается к любому серверу
- N + M вместо N × M
Что такое MCP
MCP (Model Context Protocol) — открытый стандарт, который Anthropic выпустила в ноябре 2024 года. Он определяет единый протокол общения между ИИ-приложением и внешними инструментами. Лучшая аналогия — USB-C для ИИ: один разъём, который подходит почти ко всем девайсам.
На текущий момент MCP поддерживают Claude, ChatGPT, Cursor, VS Code Copilot и десятки других инструментов. Количество скачиваний SDK почти 100 миллионов в месяц. Salesforce, ServiceNow, Workday — все уже выпустили свои MCP-серверы.
Архитектура за 2 минуты
В MCP есть три роли:
Схема взаимодействия:
Host: Claude Desktop / Cursor / ваше приложение→ управляет
Client: MCP Client (внутри host) ↔ JSON-RPC
Server: Ваш MCP-сервер → вызывает PostgreSQL / API / файлы
Host — это приложение, в котором живёт ИИ (Claude Desktop, Cursor и т.д.). Он запускает Client, который общается с вашим MCP-сервером по протоколу JSON-RPC 2.0. Сервер, в свою очередь, обращается к реальным данным: базе, API, файловой системе.
Три примитива MCP
MCP-сервер может предоставлять три типа сущностей:
Tools — Действия, которые может вызвать модель. Запись в БД, отправка запроса, выполнение команды.
Resources — Данные только для чтения: файлы, записи из БД, результаты API. Контекст для модели.
Prompts — Переиспользуемые шаблоны промптов. Помогают стандартизировать сложные запросы.
На практике 90% времени вы будете работать с Tools — именно они дают модели возможность что-то делать, а не просто читать.
Пишем первый MCP-сервер на Python
Используем FastMCP — высокоуровневый фреймворк поверх официального SDK. Он скрывает всю JSON-RPC механику и позволяет описывать инструменты через декораторы — как Flask-роуты.
Установка
# Устанавливаем официальный SDK (включает FastMCP)
pip install mcp
# Или через uv (рекомендуется)
uv add mcpПростой сервер: инструменты для работы с PostgreSQL
Создадим MCP-сервер, который даёт Claude доступ к базе данных — читать таблицы и выполнять запросы:
# server.py
from mcp.server.fastmcp import FastMCP
import psycopg2
import os
# Инициализируем сервер с именем
mcp = FastMCP("database-assistant")
def get_conn():
return psycopg2.connect(os.environ["DATABASE_URL"])
# Декоратор @mcp.tool() — вот и весь MCP
@mcp.tool()
def list_tables() -> list[str]:
"""Показать список всех таблиц в базе данных."""
conn = get_conn()
with conn.cursor() as cur:
cur.execute("""
SELECT tablename FROM pg_tables
WHERE schemaname = 'public'
ORDER BY tablename
""")
return [row[0] for row in cur.fetchall()]
@mcp.tool()
def query_table(table: str, limit: int = 10) -> list[dict]:
"""Получить первые N строк из таблицы.
Args:
table: Название таблицы
limit: Количество строк (макс. 100)
"""
limit = min(limit, 100) # защита от огромных выборок
conn = get_conn()
with conn.cursor() as cur:
cur.execute(
f"SELECT * FROM {table} LIMIT %s",
(limit,)
)
cols = [desc[0] for desc in cur.description]
return [dict(zip(cols, row)) for row in cur.fetchall()]
# Запускаем через stdio (для Claude Desktop)
if __name__ == "__main__":
mcp.run(transport="stdio")Почему docstring важен: FastMCP автоматически отправляет текст docstring в модель как описание инструмента. Чем точнее описание — тем лучше модель понимает, когда и как использовать этот tool. Это буквально промпт-инжиниринг внутри кода.
Подключаем к Claude Desktop
Добавляем сервер в конфиг Claude Desktop (файл claude_desktop_config.json):
{
"mcpServers": {
"database-assistant": {
"command": "python",
"args": ["/path/to/server.py"],
"env": {
"DATABASE_URL": "postgresql://user:pass@localhost/mydb"
}
}
}
}После перезапуска Claude Desktop — в интерфейсе появится иконка молотка 🔨. Это значит, что инструменты подключены. Теперь можно написать:
Покажи все таблицы в базе данных и выведи первые 5 строк из таблицы users
→ Claude сам вызовет list_tables(), потом query_table("users", 5)
→ и вернёт результат в виде читаемого текстаРеальные примеры использования
Вот что уже существует в реестре MCP-серверов и что можно подключить за минуты:
GitHub MCP — читать issues, PR, коммиты. Claude сам пишет код под реальные задачи из репозитория.
PostgreSQL MCP — официальный сервер. Даём Claude доступ к БД и спрашиваем на русском языке.
Filesystem MCP — безопасный доступ к файлам. Можно попросить проанализировать логи или структуру проекта.
Ваш внутренний API — любой REST-эндпоинт превращается в MCP-tool за 20 строк кода.
Транспорты: stdio vs HTTP
MCP поддерживает два способа соединения:
- stdio — сервер запускается как дочерний процесс. Идеально для локальных инструментов и Claude Desktop. Просто, никаких портов.
- Streamable HTTP — сервер живёт отдельно, доступен по URL. Для команд и продакшн-деплоя. В 2026 году это предпочтительный транспорт для удалённых серверов.
# HTTP-транспорт для деплоя на сервер
if __name__ == "__main__":
mcp.run(
transport="streamable-http",
host="0.0.0.0",
port=8000
)
# Конфиг для Claude Desktop с удалённым сервером:
# "url": "http://localhost:8000/mcp"Про безопасность: MCP-сервер с доступом к БД — это фактически API без аутентификации по умолчанию. Для продакшна обязательно добавьте токен-авторизацию и ограничьте разрешённые операции. Никакого DROP TABLE в списке доступных инструментов.
MCP vs function calling — в чём разница
Часто путают MCP с function calling (tool use) в API. Это разные уровни:
- Function calling — это API-механизм внутри конкретной модели. Вы описываете функции в JSON-схеме при каждом запросе.
- MCP — протокол на уровень выше. Сервер один раз объявляет свои инструменты, и любой MCP-совместимый хост их видит. Под капотом MCP всё равно использует function calling — но вы об этом не думаете.
Короче: function calling — это двигатель, MCP — это стандарт на разъём. Можно использовать двигатель без стандарта, но тогда каждый раз придётся паять провода вручную.
Итог
MCP — новый стандарт, который принят всеми крупными AI-игроками. Если вы пишете что-то, что интегрируется с ИИ — скоро клиенты будут спрашивать «а у вас есть MCP-сервер?» так же, как сейчас спрашивают про REST API.