# CLAUDE.md: MCP server (Python)

## Commands
- `uv sync` · `uv run pytest -q` · `uv run ruff check .`
- Try it: `uv run mcp dev server.py` (MCP Inspector) or `npx @modelcontextprotocol/inspector uv run server.py`

## Building blocks
- Server: `from mcp.server.fastmcp import FastMCP`; `mcp = FastMCP("name")`; run with `mcp.run()` (stdio) or the streamable HTTP transport for remote servers.
- Tools: `@mcp.tool()` on typed functions. The docstring is the tool description the model reads, so say what it does, when to use it, and what it returns. Use Pydantic models or `Annotated[..., Field(description=...)]` for arguments.
- Resources (`@mcp.resource("notes://{id}")`) for read-only data; prompts (`@mcp.prompt()`) for reusable templates.
- Return concise, structured results. Paginate or truncate large outputs and say so in the result.

## Rules
- Never print to stdout in a stdio server; it corrupts the protocol. Log to stderr or via `ctx.info()`.
- Validate inputs and return clear error messages the model can act on, rather than stack traces.
- Tool names are `snake_case` verbs (`search_issues`). Mark destructive tools clearly in the description and require explicit parameters (no "delete all" defaults).
- Secrets come from env vars passed by the client config; never hard-code them or echo them in results.
- Remote HTTP servers need auth (OAuth per the MCP spec) and must check the `Origin` header.

## Tests
Call tool functions directly in pytest, and add one in-memory client/server session test per tool.
