|
47 | 47 | from pydantic import BaseModel |
48 | 48 | from pydantic.networks import AnyUrl |
49 | 49 |
|
| 50 | +import mcp |
50 | 51 | from mcp.server._http_defaults import DEFAULT_MAX_REQUEST_BODY_SIZE |
51 | | -from mcp.server.auth.provider import OAuthAuthorizationServerProvider, ProviderTokenVerifier, TokenVerifier |
52 | | -from mcp.server.auth.settings import AuthSettings |
| 52 | + |
| 53 | +# `MCPServer.__init__`'s auth-provider annotations are spelled through the lazy |
| 54 | +# `mcp.server.auth` namespace, so this module never imports the OAuth provider |
| 55 | +# stack (it loads with the first auth-enabled server instead). |
| 56 | +from mcp.server.auth.settings import AuthSettings # light (pydantic-only); the Settings model needs it |
53 | 57 | from mcp.server.caching import CacheableMethod, CacheHint |
54 | 58 | from mcp.server.context import HandlerResult, ServerMiddleware, ServerRequestContext |
| 59 | +from mcp.server.event_store import EventStore |
55 | 60 | from mcp.server.extension import ( |
56 | 61 | Extension, |
57 | 62 | MethodBinding, |
|
78 | 83 | from mcp.server.request_state import RequestStateBoundary, RequestStateSecurity |
79 | 84 | from mcp.server.stdio import stdio_server |
80 | 85 | from mcp.server.subscriptions import InMemorySubscriptionBus, ListenHandler, SubscriptionBus |
| 86 | +from mcp.server.transport_security import TransportSecuritySettings |
81 | 87 | from mcp.shared.exceptions import MCPError |
82 | 88 | from mcp.shared.uri_template import UriTemplate |
83 | 89 |
|
84 | 90 | if TYPE_CHECKING: |
85 | | - # HTTP transport types appear only in the SSE / streamable-HTTP methods' |
| 91 | + # Starlette types appear only in the SSE / streamable-HTTP methods' |
86 | 92 | # signatures and in narrowed attributes. Their runtime imports live inside |
87 | 93 | # those methods (and `custom_route`), so `import mcp.server.mcpserver` |
88 | 94 | # (and every stdio server) never loads starlette, sse_starlette or |
89 | | - # uvicorn - only building an HTTP app pays for the web stack, once. |
| 95 | + # uvicorn - only building an HTTP app pays for the web stack, once. The |
| 96 | + # session-manager annotation is spelled through the lazy `mcp.server` |
| 97 | + # namespace instead, so `typing.get_type_hints` resolves it on demand. |
90 | 98 | from starlette.applications import Starlette |
91 | 99 | from starlette.requests import Request |
92 | 100 | from starlette.responses import Response |
93 | 101 | from starlette.routing import Route |
94 | 102 | from starlette.types import Receive, Scope, Send |
95 | 103 |
|
96 | | - from mcp.server.streamable_http import EventStore |
97 | | - from mcp.server.streamable_http_manager import StreamableHTTPSessionManager |
98 | | - from mcp.server.transport_security import TransportSecuritySettings |
99 | | - |
100 | 104 | logger = get_logger(__name__) |
101 | 105 |
|
102 | 106 | _CallableT = TypeVar("_CallableT", bound=Callable[..., Any]) |
@@ -158,8 +162,8 @@ def __init__( |
158 | 162 | website_url: str | None = None, |
159 | 163 | icons: list[Icon] | None = None, |
160 | 164 | version: str = "", |
161 | | - auth_server_provider: OAuthAuthorizationServerProvider[Any, Any, Any] | None = None, |
162 | | - token_verifier: TokenVerifier | None = None, |
| 165 | + auth_server_provider: mcp.server.auth.provider.OAuthAuthorizationServerProvider[Any, Any, Any] | None = None, |
| 166 | + token_verifier: mcp.server.auth.provider.TokenVerifier | None = None, |
163 | 167 | *, |
164 | 168 | tools: list[Tool] | None = None, |
165 | 169 | resources: list[Resource] | None = None, |
@@ -250,6 +254,9 @@ def __init__( |
250 | 254 |
|
251 | 255 | # Create token verifier from provider if needed (backwards compatibility) |
252 | 256 | if auth_server_provider and not token_verifier: |
| 257 | + # The OAuth provider stack loads only for a server configured with one. |
| 258 | + from mcp.server.auth.provider import ProviderTokenVerifier |
| 259 | + |
253 | 260 | self._token_verifier = ProviderTokenVerifier(auth_server_provider) |
254 | 261 | self._custom_starlette_routes: list[Route] = [] |
255 | 262 |
|
@@ -301,7 +308,7 @@ def version(self) -> str: |
301 | 308 | return self._lowlevel_server.version |
302 | 309 |
|
303 | 310 | @property |
304 | | - def session_manager(self) -> StreamableHTTPSessionManager: |
| 311 | + def session_manager(self) -> mcp.server.streamable_http_manager.StreamableHTTPSessionManager: |
305 | 312 | """Get the StreamableHTTP session manager. |
306 | 313 |
|
307 | 314 | This is exposed to enable advanced use cases like mounting multiple |
@@ -1118,7 +1125,6 @@ def sse_app( |
1118 | 1125 | from mcp.server.auth.middleware.auth_context import AuthContextMiddleware |
1119 | 1126 | from mcp.server.auth.middleware.bearer_auth import BearerAuthBackend, RequireAuthMiddleware |
1120 | 1127 | from mcp.server.sse import SseServerTransport |
1121 | | - from mcp.server.transport_security import TransportSecuritySettings |
1122 | 1128 |
|
1123 | 1129 | # Auto-enable DNS rebinding protection for localhost (IPv4 and IPv6) |
1124 | 1130 | if transport_security is None and host in ("127.0.0.1", "localhost", "::1"): |
|
0 commit comments