Skip to content

Commit 6a874a3

Browse files
committed
Merge branch 'main' of github.com:emsi/mcp-python-sdk-linux
2 parents b2372b0 + 7585b23 commit 6a874a3

File tree

6 files changed

+51
-40
lines changed

6 files changed

+51
-40
lines changed

src/mcp/server/fastmcp/server.py

+19-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""FastMCP - A more ergonomic interface for MCP servers."""
22

3+
from __future__ import annotations as _annotations
4+
35
import inspect
46
import json
57
import re
@@ -25,16 +27,10 @@
2527
from mcp.server.fastmcp.utilities.logging import configure_logging, get_logger
2628
from mcp.server.fastmcp.utilities.types import Image
2729
from mcp.server.lowlevel.helper_types import ReadResourceContents
28-
from mcp.server.lowlevel.server import (
29-
LifespanResultT,
30-
)
31-
from mcp.server.lowlevel.server import (
32-
Server as MCPServer,
33-
)
34-
from mcp.server.lowlevel.server import (
35-
lifespan as default_lifespan,
36-
)
37-
from mcp.server.session import ServerSession
30+
from mcp.server.lowlevel.server import LifespanResultT
31+
from mcp.server.lowlevel.server import Server as MCPServer
32+
from mcp.server.lowlevel.server import lifespan as default_lifespan
33+
from mcp.server.session import ServerSession, ServerSessionT
3834
from mcp.server.sse import SseServerTransport
3935
from mcp.server.stdio import stdio_server
4036
from mcp.shared.context import LifespanContextT, RequestContext
@@ -45,21 +41,11 @@
4541
ImageContent,
4642
TextContent,
4743
)
48-
from mcp.types import (
49-
Prompt as MCPPrompt,
50-
)
51-
from mcp.types import (
52-
PromptArgument as MCPPromptArgument,
53-
)
54-
from mcp.types import (
55-
Resource as MCPResource,
56-
)
57-
from mcp.types import (
58-
ResourceTemplate as MCPResourceTemplate,
59-
)
60-
from mcp.types import (
61-
Tool as MCPTool,
62-
)
44+
from mcp.types import Prompt as MCPPrompt
45+
from mcp.types import PromptArgument as MCPPromptArgument
46+
from mcp.types import Resource as MCPResource
47+
from mcp.types import ResourceTemplate as MCPResourceTemplate
48+
from mcp.types import Tool as MCPTool
6349

6450
logger = get_logger(__name__)
6551

@@ -105,11 +91,11 @@ class Settings(BaseSettings, Generic[LifespanResultT]):
10591

10692

10793
def lifespan_wrapper(
108-
app: "FastMCP",
94+
app: FastMCP,
10995
lifespan: Callable[["FastMCP"], AbstractAsyncContextManager[LifespanResultT]],
110-
) -> Callable[[MCPServer], AbstractAsyncContextManager[object]]:
96+
) -> Callable[[MCPServer[LifespanResultT]], AbstractAsyncContextManager[object]]:
11197
@asynccontextmanager
112-
async def wrap(s: MCPServer) -> AsyncIterator[object]:
98+
async def wrap(s: MCPServer[LifespanResultT]) -> AsyncIterator[object]:
11399
async with lifespan(app) as context:
114100
yield context
115101

@@ -191,7 +177,7 @@ async def list_tools(self) -> list[MCPTool]:
191177
for info in tools
192178
]
193179

194-
def get_context(self) -> "Context":
180+
def get_context(self) -> "Context[ServerSession, object]":
195181
"""
196182
Returns a Context object. Note that the context will only be valid
197183
during a request; outside a request, most methods will error.
@@ -564,7 +550,7 @@ def _convert_to_content(
564550
return [TextContent(type="text", text=result)]
565551

566552

567-
class Context(BaseModel, Generic[LifespanContextT]):
553+
class Context(BaseModel, Generic[ServerSessionT, LifespanContextT]):
568554
"""Context object providing access to MCP capabilities.
569555
570556
This provides a cleaner interface to MCP's RequestContext functionality.
@@ -598,13 +584,13 @@ def my_tool(x: int, ctx: Context) -> str:
598584
The context is optional - tools that don't need it can omit the parameter.
599585
"""
600586

601-
_request_context: RequestContext[ServerSession, LifespanContextT] | None
587+
_request_context: RequestContext[ServerSessionT, LifespanContextT] | None
602588
_fastmcp: FastMCP | None
603589

604590
def __init__(
605591
self,
606592
*,
607-
request_context: RequestContext[ServerSession, LifespanContextT] | None = None,
593+
request_context: RequestContext[ServerSessionT, LifespanContextT] | None = None,
608594
fastmcp: FastMCP | None = None,
609595
**kwargs: Any,
610596
):
@@ -620,7 +606,7 @@ def fastmcp(self) -> FastMCP:
620606
return self._fastmcp
621607

622608
@property
623-
def request_context(self) -> RequestContext[ServerSession, LifespanContextT]:
609+
def request_context(self) -> RequestContext[ServerSessionT, LifespanContextT]:
624610
"""Access to the underlying request context."""
625611
if self._request_context is None:
626612
raise ValueError("Context is not available outside of a request")

src/mcp/server/fastmcp/tools/base.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations as _annotations
2+
13
import inspect
24
from typing import TYPE_CHECKING, Any, Callable
35

@@ -9,6 +11,8 @@
911

1012
if TYPE_CHECKING:
1113
from mcp.server.fastmcp.server import Context
14+
from mcp.server.session import ServerSessionT
15+
from mcp.shared.context import LifespanContextT
1216

1317

1418
class Tool(BaseModel):
@@ -68,7 +72,11 @@ def from_function(
6872
context_kwarg=context_kwarg,
6973
)
7074

71-
async def run(self, arguments: dict, context: "Context | None" = None) -> Any:
75+
async def run(
76+
self,
77+
arguments: dict[str, Any],
78+
context: Context[ServerSessionT, LifespanContextT] | None = None,
79+
) -> Any:
7280
"""Run the tool with arguments."""
7381
try:
7482
return await self.fn_metadata.call_fn_with_arg_validation(

src/mcp/server/fastmcp/tools/tool_manager.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1+
from __future__ import annotations as _annotations
2+
13
from collections.abc import Callable
24
from typing import TYPE_CHECKING, Any
35

46
from mcp.server.fastmcp.exceptions import ToolError
57
from mcp.server.fastmcp.tools.base import Tool
68
from mcp.server.fastmcp.utilities.logging import get_logger
9+
from mcp.shared.context import LifespanContextT
710

811
if TYPE_CHECKING:
912
from mcp.server.fastmcp.server import Context
13+
from mcp.server.session import ServerSessionT
1014

1115
logger = get_logger(__name__)
1216

@@ -43,7 +47,10 @@ def add_tool(
4347
return tool
4448

4549
async def call_tool(
46-
self, name: str, arguments: dict, context: "Context | None" = None
50+
self,
51+
name: str,
52+
arguments: dict[str, Any],
53+
context: Context[ServerSessionT, LifespanContextT] | None = None,
4754
) -> Any:
4855
"""Call a tool by name with arguments."""
4956
tool = self.get_tool(name)

src/mcp/server/lowlevel/server.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ async def main():
6464
messages from the client.
6565
"""
6666

67+
from __future__ import annotations as _annotations
68+
6769
import contextvars
6870
import logging
6971
import warnings
@@ -107,7 +109,7 @@ def __init__(
107109

108110

109111
@asynccontextmanager
110-
async def lifespan(server: "Server") -> AsyncIterator[object]:
112+
async def lifespan(server: Server[LifespanResultT]) -> AsyncIterator[object]:
111113
"""Default lifespan context manager that does nothing.
112114
113115
Args:
@@ -126,7 +128,7 @@ def __init__(
126128
version: str | None = None,
127129
instructions: str | None = None,
128130
lifespan: Callable[
129-
["Server"], AbstractAsyncContextManager[LifespanResultT]
131+
[Server[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]
130132
] = lifespan,
131133
):
132134
self.name = name

src/mcp/server/session.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ async def handle_list_prompts(ctx: RequestContext) -> list[types.Prompt]:
3838
"""
3939

4040
from enum import Enum
41-
from typing import Any
41+
from typing import Any, TypeVar
4242

4343
import anyio
4444
import anyio.lowlevel
@@ -59,6 +59,9 @@ class InitializationState(Enum):
5959
Initialized = 3
6060

6161

62+
ServerSessionT = TypeVar("ServerSessionT", bound="ServerSession")
63+
64+
6265
class ServerSession(
6366
BaseSession[
6467
types.ServerRequest,

src/mcp/shared/session.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import logging
2-
from contextlib import AbstractAsyncContextManager
32
from datetime import timedelta
43
from typing import Any, Callable, Generic, TypeVar
54

@@ -61,7 +60,13 @@ def __init__(
6160
request_id: RequestId,
6261
request_meta: RequestParams.Meta | None,
6362
request: ReceiveRequestT,
64-
session: "BaseSession[SendRequestT, SendNotificationT, SendResultT, ReceiveRequestT, ReceiveNotificationT]",
63+
session: """BaseSession[
64+
SendRequestT,
65+
SendNotificationT,
66+
SendResultT,
67+
ReceiveRequestT,
68+
ReceiveNotificationT
69+
]""",
6570
on_complete: Callable[["RequestResponder[ReceiveRequestT, SendResultT]"], Any],
6671
) -> None:
6772
self.request_id = request_id

0 commit comments

Comments
 (0)