DevTools MCP Server

DevTools MCP Server

Enables LLM clients to fetch web pages as clean text, tail local logs, search the live web via DuckDuckGo, and run read-only SQL queries against SQLite or Postgres/Supabase.

Category
访问服务器

README

🛠️ DevTools MCP Server

A lightweight Model Context Protocol (MCP) server that gives any MCP-compatible LLM client (Claude Desktop, Claude Code, Cursor, etc.) a developer toolbox: web scraping, log inspection, live web search, and read-only SQL querying against SQLite or Postgres/Supabase — all through one server.

MCP Python Tests License

🔗 Live Playground: Glama MCP Link — try the tools directly in the browser once listed (see Deployment).


📖 Overview

DevTools MCP exposes four tools over MCP so an LLM assistant can:

  • Pull clean, readable text from any webpage
  • Tail your local log files to debug errors
  • Search the live web for current documentation before writing code
  • Run read-only SELECT queries against a local SQLite file or a live Postgres/Supabase database

Every tool is a plain, testable Python function — nothing here depends on paid APIs except your own optional Supabase project.


✨ Features

Tool Description
🌐 fetch_markdown(url) Fetches a webpage, strips script/style/nav/footer, and returns clean text (capped at 8,000 characters).
📄 read_log(file_path, lines) Reads the last N lines of a local file — surfaces recent stack traces or error output.
🔍 search_web(query, max_results) Searches the live web via DuckDuckGo (ddgs, no API key required) for up-to-date docs or solutions.
🗄️ query_database(db_path_or_url, sql_query, limit) Runs a read-only SELECT against a local SQLite file or a Postgres/Supabase connection string, capped at limit rows.

🏗️ Architecture

┌──────────────────────┐
│    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
│  └──────────────────┘  │
└────────────────────────┘

How query_database decides where to send a query

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 is a hard gate that only allows single, plain SELECT statements — no INSERT/UPDATE/DELETE/DROP/ALTER/etc., and no stacked queries chained with ;. This matters because the SQL text is generated by an LLM, not typed by hand — the gate is there so a hallucinated or manipulated query can't mutate or destroy your data.

Stack:

  • fastmcp — MCP server framework; turns Python functions into MCP tools via @mcp.tool
  • requests + beautifulsoup4 — web scraping
  • ddgs — key-free live web search (formerly duckduckgo-search)
  • sqlite3 — built into Python, used for local database queries
  • psycopg2 — Postgres/Supabase client, imported lazily only when a Postgres URL is used
  • python-dotenv — loads local .env variables
  • pytest + pytest-mock — test suite

📂 Project Structure

.
├── 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

🚀 Getting Started

1. Clone the repo

git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git
cd YOUR_REPO

2. Create a virtual environment & install dependencies

python -m venv venv
source venv/bin/activate   # On Windows: venv\Scripts\activate

pip install -r requirements.txt

3. Configure environment variables (optional)

server.py calls load_dotenv() on startup, so any variables in a local .env file are picked up automatically. None of the current tools require env vars — query_database takes its connection info as a direct parameter — but you may still want a .env for local convenience:

# 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

⚠️ Never commit your .env file. It's already excluded via .gitignore.

Note: this is different from a Supabase project's SUPABASE_URL / SUPABASE_KEY (used by the REST/JS client). query_database talks to Postgres directly via psycopg2, so it needs the Postgres connection string from your Supabase dashboard under Settings → Database → Connection string, not the API URL/key pair.

4. Run the server locally

python server.py

This starts the MCP server over stdio, ready to be connected to any MCP client.


🔌 Connecting to Claude Desktop / Claude Code

Add the server to your MCP client config (e.g. claude_desktop_config.json):

{
  "mcpServers": {
    "devtools": {
      "command": "python",
      "args": ["/absolute/path/to/server.py"]
    }
  }
}

Restart your client — the four tools (fetch_markdown, read_log, search_web, query_database) will appear as functions the assistant can call.


🧰 Tool Reference

fetch_markdown(url: str) -> str

Fetches a webpage, strips <script>, <style>, <nav>, and <footer> tags, and returns cleaned plain text (capped at 8,000 characters).

fetch_markdown("https://docs.python.org/3/library/asyncio.html")

read_log(file_path: str, lines: int = 50) -> str

Reads the last lines lines of a local text/log file.

read_log("/var/log/app/error.log", lines=100)

search_web(query: str, max_results: int = 3) -> str

Searches DuckDuckGo for the given query and returns title, link, and snippet for each result.

search_web("fastapi background tasks example")

query_database(db_path_or_url: str, sql_query: str, limit: int = 50) -> str

Runs a read-only SELECT against:

  • a local SQLite file (pass a file path), or
  • a Postgres/Supabase database (pass a connection string starting with postgres:// or postgresql://)

Results are returned as a list of {column: value} dictionaries, capped at limit rows.

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)

Safety guarantees:

  • Only queries starting with SELECT are allowed
  • Queries containing INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE, GRANT, REVOKE, CREATE, or ATTACH anywhere are rejected
  • Stacked queries (SELECT ...; DROP TABLE ...) are rejected
  • Known limitation: the check is a substring match, not a full SQL parser — a harmless query like SELECT * FROM updates_log will also be rejected, since it contains the substring update. This is a deliberate false-positive-over-false-negative tradeoff.

🧪 Testing

The project ships with a 27-test pytest suite covering all four tools, run fully offline via mocked network calls and throwaway tmp_path fixtures — nothing touches a real file, database, or website.

pip install -r requirements.txt
pytest test_server.py -v

What's covered:

  • _is_safe_select — 10+ cases across valid selects, every forbidden keyword, stacked queries, and known false-positive behavior
  • query_database (SQLite) — basic select, limit, WHERE filtering, blocked unsafe queries, missing file, missing table, empty result set, and Postgres URL routing (mocked)
  • read_log — tail behavior, missing file, default line count
  • fetch_markdown — HTML stripping and error handling (network mocked)
  • search_web — result formatting, empty results, error handling (network mocked)

_query_postgres itself is not exercised against a live database in this suite — only the routing logic that decides whether to call it. Testing it live requires a real Postgres/Supabase connection string, which should never be hardcoded into test files or committed to the repo.


🌐 Deployment

Option A — Glama (free directory listing + browser inspector)

Submit this repo's GitHub URL at glama.ai/mcp — Glama indexes your tools directly from the source, no build or manifest required. Visitors get an in-browser inspector to try fetch_markdown, read_log, search_web, and query_database without installing anything locally.

Optional: add glama.json (already included) to claim/attribute the listing to your GitHub account.

Option B — Glama hosted deployment (Glama runs it for you, 24/7)

Connect the Glama GitHub App to this repo and it builds the included Dockerfile into a running instance behind Glama's gateway (managed TLS, auth, logging). Check glama.ai/mcp/hosting for current plan details before committing to this path.

Option C — Smithery

⚠️ As of early 2026, Smithery no longer accepts new free hosted deployments via GitHub — that now requires a paid plan. The free path on Smithery is registering this server as an external server (i.e. you host it yourself — e.g. via Glama's hosted option above — and just point Smithery's listing at that URL). smithery.yaml is still included in this repo in case you go that route; see smithery.ai for current details, since their hosting model is actively changing.


🔐 Environment Variables

Variable Required Used by
SUPABASE_DB_URL (or any Postgres URL) ❌ Optional Not read automatically — query_database takes the connection string as a direct argument. Useful only as a personal reference/convenience in .env.

query_database is intentionally stateless with respect to credentials — nothing is read from environment variables inside the tool itself, so no database credentials are ever stored server-side by default.


🗺️ Roadmap

  • [ ] Add a real integration test against a disposable Postgres/Supabase instance (CI-only, credentials never committed)
  • [ ] Replace the substring-based SQL keyword check with a proper SQL parser (e.g. sqlparse) to eliminate false positives
  • [ ] Add caching for search_web and fetch_markdown
  • [ ] Add an authentication layer for hosted Smithery deployments

🤝 Contributing

Contributions, issues, and feature requests are welcome — feel free to open a PR or issue.


📄 License

This project is licensed under the MIT License.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选