Skip to main content
Glama

DevTools MCP

Небольшой MCP-сервер с утилитами для разработчика, созданный, чтобы изучить Model Context Protocol от начала до конца: реализация сервера, локальное тестирование, использование существующего MCP, публичное развертывание и публикация в Smithery.

1. Обзор

DevTools MCP предоставляет четыре небольших инструмента для разработчика через Model Context Protocol: объяснение сообщения об ошибке, проверка/форматирование JSON, генерация регулярного выражения по описанию и суммаризация текста с помощью LLM (Groq). Минимальная панель на TypeScript/Vite позволяет опробовать инструменты из браузера, подключаясь как настоящий MCP-клиент.

Related MCP server: ai-assistant

2. Зачем нужен MCP

MCP стандартизирует, каким образом LLM-хост (Claude Desktop, IDE, агент) обнаруживает и вызывает инструменты, вместо того чтобы каждый проект изобретал собственный API для вызова инструментов. Создание настоящего MCP-сервера — а не REST API с ярлыком MCP — было основной целью обучения в этом проекте.

3. Архитектура

MCP Client
    |
MCP Protocol
    |
DevTools MCP Server
    |-- explain_error    (local/deterministic)
    |-- format_json      (local/deterministic)
    |-- generate_regex   (local/deterministic)
    `-- summarize_text
            |
        Groq API
            |
        GPT-OSS 120B

Сервер (server/server.py) — это mcp.server.MCPServer (пакет MCP Python SDK v2). Он работает через stdio для локального тестирования (MCP Inspector, Client(mcp)) и через Streamable HTTP (/mcp) для удаленного/браузерного доступа. Фронтенд на TypeScript (frontend/) — настоящий MCP-клиент: он использует Client и StreamableHTTPClientTransport из @modelcontextprotocol/sdk для общения с сервером напрямую через Streamable HTTP (на сервере включен CORS), а не через самодельный REST-мост.

4. Инструменты

Инструмент

Входные данные

Что делает

explain_error

error_message

Сопоставляет ошибку со списком частых шаблонов ошибки (Python/JS/общий) и возвращает возможную причину и практическое решение. Локально и детерминированно.

format_json

json_text

Проверяет JSON и возвращает отформатированную версию или точную ошибку разбора (строка/столбец). Локально и детерминированно.

generate_regex

description

Сопоставляет описание с небольшой библиотекой общих regex-шаблонов (email, URL, IPv4, дата, UUID и др.) и возвращает шаблон и пояснение. Локально и детерминированно.

summarize_text

text, max_length?

Вызывает Groq (openai/gpt-oss-120b) и возвращает краткую сводку. Аккуратно обрабатывает отсутствие ключа, таймауты и ошибки API.

5. Структура проекта

devtools-mcp/
├── server/
│   ├── server.py               # MCPServer + tool registration + ASGI app
│   ├── tools.py                # explain_error / format_json / generate_regex logic
│   ├── ai.py                   # Groq-backed summarize_text logic
│   └── tests/
│       └── test_server.py      # pytest suite using the SDK's in-memory Client
├── frontend/
│   ├── index.html
│   ├── src/
│   │   ├── main.ts             # real MCP client (StreamableHTTPClientTransport)
│   │   └── style.css
│   ├── package.json
│   ├── tsconfig.json
│   └── vite.config.ts
├── .env.example
├── .gitignore
├── requirements.txt
├── render.yaml                 # optional Render Blueprint
├── README.md
└── EXISTING_MCP_EXPERIENCE.md

6. Необходимые условия

  • Python 3.10+

  • Node.js 18+ и npm (для фронтенда и для запуска MCP Inspector через npx)

  • API-ключ Groq (нужен только для summarize_text)

  • (Необязательно, для обслуживания) аккаунт Render и аккаунт Smithery

7. Установка

git clone <this-repo>
cd devtools-mcp
python3 -m venv .venv
. .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install -r requirements.txt

8. Переменные окружения

Скопируйте .env.example в .env и заполните необходимое:

GROQ_API_KEY=            # required for summarize_text
GROQ_MODEL=openai/gpt-oss-120b
MCP_ALLOWED_HOSTS=        # only needed when deployed behind a real hostname
MCP_ALLOWED_ORIGINS=      # comma-separated browser origins allowed via CORS

Файл .env игнорируется git. Никогда не коммитьте реальные секреты.

9. Локальная настройка

Stdio (по умолчанию, для локальных MCP-клиентов):

python -m server.server

Streamable HTTP (для фронтенда или любого HTTP-клиента MCP) — только локально:

uvicorn server.server:app --host 127.0.0.1 --port 8000

MCP_ALLOWED_HOSTS локально можно не задавать — встроенная защита SDK от DNS-rebinding, которая допускает только 127.0.0.1/localhost, срабатывает автоматически. Проверка состояния: curl http://127.0.0.1:8000/health.

10. Тестирование MCP Inspector

# Against stdio:
uv run mcp dev server/server.py     # requires uv; or: npx @modelcontextprotocol/inspector
# Against a running Streamable HTTP server:
npx @modelcontextprotocol/inspector --cli http://127.0.0.1:8000/mcp --method tools/list

Во время разработки это было проверено на локальном Streamable HTTP-сервере; подтвердилось, что все четыре инструмента обнаруживаются с правильными схемами ввода/вывода (точные результаты — см. раздел «Тестирование» ниже).

11. Настройка фронтенда

cd frontend
npm install
npm run dev          # http://localhost:5173

В открытой панели задайте в поле URL сервера ваш ендпоинт /mcp (по умолчанию http://localhost:8000/mcp), нажмите Connect, выберите инструмент, заполните форму и нажмите Run. Для локального использования запускайте бэкенд с MCP_ALLOWED_ORIGINS=http://localhost:5173, чтобы CORS разрешил доступ.

Продакшен-сборка: npm run build (вывод в frontend/dist/).

12. Настройка Groq

  1. Создайте API-ключ на console.groq.com.

  2. Задайте GROQ_API_KEY (и при желании GROQ_MODEL, по умолчанию openai/gpt-oss-120b) в .env или в переменных окружения вашей платформы развертывания.

  3. Никакой другой LLM-провайдер в проекте не используется.

13. Работа с существующим MCP

См. EXISTING_MCP_EXPERIENCE.md — там требования продемонстрировать использование существующего MCP-сервера (Context7): что это такое, как был выполнен запрос и какие выводы сделаны.

14. Развертывание на Render

Используется нативный Python-рантайм Render (Docker не требуется).

Настройка в дашборде:

  1. Запушьте этот репозиторий на GitHub.

  2. В Render: New → Web Service → подключите репозиторий.

  3. Runtime: Python 3. Build: pip install -r requirements.txt. Start: uvicorn server.server:app --host 0.0.0.0 --port $PORT.

  4. Задайте переменные окружения: GROQ_API_KEY, GROQ_MODEL, MCP_ALLOWED_HOSTS=<your-service>.onrender.com,<your-service>.onrender.com:* и MCP_ALLOWED_ORIGINS=<your-frontend-origin> (если разворачиваете также фронтенд).

  5. Деплой производится. MCP endpoint будет https://<your-service>.onrender.com/mcp.

Включен render.yaml Blueprint как удобство для той же настройки.

Обязательный ручной шаг: реальное развертывание требует аккаунта Render; в рамках этого ответа оно не выполнялось — подробнее, что осталось ручным, см. в отчете о выполненной работе.

15. Публикация на Smithery

Текущий Smithery CLI поддерживает публикацию уже размещенного удаленного URL MCP-сервера напрямую (для этого пути не требуется Docker/контейнерная сборка):

npm install -g smithery
smithery auth login
smithery mcp publish "https://<your-service>.onrender.com/mcp" -n "<your-org>/devtools-mcp"

После публикации проверьте, что все четыре инструмента доступны:

smithery mcp add "https://<your-service>.onrender.com/mcp" --id devtools-mcp
smithery tool list devtools-mcp

Обязательный ручной шаг: для этого нужен аккаунт Smithery и публично доступный, работающий деплой на Render; в рамках этого ответа это не выполнялось.

16. Публичное использование MCP

После развертывания любой Streamable HTTP MCP-клиент может подключиться:

https://<your-service>.onrender.com/mcp

Пример с Client из SDK:

from mcp import Client
from mcp.client.streamable_http import streamable_http_client

async with streamable_http_client("https://<your-service>.onrender.com/mcp") as (r, w, _):
    async with Client(r, w) as client:
        await client.initialize()
        print(await client.list_tools())

17. Тестирование

Реально запускалось в этом окружении:

pytest server/tests/ -v

Результат: 11 прошло — обнаружение инструментов; валидный, некорректный и пустой ввод в format_json; совпадение и несовпадение шаблонов в explain_error (включая пустой ввод); generate_regex для известного шаблона (с проверкой живого совпадения) и для нераспознанного описания; summarize_text без GROQ_API_KEY и с пустым вводом.

Также реально выполнено (вручную, вне pytest):

  • uvicorn server.server:app успешно стартовал; /health вернул {"status":"ok",...}.

  • Простой JSON-RPC POST initialize на /mcp вернул 200.

  • Реальный CLI MCP Inspector (npx @modelcontextprotocol/inspector --cli) подключался через Streamable HTTP, показал все четыре инструмента с правильными схемами и успешно вызывал generate_regex, explain_error, format_json (для валидного и невалидного JSON) и summarize_text (верно сообщил об отсутствующем API-ключе, так как реального Groq-ключа в этом окружении не было).

  • Проверка безопасности транспорта: запрос с подделанным заголовком Host правильно получил ответ 421 Misdirected Request.

  • Проверен CORS preflight: OPTIONS /mcp с Origin: http://localhost:5173 вернул 200 и корректные заголовки access-control-* после установки MCP_ALLOWED_ORIGINS.

  • Фронтенд: npx tsc --noEmit завершился без ошибок; npm run build прошел и создал frontend/dist/.

Не проверено (требуются внешние аккаунты/доступы, недоступные в этом окружении): реальный вызов summarize_text с живым ключом Groq, сам деплой на Render и публикация/листинг на Smithery.

18. Ограничения

  • summarize_text был испытан сквозным образом только на путях ошибок; с реальными Groq-ключами он не вызывался.

  • Деплой на Render и публикация на Smithery требуют ручных шагов в ваших собственных аккаунтах (см. разделы «14–15») и здесь не выполнялись.

  • explain_error и generate_regex используют небольшие, вручную написанные библиотеки шаблонов, а не LLM — они намеренно простые/детерминированные по замыслу проекта, поэтому не распознают любые возможные ошибки и описания шаблонов.

  • Фронтенд не имеет аутентификации и предназначен для локального/демонстрационного использования в соответствии с явной областью проекта «без аккаунтов/авторизации».

19. Результаты обучения

  • Что такое MCP: это стандартный протокол, отделяющий «предоставление контекста/действий LLM» от «взаимодействия с самой LLM», поэтому созданный раз сервер (как этот) работает с любым совместимым клиентом.

  • Хост / клиент / сервер: хостом является LLM-приложение (Claude Desktop или приложение за браузерной панелью); клиент — говорящая по-MCP часть внутри него (SDK Client или наш клиент на StreamableHTTPClientTransport); сервер — то, что мы разработали — он никогда напрямую с моделью не общается.

  • Инструменты vs ресурсы vs промпты: инструменты контролируются моделью (LLM сам решает вызвать format_json); ресурсы — загрузка данных по инициативе приложения; промпты — шаблоны, вызываемые пользователем. Этот проект требовал только инструменты.

  • Обнаружение и вызов инструментов: клиент вызывает tools/list, чтобы узнать, что доступно (имя, описание, JSON-схема входов/выходов — все автоматически выводится из аннотаций типов Python и docstrings), а затем tools/call, чтобы вызвать конкретный инструмент по имени с аргументами.

  • Почему MCP вместо простого REST API: REST API тре参会 специфическую интеграцию для каждого клиента; MCP-сервер описывает собственные возможности и схемы, поэтому любой MCP-совместимый хост использует его без своего склей-кода — что видно на практике: к одному и тому же серверу подключались и MCP Inspector, и наш собственный фронтенд без каких-либо изменений на стороне сервера.

  • Где применяется LLM: только в summarize_text, потому что он вызовет Groq. Вся остальная часть сервера — обычный детерминированный код, что является полезным напоминанием, что «» и «AI-приложение» — не одно и то же.

  • Реалии развертывания: Streamable HTTP-серверы по умолчанию принимают Host/Origin только для localhost — это требуется явно расширять через TransportSecuritySettings при публичном развертывании. Я подтвердил это руками: запустил и поймал 421, затем исправил.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables AI clients to use developer utilities like JSON formatting, JWT decoding, UUID generation, and more via MCP.
    12
    36 npm
    2
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables MCP-compatible applications to interact with local and cloud-hosted LLM models for model management, text generation, chat, embeddings, and web search/fetch.
    958 npm
    AGPL 3.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables MCP-compatible applications to manage and use local or cloud LLM models through comprehensive SDK tools, including model management, text generation, chat with tool support, embeddings, and web search/fetch.
    958 npm
    AGPL 3.0