You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 1facb57
Browse filesBrowse the repository at this point in the historyBrowse files
Document the import-cost contract and the deferred-work model
- AGENTS.md: state the import-cost exception to the imports-at-top rule,
listing which stacks stay off which import paths and pointing at the
ratchet test that enforces it.
- New docs page "Imports & startup time" (Advanced): what loads when, the
one-time first-use costs, and a tested prewarm recipe for hosts that want
the deferred work paid at startup.
- Migration guide: the lazy import graph, the incidental namespace bindings
that moved to their defining modules, and defer_build inheritance for user
subclasses of SDK models.
- What's new: one paragraph on imports paying only for what they use.
Copy file name to clipboardExpand all lines: docs/migration.md
+52Lines changed: 52 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,6 +40,7 @@ Every section heading below names the API it affects, so searching this page for
40
40
| use stdio or streamable HTTP directly, or maintain a custom transport |[Transports](#transports)|
41
41
| maintain OAuth client auth or a protected server |[OAuth and server auth](#oauth-and-server-auth)|
42
42
| relied on lenient handling of off-schema traffic, or assert on exact wire bytes |[Stricter protocol validation and wire behavior](#stricter-protocol-validation-and-wire-behavior)|
43
+
| rely on `import mcp` importing submodules, patch SDK internals, or subclass SDK pydantic models |[Import graph and startup](#import-graph-and-startup)|
43
44
| test against in-memory server/client pairs |[Testing utilities](#testing-utilities)|
44
45
| use roots, sampling, logging, or client-to-server progress |[Deprecations](#deprecations)|
45
46
| operate servers that 2026-era clients will also connect to |[Notes for 2026-era connections](#notes-for-2026-era-connections)|
@@ -2678,6 +2679,57 @@ The envelope exists for OpenTelemetry trace propagation ([SEP-414](https://githu
2678
2679
2679
2680
The SDK's new `opentelemetry-api` runtime dependency is covered under [Packaging, dependencies, and CLI](#packaging-dependencies-and-cli).
2680
2681
2682
+
## Import graph and startup
2683
+
2684
+
### Imports are lazy; explicit imports are the supported form
2685
+
2686
+
`import mcp` no longer imports the SDK's whole module graph: the `mcp` package resolves each
2687
+
export from its home module on first access, and every entry point loads only its own stack
2688
+
(no server code behind a client, no web framework behind a stdio server, no wire schemas
2689
+
before a message needs them). Nothing you import changes name or location, and
2690
+
`from mcp import Client`, `mcp.types.Tool`, `from mcp import *` and object identity behave as
2691
+
before. See [Imports & startup time](advanced/import-cost.md) for what loads when and how to
2692
+
prewarm it.
2693
+
2694
+
Two incidental things did change:
2695
+
2696
+
***Attribute chains that were never imported explicitly.**`import mcp` used to bind most
2697
+
submodules as a side effect, so `import mcp` followed by `mcp.client.stdio.stdio_client(...)`
2698
+
happened to work. It still resolves (the packages import a submodule on attribute access), but
2699
+
the supported form is to import what you use: `from mcp.client.stdio import stdio_client`, or
2700
+
`import mcp.client.stdio`.
2701
+
***Namespace bindings that tests used to patch.** Modules stopped re-binding names they only
2702
+
imported: patch or import each object where it is defined. In particular,
2703
+
`mcp.client.client.streamable_http_client` is `mcp.client.streamable_http.streamable_http_client`,
2704
+
the HTTP-app pieces formerly bound in `mcp.server.lowlevel.server` / `mcp.server.mcpserver.server`
2705
+
(`SseServerTransport`, `StreamableHTTPSessionManager`, the auth middleware and route builders)
2706
+
live in `mcp.server.sse`, `mcp.server.streamable_http_manager` and `mcp.server.auth.*`, and
2707
+
`get_access_token` / `auth_context_var` are defined in the transport-agnostic
2708
+
`mcp.server.auth.access_token` (still importable from `mcp.server.auth.middleware.auth_context`).
2709
+
***Two web-framework-free homes.** The resumability contract (`EventStore`, `EventMessage`,
2710
+
`EventCallback`, `EventId`, `StreamId`) is defined in `mcp.server.event_store`, and
2711
+
`TransportSecurityMiddleware` now lives beside the transports rather than in
2712
+
`mcp.server.transport_security`; both keep their previous import paths
Copy file name to clipboardExpand all lines: docs/whats-new.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -124,6 +124,10 @@ On those types, every Python attribute is now snake_case: `result.is_error`, `to
124
124
125
125
**[Running your server](run/index.md)** covers the options; **[Add to an existing app](run/asgi.md)** covers mounting.
126
126
127
+
### Imports pay for what you use
128
+
129
+
`import mcp` is now nearly free, and every entry point loads only its own stack: a stdio server never loads the web framework, client code never loads the server, and the protocol's wire schemas load per negotiated version. The work did not vanish, it moved to first use (the first URL `Client`, the first HTTP app, the first message per protocol version), each a one-time cost. **[Imports & startup time](advanced/import-cost.md)** lists what loads when, and how to prewarm all of it at startup if that is where you want it.
0 commit comments