my-mcp-template
A generic FastMCP server template for building CLI coding agent tools, with example tools, authentication, and a comprehensive test suite.
README
my-mcp-template
A generic template for building FastMCP servers
for CLI coding agents (Claude Code and similar) -- not chat UIs. It ships
with two working example tools (pure logic, and an external-call tool with
tenacity retries), a unified error format, a Prometheus /metrics
endpoint, optional Langfuse tool-call tracing, Docker Compose deployment,
and a two-axis test suite. Not RAG-specific: just as suited to DB-query or
file-operation tools. Ships with no auth layer -- see
docs/DEPLOYMENT.md if your deployment needs one.
Using this as a template
This repo is a plain [GitHub template repository]("Use this template" button), not a cookiecutter project -- there's no templating variables to fill in. To start a new project from it:
- Click "Use this template" on GitHub (or
git clone+ re-init). - Rename the package path if you want something other than
src.main.python-- it's a literal directory structure (src/main/python/), so a plain find-replace across the repo handles it. - Replace
example_tool.pywith your own tools (seedocs/TOOL_GUIDELINES.md).
Local development
uv sync
cp .env.example .env
uv run python -m src.main.python.main
The server listens on http://0.0.0.0:8000/mcp (streamable HTTP,
stateless). Point MCP Inspector
or any streamable-HTTP-capable client at that URL to try it out.
Running with Docker Compose
cp .env.example .env
docker compose up --build
Health check: curl http://localhost:8000/health.
Tests
Two independent groups, plus a fast/slow cost axis that cuts across both.
See docs/TESTING.md for how these map onto a general 4-layer scope/determinism
ladder (contract -> real-dependency component -> LLM-judged pipeline -> full
agent E2E), and where the current suite's gaps are relative to it.
tests/server/-- does the MCP server itself work correctly? Schema/description contract, golden-case functional correctness, and a real container integration smoke test.tests/agent/-- can an agent actually use it? Feeds your tool descriptions to your configuredLLM_JUDGE_*model and checks it picks the right tool (scored with deepeval'sToolCorrectnessMetric,evaldependency group).test_tool_selection.py/test_tool_selection_quality.pyare deterministic/LLM-judged variants of the same check (layer 1/2);test_agent_e2e_multiturn.pyis a real multi-turn Claude Agent SDK session (agent-sdkgroup, needs the Claude Code CLI installed -- layer 3). This is the group that actually tests description quality.
uv sync --group eval # tests/agent/'s deterministic + LLM-judged checks
uv sync --group agent-sdk # tests/agent/test_agent_e2e_multiturn.py only (needs Claude Code CLI too)
uv run pytest -m "not slow" # fast: no LLM calls, no docker. Run on every PR.
uv run pytest -m slow # slow: calls your LLM_JUDGE_* provider + docker compose. Run on merge to main.
uv run pytest # everything
Security scanning (CI, part of the fast job)
ruff check .includes theS(flake8-bandit) ruleset -- basic Python SAST, e.g. hardcoded credentials, insecure defaults.pip-audit-- known CVEs in resolved Python dependencies.- Trivy -- scans the built container image (OS packages + Python deps baked into it) and uploads results to the repo's Security tab. Report-only (doesn't fail the build): base-image OS CVEs with no fix published yet are common and not actionable, and failing on those would make this template permanently red for no fixable reason.
LLM_JUDGE_BASE_URL/LLM_JUDGE_API_KEY/LLM_JUDGE_MODEL are required for
both llm_judge golden cases and tests/agent/ (tool-selection check) --
bring your own OpenAI-compatible provider (OpenAI, NVIDIA NIM, DeepSeek,
Together, a local vLLM/Ollama, ...); the model must support tool/function
calling for tests/agent/ to work. Without them, both skip with a clear
reason rather than fail.
Golden cases
Add your own in tests/golden/*.yaml. Six assert_types:
exact_match, contains, regex_match, numeric_tolerance, llm_judge,
custom -- see tests/golden/schema.py for the shape and
tests/golden/example.yaml for one of each.
deepeval (eval dependency group)
deepeval is used a few ways:
tests/agent/test_tool_selection.py--ToolCorrectnessMetric, noavailable_tools=: deterministic set comparison, no real LLM judge call. Handed aLocalModelbuilt fromLLM_JUDGE_*directly, so it never touchesOPENAI_API_KEY.tests/agent/test_tool_selection_quality.py-- same metric, withavailable_tools=: a real LLM-judged "was this the best tool among alternatives" score, not just presence/absence. Seedocs/TESTING.md.- RAG faithfulness (optional, bring your own) -- for RAG-style tools where you want to check answers stay grounded in retrieved context, add deepeval assertions in your own test module. Not wired into a specific test file here since it only applies if your tools actually do retrieval.
uv sync --group eval installs it.
Claude Agent SDK (agent-sdk dependency group)
tests/agent/test_agent_e2e_multiturn.py is the layer-3 test in
docs/TESTING.md's ladder -- a real multi-turn claude-agent-sdk session
driving this repo's actual MCP server over HTTP on a real port, not the
in-memory client the rest of the suite uses. Needs the Claude Code CLI
installed (the SDK shells out to it) on top of uv sync --group agent-sdk.
Categorically Claude-only -- unlike LLM_JUDGE_*, there's no
bring-your-own-provider option here, because the SDK itself only drives
Claude.
Connecting a client
{
"mcpServers": {
"my-mcp-template": {
"url": "http://localhost:8000/mcp"
}
}
}
No auth by default -- see docs/DEPLOYMENT.md if your deployment needs
one; a client would then pass a bearer token via headers.
Project structure
src/main/python/ server code (main.py, config.py, errors.py, tools/)
tests/server/ does the server work correctly?
tests/agent/ can an agent actually use it?
tests/golden/ golden case schema + data
docs/ TOOL_GUIDELINES.md, DEPLOYMENT.md
Checklist: what you still need to fill in
Blocking:
- Real golden case content in
tests/golden/*.yamlfor your own tools.
Conditional (only if you add the matching feature):
- Auth, if your deployment needs it -- see
docs/DEPLOYMENT.md. Not wired in by default. - A
volumes:entry indocker-compose.yml, if you add a real file-operation tool. LLM_JUDGE_BASE_URL/LLM_JUDGE_API_KEY/LLM_JUDGE_MODEL, only if you use thellm_judgeassert_type in a golden case -- no universal default, bring your own OpenAI-compatible provider. Cases skip (not fail) if unset.LANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY/LANGFUSE_BASE_URL, only if you want tool-call tracing. Unset = no middleware added.
Already have a reasonable default -- tune if needed:
LLM_JUDGE_THRESHOLDinconfig.py.ALLOWED_ORIGINS(empty = CORS off; only needed for browser clients).
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.