Writing an MCP server
From an empty file to a server a host can plug in, in about a hundred lines
The first MCP server you write rarely works on the first try, and almost never for the reason you'd expect. The protocol isn't the problem: the libraries handle it. The problem is a debugging print that lands on standard output and corrupts the JSON-RPC stream; a tool that raises an exception instead of returning a readable error; a server that starts perfectly by hand but that the host can't launch because it can't find the interpreter from the right virtual environment.
This lesson builds a complete server — two tools and one resource on a billing domain — and then tests it without an agent, without a model, and without a host. The order matters: until you've seen your JSON-RPC responses with your own eyes, plugging an agent into the server means debugging two nondeterministic systems at once. An MCP server is an ordinary program, it is tested like an ordinary program, and that's precisely what makes the protocol pleasant to work with.
Setup
python -m venv .venv
.venv/bin/pip install "mcp[cli]>=1.9"
The official package provides two API levels. FastMCP generates JSON schemas from your type annotations and docstrings; the low-level server lets you write the tools/list and tools/call handlers by hand. Use the former unless you explicitly need full control over the schemas.
Comments
Comments are powered by GitHub Discussions
Sign in with GitHub to join the discussion