mcp-server-template
README.md
# mcp-server-template
[](https://github.com/projectsofadi/mcp-server-template/actions/workflows/ci.yml)
Opinionated template for building **read-only MCP servers** that coding agents can actually use well: I/O seams with timeouts, offline tests, compact text outputs, least-privilege docs.
**Start here → [BUILDING.md](https://github.com/projectsofadi/mcp-server-template/blob/HEAD/BUILDING.md)** — the full workflow from idea to published server (~half a day).
What's inside: a working example server (`pypi_project` fixed-origin HTTP tool behind a stubbed seam + `word_stats` pure tool), offline test suite, CI workflow, `CLAUDE.md` conventions, and a README skeleton below.
The network example deliberately does **not** accept arbitrary URLs. "Read-only" does not make a URL fetcher safe: unrestricted destinations and followed redirects can expose loopback, private-network, or cloud-metadata services. `pypi_project` constructs only `https://pypi.org/...` requests, rejects URL/path-shaped input, never follows redirects, caps the decoded response at 2 MiB, and applies a 15-second whole-operation deadline.
## README skeleton for your server (replace this whole file)
1. `# mcp-<name>` + one-line value prop in bold
2. 4-line usage transcript (You: … / Agent: → tool calls / Agent: answer)
3. Tools table (tool → what it returns)
4. Install: `claude mcp add <name> -- python -m mcp_<name>` with any token preloaded into the launching environment from your shell or OS secret manager — never a `-e TOKEN=...` literal (command arguments can enter shell history and process listings) — plus a `.mcp.json` block using an env reference (`"env": { "TOKEN": "${TOKEN}" }`)
5. Token scope / security (least privilege, read-only statement)
6. Design notes (why read-only, why compact text, why timeouts)
7. License + contact line
Use the structure above directly; replace every template name and example before publishing a derived server.
## Security and privacy
- The example sends only the supplied package name to PyPI. Do not put secrets or private identifiers in tool arguments.
- PyPI project summaries are uploader-controlled prose, so the example deliberately omits them from agent-visible output. Treat all external text as untrusted data.
- Never log credentials, authorization headers, raw private responses, or user prompts.
- Document which external service receives each argument. Private CI logs and internal URLs are sensitive even when a tool only reads them.
- Keep arbitrary URL fetching out of derived servers unless you implement a destination allowlist and a transport that cannot be bypassed by redirects or DNS rebinding.
## Development
```bash
python -m pip install -e ".[dev]"
ruff check . && ruff format --check .
pytest
python -m build
```
MIT — see [LICENSE](https://github.com/projectsofadi/mcp-server-template/blob/HEAD/LICENSE).
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues