Skip to main content
Glama
projectsofadi

mcp-server-template

README.md
# mcp-server-template

[![CI](https://github.com/projectsofadi/mcp-server-template/actions/workflows/ci.yml/badge.svg)](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).

TDQS

A3.5/5.0

Scored across 2 tools

Disambiguation5/5

The two tools target completely different domains (PyPI project lookup vs. text word statistics) with no overlap in function or purpose. An agent can easily select the correct tool without confusion.

Naming Consistency5/5

Both tool names use consistent snake_case noun phrases (pypi_project, word_stats), adhering to a predictable naming pattern. Although not verb_noun, the convention is applied uniformly across the set.

Tool Count3/5

Two tools is very thin for a functional MCP server and falls into the borderline '1-2 tools feels thin' category. However, as a template server, the small count may be intentional to demonstrate different tool types.

Completeness2/5

There is no coherent domain or lifecycle; the tools are isolated utilities with no way to list, search, update, or otherwise extend the surface. This leaves significant gaps for any real workflow an agent might attempt.

Maintenance

ActivityStale
ResponsivenessNo issues