refactor: split RequestContext between server and client (#1987)
This commit is contained in:
parent
050aeb6456
commit
b1f7eec3cd
2 changed files with 210 additions and 212 deletions
|
|
@ -1,30 +1,20 @@
|
|||
"""Request context for MCP handlers."""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Generic
|
||||
|
||||
from typing_extensions import TypeVar
|
||||
|
||||
from mcp.shared.message import CloseSSEStreamCallback
|
||||
from mcp.shared.session import BaseSession
|
||||
from mcp.types import RequestId, RequestParamsMeta
|
||||
|
||||
SessionT = TypeVar("SessionT", bound=BaseSession[Any, Any, Any, Any, Any])
|
||||
LifespanContextT = TypeVar("LifespanContextT")
|
||||
RequestT = TypeVar("RequestT", default=Any)
|
||||
|
||||
|
||||
@dataclass
|
||||
class RequestContext(Generic[SessionT, LifespanContextT, RequestT]):
|
||||
@dataclass(kw_only=True)
|
||||
class RequestContext(Generic[SessionT]):
|
||||
"""Common context for handling incoming requests."""
|
||||
|
||||
request_id: RequestId
|
||||
meta: RequestParamsMeta | None
|
||||
session: SessionT
|
||||
lifespan_context: LifespanContextT
|
||||
# NOTE: This is typed as Any to avoid circular imports. The actual type is
|
||||
# mcp.server.experimental.request_context.Experimental, but importing it here
|
||||
# triggers mcp.server.__init__ -> mcpserver -> tools -> back to this module.
|
||||
# The Server sets this to an Experimental instance at runtime.
|
||||
experimental: Any = field(default=None)
|
||||
request: RequestT | None = None
|
||||
close_sse_stream: CloseSSEStreamCallback | None = None
|
||||
close_standalone_sse_stream: CloseSSEStreamCallback | None = None
|
||||
|
|
|
|||
|
|
@ -5,15 +5,7 @@ from typing import Generic
|
|||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from mcp.shared.context import LifespanContextT, RequestContext
|
||||
from mcp.shared.session import (
|
||||
BaseSession,
|
||||
ReceiveNotificationT,
|
||||
ReceiveRequestT,
|
||||
SendNotificationT,
|
||||
SendRequestT,
|
||||
SendResultT,
|
||||
)
|
||||
from mcp.shared.context import RequestContext, SessionT
|
||||
from mcp.types import ProgressToken
|
||||
|
||||
|
||||
|
|
@ -23,8 +15,8 @@ class Progress(BaseModel):
|
|||
|
||||
|
||||
@dataclass
|
||||
class ProgressContext(Generic[SendRequestT, SendNotificationT, SendResultT, ReceiveRequestT, ReceiveNotificationT]):
|
||||
session: BaseSession[SendRequestT, SendNotificationT, SendResultT, ReceiveRequestT, ReceiveNotificationT]
|
||||
class ProgressContext(Generic[SessionT]):
|
||||
session: SessionT
|
||||
progress_token: ProgressToken
|
||||
total: float | None
|
||||
current: float = field(default=0.0, init=False)
|
||||
|
|
@ -39,15 +31,9 @@ class ProgressContext(Generic[SendRequestT, SendNotificationT, SendResultT, Rece
|
|||
|
||||
@contextmanager
|
||||
def progress(
|
||||
ctx: RequestContext[
|
||||
BaseSession[SendRequestT, SendNotificationT, SendResultT, ReceiveRequestT, ReceiveNotificationT],
|
||||
LifespanContextT,
|
||||
],
|
||||
ctx: RequestContext[SessionT],
|
||||
total: float | None = None,
|
||||
) -> Generator[
|
||||
ProgressContext[SendRequestT, SendNotificationT, SendResultT, ReceiveRequestT, ReceiveNotificationT],
|
||||
None,
|
||||
]:
|
||||
) -> Generator[ProgressContext[SessionT], None]:
|
||||
progress_token = ctx.meta.get("progress_token") if ctx.meta else None
|
||||
if progress_token is None: # pragma: no cover
|
||||
raise ValueError("No progress token provided")
|
||||
|
|
|
|||
Loading…
Reference in a new issue