mcp-server-template
README.md
# mcp-server-template
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> -e TOKEN=... -- python -m mcp_<name>` + `.mcp.json` block
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
ActivityMaintained
ResponsivenessSyncing