Skip to main content
Glama
README.md
# local-dev-tools

[![tests](https://github.com/a0939151628-cmd/mcp-dev-tools/actions/workflows/tests.yml/badge.svg)](https://github.com/a0939151628-cmd/mcp-dev-tools/actions/workflows/tests.yml)
[![python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)](https://www.python.org/)
[![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)

A small, production-quality **MCP (Model Context Protocol)** server built on
[FastMCP](https://gofastmcp.com). It gives any MCP client — Claude Code, Claude
Desktop, or your own — three read-only introspection tools for everyday local
development.

```text
sqlite_query(db_path="./app.db", query="SELECT id, email FROM users LIMIT 10")
check_port(port=5432)                       # is local Postgres up?
git_diff_summary(repo_path=".")             # what have I touched?
```

## Tools

| Tool | Signature | Returns |
| --- | --- | --- |
| `sqlite_query` | `(db_path: str, query: str) -> str` | Aligned text table, capped at 50 rows with a truncation note |
| `check_port` | `(port: int, host: str = "127.0.0.1") -> dict` | `{host, port, open, message}` |
| `git_diff_summary` | `(repo_path: str = ".") -> dict` | `{repo_path, modified, added, deleted, renamed, untracked, total_changes}` or `{error}` |

## Design

* **Every tool is total.** Tools validate inputs and catch all internal
  exceptions, returning a structured error value (`"Error: ..."` or
  `{"error": ...}`) instead of raising. A bad argument produces a readable
  message rather than killing the server process the client depends on.
* **Read-only by construction.** `sqlite_query` uses three independent layers:
  path and file-header validation (the file must begin with the SQLite magic
  bytes), query screening (statement allowlist + keyword blocklist
  applied after comments and quoted literals are blanked out), and a
  `file:...?mode=ro` connection — so SQLite itself refuses writes even if the
  screening were bypassed.
* **Bounded output and time.** Results cap at 50 rows and 200-character cells;
  port probes time out after 1s, `git` subprocesses after 15s. No tool can
  flood the context or hang the server.
* **Discoverable.** Numpydoc docstrings put purpose, return shape, and failure
  conditions into the tool description and per-parameter JSON Schema that the
  model sees at discovery time.

## Quick Start

```bash
python3 -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate.bat
pip install -r requirements.txt    # or requirements-dev.txt to include pycodestyle

python server.py                   # start the server (stdio transport)
python test_server.py              # run the test suite
```

Dependencies are pinned in [`requirements.txt`](requirements.txt)
(`fastmcp==3.4.5`).

## Register with Claude Code

```bash
claude mcp add local-dev-tools -- "$(pwd)/.venv/bin/python" "$(pwd)/server.py"
```

For Claude Desktop configuration, usage examples, and extension guidance, see
[`CLAUDE.md`](CLAUDE.md).

## Testing

28 `unittest` tests covering each tool's happy path, input validation, and
failure modes — plus end-to-end checks that the tools are discoverable and
callable over the real MCP protocol via an in-memory FastMCP client. All
fixtures (SQLite databases, temporary Git repositories, listening sockets) are
created in temp directories and cleaned up; nothing is written outside
`tempfile.gettempdir()`.

```bash
.venv/bin/python test_server.py
# Ran 28 tests — OK
```

Continuous integration runs the suite, a `pycodestyle` check, and a stdio
startup smoke test against Python 3.10, 3.11, 3.12, and 3.13 on every push and
pull request — see [`.github/workflows/tests.yml`](.github/workflows/tests.yml).

See [`NIGHTLY_BUILD_REPORT.md`](NIGHTLY_BUILD_REPORT.md) for the full test
matrix, environment details, and known limitations.

## Requirements

Python 3.10+ (developed on 3.14; CI verifies 3.10–3.13), `fastmcp` 3.x, and
`git` on PATH for `git_diff_summary`.

## License

MIT © Emma Huang — see [`LICENSE`](LICENSE).