Добавить в корзинуПозвонить
Найти в Дзене

Как создать MCP-сервер на Python и подключить его к Cursor через mcp.json?

Дима хотел тянуть цифры из Google Sheet в Cursor без копипасты. Скопировал Habr-гайд на TypeScript, в mcp.json прописал npx — Agent молчал: Failed to parse JSON, потому что console.log шёл в stdout. Боль без бэкенд-опыта: готовый MCP не закрывает ваш CRM, свой tool тонет в JSON-RPC, сервер зелёный, вызовов нет. Ниже — один вечер: server.py на Python, Inspector, stderr-only, пять тестов в Agent mode. TL;DR / Быстрый инсайт: MCP (Model Context Protocol) — это «розетка», через которую Cursor запускает ваш код как инструмент агента, а не как текст в промпте. Для первого пилота выберите одну задачу (lookup в CRM, строка из таблицы, дайджест webhook), соберите FastMCP на Python с 1-2 tools, проверьте в MCP Inspector, подключите через .cursor/mcp.json с PYTHONUNBUFFERED. Готовый сервер из Marketplace — в гайде по подключению MCP к Cursor; сборка workflow в n8n из чата — в гайде по n8n MCP. Здесь — свой tool под ваш API. Как USB-кабель под одно устройство, не зарядка на весь офис. В июне 2026
Оглавление

Дима хотел тянуть цифры из Google Sheet в Cursor без копипасты. Скопировал Habr-гайд на TypeScript, в mcp.json прописал npx — Agent молчал: Failed to parse JSON, потому что console.log шёл в stdout. Боль без бэкенд-опыта: готовый MCP не закрывает ваш CRM, свой tool тонет в JSON-RPC, сервер зелёный, вызовов нет. Ниже — один вечер: server.py на Python, Inspector, stderr-only, пять тестов в Agent mode.

TL;DR / Быстрый инсайт: MCP (Model Context Protocol) — это «розетка», через которую Cursor запускает ваш код как инструмент агента, а не как текст в промпте. Для первого пилота выберите одну задачу (lookup в CRM, строка из таблицы, дайджест webhook), соберите FastMCP на Python с 1-2 tools, проверьте в MCP Inspector, подключите через .cursor/mcp.json с PYTHONUNBUFFERED. Готовый сервер из Marketplace — в гайде по подключению MCP к Cursor; сборка workflow в n8n из чата — в гайде по n8n MCP. Здесь — свой tool под ваш API.

Как USB-кабель под одно устройство, не зарядка на весь офис. В июне 2026 Python SDK MCP уже в alpha v2 (2.0.0a3), beta обещана на 30 июня, а туториалы всё ещё учат from mcp.server.fastmcp import FastMCP из ветки 1.x. Типичная ошибка — pip install mcp без пина: через месяц сломается. Фиксируйте mcp>=1.27,<2 до stable v2. RU-конкуренты чаще ведут на TypeScript, хотя Wordstat даёт mcp server python наравне с узким запросом «как создать mcp сервер» (66 показов/мес), а англоязычный хвост mcp server creating — 845.

Одна бизнес-задача — один tool, не «сервер на всё»

-2

Формулируйте на языке отдела: «найти контакт в CRM по email», «прочитать события webhook», «строка 12 из Google Sheet». Запишите имя будущего tool — lookup_contact, get_webhook_events, get_sheet_row. Не закрывайте пять API одним server.py: Agent путает похожие tools и чаще галлюцинирует, чем вызывает нужный.

В реальном проекте Дима выбрал одну строку таблицы — и только после этого написал get_sheet_row. На старте read-only: без delete, post_message и write в CRM. Типичная ошибка — скопировать обзор «тысячи MCP» и поставить три чужих пакета вместо одного своего tool.

Сценарий Куда идти Что делаете Нужен готовый Slack/GitHub/CRM из каталога B04 — подключить MCP к Cursor mcp.json + read-only токен, без своего кода Собрать workflow n8n из промпта в чате B02 — n8n MCP в Cursor Instance-level MCP, HTTP, не Python stdio Свой API, внутренний webhook, кастомная таблица Этот гайд (B08) FastMCP server.py, 1-2 @mcp.tool Удалённый доступ всей команде без локального ПК HTTP transport + Docker позже Не stdio на ноутбуке одного человека

Итоговый вердикт: Если задача закрывается готовым MCP из Marketplace — не пишите код, смотрите B04. Если нужен именно ваш endpoint — остаётесь здесь.

Соберите FastMCP на Python за 15-40 строк

-3

MCP-сервер — отдельная программа, которая говорит с Cursor по JSON-RPC через stdin/stdout (транспорт stdio). FastMCP — обёртка в официальном Python SDK: функции с @mcp.tool становятся инструментами агента. API (Application Programming Interface) здесь — HTTP-запрос к вашему сервису внутри tool, как официант, который ходит на кухню за данными, пока вы общаетесь с агентом.

Минимальный стек: Python 3.10+, менеджер uv (или venv), пин mcp>=1.27,<2 в pyproject.toml — ветка 2.x пока alpha и меняет импорты.

  1. Создайте проект: uv init sheet-mcp && cd sheet-mcp
  2. Добавьте зависимости: uv add «mcp[cli]» httpx — cli даёт команду mcp dev для Inspector
  3. Создайте server.py с FastMCP, именем сервера и одним read-only tool
  4. Опишите tool: type hints + docstring с примером аргумента — агент читает описание, чтобы понять когда звать функцию
  5. Запустите локально: uv run python server.py — пока без Cursor, просто убедитесь что нет синтаксических ошибок
Пример server.py (каркас): from mcp.server.fastmcp import FastMCP; mcp = FastMCP(«sheet-tools»); @mcp.tool get_sheet_row(sheet_id, row) с docstring-примером sheet_id=abc, row=12; API-ключ из os.environ SHEET_API_KEY; httpx.get к вашему API; if __name__ == __main__: mcp.run(). Логи только в stderr, print в stdout не делайте.

Типичная ошибка: print() для отладки. На stdout — только JSON-RPC, любой лишний байт ломает парсер. Логи — в stderr через logging. Дима после переписывания с TypeScript уложился в 40 строк Python и увидел tool в Inspector раньше, чем открыл Cursor.

Сначала MCP Inspector — потом Cursor

-4

Не подключайте Cursor, пока tool не вызывается в Inspector — отдельное окно, где вы видите список tools и жмёте «вызвать» вручную. Это тестовая розетка до подключения ноутбука к сети.

Команда Inspector: uv run mcp dev server.py — из корня проекта, где лежит server.py.

Альтернатива без uv cli: npx @modelcontextprotocol/inspector python server.py. В UI выберите tool, передайте аргументы, проверьте ответ. Ошибка в Inspector — та же в Cursor, только без потерянного вечера.

Часто ломается stdio из-за буферизации Python: процесс «висит» на initialize. Решение — флаг -u и PYTHONUNBUFFERED=1 в mcp.json. Логи FastMCP на DEBUG забивают pipe — для пилота держите WARNING.

Схема отладки:Одна задача → server.py с @mcp.tool → uv run mcp dev → успешный вызов в Inspector → только потом .cursor/mcp.json → Tools & MCP зелёный → Agent mode

Подключите server к Cursor через .cursor/mcp.json

Конфиг: .cursor/mcp.json в корне проекта (удобно команде) или ~/.cursor/mcp.json для личного пилота. Cursor запускает дочерний процесс stdio — ту же команду, что вы гоняли в терминале.

Пример .cursor/mcp.json: mcpServers.sheet-tools с command uv; args run, —directory, ${workspaceFolder}, python, -u, server.py; env PYTHONUNBUFFERED=1 и SHEET_API_KEY через ${env:SHEET_API_KEY}.

Секреты — только через ${env:KEY} или envFile, .env в .gitignore. Не коммитьте API-ключ в server.py или JSON. После правки — полный перезапуск Cursor. Ctrl+Shift+J → Tools & MCP: зелёный статус, tools в списке. Красный — MCP Logs и ручной запуск команды. Путь к server.py — с ${workspaceFolder}, иначе на другой машине сломается.

Пять тестов в Agent mode и лимит ответа

Тесты — не «поболтать», а таблица ожиданий. Пример для get_sheet_row:

  • «Верни строку 12 из таблицы abc» — ожидается вызов get_sheet_row, не выдуманные цифры.
  • «Какие MCP tools у тебя есть?» — перечисление без лишних серверов.
  • «Сводка по строке 5» — тот же tool, другой row.
  • «Удали строку 12» — агент должен отказать при read-only tool.
  • «Покажи сырой JSON всей таблицы на 500 строк» — обрежьте ответ; на macOS stdio зависает при ответе tool больше ~8 KB.

Логируйте по каждому промпту: tool вызван (да/нет), имя tool, approval stuck, строка из MCP Logs. Если агент отвечает из головы — правило в .cursor/rules: для запросов про таблицу обязателен вызов get_sheet_row.

Как понять, что сработало: uv run mcp dev server.py показывает tools и успешный вызов; Tools & MCP зелёный; Agent вызывает tool и возвращает данные API; секретов нет в git; пять промптов с логом; ясно B04 (готовый MCP) vs B08 (свой код). Важно: убедитесь, что stdout чист от print. Советуем прогнать пять тестов до merge. Рекомендуем не подключать Cursor до успеха в Inspector: лучше 10 минут там, чем вечер в MCP Logs. Не стоит коммитить ключи в mcp.json или server.py. У Димы lookup заработал до полуночи после PYTHONUNBUFFERED=1.

Пилот под CRM, таблицу или webhook — neuroalex.site. Доки: Cursor MCP, build server. Актуальность — 2026-06-26.

Редакционная проверка: Алексей Доронин, эксперт по автоматизации бизнеса и ИИ (neuroalex.site).
Факты и версии: SDK, stdio-ограничения и команды Inspector сверены с modelcontextprotocol.io, cursor.com/docs/mcp и GitHub modelcontextprotocol/python-sdk на 2026-06-26; оценки спроса — Яндекс Вордстат (как создать mcp сервер — 66 показов/мес, mcp server creating — 845, mcp server python — 66, cursor mcp — 634, регион РФ).

Частые вопросы

Чем свой MCP-сервер отличается от готового из Marketplace?

Готовый — чужой код под типовой API (Slack, GitHub). Свой — когда нужен внутренний endpoint, кастомная CRM или webhook, которого нет в каталоге. Подключение готового — в B04; написание server.py — здесь.

stdio или HTTP — что выбрать для Cursor?

Для одного разработчика на локальном ПК достаточно stdio: Cursor сам запускает python server.py. HTTP/SSE нужен, если сервер крутится на VPS и им пользуется вся команда без установки Python у каждого.

Нужен ли Docker, если сервер только на вашем ПК?

Нет. Docker имеет смысл для деплоя HTTP MCP на сервер. Для вечернего пилота — uv, server.py и Inspector.

Почему pin mcp>=1.27,<2, а не последняя версия?

В июне 2026 ветка 2.x в alpha (2.0.0a3), импорты и API меняются. Stable v1.x — проверенный FastMCP из mcp.server.fastmcp. Обновитесь на v2 после stable релиза и миграционного гайда.

Agent зелёный MCP, но tool не вызывается — с чего начать?

Сначала Inspector и MCP Logs. Проверьте stdout без print, PYTHONUNBUFFERED=1, docstring у tool и явное имя в промпте. Часто помогает правило в .cursor/rules с триггерными словами задачи.

Можно ли писать MCP на TypeScript вместо Python?

Да, официальный SDK есть для Node. Этот гайд — Python: FastMCP укладывается в десятки строк, Wordstat фиксирует спрос на mcp server python, а Habr-гайды на TS часто пропускают PYTHONUNBUFFERED и Inspector-first.

Что если ответ tool слишком большой?

Делите на страницы, возвращайте summary или топ-N. На macOS stdio зависает при ответе больше ~8 KB — не отдавайте гигантский JSON за один вызов.