Skip to content

Commit 7ddd731

Browse files
committed
refactor: replace decorator-based handlers with RequestHandler/NotificationHandler pattern
- Extract RequestHandler class into request_handler.py with typed overloads - Extract NotificationHandler class into notification_handler.py with typed overloads - Refactor Server to dispatch by method string instead of request type - Remove decorator methods, tool cache, and request_ctx contextvar - Delete new_server.py sketch (superseded by extracted handler files) Known breakages: MCPServer, ExperimentalHandlers, tests, examples
1 parent b4da788 commit 7ddd731

File tree

5 files changed

+320
-707
lines changed

5 files changed

+320
-707
lines changed
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from .notification_handler import NotificationHandler
2+
from .request_handler import RequestHandler
13
from .server import NotificationOptions, Server
24

3-
__all__ = ["Server", "NotificationOptions"]
5+
__all__ = ["NotificationHandler", "NotificationOptions", "RequestHandler", "Server"]

src/mcp/server/lowlevel/new_server.py

Lines changed: 0 additions & 220 deletions
This file was deleted.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
"""Notification handler for the low-level MCP server."""
2+
3+
from collections.abc import Awaitable, Callable
4+
from typing import Any, Generic, Literal, overload
5+
6+
from typing_extensions import TypeVar
7+
8+
from mcp.server.session import ServerSession
9+
from mcp.shared.context import RequestContext
10+
from mcp.types import (
11+
CancelledNotificationParams,
12+
NotificationParams,
13+
ProgressNotificationParams,
14+
)
15+
16+
LifespanResultT = TypeVar("LifespanResultT", default=Any)
17+
RequestT = TypeVar("RequestT", default=Any)
18+
19+
Ctx = RequestContext[ServerSession, LifespanResultT, RequestT]
20+
21+
22+
class NotificationHandler(Generic[LifespanResultT, RequestT]):
23+
"""Handler for MCP notification methods.
24+
25+
Each handler is associated with a method string (e.g. "notifications/progress") and
26+
an async endpoint function that receives a RequestContext and the notification params.
27+
"""
28+
29+
@overload
30+
def __init__(
31+
self,
32+
method: Literal["notifications/initialized"],
33+
handler: Callable[[Ctx, NotificationParams | None], Awaitable[None]],
34+
) -> None: ...
35+
36+
@overload
37+
def __init__(
38+
self,
39+
method: Literal["notifications/cancelled"],
40+
handler: Callable[[Ctx, CancelledNotificationParams], Awaitable[None]],
41+
) -> None: ...
42+
43+
@overload
44+
def __init__(
45+
self,
46+
method: Literal["notifications/progress"],
47+
handler: Callable[[Ctx, ProgressNotificationParams], Awaitable[None]],
48+
) -> None: ...
49+
50+
@overload
51+
def __init__(
52+
self,
53+
method: Literal["notifications/roots/list_changed"],
54+
handler: Callable[[Ctx, NotificationParams | None], Awaitable[None]],
55+
) -> None: ...
56+
57+
@overload
58+
def __init__(
59+
self,
60+
method: str,
61+
handler: Callable[..., Awaitable[None]],
62+
) -> None: ...
63+
64+
def __init__(self, method: str, handler: Callable[..., Awaitable[None]]) -> None:
65+
self.method = method
66+
self.endpoint = handler
67+
68+
async def handle(self, ctx: Ctx, params: Any) -> None:
69+
await self.endpoint(ctx, params)

0 commit comments

Comments
 (0)