From f33a9fb95a7101379c6f8ed716c9a176272353a1 Mon Sep 17 00:00:00 2001 From: daamitt Date: Tue, 14 Oct 2025 16:38:13 +0530 Subject: [PATCH] feat: Add support for specifying NotificationOptions in FastMCP and lowlevel Server creation --- README.md | 6 +++++- examples/snippets/servers/notifications.py | 6 +++++- src/mcp/server/fastmcp/server.py | 4 +++- src/mcp/server/lowlevel/server.py | 4 +++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a0daf5c6d6..a326dffbc7 100644 --- a/README.md +++ b/README.md @@ -833,9 +833,13 @@ Tools can send logs and notifications through the context: ```python from mcp.server.fastmcp import Context, FastMCP +from mcp.server.lowlevel.server import NotificationOptions from mcp.server.session import ServerSession -mcp = FastMCP(name="Notifications Example") +# Setup Server Capabilities +notification_options = NotificationOptions(prompts_changed=False, resources_changed=True, tools_changed=False) + +mcp = FastMCP(name="Notifications Example", notification_options=notification_options) @mcp.tool() diff --git a/examples/snippets/servers/notifications.py b/examples/snippets/servers/notifications.py index 833bc89053..15a28ba883 100644 --- a/examples/snippets/servers/notifications.py +++ b/examples/snippets/servers/notifications.py @@ -1,7 +1,11 @@ from mcp.server.fastmcp import Context, FastMCP +from mcp.server.lowlevel.server import NotificationOptions from mcp.server.session import ServerSession -mcp = FastMCP(name="Notifications Example") +# Setup Server Capabilities +notification_options = NotificationOptions(prompts_changed=False, resources_changed=True, tools_changed=False) + +mcp = FastMCP(name="Notifications Example", notification_options=notification_options) @mcp.tool() diff --git a/src/mcp/server/fastmcp/server.py b/src/mcp/server/fastmcp/server.py index deccdb4e1c..c1cd82f2ca 100644 --- a/src/mcp/server/fastmcp/server.py +++ b/src/mcp/server/fastmcp/server.py @@ -33,7 +33,7 @@ from mcp.server.fastmcp.utilities.context_injection import find_context_parameter from mcp.server.fastmcp.utilities.logging import configure_logging, get_logger from mcp.server.lowlevel.helper_types import ReadResourceContents -from mcp.server.lowlevel.server import LifespanResultT +from mcp.server.lowlevel.server import LifespanResultT, NotificationOptions from mcp.server.lowlevel.server import Server as MCPServer from mcp.server.lowlevel.server import lifespan as default_lifespan from mcp.server.session import ServerSession, ServerSessionT @@ -148,6 +148,7 @@ def __init__( # noqa: PLR0913 lifespan: Callable[[FastMCP[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]] | None = None, auth: AuthSettings | None = None, transport_security: TransportSecuritySettings | None = None, + notification_options: NotificationOptions | None = None, ): self.settings = Settings( debug=debug, @@ -177,6 +178,7 @@ def __init__( # noqa: PLR0913 # TODO(Marcelo): It seems there's a type mismatch between the lifespan type from an FastMCP and Server. # We need to create a Lifespan type that is a generic on the server type, like Starlette does. lifespan=(lifespan_wrapper(self, self.settings.lifespan) if self.settings.lifespan else default_lifespan), # type: ignore + notification_options=notification_options, ) self._tool_manager = ToolManager(tools=tools, warn_on_duplicate_tools=self.settings.warn_on_duplicate_tools) self._resource_manager = ResourceManager(warn_on_duplicate_resources=self.settings.warn_on_duplicate_resources) diff --git a/src/mcp/server/lowlevel/server.py b/src/mcp/server/lowlevel/server.py index 1a69cbe485..dfaa7843ad 100644 --- a/src/mcp/server/lowlevel/server.py +++ b/src/mcp/server/lowlevel/server.py @@ -142,10 +142,12 @@ def __init__( [Server[LifespanResultT, RequestT]], AbstractAsyncContextManager[LifespanResultT], ] = lifespan, + notification_options: NotificationOptions | None = None, ): self.name = name self.version = version self.instructions = instructions + self.notification_options = notification_options or NotificationOptions() self.website_url = website_url self.icons = icons self.lifespan = lifespan @@ -177,7 +179,7 @@ def pkg_version(package: str) -> str: server_name=self.name, server_version=self.version if self.version else pkg_version("mcp"), capabilities=self.get_capabilities( - notification_options or NotificationOptions(), + notification_options or self.notification_options, experimental_capabilities or {}, ), instructions=self.instructions,