DevTools MCP Server
🛠️ DevTools MCP Server
Легковесный сервер Model Context Protocol (MCP), который предоставляет любому MCP-совместимому LLM-клиенту (Claude Desktop, Claude Code, Cursor и т.д.) набор инструментов разработчика: веб-скрапинг, просмотр журналов, живой веб-поиск и выполнение SQL-запросов только для чтения к SQLite или Postgres/Supabase — всё через один сервер.
🔗 Живая песочница: Glama MCP Link — попробуйте инструменты прямо в браузере после публикации (см. Развёртывание).
📖 Обзор
DevTools MCP предоставляет четыре инструмента через MCP, чтобы LLM-ассистент мог:
Извлекать чистый читаемый текст с любой веб-страницы
Просматривать последние строки локальных файлов журналов для отладки ошибок
Искать в живом вебе актуальную документацию перед написанием кода
Выполнять запросы
SELECTтолько для чтения к локальному файлу SQLite или живой базе данных Postgres/Supabase
Каждый инструмент — это простая тестируемая Python-функция; здесь ничто не зависит от платных API, кроме вашего собственного необязательного проекта Supabase.
Related MCP server: MCP Server Toolkit
✨ Возможности
Инструмент | Описание |
🌐 | Загружает веб-страницу, удаляет |
📄 | Читает последние N строк локального файла — показывает недавние стектрейсы или вывод ошибок. |
🔍 | Ищет в живом вебе через DuckDuckGo ( |
🗄️ | Выполняет только для чтения |
🏗️ Архитектура
┌──────────────────────┐
│ MCP Client │ (Claude Desktop / Claude Code / Cursor / etc.)
└──────────┬────────────┘
│ MCP protocol (stdio)
┌──────────▼────────────┐
│ DevTools MCP Server │ FastMCP("DevTools") — server.py
│ │
│ ┌──────────────────┐ │
│ │ fetch_markdown │ │──▶ requests + BeautifulSoup ──▶ any URL
│ ├──────────────────┤ │
│ │ read_log │ │──▶ local filesystem
│ ├──────────────────┤ │
│ │ search_web │ │──▶ DDGS (DuckDuckGo, key-free)
│ ├──────────────────┤ │
│ │ query_database │ │──▶ _is_safe_select() (SQL safety gate)
│ │ │ │ │
│ │ │ │ ├──▶ _query_sqlite() ──▶ local .db file
│ │ │ │ └──▶ _query_postgres() ──▶ Postgres / Supabase
│ └──────────────────┘ │
└────────────────────────┘Как query_database решает, куда отправить запрос
query_database(db_path_or_url, sql_query, limit)
│
▼
_is_safe_select(sql_query)?
│
┌────┴────┐
NO YES
│ │
reject does db_path_or_url start with
query "postgres://" or "postgresql://" ?
│
┌─────┴─────┐
YES NO
│ │
_query_postgres() _query_sqlite()_is_safe_select — это жёсткий шлюз, который разрешает только одиночные простые операторы SELECT — никаких INSERT/UPDATE/DELETE/DROP/ALTER/и т.д., а также никаких составных запросов, склеенных через ;. Это важно, потому что SQL-текст генерируется LLM, а не вводится вручную — шлюз нужен, чтобы галлюцинированный или подделанный запрос не мог изменить или уничтожить ваши данные.
Стек:
fastmcp— MCP-серверный фреймворк; превращает Python-функции в MCP-инструменты через@mcp.toolrequests+beautifulsoup4— веб-скрапингddgs— веб-поиск без ключа (ранееduckduckgo-search)sqlite3— встроен в Python, используется для локальных запросов к БДpsycopg2— клиент Postgres/Supabase, импортируется лениво, только когда используется Postgres URLpython-dotenv— загружает локальные переменные.envpytest+pytest-mock— набор тестов
📂 Структура проекта
.
├── venv/ # Local virtual environment (not committed)
├── .env # Local secrets — real keys/paths, never committed
├── .gitignore
├── README.md
├── requirements.txt # Runtime + dev/test dependencies
├── server.py # Main MCP server — all 4 tools live here
├── test_server.py # Pytest suite covering all 4 tools
├── Dockerfile # Optional — only needed for Glama's hosted deployment
├── glama.json # Optional — repo attribution for Glama's listing
└── smithery.yaml # Optional — only relevant if also listing on Smithery🚀 Начало работы
1. Клонируйте репозиторий
git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git
cd YOUR_REPO2. Создайте виртуальное окружение и установите зависимости
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt3. Настройте переменные окружения (необязательно)
server.py вызывает load_dotenv() при запуске, поэтому все переменные из локального файла .env подхватываются автоматически. Ни один из текущих инструментов не требует переменных окружения — query_database принимает информацию о подключении как прямой параметр, — но вы всё равно можете создать .env для локального удобства:
# Only needed if you want a default connection string handy locally.
# Real credentials should live here and nowhere else.
SUPABASE_DB_URL=postgresql://postgres:your-password@db.xxxxxxxx.supabase.co:5432/postgres⚠️ Никогда не коммитьте файл
.env. Он уже исключён через.gitignore.Примечание: это не то же самое, что
SUPABASE_URL/SUPABASE_KEYпроекта Supabase (используется REST/JS-клиентом).query_databaseобщается с Postgres напрямую черезpsycopg2, поэтому ему нужна строка подключения Postgres из панели Supabase в разделе Настройки → База данных → Строка подключения, а не пара API URL/ключ.
4. Запустите сервер локально
python server.pyЭто запускает MCP-сервер через stdio, готовый к подключению к любому MCP-клиенту.
🔌 Подключение к Claude Desktop / Claude Code
Добавьте сервер в конфигурацию MCP-клиента (например, claude_desktop_config.json):
{
"mcpServers": {
"devtools": {
"command": "python",
"args": ["/absolute/path/to/server.py"]
}
}
}Перезапустите клиент — четыре инструмента (fetch_markdown, read_log, search_web, query_database) появятся как функции, которые ассистент может вызывать.
🧰 Справочник инструментов
fetch_markdown(url: str) -> str
Загружает веб-страницу, удаляет теги <script>, <style>, <nav> и <footer> и возвращает очищенный обычный текст (не более 8 000 символов).
fetch_markdown("https://docs.python.org/3/library/asyncio.html")read_log(file_path: str, lines: int = 50) -> str
Читает последние lines строк локального текстового/журнального файла.
read_log("/var/log/app/error.log", lines=100)search_web(query: str, max_results: int = 3) -> str
Выполняет поиск в DuckDuckGo по заданному запросу и возвращает заголовок, ссылку и фрагмент для каждого результата.
search_web("fastapi background tasks example")query_database(db_path_or_url: str, sql_query: str, limit: int = 50) -> str
Выполняет SELECT только для чтения для:
локального файла SQLite (укажите путь к файлу), или
базы данных Postgres/Supabase (передайте строку подключения, начинающуюся с
postgres://илиpostgresql://)
Результаты возвращаются в виде списка словарей {column: value}, ограниченного limit строками.
query_database("app.db", "SELECT * FROM users WHERE status = 'active'", limit=5)
query_database("postgresql://user:pass@host:5432/db", "SELECT id, email FROM users", limit=10)Гарантии безопасности:
Разрешены только запросы, начинающиеся с
SELECTЗапросы, содержащие
INSERT,UPDATE,DELETE,DROP,ALTER,TRUNCATE,GRANT,REVOKE,CREATEилиATTACHв любом месте, отклоняютсяСоставные запросы (
SELECT ...; DROP TABLE ...) отклоняютсяИзвестное ограничение: проверка основана на поиске подстроки, а не на полноценном SQL-парсере — безобидный запрос вроде
SELECT * FROM updates_logтакже будет отклонён, поскольку содержит подстрокуupdate. Это намеренный компромисс в пользу ложных срабатываний, а не пропуска опасных запросов.
🧪 Тестирование
В проект входит набор из 27 тестов pytest, покрывающий все четыре инструмента. Набор полностью запускается офлайн благодаря замоканным сетевым вызовам и одноразовым фикстурам tmp_path — ничего не касается реальных файлов, баз данных или веб-сайтов.
pip install -r requirements.txt
pytest test_server.py -vЧто покрыто:
_is_safe_select— более 10 сценариев: корректные SELECT, каждое запрещённое ключевое слово, составные запросы и известное поведение с ложными срабатываниямиquery_database(SQLite) — простой SELECT,limit, фильтрация поWHERE, блокировка небезопасных запросов, отсутствующий файл, отсутствующая таблица, пустой результат и маршрутизация Postgres URL (замокано)read_log— чтение хвоста, отсутствующий файл, количество строк по умолчаниюfetch_markdown— удаление HTML и обработка ошибок (сеть замокана)search_web— форматирование результатов, пустые результаты, обработка ошибок (сеть замокана)
Сам
_query_postgresне проверяется в этом наборе против живой базы данных — только логика маршрутизации, которая решает, нужно ли его вызывать. Живое тестирование требует реальной строки подключения Postgres/Supabase, которую никогда нельзя жёстко прописывать в тестовых файлах или коммитить в репозиторий.
🌐 Развёртывание
Вариант A — Glama (бесплатная публикация в каталоге + браузерный инспектор)
Отправьте GitHub URL этого репозитория на glama.ai/mcp — Glama индексирует ваши инструменты прямо из исходного кода, без сборки или манифеста. Посетители получают браузерный инспектор, чтобы попробовать fetch_markdown, read_log, search_web и query_database, без установки чего-либо локально.
Необязательно: добавьте glama.json (уже включён), чтобы подтвердить/привязать публикацию к вашему GitHub-аккаунту.
Вариант B — размещение на Glama (Glama запускает сервер за вас, 24/7)
Подключите Glama GitHub App к этому репозиторию, и он соберёт включённый Dockerfile в работающий экземпляр за шлюзом Glama (управляемый TLS, аутентификация, логирование). Перед выбором этого пути ознакомьтесь с актуальными тарифами на glama.ai/mcp/hosting.
Вариант C — Smithery
⚠️ По состоянию на начало 2026 года Smithery больше не принимает новые бесплатные размещённые развёртывания через GitHub — теперь для этого требуется платный тариф. Бесплатный путь на Smithery — регистрация этого сервера как внешнего сервера (то есть вы размещаете его самостоятельно — например, через вариант размещения Glama выше — и просто указываете этот URL в публикации Smithery). smithery.yaml по-прежнему включён в этот репозиторий на случай, если вы выберете этот путь; актуальные подробности смотрите на smithery.ai, так как их модель размещения активно меняется.
🔐 Переменные окружения
Переменная | Обязательность | Используется |
| ❌ Необязательно | Не читается автоматически — |
query_database намеренно не хранит состояние в отношении учётных данных — внутри самого инструмента ничего не читается из переменных окружения, поэтому по умолчанию учётные данные базы данных никогда не сохраняются на стороне сервера.
🗺️ Дорожная карта
Добавить настоящий интеграционный тест с одноразовым экземпляром Postgres/Supabase (только в CI, учётные данные никогда не коммитятся)
Заменить проверку ключевых слов SQL по подстрокам на полноценный SQL-парсер (например,
sqlparse), чтобы устранить ложные срабатыванияДобавить кэширование для
search_webиfetch_markdownДобавить слой аутентификации для размещённых развёртываний Smithery
🤝 Вклад в проект
Приветствуются вклады, вопросы и запросы новых функций — не стесняйтесь открывать PR или issue.
📄 Лицензия
Этот проект распространяется под лицензией MIT.
This server cannot be deployed
Maintenance
Related MCP Connectors
LLM-ready web search + instant answers + URL-to-clean-text fetch for agents and RAG.
Web data for agents: YouTube transcripts, screenshots, Google News, WHOIS, jobs, tech stack, more.
Give your agent live data from Twitter, Reddit, the web and GitHub. No API keys, no scraping stack.
Web search and page-reading for AI agents. One-click OAuth connect, or a Caesar API key.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI models to search the web using DuckDuckGo, scrape webpage content in markdown format, and browse/read local files for code analysis and debugging.8 npm1MIT
- AlicenseAqualityCmaintenanceProvides filesystem, web search, SQLite, and system tools for AI assistants like Claude, enabling secure access to local resources and the web.6MIT
- AlicenseAqualityCmaintenanceEnables web search, scraping, and live package version lookup for local LLMs, with no API keys required.52MIT
- FlicenseAqualityCmaintenanceEnables a locally-run LLM to search the web, fetch pages as markdown, make arbitrary HTTP requests, and optionally render pages with headless Chromium.3-