Skip to main content
Glama

🛠️ DevTools MCP 서버

모든 MCP 호환 LLM 클라이언트(Claude Desktop, Claude Code, Cursor 등)에 개발자 도구 모음을 제공하는 경량 Model Context Protocol (MCP) 서버입니다. 웹 스크래핑, 로그 검사, 실시간 웹 검색, SQLite 또는 Postgres/Supabase에 대한 읽기 전용 SQL 쿼리까지 — 모두 하나의 서버로 처리합니다.

MCP Python Tests License

🔗 라이브 플레이그라운드: Glama MCP 링크 — 등록되면 브라우저에서 도구를 직접 사용해 볼 수 있습니다 (배포 참조).


📖 개요

DevTools MCP는 MCP를 통해 네 가지 도구를 노출하여 LLM 어시스턴트가 다음을 수행할 수 있게 합니다:

  • 모든 웹페이지에서 깔끔하고 읽기 쉬운 텍스트 가져오기

  • 로컬 로그 파일을 tail하여 오류 디버깅

  • 코드를 작성하기 전에 최신 문서를 위해 라이브 웹 검색

  • 로컬 SQLite 파일 또는 라이브 Postgres/Supabase 데이터베이스에 대해 읽기 전용 SELECT 쿼리 실행

모든 도구는 일반적이고 테스트 가능한 Python 함수입니다 — 유료 API에 의존하는 것은 없으며, 선택적인 Supabase 프로젝트만 제외하면 됩니다.


Related MCP server: MCP Server Toolkit

✨ 기능

도구

설명

🌐 fetch_markdown(url)

웹페이지를 가져와 script/style/nav/footer를 제거하고 깨끗한 텍스트를 반환합니다 (8,000자로 제한).

📄 read_log(file_path, lines)

로컬 파일의 마지막 N줄을 읽습니다 — 최근 스택 트레이스나 오류 출력을 표시합니다.

🔍 search_web(query, max_results)

DuckDuckGo(ddgs, API 키 불필요)를 통해 라이브 웹에서 최신 문서나 솔루션을 검색합니다.

🗄️ query_database(db_path_or_url, sql_query, limit)

로컬 SQLite 파일 또는 Postgres/Supabase 연결 문자열에 대해 읽기 전용 SELECT를 실행하며, limit 행으로 제한됩니다.


🏗️ 아키텍처

┌──────────────────────┐
│    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 서버 프레임워크; @mcp.tool을 통해 Python 함수를 MCP 도구로 변환

  • requests + beautifulsoup4 — 웹 스크래핑

  • ddgs — 키 없는 라이브 웹 검색 (이전 명칭 duckduckgo-search)

  • sqlite3 — Python 내장, 로컬 데이터베이스 쿼리에 사용

  • psycopg2 — Postgres/Supabase 클라이언트, Postgres URL이 사용될 때만 지연 가져오기

  • python-dotenv — 로컬 .env 변수 로드

  • pytest + 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_REPO

2. 가상 환경 생성 및 의존성 설치

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

pip install -r requirements.txt

3. 환경 변수 구성 (선택 사항)

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 프로젝트의 SUPABASE_URL / SUPABASE_KEY(REST/JS 클라이언트에서 사용)와 다릅니다. query_database는 psycopg2를 통해 Postgres에 직접 연결하므로 Supabase 대시보드의 Settings → Database → Connection string에 있는 Postgres 연결 문자열이 필요합니다. API URL/키 쌍이 아닙니다.

4. 서버를 로컬에서 실행

python server.py

이렇게 하면 stdio를 통해 MCP 서버가 시작되어 모든 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 — 유효한 SELECT, 모든 금지 키워드, 스택 쿼리, 알려진 오탐 동작에 걸친 10개 이상의 케이스

  • query_database (SQLite) — 기본 select, limit, WHERE 필터링, 차단된 안전하지 않은 쿼리, 파일 없음, 테이블 없음, 빈 결과 집합, Postgres URL 라우팅 (모의)

  • read_log — tail 동작, 파일 없음, 기본 줄 수

  • 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 호스팅 옵션 — 하고 Smithery 등록을 해당 URL에 연결). smithery.yaml은 그 경로를 택할 경우를 대비해 이 저장소에 여전히 포함되어 있습니다. 호스팅 모델이 활발히 변경 중이므로 현재 세부 사항은 smithery.ai를 참조하세요.


🔐 환경 변수

변수

필수 여부

사용처

SUPABASE_DB_URL (또는 모든 Postgres URL)

❌ 선택 사항

자동으로 읽히지 않음 — query_database는 연결 문자열을 직접 인자로 받습니다. .env에서 개인 참조/편의용으로만 유용합니다.

query_database는 의도적으로 자격 증명에 대해 상태 비저장입니다 — 도구 내부에서 환경 변수에서 아무것도 읽지 않으므로 기본적으로 데이터베이스 자격 증명이 서버 측에 저장되지 않습니다.


🗺️ 로드맵

  • 일회용 Postgres/Supabase 인스턴스에 대한 실제 통합 테스트 추가 (CI 전용, 자격 증명은 절대 커밋하지 않음)

  • 부분 문자열 기반 SQL 키워드 검사를 적절한 SQL 파서(예: sqlparse)로 교체하여 오탐 제거

  • search_web 및 fetch_markdown에 캐싱 추가

  • 호스팅된 Smithery 배포를 위한 인증 계층 추가


🤝 기여

기여, 이슈, 기능 요청을 환영합니다 — PR이나 이슈를 자유롭게 열어 주세요.


📄 라이선스

이 프로젝트는 MIT 라이선스에 따라 라이선스가 부여됩니다.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers