refactor: split RequestContext between server and client (#1987)
This commit is contained in:
parent
050aeb6456
commit
b1f7eec3cd
7 changed files with 210 additions and 212 deletions
|
|
@ -14,9 +14,8 @@ from mcp.server.mcpserver.utilities.func_metadata import func_metadata
|
|||
from mcp.types import ContentBlock, Icon, TextContent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mcp.server.context import LifespanContextT, RequestT
|
||||
from mcp.server.mcpserver.server import Context
|
||||
from mcp.server.session import ServerSessionT
|
||||
from mcp.shared.context import LifespanContextT, RequestT
|
||||
|
||||
|
||||
class Message(BaseModel):
|
||||
|
|
@ -137,7 +136,7 @@ class Prompt(BaseModel):
|
|||
async def render(
|
||||
self,
|
||||
arguments: dict[str, Any] | None = None,
|
||||
context: Context[ServerSessionT, LifespanContextT, RequestT] | None = None,
|
||||
context: Context[LifespanContextT, RequestT] | None = None,
|
||||
) -> list[Message]:
|
||||
"""Render the prompt with arguments."""
|
||||
# Validate required arguments
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@ from mcp.server.mcpserver.prompts.base import Message, Prompt
|
|||
from mcp.server.mcpserver.utilities.logging import get_logger
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mcp.server.context import LifespanContextT, RequestT
|
||||
from mcp.server.mcpserver.server import Context
|
||||
from mcp.server.session import ServerSessionT
|
||||
from mcp.shared.context import LifespanContextT, RequestT
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
|
@ -50,7 +49,7 @@ class PromptManager:
|
|||
self,
|
||||
name: str,
|
||||
arguments: dict[str, Any] | None = None,
|
||||
context: Context[ServerSessionT, LifespanContextT, RequestT] | None = None,
|
||||
context: Context[LifespanContextT, RequestT] | None = None,
|
||||
) -> list[Message]:
|
||||
"""Render a prompt by name with arguments."""
|
||||
prompt = self.get_prompt(name)
|
||||
|
|
|
|||
|
|
@ -13,9 +13,8 @@ from mcp.server.mcpserver.utilities.logging import get_logger
|
|||
from mcp.types import Annotations, Icon
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mcp.server.context import LifespanContextT, RequestT
|
||||
from mcp.server.mcpserver.server import Context
|
||||
from mcp.server.session import ServerSessionT
|
||||
from mcp.shared.context import LifespanContextT, RequestT
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
|
@ -82,7 +81,7 @@ class ResourceManager:
|
|||
return template
|
||||
|
||||
async def get_resource(
|
||||
self, uri: AnyUrl | str, context: Context[ServerSessionT, LifespanContextT, RequestT] | None = None
|
||||
self, uri: AnyUrl | str, context: Context[LifespanContextT, RequestT] | None = None
|
||||
) -> Resource:
|
||||
"""Get resource by URI, checking concrete resources first, then templates."""
|
||||
uri_str = str(uri)
|
||||
|
|
|
|||
|
|
@ -16,9 +16,8 @@ from mcp.server.mcpserver.utilities.func_metadata import func_metadata
|
|||
from mcp.types import Annotations, Icon
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mcp.server.context import LifespanContextT, RequestT
|
||||
from mcp.server.mcpserver.server import Context
|
||||
from mcp.server.session import ServerSessionT
|
||||
from mcp.shared.context import LifespanContextT, RequestT
|
||||
|
||||
|
||||
class ResourceTemplate(BaseModel):
|
||||
|
|
@ -100,7 +99,7 @@ class ResourceTemplate(BaseModel):
|
|||
self,
|
||||
uri: str,
|
||||
params: dict[str, Any],
|
||||
context: Context[ServerSessionT, LifespanContextT, RequestT] | None = None,
|
||||
context: Context[LifespanContextT, RequestT] | None = None,
|
||||
) -> Resource:
|
||||
"""Create a resource from the template with the given parameters."""
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ from mcp.server.auth.middleware.auth_context import AuthContextMiddleware
|
|||
from mcp.server.auth.middleware.bearer_auth import BearerAuthBackend, RequireAuthMiddleware
|
||||
from mcp.server.auth.provider import OAuthAuthorizationServerProvider, ProviderTokenVerifier, TokenVerifier
|
||||
from mcp.server.auth.settings import AuthSettings
|
||||
from mcp.server.context import LifespanContextT, RequestT, ServerRequestContext
|
||||
from mcp.server.elicitation import ElicitationResult, ElicitSchemaModelT, UrlElicitationResult, elicit_with_validation
|
||||
from mcp.server.elicitation import elicit_url as _elicit_url
|
||||
from mcp.server.lowlevel.helper_types import ReadResourceContents
|
||||
|
|
@ -36,13 +37,11 @@ from mcp.server.mcpserver.resources import FunctionResource, Resource, ResourceM
|
|||
from mcp.server.mcpserver.tools import Tool, ToolManager
|
||||
from mcp.server.mcpserver.utilities.context_injection import find_context_parameter
|
||||
from mcp.server.mcpserver.utilities.logging import configure_logging, get_logger
|
||||
from mcp.server.session import ServerSession, ServerSessionT
|
||||
from mcp.server.sse import SseServerTransport
|
||||
from mcp.server.stdio import stdio_server
|
||||
from mcp.server.streamable_http import EventStore
|
||||
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
|
||||
from mcp.server.transport_security import TransportSecuritySettings
|
||||
from mcp.shared.context import LifespanContextT, RequestContext, RequestT
|
||||
from mcp.types import Annotations, ContentBlock, GetPromptResult, Icon, ToolAnnotations
|
||||
from mcp.types import Prompt as MCPPrompt
|
||||
from mcp.types import PromptArgument as MCPPromptArgument
|
||||
|
|
@ -294,7 +293,7 @@ class MCPServer(Generic[LifespanResultT]):
|
|||
for info in tools
|
||||
]
|
||||
|
||||
def get_context(self) -> Context[ServerSession, LifespanResultT, Request]:
|
||||
def get_context(self) -> Context[LifespanResultT, Request]:
|
||||
"""Returns a Context object. Note that the context will only be valid
|
||||
during a request; outside a request, most methods will error.
|
||||
"""
|
||||
|
|
@ -972,7 +971,7 @@ class MCPServer(Generic[LifespanResultT]):
|
|||
raise ValueError(str(e))
|
||||
|
||||
|
||||
class Context(BaseModel, Generic[ServerSessionT, LifespanContextT, RequestT]):
|
||||
class Context(BaseModel, Generic[LifespanContextT, RequestT]):
|
||||
"""Context object providing access to MCP capabilities.
|
||||
|
||||
This provides a cleaner interface to MCP's RequestContext functionality.
|
||||
|
|
@ -1006,14 +1005,15 @@ class Context(BaseModel, Generic[ServerSessionT, LifespanContextT, RequestT]):
|
|||
The context is optional - tools that don't need it can omit the parameter.
|
||||
"""
|
||||
|
||||
_request_context: RequestContext[ServerSessionT, LifespanContextT, RequestT] | None
|
||||
_request_context: ServerRequestContext[LifespanContextT, RequestT] | None
|
||||
_mcp_server: MCPServer | None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
request_context: (RequestContext[ServerSessionT, LifespanContextT, RequestT] | None) = None,
|
||||
request_context: ServerRequestContext[LifespanContextT, RequestT] | None = None,
|
||||
mcp_server: MCPServer | None = None,
|
||||
# TODO(Marcelo): We should drop this kwargs parameter.
|
||||
**kwargs: Any,
|
||||
):
|
||||
super().__init__(**kwargs)
|
||||
|
|
@ -1028,9 +1028,7 @@ class Context(BaseModel, Generic[ServerSessionT, LifespanContextT, RequestT]):
|
|||
return self._mcp_server # pragma: no cover
|
||||
|
||||
@property
|
||||
def request_context(
|
||||
self,
|
||||
) -> RequestContext[ServerSessionT, LifespanContextT, RequestT]:
|
||||
def request_context(self) -> ServerRequestContext[LifespanContextT, RequestT]:
|
||||
"""Access to the underlying request context."""
|
||||
if self._request_context is None: # pragma: no cover
|
||||
raise ValueError("Context is not available outside of a request")
|
||||
|
|
|
|||
|
|
@ -16,9 +16,8 @@ from mcp.shared.tool_name_validation import validate_and_warn_tool_name
|
|||
from mcp.types import Icon, ToolAnnotations
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mcp.server.context import LifespanContextT, RequestT
|
||||
from mcp.server.mcpserver.server import Context
|
||||
from mcp.server.session import ServerSessionT
|
||||
from mcp.shared.context import LifespanContextT, RequestT
|
||||
|
||||
|
||||
class Tool(BaseModel):
|
||||
|
|
@ -93,7 +92,7 @@ class Tool(BaseModel):
|
|||
async def run(
|
||||
self,
|
||||
arguments: dict[str, Any],
|
||||
context: Context[ServerSessionT, LifespanContextT, RequestT] | None = None,
|
||||
context: Context[LifespanContextT, RequestT] | None = None,
|
||||
convert_result: bool = False,
|
||||
) -> Any:
|
||||
"""Run the tool with arguments."""
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@ from typing import TYPE_CHECKING, Any
|
|||
from mcp.server.mcpserver.exceptions import ToolError
|
||||
from mcp.server.mcpserver.tools.base import Tool
|
||||
from mcp.server.mcpserver.utilities.logging import get_logger
|
||||
from mcp.shared.context import LifespanContextT, RequestT
|
||||
from mcp.types import Icon, ToolAnnotations
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mcp.server.context import LifespanContextT, RequestT
|
||||
from mcp.server.mcpserver.server import Context
|
||||
from mcp.server.session import ServerSessionT
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
|
@ -82,7 +81,7 @@ class ToolManager:
|
|||
self,
|
||||
name: str,
|
||||
arguments: dict[str, Any],
|
||||
context: Context[ServerSessionT, LifespanContextT, RequestT] | None = None,
|
||||
context: Context[LifespanContextT, RequestT] | None = None,
|
||||
convert_result: bool = False,
|
||||
) -> Any:
|
||||
"""Call a tool by name with arguments."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue