diff --git a/examples/mount_example.py b/examples/mount_example.py index 761689783..5e42b67a1 100644 --- a/examples/mount_example.py +++ b/examples/mount_example.py @@ -104,7 +104,7 @@ async def get_server_details(): print(f" - Imported from news app: {news_resources}") # Let's try to access resources using the prefixed URI - weather_data = await app._mcp_read_resource(uri="weather://weather/forecast") + weather_data = await app._read_resource_mcp(uri="weather://weather/forecast") print(f"\nWeather data from prefixed URI: {weather_data}") diff --git a/examples/serializer.py b/examples/serializer.py index 4ee5ca17a..ffd8ee117 100644 --- a/examples/serializer.py +++ b/examples/serializer.py @@ -21,7 +21,7 @@ def get_example_data() -> dict: async def example_usage(): - result = await server._mcp_call_tool("get_example_data", {}) + result = await server._call_tool_mcp("get_example_data", {}) print("Tool Result:") print(result) print("This is an example of using a custom serializer with FastMCP.") diff --git a/src/fastmcp/prompts/prompt_manager.py b/src/fastmcp/prompts/prompt_manager.py index ab1a944e2..56da9289c 100644 --- a/src/fastmcp/prompts/prompt_manager.py +++ b/src/fastmcp/prompts/prompt_manager.py @@ -46,21 +46,23 @@ class PromptManager: """Adds a mounted server as a source for prompts.""" self._mounted_servers.append(server) - async def _load_prompts(self, *, via_server: bool = False) -> dict[str, Prompt]: + async def _load_prompts( + self, *, apply_filtering: bool = False + ) -> dict[str, Prompt]: """ - The single, consolidated recursive method for fetching prompts. The 'via_server' + The single, consolidated recursive method for fetching prompts. The 'apply_filtering' parameter determines the communication path. - - via_server=False: Manager-to-manager path for complete, unfiltered inventory - - via_server=True: Server-to-server path for filtered MCP requests + - apply_filtering=False: Manager-to-manager path for complete, unfiltered inventory + - apply_filtering=True: Server-to-server path for filtered MCP requests """ all_prompts: dict[str, Prompt] = {} for mounted in self._mounted_servers: try: - if via_server: + if apply_filtering: # Use the server-to-server filtered path - child_results = await mounted.server._list_prompts() + child_results = await mounted.server._list_prompts_middleware() else: # Use the manager-to-manager unfiltered path child_results = await mounted.server._prompt_manager.list_prompts() @@ -104,13 +106,13 @@ class PromptManager: """ Gets the complete, unfiltered inventory of all prompts. """ - return await self._load_prompts(via_server=False) + return await self._load_prompts(apply_filtering=False) async def list_prompts(self) -> list[Prompt]: """ Lists all prompts, applying protocol filtering. """ - prompts_dict = await self._load_prompts(via_server=True) + prompts_dict = await self._load_prompts(apply_filtering=True) return list(prompts_dict.values()) def add_prompt_from_fn( @@ -196,7 +198,9 @@ class PromptManager: else: continue try: - return await mounted.server._get_prompt(prompt_key, arguments) + return await mounted.server._get_prompt_middleware( + prompt_key, arguments + ) except NotFoundError: continue diff --git a/src/fastmcp/resources/resource_manager.py b/src/fastmcp/resources/resource_manager.py index c646c71aa..d66a49ccf 100644 --- a/src/fastmcp/resources/resource_manager.py +++ b/src/fastmcp/resources/resource_manager.py @@ -63,27 +63,31 @@ class ResourceManager: async def get_resources(self) -> dict[str, Resource]: """Get all registered resources, keyed by URI.""" - return await self._load_resources(via_server=False) + return await self._load_resources(apply_filtering=False) async def get_resource_templates(self) -> dict[str, ResourceTemplate]: """Get all registered templates, keyed by URI template.""" - return await self._load_resource_templates(via_server=False) + return await self._load_resource_templates(apply_filtering=False) - async def _load_resources(self, *, via_server: bool = False) -> dict[str, Resource]: + async def _load_resources( + self, *, apply_filtering: bool = False + ) -> dict[str, Resource]: """ - The single, consolidated recursive method for fetching resources. The 'via_server' + The single, consolidated recursive method for fetching resources. The 'apply_filtering' parameter determines the communication path. - - via_server=False: Manager-to-manager path for complete, unfiltered inventory - - via_server=True: Server-to-server path for filtered MCP requests + - apply_filtering=False: Manager-to-manager path for complete, unfiltered inventory + - apply_filtering=True: Server-to-server path for filtered MCP requests """ all_resources: dict[str, Resource] = {} for mounted in self._mounted_servers: try: - if via_server: + if apply_filtering: # Use the server-to-server filtered path - child_resources_list = await mounted.server._list_resources() + child_resources_list = ( + await mounted.server._list_resources_middleware() + ) child_resources = { resource.key: resource for resource in child_resources_list } @@ -123,22 +127,24 @@ class ResourceManager: return all_resources async def _load_resource_templates( - self, *, via_server: bool = False + self, *, apply_filtering: bool = False ) -> dict[str, ResourceTemplate]: """ - The single, consolidated recursive method for fetching templates. The 'via_server' + The single, consolidated recursive method for fetching templates. The 'apply_filtering' parameter determines the communication path. - - via_server=False: Manager-to-manager path for complete, unfiltered inventory - - via_server=True: Server-to-server path for filtered MCP requests + - apply_filtering=False: Manager-to-manager path for complete, unfiltered inventory + - apply_filtering=True: Server-to-server path for filtered MCP requests """ all_templates: dict[str, ResourceTemplate] = {} for mounted in self._mounted_servers: try: - if via_server: + if apply_filtering: # Use the server-to-server filtered path - child_templates = await mounted.server._list_resource_templates() + child_templates = ( + await mounted.server._list_resource_templates_middleware() + ) else: # Use the manager-to-manager unfiltered path child_templates = ( @@ -179,14 +185,14 @@ class ResourceManager: """ Lists all resources, applying protocol filtering. """ - resources_dict = await self._load_resources(via_server=True) + resources_dict = await self._load_resources(apply_filtering=True) return list(resources_dict.values()) async def list_resource_templates(self) -> list[ResourceTemplate]: """ Lists all templates, applying protocol filtering. """ - templates_dict = await self._load_resource_templates(via_server=True) + templates_dict = await self._load_resource_templates(apply_filtering=True) return list(templates_dict.values()) def add_resource_or_template_from_fn( @@ -492,7 +498,7 @@ class ResourceManager: continue try: - result = await mounted.server._read_resource(key) + result = await mounted.server._read_resource_middleware(key) return result[0].content except NotFoundError: continue diff --git a/src/fastmcp/server/context.py b/src/fastmcp/server/context.py index 7e46d0f8d..c1b39b805 100644 --- a/src/fastmcp/server/context.py +++ b/src/fastmcp/server/context.py @@ -205,7 +205,7 @@ class Context: """ if self.fastmcp is None: raise ValueError("Context is not available outside of a request") - return await self.fastmcp._mcp_read_resource(uri) + return await self.fastmcp._read_resource_mcp(uri) async def log( self, diff --git a/src/fastmcp/server/server.py b/src/fastmcp/server/server.py index 489561166..22b434d06 100644 --- a/src/fastmcp/server/server.py +++ b/src/fastmcp/server/server.py @@ -386,13 +386,13 @@ class FastMCP(Generic[LifespanResultT]): def _setup_handlers(self) -> None: """Set up core MCP protocol handlers.""" - self._mcp_server.list_tools()(self._mcp_list_tools) - self._mcp_server.list_resources()(self._mcp_list_resources) - self._mcp_server.list_resource_templates()(self._mcp_list_resource_templates) - self._mcp_server.list_prompts()(self._mcp_list_prompts) - self._mcp_server.call_tool()(self._mcp_call_tool) - self._mcp_server.read_resource()(self._mcp_read_resource) - self._mcp_server.get_prompt()(self._mcp_get_prompt) + self._mcp_server.list_tools()(self._list_tools_mcp) + self._mcp_server.list_resources()(self._list_resources_mcp) + self._mcp_server.list_resource_templates()(self._list_resource_templates_mcp) + self._mcp_server.list_prompts()(self._list_prompts_mcp) + self._mcp_server.call_tool()(self._call_tool_mcp) + self._mcp_server.read_resource()(self._read_resource_mcp) + self._mcp_server.get_prompt()(self._get_prompt_mcp) async def _apply_middleware( self, @@ -519,11 +519,15 @@ class FastMCP(Generic[LifespanResultT]): return routes - async def _mcp_list_tools(self) -> list[MCPTool]: + async def _list_tools_mcp(self) -> list[MCPTool]: + """ + List all available tools, in the format expected by the low-level MCP + server. + """ logger.debug(f"[{self.name}] Handler called: list_tools") async with fastmcp.server.context.Context(fastmcp=self): - tools = await self._list_tools() + tools = await self._list_tools_middleware() return [ tool.to_mcp_tool( name=tool.key, @@ -532,24 +536,11 @@ class FastMCP(Generic[LifespanResultT]): for tool in tools ] - async def _list_tools(self) -> list[Tool]: + async def _list_tools_middleware(self) -> list[Tool]: """ - List all available tools, in the format expected by the low-level MCP - server. + List all available tools, applying MCP middleware. """ - async def _handler( - context: MiddlewareContext[mcp.types.ListToolsRequest], - ) -> list[Tool]: - tools = await self._tool_manager.list_tools() # type: ignore[reportPrivateUsage] - - mcp_tools: list[Tool] = [] - for tool in tools: - if self._should_enable_component(tool): - mcp_tools.append(tool) - - return mcp_tools - async with fastmcp.server.context.Context(fastmcp=self) as fastmcp_ctx: # Create the middleware context. mw_context = MiddlewareContext( @@ -561,13 +552,33 @@ class FastMCP(Generic[LifespanResultT]): ) # Apply the middleware chain. - return await self._apply_middleware(mw_context, _handler) + return await self._apply_middleware(mw_context, self._list_tools) - async def _mcp_list_resources(self) -> list[MCPResource]: + async def _list_tools( + self, + context: MiddlewareContext[mcp.types.ListToolsRequest], + ) -> list[Tool]: + """ + List all available tools + """ + tools = await self._tool_manager.list_tools() # type: ignore[reportPrivateUsage] + + mcp_tools: list[Tool] = [] + for tool in tools: + if self._should_enable_component(tool): + mcp_tools.append(tool) + + return mcp_tools + + async def _list_resources_mcp(self) -> list[MCPResource]: + """ + List all available resources, in the format expected by the low-level MCP + server. + """ logger.debug(f"[{self.name}] Handler called: list_resources") async with fastmcp.server.context.Context(fastmcp=self): - resources = await self._list_resources() + resources = await self._list_resources_middleware() return [ resource.to_mcp_resource( uri=resource.key, @@ -576,25 +587,11 @@ class FastMCP(Generic[LifespanResultT]): for resource in resources ] - async def _list_resources(self) -> list[Resource]: + async def _list_resources_middleware(self) -> list[Resource]: """ - List all available resources, in the format expected by the low-level MCP - server. - + List all available resources, applying MCP middleware. """ - async def _handler( - context: MiddlewareContext[dict[str, Any]], - ) -> list[Resource]: - resources = await self._resource_manager.list_resources() # type: ignore[reportPrivateUsage] - - mcp_resources: list[Resource] = [] - for resource in resources: - if self._should_enable_component(resource): - mcp_resources.append(resource) - - return mcp_resources - async with fastmcp.server.context.Context(fastmcp=self) as fastmcp_ctx: # Create the middleware context. mw_context = MiddlewareContext( @@ -606,13 +603,33 @@ class FastMCP(Generic[LifespanResultT]): ) # Apply the middleware chain. - return await self._apply_middleware(mw_context, _handler) + return await self._apply_middleware(mw_context, self._list_resources) - async def _mcp_list_resource_templates(self) -> list[MCPResourceTemplate]: + async def _list_resources( + self, + context: MiddlewareContext[dict[str, Any]], + ) -> list[Resource]: + """ + List all available resources + """ + resources = await self._resource_manager.list_resources() # type: ignore[reportPrivateUsage] + + mcp_resources: list[Resource] = [] + for resource in resources: + if self._should_enable_component(resource): + mcp_resources.append(resource) + + return mcp_resources + + async def _list_resource_templates_mcp(self) -> list[MCPResourceTemplate]: + """ + List all available resource templates, in the format expected by the low-level MCP + server. + """ logger.debug(f"[{self.name}] Handler called: list_resource_templates") async with fastmcp.server.context.Context(fastmcp=self): - templates = await self._list_resource_templates() + templates = await self._list_resource_templates_middleware() return [ template.to_mcp_template( uriTemplate=template.key, @@ -621,25 +638,12 @@ class FastMCP(Generic[LifespanResultT]): for template in templates ] - async def _list_resource_templates(self) -> list[ResourceTemplate]: + async def _list_resource_templates_middleware(self) -> list[ResourceTemplate]: """ - List all available resource templates, in the format expected by the low-level MCP - server. + List all available resource templates, applying MCP middleware. """ - async def _handler( - context: MiddlewareContext[dict[str, Any]], - ) -> list[ResourceTemplate]: - templates = await self._resource_manager.list_resource_templates() - - mcp_templates: list[ResourceTemplate] = [] - for template in templates: - if self._should_enable_component(template): - mcp_templates.append(template) - - return mcp_templates - async with fastmcp.server.context.Context(fastmcp=self) as fastmcp_ctx: # Create the middleware context. mw_context = MiddlewareContext( @@ -651,13 +655,35 @@ class FastMCP(Generic[LifespanResultT]): ) # Apply the middleware chain. - return await self._apply_middleware(mw_context, _handler) + return await self._apply_middleware( + mw_context, self._list_resource_templates + ) - async def _mcp_list_prompts(self) -> list[MCPPrompt]: + async def _list_resource_templates( + self, + context: MiddlewareContext[dict[str, Any]], + ) -> list[ResourceTemplate]: + """ + List all available resource templates + """ + templates = await self._resource_manager.list_resource_templates() # type: ignore[reportPrivateUsage] + + mcp_templates: list[ResourceTemplate] = [] + for template in templates: + if self._should_enable_component(template): + mcp_templates.append(template) + + return mcp_templates + + async def _list_prompts_mcp(self) -> list[MCPPrompt]: + """ + List all available prompts, in the format expected by the low-level MCP + server. + """ logger.debug(f"[{self.name}] Handler called: list_prompts") async with fastmcp.server.context.Context(fastmcp=self): - prompts = await self._list_prompts() + prompts = await self._list_prompts_middleware() return [ prompt.to_mcp_prompt( name=prompt.key, @@ -666,25 +692,12 @@ class FastMCP(Generic[LifespanResultT]): for prompt in prompts ] - async def _list_prompts(self) -> list[Prompt]: + async def _list_prompts_middleware(self) -> list[Prompt]: """ - List all available prompts, in the format expected by the low-level MCP - server. + List all available prompts, applying MCP middleware. """ - async def _handler( - context: MiddlewareContext[mcp.types.ListPromptsRequest], - ) -> list[Prompt]: - prompts = await self._prompt_manager.list_prompts() # type: ignore[reportPrivateUsage] - - mcp_prompts: list[Prompt] = [] - for prompt in prompts: - if self._should_enable_component(prompt): - mcp_prompts.append(prompt) - - return mcp_prompts - async with fastmcp.server.context.Context(fastmcp=self) as fastmcp_ctx: # Create the middleware context. mw_context = MiddlewareContext( @@ -696,9 +709,25 @@ class FastMCP(Generic[LifespanResultT]): ) # Apply the middleware chain. - return await self._apply_middleware(mw_context, _handler) + return await self._apply_middleware(mw_context, self._list_prompts) - async def _mcp_call_tool( + async def _list_prompts( + self, + context: MiddlewareContext[mcp.types.ListPromptsRequest], + ) -> list[Prompt]: + """ + List all available prompts + """ + prompts = await self._prompt_manager.list_prompts() # type: ignore[reportPrivateUsage] + + mcp_prompts: list[Prompt] = [] + for prompt in prompts: + if self._should_enable_component(prompt): + mcp_prompts.append(prompt) + + return mcp_prompts + + async def _call_tool_mcp( self, key: str, arguments: dict[str, Any] ) -> list[ContentBlock] | tuple[list[ContentBlock], dict[str, Any]]: """ @@ -719,29 +748,22 @@ class FastMCP(Generic[LifespanResultT]): async with fastmcp.server.context.Context(fastmcp=self): try: - result = await self._call_tool(key, arguments) + result = await self._call_tool_middleware(key, arguments) return result.to_mcp_result() except DisabledError: raise NotFoundError(f"Unknown tool: {key}") except NotFoundError: raise NotFoundError(f"Unknown tool: {key}") - async def _call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult: + async def _call_tool_middleware( + self, + key: str, + arguments: dict[str, Any], + ) -> ToolResult: """ Applies this server's middleware and delegates the filtered call to the manager. """ - async def _handler( - context: MiddlewareContext[mcp.types.CallToolRequestParams], - ) -> ToolResult: - tool = await self._tool_manager.get_tool(context.message.name) - if not self._should_enable_component(tool): - raise NotFoundError(f"Unknown tool: {context.message.name!r}") - - return await self._tool_manager.call_tool( - key=context.message.name, arguments=context.message.arguments or {} - ) - mw_context = MiddlewareContext[CallToolRequestParams]( message=mcp.types.CallToolRequestParams(name=key, arguments=arguments), source="client", @@ -749,9 +771,24 @@ class FastMCP(Generic[LifespanResultT]): method="tools/call", fastmcp_context=fastmcp.server.dependencies.get_context(), ) - return await self._apply_middleware(mw_context, _handler) + return await self._apply_middleware(mw_context, self._call_tool) - async def _mcp_read_resource(self, uri: AnyUrl | str) -> list[ReadResourceContents]: + async def _call_tool( + self, + context: MiddlewareContext[mcp.types.CallToolRequestParams], + ) -> ToolResult: + """ + Call a tool + """ + tool = await self._tool_manager.get_tool(context.message.name) + if not self._should_enable_component(tool): + raise NotFoundError(f"Unknown tool: {context.message.name!r}") + + return await self._tool_manager.call_tool( + key=context.message.name, arguments=context.message.arguments or {} + ) + + async def _read_resource_mcp(self, uri: AnyUrl | str) -> list[ReadResourceContents]: """ Handle MCP 'readResource' requests. @@ -761,7 +798,7 @@ class FastMCP(Generic[LifespanResultT]): async with fastmcp.server.context.Context(fastmcp=self): try: - return await self._read_resource(uri) + return await self._read_resource_middleware(uri) except DisabledError: # convert to NotFoundError to avoid leaking resource presence raise NotFoundError(f"Unknown resource: {str(uri)!r}") @@ -769,26 +806,14 @@ class FastMCP(Generic[LifespanResultT]): # standardize NotFound message raise NotFoundError(f"Unknown resource: {str(uri)!r}") - async def _read_resource(self, uri: AnyUrl | str) -> list[ReadResourceContents]: + async def _read_resource_middleware( + self, + uri: AnyUrl | str, + ) -> list[ReadResourceContents]: """ Applies this server's middleware and delegates the filtered call to the manager. """ - async def _handler( - context: MiddlewareContext[mcp.types.ReadResourceRequestParams], - ) -> list[ReadResourceContents]: - resource = await self._resource_manager.get_resource(context.message.uri) - if not self._should_enable_component(resource): - raise NotFoundError(f"Unknown resource: {str(context.message.uri)!r}") - - content = await self._resource_manager.read_resource(context.message.uri) - return [ - ReadResourceContents( - content=content, - mime_type=resource.mime_type, - ) - ] - # Convert string URI to AnyUrl if needed if isinstance(uri, str): uri_param = AnyUrl(uri) @@ -802,9 +827,28 @@ class FastMCP(Generic[LifespanResultT]): method="resources/read", fastmcp_context=fastmcp.server.dependencies.get_context(), ) - return await self._apply_middleware(mw_context, _handler) + return await self._apply_middleware(mw_context, self._read_resource) - async def _mcp_get_prompt( + async def _read_resource( + self, + context: MiddlewareContext[mcp.types.ReadResourceRequestParams], + ) -> list[ReadResourceContents]: + """ + Read a resource + """ + resource = await self._resource_manager.get_resource(context.message.uri) + if not self._should_enable_component(resource): + raise NotFoundError(f"Unknown resource: {str(context.message.uri)!r}") + + content = await self._resource_manager.read_resource(context.message.uri) + return [ + ReadResourceContents( + content=content, + mime_type=resource.mime_type, + ) + ] + + async def _get_prompt_mcp( self, name: str, arguments: dict[str, Any] | None = None ) -> GetPromptResult: """ @@ -820,7 +864,7 @@ class FastMCP(Generic[LifespanResultT]): async with fastmcp.server.context.Context(fastmcp=self): try: - return await self._get_prompt(name, arguments) + return await self._get_prompt_middleware(name, arguments) except DisabledError: # convert to NotFoundError to avoid leaking prompt presence raise NotFoundError(f"Unknown prompt: {name}") @@ -828,24 +872,13 @@ class FastMCP(Generic[LifespanResultT]): # standardize NotFound message raise NotFoundError(f"Unknown prompt: {name}") - async def _get_prompt( + async def _get_prompt_middleware( self, name: str, arguments: dict[str, Any] | None = None ) -> GetPromptResult: """ Applies this server's middleware and delegates the filtered call to the manager. """ - async def _handler( - context: MiddlewareContext[mcp.types.GetPromptRequestParams], - ) -> GetPromptResult: - prompt = await self._prompt_manager.get_prompt(context.message.name) - if not self._should_enable_component(prompt): - raise NotFoundError(f"Unknown prompt: {context.message.name!r}") - - return await self._prompt_manager.render_prompt( - name=context.message.name, arguments=context.message.arguments - ) - mw_context = MiddlewareContext( message=mcp.types.GetPromptRequestParams(name=name, arguments=arguments), source="client", @@ -853,7 +886,19 @@ class FastMCP(Generic[LifespanResultT]): method="prompts/get", fastmcp_context=fastmcp.server.dependencies.get_context(), ) - return await self._apply_middleware(mw_context, _handler) + return await self._apply_middleware(mw_context, self._get_prompt) + + async def _get_prompt( + self, + context: MiddlewareContext[mcp.types.GetPromptRequestParams], + ) -> GetPromptResult: + prompt = await self._prompt_manager.get_prompt(context.message.name) + if not self._should_enable_component(prompt): + raise NotFoundError(f"Unknown prompt: {context.message.name!r}") + + return await self._prompt_manager.render_prompt( + name=context.message.name, arguments=context.message.arguments + ) def add_tool(self, tool: Tool) -> Tool: """Add a tool to the server. diff --git a/src/fastmcp/tools/tool_manager.py b/src/fastmcp/tools/tool_manager.py index a40a9877c..02797f55f 100644 --- a/src/fastmcp/tools/tool_manager.py +++ b/src/fastmcp/tools/tool_manager.py @@ -52,21 +52,21 @@ class ToolManager: """Adds a mounted server as a source for tools.""" self._mounted_servers.append(server) - async def _load_tools(self, *, via_server: bool = False) -> dict[str, Tool]: + async def _load_tools(self, *, apply_filtering: bool = False) -> dict[str, Tool]: """ - The single, consolidated recursive method for fetching tools. The 'via_server' + The single, consolidated recursive method for fetching tools. The 'apply_filtering' parameter determines the communication path. - - via_server=False: Manager-to-manager path for complete, unfiltered inventory - - via_server=True: Server-to-server path for filtered MCP requests + - apply_filtering=False: Manager-to-manager path for complete, unfiltered inventory + - apply_filtering=True: Server-to-server path for filtered MCP requests """ all_tools: dict[str, Tool] = {} for mounted in self._mounted_servers: try: - if via_server: + if apply_filtering: # Use the server-to-server filtered path - child_results = await mounted.server._list_tools() + child_results = await mounted.server._list_tools_middleware() else: # Use the manager-to-manager unfiltered path child_results = await mounted.server._tool_manager.list_tools() @@ -116,13 +116,13 @@ class ToolManager: """ Gets the complete, unfiltered inventory of all tools. """ - return await self._load_tools(via_server=False) + return await self._load_tools(apply_filtering=False) async def list_tools(self) -> list[Tool]: """ Lists all tools, applying protocol filtering. """ - tools_dict = await self._load_tools(via_server=True) + tools_dict = await self._load_tools(apply_filtering=True) return list(tools_dict.values()) @property @@ -247,7 +247,7 @@ class ToolManager: else: continue try: - return await mounted.server._call_tool(tool_key, arguments) + return await mounted.server._call_tool_middleware(tool_key, arguments) except NotFoundError: continue diff --git a/tests/server/http/test_custom_routes.py b/tests/server/http/test_custom_routes.py index c43444756..d0a757be4 100644 --- a/tests/server/http/test_custom_routes.py +++ b/tests/server/http/test_custom_routes.py @@ -19,7 +19,7 @@ class TestCustomRoutes: return server - def test_custom_routes_via_server_http_app(self, server_with_custom_route): + def test_custom_routes_apply_filtering_http_app(self, server_with_custom_route): """Test that custom routes are included when using server.http_app().""" # Get the app via server.http_app() app = server_with_custom_route.http_app() diff --git a/tests/server/openapi/test_openapi_path_parameters.py b/tests/server/openapi/test_openapi_path_parameters.py index a9ec8348d..db782b938 100644 --- a/tests/server/openapi/test_openapi_path_parameters.py +++ b/tests/server/openapi/test_openapi_path_parameters.py @@ -163,7 +163,7 @@ async def test_integration_array_path_parameter(array_path_spec, mock_client): mcp = FastMCP.from_openapi(array_path_spec, client=mock_client) # Call the tool with a single value - await mcp._mcp_call_tool("test_operation", {"days": ["monday"]}) + await mcp._call_tool_mcp("test_operation", {"days": ["monday"]}) # Check the request was made correctly mock_client.request.assert_called_with( @@ -177,7 +177,7 @@ async def test_integration_array_path_parameter(array_path_spec, mock_client): mock_client.request.reset_mock() # Call the tool with multiple values - await mcp._mcp_call_tool("test_operation", {"days": ["monday", "tuesday"]}) + await mcp._call_tool_mcp("test_operation", {"days": ["monday", "tuesday"]}) # Check the request was made correctly mock_client.request.assert_called_with( diff --git a/tests/server/proxy/test_proxy_server.py b/tests/server/proxy/test_proxy_server.py index 561353084..fd82a7f9b 100644 --- a/tests/server/proxy/test_proxy_server.py +++ b/tests/server/proxy/test_proxy_server.py @@ -173,15 +173,15 @@ class TestTools: async def test_list_tools_same_as_original(self, fastmcp_server, proxy_server): assert ( - await proxy_server._mcp_list_tools() - == await fastmcp_server._mcp_list_tools() + await proxy_server._list_tools_mcp() + == await fastmcp_server._list_tools_mcp() ) async def test_call_tool_result_same_as_original( self, fastmcp_server: FastMCP, proxy_server: FastMCPProxy ): - result = await fastmcp_server._mcp_call_tool("greet", {"name": "Alice"}) - proxy_result = await proxy_server._mcp_call_tool("greet", {"name": "Alice"}) + result = await fastmcp_server._call_tool_mcp("greet", {"name": "Alice"}) + proxy_result = await proxy_server._call_tool_mcp("greet", {"name": "Alice"}) assert result == proxy_result @@ -267,8 +267,8 @@ class TestResources: async def test_list_resources_same_as_original(self, fastmcp_server, proxy_server): assert ( - await proxy_server._mcp_list_resources() - == await fastmcp_server._mcp_list_resources() + await proxy_server._list_resources_mcp() + == await fastmcp_server._list_resources_mcp() ) async def test_read_resource(self, proxy_server: FastMCPProxy): @@ -367,8 +367,8 @@ class TestResourceTemplates: async def test_list_resource_templates_same_as_original( self, fastmcp_server, proxy_server ): - result = await fastmcp_server._mcp_list_resource_templates() - proxy_result = await proxy_server._mcp_list_resource_templates() + result = await fastmcp_server._list_resource_templates_mcp() + proxy_result = await proxy_server._list_resource_templates_mcp() assert proxy_result == result @pytest.mark.parametrize("id", [1, 2, 3]) diff --git a/tests/server/test_file_server.py b/tests/server/test_file_server.py index c10b44519..592803d78 100644 --- a/tests/server/test_file_server.py +++ b/tests/server/test_file_server.py @@ -74,7 +74,7 @@ def tools(mcp: FastMCP, test_dir: Path) -> FastMCP: async def test_list_resources(mcp: FastMCP): - resources = await mcp._mcp_list_resources() + resources = await mcp._list_resources_mcp() assert len(resources) == 4 assert [str(r.uri) for r in resources] == [ @@ -86,7 +86,7 @@ async def test_list_resources(mcp: FastMCP): async def test_read_resource_dir(mcp: FastMCP): - res_iter = await mcp._mcp_read_resource("dir://test_dir") + res_iter = await mcp._read_resource_mcp("dir://test_dir") res_list = list(res_iter) assert len(res_list) == 1 res = res_list[0] @@ -102,7 +102,7 @@ async def test_read_resource_dir(mcp: FastMCP): async def test_read_resource_file(mcp: FastMCP): - res_iter = await mcp._mcp_read_resource("file://test_dir/example.py") + res_iter = await mcp._read_resource_mcp("file://test_dir/example.py") res_list = list(res_iter) assert len(res_list) == 1 res = res_list[0] @@ -110,17 +110,17 @@ async def test_read_resource_file(mcp: FastMCP): async def test_delete_file(mcp: FastMCP, test_dir: Path): - await mcp._mcp_call_tool( + await mcp._call_tool_mcp( "delete_file", arguments=dict(path=str(test_dir / "example.py")) ) assert not (test_dir / "example.py").exists() async def test_delete_file_and_check_resources(mcp: FastMCP, test_dir: Path): - await mcp._mcp_call_tool( + await mcp._call_tool_mcp( "delete_file", arguments=dict(path=str(test_dir / "example.py")) ) - res_iter = await mcp._mcp_read_resource("file://test_dir/example.py") + res_iter = await mcp._read_resource_mcp("file://test_dir/example.py") res_list = list(res_iter) assert len(res_list) == 1 res = res_list[0] diff --git a/tests/server/test_server.py b/tests/server/test_server.py index af0b9dcd8..819cb2146 100644 --- a/tests/server/test_server.py +++ b/tests/server/test_server.py @@ -76,7 +76,7 @@ class TestTools: def fn(x: int) -> int: return x + 1 - mcp_tools = await mcp._mcp_list_tools() + mcp_tools = await mcp._list_tools_mcp() assert len(mcp_tools) == 1 assert mcp_tools[0].name == "fn" @@ -89,7 +89,7 @@ class TestTools: def fn(x: int) -> int: return x + 1 - mcp_tools = await mcp._mcp_list_tools() + mcp_tools = await mcp._list_tools_mcp() assert len(mcp_tools) == 1 assert mcp_tools[0].name == "custom_name" @@ -110,7 +110,7 @@ class TestTools: assert "adder" not in mcp_tools with pytest.raises(NotFoundError, match="Unknown tool: adder"): - await mcp._mcp_call_tool("adder", {"a": 1, "b": 2}) + await mcp._call_tool_mcp("adder", {"a": 1, "b": 2}) async def test_add_tool_at_init(self): def f(x: int) -> int: @@ -136,7 +136,7 @@ class TestToolDecorator: mcp = FastMCP() with pytest.raises(NotFoundError, match="Unknown tool: add"): - await mcp._mcp_call_tool("add", {"x": 1, "y": 2}) + await mcp._call_tool_mcp("add", {"x": 1, "y": 2}) async def test_tool_decorator(self): mcp = FastMCP() @@ -185,7 +185,7 @@ class TestToolDecorator: def add(x: int, y: int) -> int: return x + y - tools = await mcp._mcp_list_tools() + tools = await mcp._list_tools_mcp() assert len(tools) == 1 tool = tools[0] assert tool.description == "Add two numbers" diff --git a/tests/server/test_tool_annotations.py b/tests/server/test_tool_annotations.py index d0f03876c..cbe47465b 100644 --- a/tests/server/test_tool_annotations.py +++ b/tests/server/test_tool_annotations.py @@ -47,7 +47,7 @@ async def test_tool_annotations_in_mcp_protocol(): return message # Check via MCP protocol - mcp_tools = await mcp._mcp_list_tools() + mcp_tools = await mcp._list_tools_mcp() assert len(mcp_tools) == 1 assert mcp_tools[0].annotations is not None assert mcp_tools[0].annotations.title == "Echo Tool" diff --git a/tests/server/test_tool_transformation.py b/tests/server/test_tool_transformation.py index 977d4abab..a35289fc1 100644 --- a/tests/server/test_tool_transformation.py +++ b/tests/server/test_tool_transformation.py @@ -29,14 +29,14 @@ async def test_transformed_tool_filtering(): """Echo back the message provided.""" return message - tools = list(await mcp._list_tools()) + tools = list(await mcp._list_tools_middleware()) assert len(tools) == 0 mcp.add_tool_transformation( "echo", ToolTransformConfig(name="echo_transformed", tags={"enabled_tools"}) ) - tools = list(await mcp._list_tools()) + tools = list(await mcp._list_tools_middleware()) assert len(tools) == 1