Files
modelcontextprotocol--pytho…/examples/stories/tools/README.md
T
wehub-resource-sync 49b9bb6724
Deploy Docs / deploy-docs (push) Failing after 1s
Conformance Tests / client-conformance (push) Failing after 3s
Conformance Tests / server-conformance (push) Failing after 1s
GitHub Actions Security Analysis / zizmor (push) Failing after 1s
CI / checks (push) Failing after 59m20s
CI / all-green (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 12:10:27 +08:00

1.5 KiB

tools

Start here. Register tools with @mcp.tool(); the SDK infers the JSON input schema from type hints, the output schema from the return annotation, and returns structuredContent alongside text. ToolAnnotations carries behavioural hints (readOnlyHint, idempotentHint) the host can show to users. The client lists tools, inspects schemas + annotations, calls both, and asserts structured output.

Run it

# stdio (default — the client spawns the server as a subprocess)
uv run python -m stories.tools.client

# HTTP — the client self-hosts the server on a free port, runs, then tears it down
uv run python -m stories.tools.client --http
# same, against the lowlevel-API server variant
uv run python -m stories.tools.client --http --server server_lowlevel

What to look at

  • server.py calcLiteral[...] and BaseModel in the signature become the tool's inputSchema / outputSchema with zero hand-written JSON.
  • server.py echostructured_output=False opts out of schema inference for a plain text-only tool.
  • server_lowlevel.py — the same wire contract built by hand: this is what MCPServer generates for you.

Spec

Tools — server features

See also

schema_validators/ (every input-schema source: pydantic / TypedDict / dataclass / dict), error_handling/ (is_error vs protocol error), streaming/ (progress mid-call).