diff --git a/fastmcp_slim/fastmcp/cli/run.py b/fastmcp_slim/fastmcp/cli/run.py index 9e3562793..476c0267d 100644 --- a/fastmcp_slim/fastmcp/cli/run.py +++ b/fastmcp_slim/fastmcp/cli/run.py @@ -12,7 +12,7 @@ from collections.abc import Callable from pathlib import Path from typing import Any, Literal -from mcp.server.mcpserver import MCPServer as FastMCP1x +from mcp.server.mcpserver import MCPServer as SDKServer from watchfiles import Change, awatch import fastmcp @@ -233,8 +233,8 @@ async def run_command( # Run the server - # handle v1 servers - if isinstance(server, FastMCP1x): + # handle the SDK's own high-level MCPServer (not a fastmcp.FastMCP) + if isinstance(server, SDKServer): await run_v1_server_async(server, host=host, port=port, transport=transport) return @@ -309,7 +309,7 @@ def run_module_command( async def run_v1_server_async( - server: FastMCP1x, + server: SDKServer, host: str | None = None, port: int | None = None, transport: TransportType | None = None, diff --git a/fastmcp_slim/fastmcp/client/client.py b/fastmcp_slim/fastmcp/client/client.py index 53f340c8f..94ec0ee49 100644 --- a/fastmcp_slim/fastmcp/client/client.py +++ b/fastmcp_slim/fastmcp/client/client.py @@ -72,11 +72,11 @@ else: from .transports import ( ClientTransport, ClientTransportT, - FastMCP1Server, FastMCPTransport, MCPConfigTransport, NodeStdioTransport, PythonStdioTransport, + SDKServer, SessionKwargs, SSETransport, StreamableHttpTransport, @@ -209,7 +209,7 @@ class Client( @overload def __init__( self: Client[FastMCPTransport], - transport: FastMCP | FastMCP1Server, + transport: FastMCP | SDKServer, *args: Any, **kwargs: Any, ) -> None: ... @@ -248,7 +248,7 @@ class Client( transport: ( ClientTransportT | FastMCP - | FastMCP1Server + | SDKServer | AnyUrl | Path | MCPConfig diff --git a/fastmcp_slim/fastmcp/client/transports/__init__.py b/fastmcp_slim/fastmcp/client/transports/__init__.py index 2cc594281..287697b5c 100644 --- a/fastmcp_slim/fastmcp/client/transports/__init__.py +++ b/fastmcp_slim/fastmcp/client/transports/__init__.py @@ -1,4 +1,4 @@ -from mcp.server.mcpserver import MCPServer as FastMCP1Server +from mcp.server.mcpserver import MCPServer as SDKServer from fastmcp.client.transports.base import ( ClientTransport, diff --git a/fastmcp_slim/fastmcp/client/transports/inference.py b/fastmcp_slim/fastmcp/client/transports/inference.py index 4d3d82412..84711d198 100644 --- a/fastmcp_slim/fastmcp/client/transports/inference.py +++ b/fastmcp_slim/fastmcp/client/transports/inference.py @@ -1,7 +1,7 @@ from pathlib import Path from typing import TYPE_CHECKING, Any, cast, overload -from mcp.server.mcpserver import MCPServer as FastMCP1Server +from mcp.server.mcpserver import MCPServer as SDKServer from pydantic import AnyUrl from fastmcp.client.transports.base import ClientTransport, ClientTransportT @@ -33,7 +33,7 @@ def infer_transport(transport: FastMCP) -> FastMCPTransport: ... @overload -def infer_transport(transport: FastMCP1Server) -> FastMCPTransport: ... +def infer_transport(transport: SDKServer) -> FastMCPTransport: ... @overload @@ -65,7 +65,7 @@ def infer_transport(transport: Path) -> PythonStdioTransport | NodeStdioTranspor def infer_transport( transport: ClientTransport | FastMCP - | FastMCP1Server + | SDKServer | AnyUrl | Path | MCPConfig @@ -81,7 +81,7 @@ def infer_transport( The function supports these input types: - ClientTransport: Used directly without modification - - FastMCP or FastMCP1Server: Creates an in-memory FastMCPTransport + - FastMCP or SDKServer: Creates an in-memory FastMCPTransport - Path or str (file path): Creates PythonStdioTransport (.py) or NodeStdioTransport (.js) - AnyUrl or str (URL): Creates StreamableHttpTransport (default) or SSETransport (for /sse endpoints) - MCPConfig or dict: Creates MCPConfigTransport, potentially connecting to multiple servers @@ -120,7 +120,7 @@ def infer_transport( # the transport is a FastMCP server (2.x or 1.0) elif _is_fastmcp_server(transport): inferred_transport = FastMCPTransport( - mcp=cast("FastMCP[Any] | FastMCP1Server", transport) + mcp=cast("FastMCP[Any] | SDKServer", transport) ) # the transport is a path to a script @@ -159,7 +159,7 @@ def infer_transport( def _is_fastmcp_server(transport: object) -> bool: - if isinstance(transport, FastMCP1Server): + if isinstance(transport, SDKServer): return True try: diff --git a/fastmcp_slim/fastmcp/client/transports/memory.py b/fastmcp_slim/fastmcp/client/transports/memory.py index f6cbf6d41..0a622cc8b 100644 --- a/fastmcp_slim/fastmcp/client/transports/memory.py +++ b/fastmcp_slim/fastmcp/client/transports/memory.py @@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Any import anyio from mcp import ClientSession from mcp.server import Server -from mcp.server.mcpserver import MCPServer as FastMCP1Server +from mcp.server.mcpserver import MCPServer as SDKServer from mcp.shared.memory import create_client_server_memory_streams from typing_extensions import Unpack @@ -17,15 +17,15 @@ if TYPE_CHECKING: from fastmcp.server.server import FastMCP -def _lowlevel_of(server: "FastMCP[Any] | FastMCP1Server") -> Server: +def _lowlevel_of(server: "FastMCP[Any] | SDKServer") -> Server: """Resolve the underlying lowlevel MCP `Server` for either server type. - SDK v2's `MCPServer` (FastMCP 1.0) exposes its lowlevel server as + The SDK's own high-level `MCPServer` exposes its lowlevel server as `_lowlevel_server` and its own `run()` is synchronous, so we always drive - the async lowlevel `Server.run` here. FastMCP 2.x servers expose the same + the async lowlevel `Server.run` here. FastMCP servers expose the same lowlevel server as `_mcp_server`. """ - if isinstance(server, FastMCP1Server): + if isinstance(server, SDKServer): return server._lowlevel_server return server._mcp_server @@ -34,13 +34,14 @@ class FastMCPTransport(ClientTransport): """In-memory transport for FastMCP servers. This transport connects directly to a FastMCP server instance in the same - Python process. It works with both FastMCP 2.x servers and FastMCP 1.0 - servers from the low-level MCP SDK. This is particularly useful for unit - tests or scenarios where client and server run in the same runtime. + Python process. It works with both FastMCP servers and the SDK's own + high-level `MCPServer` from the low-level MCP SDK. This is particularly + useful for unit tests or scenarios where client and server run in the same + runtime. """ def __init__( - self, mcp: "FastMCP[Any] | FastMCP1Server", raise_exceptions: bool = False + self, mcp: "FastMCP[Any] | SDKServer", raise_exceptions: bool = False ): """Initialize a FastMCPTransport from a FastMCP server instance.""" @@ -110,16 +111,16 @@ class FastMCPTransport(ClientTransport): @contextlib.asynccontextmanager async def _enter_server_lifespan( - server: "FastMCP[Any] | FastMCP1Server", + server: "FastMCP[Any] | SDKServer", ) -> AsyncIterator[None]: - """Enters the server's lifespan context for FastMCP servers and does nothing for FastMCP 1 servers.""" + """Enters the server's lifespan context for FastMCP servers and does nothing for the SDK's own high-level servers.""" FastMCP2: type[Any] | None try: FastMCP2 = importlib.import_module("fastmcp.server.server").FastMCP except ImportError: FastMCP2 = None - if FastMCP2 is None and not isinstance(server, FastMCP1Server): + if FastMCP2 is None and not isinstance(server, SDKServer): raise ImportError(_install_hints.full_package("In-memory FastMCP transports")) if FastMCP2 is not None and isinstance(server, FastMCP2): diff --git a/fastmcp_slim/fastmcp/server/providers/proxy.py b/fastmcp_slim/fastmcp/server/providers/proxy.py index 536cde420..31bb074c0 100644 --- a/fastmcp_slim/fastmcp/server/providers/proxy.py +++ b/fastmcp_slim/fastmcp/server/providers/proxy.py @@ -27,7 +27,7 @@ from mcp_types import ( ) from pydantic.networks import AnyUrl -from fastmcp.client.client import Client, FastMCP1Server +from fastmcp.client.client import Client, SDKServer from fastmcp.client.elicitation import ElicitResult, create_elicitation_callback from fastmcp.client.logging import LogMessage, create_log_callback from fastmcp.client.roots import RootsList, create_roots_callback @@ -783,7 +783,7 @@ def _create_client_factory( Client[ClientTransportT] | ClientTransport | FastMCP[Any] - | FastMCP1Server + | SDKServer | AnyUrl | Path | MCPConfig @@ -1090,7 +1090,7 @@ class ProxyClient(Client[ClientTransportT]): self, transport: ClientTransportT | FastMCP[Any] - | FastMCP1Server + | SDKServer | AnyUrl | Path | MCPConfig diff --git a/fastmcp_slim/fastmcp/server/server.py b/fastmcp_slim/fastmcp/server/server.py index 256c65c06..ed1f81c26 100644 --- a/fastmcp_slim/fastmcp/server/server.py +++ b/fastmcp_slim/fastmcp/server/server.py @@ -89,7 +89,7 @@ from fastmcp.utilities.versions import ( if TYPE_CHECKING: from fastmcp.client import Client - from fastmcp.client.client import FastMCP1Server + from fastmcp.client.client import SDKServer from fastmcp.client.sampling import SamplingHandler from fastmcp.client.transports import ClientTransport, ClientTransportT from fastmcp.server.providers.openapi import ComponentFn as OpenAPIComponentFn @@ -2453,7 +2453,7 @@ class FastMCP( Client[ClientTransportT] | ClientTransport | FastMCP[Any] - | FastMCP1Server + | SDKServer | AnyUrl | Path | MCPConfig @@ -2503,7 +2503,7 @@ def create_proxy( Client[ClientTransportT] | ClientTransport | FastMCP[Any] - | FastMCP1Server + | SDKServer | AnyUrl | Path | MCPConfig diff --git a/fastmcp_slim/fastmcp/utilities/inspect.py b/fastmcp_slim/fastmcp/utilities/inspect.py index ac2b8afc9..aec06f927 100644 --- a/fastmcp_slim/fastmcp/utilities/inspect.py +++ b/fastmcp_slim/fastmcp/utilities/inspect.py @@ -8,7 +8,7 @@ from enum import Enum from typing import Any, Literal, cast import pydantic_core -from mcp.server.mcpserver import MCPServer as FastMCP1x +from mcp.server.mcpserver import MCPServer as SDKServer import fastmcp from fastmcp import Client @@ -248,7 +248,7 @@ async def inspect_fastmcp_v2(mcp: FastMCP[Any]) -> FastMCPInfo: ) -async def inspect_fastmcp_v1(mcp: FastMCP1x) -> FastMCPInfo: +async def inspect_fastmcp_v1(mcp: SDKServer) -> FastMCPInfo: """Extract information from a FastMCP v1.x instance using a Client. Args: @@ -257,7 +257,7 @@ async def inspect_fastmcp_v1(mcp: FastMCP1x) -> FastMCPInfo: Returns: FastMCPInfo dataclass containing the extracted information """ - # Use a client to interact with the FastMCP1x server + # Use a client to interact with the SDK's high-level MCPServer async with Client(mcp) as client: # Get components via client calls (these return MCP objects) mcp_tools = await client.list_tools() @@ -407,7 +407,7 @@ async def inspect_fastmcp_v1(mcp: FastMCP1x) -> FastMCPInfo: ) -async def inspect_fastmcp(mcp: FastMCP[Any] | FastMCP1x) -> FastMCPInfo: +async def inspect_fastmcp(mcp: FastMCP[Any] | SDKServer) -> FastMCPInfo: """Extract information from a FastMCP instance into a dataclass. This function automatically detects whether the instance is FastMCP v1.x or v2.x @@ -419,7 +419,7 @@ async def inspect_fastmcp(mcp: FastMCP[Any] | FastMCP1x) -> FastMCPInfo: Returns: FastMCPInfo dataclass containing the extracted information """ - if isinstance(mcp, FastMCP1x): + if isinstance(mcp, SDKServer): return await inspect_fastmcp_v1(mcp) else: return await inspect_fastmcp_v2(cast(FastMCP[Any], mcp)) @@ -461,7 +461,7 @@ def format_fastmcp_info(info: FastMCPInfo) -> bytes: return pydantic_core.to_json(result, indent=2) -async def format_mcp_info(mcp: FastMCP[Any] | FastMCP1x) -> bytes: +async def format_mcp_info(mcp: FastMCP[Any] | SDKServer) -> bytes: """Format server info as standard MCP protocol JSON. Uses Client to get the standard MCP protocol format with camelCase fields. @@ -495,7 +495,7 @@ async def format_mcp_info(mcp: FastMCP[Any] | FastMCP1x) -> bytes: async def format_info( - mcp: FastMCP[Any] | FastMCP1x, + mcp: FastMCP[Any] | SDKServer, format: InspectFormat | Literal["fastmcp", "mcp"], info: FastMCPInfo | None = None, ) -> bytes: diff --git a/fastmcp_slim/fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py b/fastmcp_slim/fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py index 24eecd9fb..2e865f85c 100644 --- a/fastmcp_slim/fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py +++ b/fastmcp_slim/fastmcp/utilities/mcp_server_config/v1/sources/filesystem.py @@ -117,7 +117,7 @@ class FileSystemSource(Source): The server object (or result of calling a factory function) """ # Avoid circular import by importing here - from mcp.server.mcpserver import MCPServer as FastMCP1x + from mcp.server.mcpserver import MCPServer as SDKServer from fastmcp.server.server import FastMCP @@ -154,7 +154,7 @@ class FileSystemSource(Source): for name in ["mcp", "server", "app"]: if hasattr(module, name): obj = getattr(module, name) - if isinstance(obj, FastMCP | FastMCP1x): + if isinstance(obj, FastMCP | SDKServer): return await self._resolve_factory(obj, file_path, name) # No server found @@ -178,7 +178,7 @@ class FileSystemSource(Source): A server instance """ # Avoid circular import by importing here - from mcp.server.mcpserver import MCPServer as FastMCP1x + from mcp.server.mcpserver import MCPServer as SDKServer from fastmcp.server.server import FastMCP @@ -195,7 +195,7 @@ class FileSystemSource(Source): server = obj() # Validate the result is a FastMCP server - if not isinstance(server, FastMCP | FastMCP1x): + if not isinstance(server, FastMCP | SDKServer): logger.error( f"Factory function '{name}' must return a FastMCP server instance, " f"got {type(server).__name__}", diff --git a/tests/cli/test_run.py b/tests/cli/test_run.py index 9ec876b92..c89c87b17 100644 --- a/tests/cli/test_run.py +++ b/tests/cli/test_run.py @@ -296,7 +296,7 @@ class TestV1ServerAsync: """Test that v1 server uses async stdio method.""" from unittest.mock import AsyncMock, patch - from mcp.server.mcpserver import MCPServer as FastMCP1x + from mcp.server.mcpserver import MCPServer as SDKServer from fastmcp.cli.run import run_command @@ -320,7 +320,7 @@ async def async_echo(text: str) -> str: # Mock the async run method with patch.object( - FastMCP1x, "run_stdio_async", new_callable=AsyncMock + SDKServer, "run_stdio_async", new_callable=AsyncMock ) as run_mock: await run_command(str(test_file), transport="stdio") run_mock.assert_called_once() @@ -329,7 +329,7 @@ async def async_echo(text: str) -> str: """Test that v1 server uses async http method.""" from unittest.mock import AsyncMock, patch - from mcp.server.mcpserver import MCPServer as FastMCP1x + from mcp.server.mcpserver import MCPServer as SDKServer from fastmcp.cli.run import run_command @@ -353,7 +353,7 @@ async def async_echo(text: str) -> str: # Mock the async run method with patch.object( - FastMCP1x, "run_streamable_http_async", new_callable=AsyncMock + SDKServer, "run_streamable_http_async", new_callable=AsyncMock ) as run_mock: await run_command(str(test_file), transport="http") run_mock.assert_called_once() @@ -362,7 +362,7 @@ async def async_echo(text: str) -> str: """Test that v1 server uses async streamable-http method.""" from unittest.mock import AsyncMock, patch - from mcp.server.mcpserver import MCPServer as FastMCP1x + from mcp.server.mcpserver import MCPServer as SDKServer from fastmcp.cli.run import run_command @@ -386,7 +386,7 @@ async def async_echo(text: str) -> str: # Mock the async run method with patch.object( - FastMCP1x, "run_streamable_http_async", new_callable=AsyncMock + SDKServer, "run_streamable_http_async", new_callable=AsyncMock ) as run_mock: await run_command(str(test_file), transport="streamable-http") run_mock.assert_called_once() @@ -395,7 +395,7 @@ async def async_echo(text: str) -> str: """Test that v1 server uses async sse method.""" from unittest.mock import AsyncMock, patch - from mcp.server.mcpserver import MCPServer as FastMCP1x + from mcp.server.mcpserver import MCPServer as SDKServer from fastmcp.cli.run import run_command @@ -419,7 +419,7 @@ async def async_echo(text: str) -> str: # Mock the async run method with patch.object( - FastMCP1x, "run_sse_async", new_callable=AsyncMock + SDKServer, "run_sse_async", new_callable=AsyncMock ) as run_mock: await run_command(str(test_file), transport="sse") run_mock.assert_called_once() @@ -428,7 +428,7 @@ async def async_echo(text: str) -> str: """Test that v1 server uses streamable-http by default.""" from unittest.mock import AsyncMock, patch - from mcp.server.mcpserver import MCPServer as FastMCP1x + from mcp.server.mcpserver import MCPServer as SDKServer from fastmcp.cli.run import run_command @@ -452,7 +452,7 @@ async def async_echo(text: str) -> str: # Mock the async run method with patch.object( - FastMCP1x, "run_streamable_http_async", new_callable=AsyncMock + SDKServer, "run_streamable_http_async", new_callable=AsyncMock ) as run_mock: await run_command(str(test_file)) run_mock.assert_called_once() @@ -461,7 +461,7 @@ async def async_echo(text: str) -> str: """Test that v1 server receives host/port settings.""" from unittest.mock import AsyncMock, patch - from mcp.server.mcpserver import MCPServer as FastMCP1x + from mcp.server.mcpserver import MCPServer as SDKServer from fastmcp.cli.run import run_command @@ -485,7 +485,7 @@ async def async_echo(text: str) -> str: # Mock the async run method with patch.object( - FastMCP1x, "run_streamable_http_async", new_callable=AsyncMock + SDKServer, "run_streamable_http_async", new_callable=AsyncMock ) as run_mock: await run_command( str(test_file), transport="http", host="0.0.0.0", port=9000 diff --git a/tests/utilities/test_inspect.py b/tests/utilities/test_inspect.py index 6e099a015..9b9b70d70 100644 --- a/tests/utilities/test_inspect.py +++ b/tests/utilities/test_inspect.py @@ -2,7 +2,7 @@ import importlib.metadata -from mcp.server.mcpserver import MCPServer as FastMCP1x +from mcp.server.mcpserver import MCPServer as SDKServer import fastmcp from fastmcp import Client, FastMCP @@ -467,7 +467,7 @@ class TestFastMCP1xCompatibility: async def test_fastmcp1x_empty_server(self): """Test get_fastmcp_info_v1 with an empty FastMCP1x server.""" - mcp = FastMCP1x("Test1x") + mcp = SDKServer("Test1x") info = await inspect_fastmcp_v1(mcp) @@ -485,7 +485,7 @@ class TestFastMCP1xCompatibility: async def test_fastmcp1x_with_tools(self): """Test get_fastmcp_info_v1 with a FastMCP1x server that has tools.""" - mcp = FastMCP1x("Test1x") + mcp = SDKServer("Test1x") @mcp.tool() def add_numbers(a: int, b: int) -> int: @@ -505,7 +505,7 @@ class TestFastMCP1xCompatibility: async def test_fastmcp1x_with_resources(self): """Test get_fastmcp_info_v1 with a FastMCP1x server that has resources.""" - mcp = FastMCP1x("Test1x") + mcp = SDKServer("Test1x") @mcp.resource("resource://data") def get_data() -> str: @@ -522,7 +522,7 @@ class TestFastMCP1xCompatibility: async def test_fastmcp1x_with_prompts(self): """Test get_fastmcp_info_v1 with a FastMCP1x server that has prompts.""" - mcp = FastMCP1x("Test1x") + mcp = SDKServer("Test1x") @mcp.prompt("analyze") def analyze_data(data: str) -> list: @@ -537,7 +537,7 @@ class TestFastMCP1xCompatibility: async def test_dispatcher_with_fastmcp1x(self): """Test that the main get_fastmcp_info function correctly dispatches to v1.""" - mcp = FastMCP1x("Test1x") + mcp = SDKServer("Test1x") @mcp.tool() def test_tool() -> str: @@ -569,7 +569,7 @@ class TestFastMCP1xCompatibility: async def test_fastmcp1x_vs_fastmcp2x_comparison(self): """Test that both versions can be inspected and compared.""" - mcp1x = FastMCP1x("Test1x") + mcp1x = SDKServer("Test1x") mcp2x = FastMCP("Test2x") @mcp1x.tool() diff --git a/tests/utilities/test_inspect_icons.py b/tests/utilities/test_inspect_icons.py index ce8b84aec..ecff87376 100644 --- a/tests/utilities/test_inspect_icons.py +++ b/tests/utilities/test_inspect_icons.py @@ -2,7 +2,7 @@ import importlib.metadata -from mcp.server.mcpserver import MCPServer as FastMCP1x +from mcp.server.mcpserver import MCPServer as SDKServer import fastmcp from fastmcp import FastMCP @@ -261,7 +261,7 @@ class TestIconExtraction: """Test that icons are extracted from FastMCP 1.x servers.""" from mcp_types import Icon - mcp = FastMCP1x("Icon1xServer") + mcp = SDKServer("Icon1xServer") @mcp.tool( icons=[Icon(src="https://example.com/v1-tool.png", mime_type="image/png")]