mcp-python-conventionslisted
Install: claude install-skill TheodoreAD/agent-skills
# MCP server code conventions
The Python inside a stdio-transport MCP server. Split out of `python-conventions` on 2026-08-31,
which keeps the general design defaults — this skill owns only what is different _because_ the code
is an MCP server, and those differences are not stylistic: two of the three are protocol
correctness.
Not about shipping. Entry points, `uv tool install`, `claude mcp add` and scope selection belong to
`mcp-server-shipping`; this is what the code does once it runs.
## MCP-stdio logging discipline
_Scope: stdio-transport MCP servers only (the `*-polite-mcp` family) — not applicable to a repo that
has no MCP server of its own._
- Snippet: [`references/snippets/mcp-tool-boundary.py`](references/snippets/mcp-tool-boundary.py)
- Default: never a bare `print()` in server package code. Route all logging through the stdlib
`logging` module, explicitly configured to write to stderr at startup (or defer to FastMCP's own
`configure_logging()`, which already defaults there).
- Why: the MCP stdio spec is unambiguous — a server **MUST NOT** write anything to stdout that isn't
a valid MCP message; a single stray `print()` or a dependency's stdout-bound log handler corrupts
the JSON-RPC stream. stderr is the sanctioned outlet for everything, logs included.
- **Don't**: trust that "no `print()` in my code" is sufficient — a dependency that logs to stdout
on its own initiative isn't caught by explicit stderr configuration of your own logging. The
robust