Merge branch 'main' into patch-1

This commit is contained in:
Jerome
2025-03-12 09:31:56 +00:00
committed by GitHub
4 changed files with 14 additions and 12 deletions

View File

@@ -37,7 +37,7 @@ from mcp.server.lowlevel.server import (
from mcp.server.session import ServerSession
from mcp.server.sse import SseServerTransport
from mcp.server.stdio import stdio_server
from mcp.shared.context import RequestContext
from mcp.shared.context import LifespanContextT, RequestContext
from mcp.types import (
AnyFunction,
EmbeddedResource,
@@ -564,7 +564,7 @@ def _convert_to_content(
return [TextContent(type="text", text=result)]
class Context(BaseModel):
class Context(BaseModel, Generic[LifespanContextT]):
"""Context object providing access to MCP capabilities.
This provides a cleaner interface to MCP's RequestContext functionality.
@@ -598,13 +598,13 @@ class Context(BaseModel):
The context is optional - tools that don't need it can omit the parameter.
"""
_request_context: RequestContext[ServerSession, Any] | None
_request_context: RequestContext[ServerSession, LifespanContextT] | None
_fastmcp: FastMCP | None
def __init__(
self,
*,
request_context: RequestContext | None = None,
request_context: RequestContext[ServerSession, LifespanContextT] | None = None,
fastmcp: FastMCP | None = None,
**kwargs: Any,
):
@@ -620,7 +620,7 @@ class Context(BaseModel):
return self._fastmcp
@property
def request_context(self) -> RequestContext:
def request_context(self) -> RequestContext[ServerSession, LifespanContextT]:
"""Access to the underlying request context."""
if self._request_context is None:
raise ValueError("Context is not available outside of a request")

View File

@@ -1,11 +1,13 @@
from dataclasses import dataclass
from typing import Generic, TypeVar
from typing import Any, Generic
from typing_extensions import TypeVar
from mcp.shared.session import BaseSession
from mcp.types import RequestId, RequestParams
SessionT = TypeVar("SessionT", bound=BaseSession)
LifespanContextT = TypeVar("LifespanContextT")
SessionT = TypeVar("SessionT", bound=BaseSession[Any, Any, Any, Any, Any])
LifespanContextT = TypeVar("LifespanContextT", default=None)
@dataclass

View File

@@ -8,6 +8,7 @@ import anyio.lowlevel
import httpx
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
from pydantic import BaseModel
from typing_extensions import Self
from mcp.shared.exceptions import McpError
from mcp.types import (
@@ -60,7 +61,7 @@ class RequestResponder(Generic[ReceiveRequestT, SendResultT]):
request_id: RequestId,
request_meta: RequestParams.Meta | None,
request: ReceiveRequestT,
session: "BaseSession",
session: "BaseSession[SendRequestT, SendNotificationT, SendResultT, ReceiveRequestT, ReceiveNotificationT]",
on_complete: Callable[["RequestResponder[ReceiveRequestT, SendResultT]"], Any],
) -> None:
self.request_id = request_id
@@ -134,7 +135,6 @@ class RequestResponder(Generic[ReceiveRequestT, SendResultT]):
class BaseSession(
AbstractAsyncContextManager,
Generic[
SendRequestT,
SendNotificationT,
@@ -183,7 +183,7 @@ class BaseSession(
]()
)
async def __aenter__(self):
async def __aenter__(self) -> Self:
self._task_group = anyio.create_task_group()
await self._task_group.__aenter__()
self._task_group.start_soon(self._receive_loop)