v3-notes/provider-test-pattern.md
This document captures the design decision to test providers via direct server method calls rather than wrapping in a Client.
Provider tests were using the Client pattern:
async with Client(mcp) as client:
result = await client.call_tool("add", {"x": 1, "y": 2})
assert result.data == 3
This conflated two concerns:
Additionally, ~1,200 lines of tests in test_server_interactions.py duplicated provider tests.
Provider tests now call server methods directly:
result = await mcp.call_tool("add", {"x": 1, "y": 2})
assert result.structured_content == {"result": 3}
This establishes clear test ownership:
Direct server calls return canonical FastMCP types, not MCP protocol types:
| Component | Access Pattern |
|---|---|
| Tool | result.structured_content or result.text |
| Resource | result.contents[0].content |
| Prompt | result.messages[0].content.text |
Direct calls raise FastMCP exceptions:
NotFoundError - component not foundDisabledError - component disabled by visibilityClient calls raise MCP protocol errors (wrapped in McpError).
test_server_interactions.py into provider test filestest_server_interactions.py from 1,455 → 179 linesTestMeta tests remain in interactions file (require Client for context injection)