diff --git a/fastapi_mcp/openapi/convert.py b/fastapi_mcp/openapi/convert.py index 22e5c5e..5da1d5a 100644 --- a/fastapi_mcp/openapi/convert.py +++ b/fastapi_mcp/openapi/convert.py @@ -18,6 +18,7 @@ def convert_openapi_to_mcp_tools( openapi_schema: Dict[str, Any], describe_all_responses: bool = False, describe_full_response_schema: bool = False, + include_response_info: bool = True, ) -> Tuple[List[types.Tool], Dict[str, Dict[str, Any]]]: """ Convert OpenAPI operations to MCP tools. @@ -26,6 +27,7 @@ def convert_openapi_to_mcp_tools( openapi_schema: The OpenAPI schema describe_all_responses: Whether to include all possible response schemas in tool descriptions describe_full_response_schema: Whether to include full response schema in tool descriptions + include_response_info: Whether to include response information in tool descriptions Returns: A tuple containing: @@ -70,7 +72,7 @@ def convert_openapi_to_mcp_tools( # Add response information to the description responses = operation.get("responses", {}) - if responses: + if responses and include_response_info: response_info = "\n\n### Responses:\n" # Find the success response diff --git a/fastapi_mcp/server.py b/fastapi_mcp/server.py index bb75106..e5ff7e4 100644 --- a/fastapi_mcp/server.py +++ b/fastapi_mcp/server.py @@ -46,6 +46,10 @@ def __init__( bool, Doc("Whether to include full json schema for responses in tool descriptions"), ] = False, + include_response_info: Annotated[ + bool, + Doc("Whether to include response information in tool descriptions"), + ] = True, http_client: Annotated[ Optional[httpx.AsyncClient], Doc( @@ -103,6 +107,7 @@ def __init__( self._base_url = "http://apiserver" self._describe_all_responses = describe_all_responses self._describe_full_response_schema = describe_full_response_schema + self._include_response_info = include_response_info self._include_operations = include_operations self._exclude_operations = exclude_operations self._include_tags = include_tags @@ -136,6 +141,7 @@ def setup_server(self) -> None: openapi_schema, describe_all_responses=self._describe_all_responses, describe_full_response_schema=self._describe_full_response_schema, + include_response_info=self._include_response_info, ) # Filter tools based on operation IDs and tags diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 79e403e..b10fa6f 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -581,3 +581,84 @@ async def empty_tags(): exclude_tags_mcp = FastApiMCP(app, exclude_tags=["items"]) assert len(exclude_tags_mcp.tools) == 1 assert {tool.name for tool in exclude_tags_mcp.tools} == {"empty_tags"} + + +def test_include_response_info_default_behavior(simple_fastapi_app: FastAPI): + """Test the default behavior of include_response_info parameter.""" + mcp_server = FastApiMCP(simple_fastapi_app) + + # Check default value + assert mcp_server._include_response_info is True + + # Check that response information is included by default + for tool in mcp_server.tools: + assert tool.description is not None + if tool.name == "raise_error": + pass + elif tool.name != "delete_item": + assert "### Responses:" in tool.description, "Response section should be present" + assert "**200**" in tool.description, "200 status code should be present" + assert "**Example Response:**" in tool.description, "Example response should be present" + else: + # The delete endpoint returns 204 with no response body + assert "### Responses:" in tool.description, "Response section should be present" + assert "**204**" in tool.description, "204 status code should be present" + + +def test_include_response_info_false_simple_app(simple_fastapi_app: FastAPI): + """Test include_response_info=False with the simple app.""" + mcp_server = FastApiMCP(simple_fastapi_app, include_response_info=False) + + # Check that response information is excluded + for tool in mcp_server.tools: + assert tool.description is not None + assert "### Responses:" not in tool.description, "Response section should not be present" + assert "**200**" not in tool.description, "200 status code should not be present" + assert "**204**" not in tool.description, "204 status code should not be present" + assert "**Example Response:**" not in tool.description, "Example response should not be present" + assert "**Output Schema:**" not in tool.description, "Output schema should not be present" + + # Basic tool information should still be present + if tool.name == "list_items": + assert "List all items" in tool.description + elif tool.name == "get_item": + assert "Get a specific item" in tool.description + elif tool.name == "create_item": + assert "Create a new item" in tool.description + + +def test_include_response_info_combined_with_other_options(simple_fastapi_app: FastAPI): + """Test include_response_info combined with other response-related options.""" + # Test with include_response_info=False and describe_all_responses=True + mcp_server = FastApiMCP( + simple_fastapi_app, + include_response_info=False, + describe_all_responses=True, + describe_full_response_schema=True, + ) + + # Even with describe_all_responses=True and describe_full_response_schema=True, + # response information should be excluded when include_response_info=False + for tool in mcp_server.tools: + assert tool.description is not None + assert "### Responses:" not in tool.description, "Response section should not be present" + assert "**Example Response:**" not in tool.description, "Example response should not be present" + assert "**Output Schema:**" not in tool.description, "Output schema should not be present" + + +def test_include_response_info_true_explicit(simple_fastapi_app: FastAPI): + """Test include_response_info=True explicitly.""" + mcp_server = FastApiMCP(simple_fastapi_app, include_response_info=True) + + # Check that response information is included + for tool in mcp_server.tools: + assert tool.description is not None + if tool.name == "raise_error": + pass + elif tool.name != "delete_item": + assert "### Responses:" in tool.description, "Response section should be present" + assert "**200**" in tool.description, "200 status code should be present" + assert "**Example Response:**" in tool.description, "Example response should be present" + else: + assert "### Responses:" in tool.description, "Response section should be present" + assert "**204**" in tool.description, "204 status code should be present"