Skip to main content
Glama
alamkanak

FastAPI MCP OpenAPI

by alamkanak
test_integration.py7.2 kB
""" Integration tests for FastAPI MCP OpenAPI. """ import json from fastapi.testclient import TestClient from fastapi_mcp_openapi import FastAPIMCPOpenAPI class TestIntegration: """Integration tests for the complete functionality.""" def test_complete_workflow(self, complex_app): """Test complete workflow from initialization to MCP tool usage.""" # Initialize with custom configuration FastAPIMCPOpenAPI( app=complex_app, mount_path="/integration-mcp", server_name="Integration Test Server", server_version="1.0.0", ) client = TestClient(complex_app) # 1. Test health endpoint (app already has one, so check both work) response = client.get("/health") assert response.status_code == 200 health_data = response.json() # This should be the app's health endpoint assert health_data["status"] == "healthy" # 2. Test MCP server info response = client.get("/integration-mcp") assert response.status_code == 200 server_info = response.json() assert server_info["name"] == "Integration Test Server" # 3. Test tools list payload = {"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}} response = client.post("/integration-mcp", json=payload) assert response.status_code == 200 tools_data = response.json() assert len(tools_data["result"]["tools"]) == 2 # 4. Test list endpoints tool payload = { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "listEndpoints", "arguments": {}}, } response = client.post("/integration-mcp", json=payload) assert response.status_code == 200 endpoints_response = response.json() endpoints_text = endpoints_response["result"]["content"][0]["text"] result = json.loads(endpoints_text) endpoints = result["endpoints"] # Should have multiple endpoints from complex_app assert len(endpoints) >= 5 endpoint_paths = [e["path"] for e in endpoints] assert "/" in endpoint_paths assert "/users/{user_id}" in endpoint_paths # 5. Test get endpoint docs tool payload = { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "getEndpointDocs", "arguments": {"endpoint_path": "/users/{user_id}", "method": "GET"}, }, } response = client.post("/integration-mcp", json=payload) assert response.status_code == 200 docs_response = response.json() docs_text = docs_response["result"]["content"][0]["text"] docs = json.loads(docs_text) assert docs["path"] == "/users/{user_id}" assert docs["method"] == "GET" assert "operation" in docs assert "parameters" in docs["operation"] def test_error_handling_workflow(self, basic_app): """Test error handling in a complete workflow.""" FastAPIMCPOpenAPI(basic_app) client = TestClient(basic_app) # Test non-existent endpoint payload = { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "getEndpointDocs", "arguments": {"endpoint_path": "/nonexistent", "method": "GET"}, }, } response = client.post("/mcp", json=payload) assert response.status_code == 200 error_response = response.json() error_text = error_response["result"]["content"][0]["text"] error_data = json.loads(error_text) assert "error" in error_data assert "not found" in error_data["error"] assert "available_endpoints" in error_data def test_multiple_instances(self, basic_app, empty_app): """Test multiple MCP instances on different apps.""" # Create two different MCP instances FastAPIMCPOpenAPI(basic_app, mount_path="/mcp1", server_name="Server 1") FastAPIMCPOpenAPI(empty_app, mount_path="/mcp2", server_name="Server 2") # Test both instances work independently client1 = TestClient(basic_app) client2 = TestClient(empty_app) # Test first instance response1 = client1.get("/mcp1") assert response1.status_code == 200 data1 = response1.json() assert data1["name"] == "Server 1" # Test second instance response2 = client2.get("/mcp2") assert response2.status_code == 200 data2 = response2.json() assert data2["name"] == "Server 2" # List endpoints should return different results payload = { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "listEndpoints", "arguments": {}}, } response1 = client1.post("/mcp1", json=payload) response2 = client2.post("/mcp2", json=payload) result1 = json.loads(response1.json()["result"]["content"][0]["text"]) result2 = json.loads(response2.json()["result"]["content"][0]["text"]) endpoints1 = result1["endpoints"] endpoints2 = result2["endpoints"] # basic_app should have more endpoints than empty_app assert len(endpoints1) > len(endpoints2) def test_real_openapi_schema_resolution(self, basic_app): """Test with real OpenAPI schema that has references.""" # Add a more complex endpoint with Pydantic models from pydantic import BaseModel class UserResponse(BaseModel): id: int name: str email: str @basic_app.get("/complex-user/{user_id}", response_model=UserResponse) async def get_complex_user(user_id: int): """Get a complex user with full model.""" return UserResponse(id=user_id, name="Test", email="test@example.com") FastAPIMCPOpenAPI(basic_app) client = TestClient(basic_app) # Get docs for the complex endpoint payload = { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "getEndpointDocs", "arguments": { "endpoint_path": "/complex-user/{user_id}", "method": "GET", }, }, } response = client.post("/mcp", json=payload) assert response.status_code == 200 docs_text = response.json()["result"]["content"][0]["text"] docs = json.loads(docs_text) # Check that response schema is resolved assert "responses" in docs["operation"] response_200 = docs["operation"]["responses"]["200"] # The schema should be fully resolved (no $ref) content = response_200["content"]["application/json"]["schema"] assert "$ref" not in json.dumps(content) # No references should remain assert "properties" in content assert "id" in content["properties"]

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/alamkanak/fastapi-mcp-openapi'

If you have feedback or need assistance with the MCP directory API, please join our Discord server