typing.get_type_hints(Client) raises TypeError on CPython 3.10 for any
dataclass using KW_ONLY (a stdlib bug fixed in 3.11), which has nothing to
do with the SDK and turned the test red on the 3.10 CI cells. Probe
Client.__init__ instead: it evaluates the same qualified mcp.server
annotation on every supported version.
tests/test_import_guards.py runs every check in a fresh interpreter and pins
the module footprint each entry point is allowed to have: `import mcp` is a
lazy namespace, client entry points never load the server or web stack (and
httpx2 only for the HTTP transports), transport-agnostic server entry points
never load starlette / sse_starlette / uvicorn / opentelemetry / httpx2, and
the wire-schema packages load only when their protocol version is used.
A positive parametrized case imports every documented module as the first
import of a fresh process, warning-free, so the lazy resolution can never
grow an import-order dependency.
The earlier per-file fresh-interpreter probes are folded into this module,
which is now the single home for import-graph assertions.
Making the server stack a typing-only import in the client module left
the `Client.server` annotation naming `Server` / `MCPServer`, which
`typing.get_type_hints` can then no longer evaluate: string annotations
are evaluated against the module dict, so a module-level `__getattr__`
would not be consulted either.
Spell the annotation through the `mcp.server` namespace instead. Evaluating
the hints then walks the lazy `mcp` package, which imports `mcp.server` at
that moment only; `import mcp.client` stays free of the server stack and the
evaluated hint is the same union of classes as before. The package's
TYPE_CHECKING mirror now also lists the subpackages that its `__getattr__`
resolves on first access, so type checkers see the same chains.
The streamable-HTTP client transport (httpx2) is now imported when the
first URL Client is constructed instead of at import time, so a stdio-only
client (or a bare `import mcp.client`) never loads it. Tests cover the
resulting import contract: the client entry points load neither the
server stack nor httpx2 until they are used, and the package's lazy
server-side re-exports still resolve to their defining objects.
The test that patched `mcp.client.client.streamable_http_client` now
patches the transport at its defining module.