--- title: OpenAPI Integration sidebarTitle: OpenAPI description: Generate MCP servers from OpenAPI specs icon: code-branch --- import { VersionBadge } from '/snippets/version-badge.mdx' FastMCP can automatically generate an MCP server from an OpenAPI specification. Users only need to provide an OpenAPI specification (3.0 or 3.1) and an API client. ```python import httpx from fastmcp import FastMCP # Create a client for your API api_client = httpx.AsyncClient(base_url="https://api.example.com") # Load your OpenAPI spec spec = {...} # Create an MCP server from your OpenAPI spec mcp = FastMCP.from_openapi(openapi_spec=spec, client=api_client) if __name__ == "__main__": mcp.run() ``` ## Configuration Options ### Timeout You can set a timeout for all requests by providing a `timeout` parameter (in seconds): ```python mcp = FastMCP.from_openapi( openapi_spec=spec, client=api_client, timeout=30.0 # 30 second timeout ) ``` ## Route Mapping By default, OpenAPI routes are mapped to MCP components based on these rules: | OpenAPI Route | Example |MCP Component | Notes | |- | - | - | - | | `GET` without path params | `GET /stats` | Resource | Simple resources for fetching data | | `GET` with path params | `GET /users/{id}` | Resource Template | Path parameters become template parameters | | `POST`, `PUT`, `PATCH`, `DELETE`, etc. | `POST /users` | Tool | Operations that modify data | Internally, FastMCP uses a priority-ordered set of `RouteMap` objects to determine the component type. Route maps indicate that a specific HTTP method (or methods) and path pattern should be treated as a specific component type. This is the default set of route maps: ```python # Simplified version of the actual mapping rules DEFAULT_ROUTE_MAPPINGS = [ # GET with path parameters -> ResourceTemplate RouteMap( methods=["GET"], pattern=r".*\{.*\}.*", mcp_type=MCPType.RESOURCE_TEMPLATE, ), # GET without path parameters -> Resource RouteMap( methods=["GET"], pattern=r".*", mcp_type=MCPType.RESOURCE, ), # All other methods -> Tool ALL_TOOLS(), ] ``` #### Custom Route Maps Users can add custom route maps to override the default mapping behavior. User-supplied route maps are always applied first, before the default route maps. ```python from fastmcp.server.openapi import RouteMap, MCPType # Custom mapping rules custom_maps = [ # Force all analytics endpoints to be Tools RouteMap(methods=["GET"], pattern=r"^/analytics/.*", mcp_type=MCPType.TOOL) ] # Apply custom mappings mcp = FastMCP.from_openapi( openapi_spec=spec, client=api_client, route_maps=custom_maps ) ``` For backward compatibility, FastMCP still supports the `route_type` parameter and `RouteType` enum, but they are deprecated and will be removed in a future version. You will see deprecation warnings if you use them. #### All Routes as Tools When building AI agent backends, it's often useful to treat all routes as callable tools regardless of their HTTP method. You can use the `ALL_TOOLS()` shortcut or create a custom route map: ```python # Make all endpoints tools using the shortcut mcp = FastMCP.from_openapi( openapi_spec=spec, client=api_client, route_maps=[ALL_TOOLS()] ) # Same effect using a custom route map mcp = FastMCP.from_openapi( openapi_spec=spec, client=api_client, route_maps=[ RouteMap(methods="*", pattern=r".*", mcp_type=MCPType.TOOL) ] ) ``` #### Excluding Routes If you want to exclude certain routes from being converted to MCP components, you can map them to `MCPType.EXCLUDE`. This is useful for endpoints that should not be accessible to the agent. ```python from fastmcp.server.openapi import RouteMap, MCPType # Custom mapping rules to exclude specific routes custom_maps = [ # Exclude all admin endpoints RouteMap( methods="*", pattern=r"^/admin/.*", mcp_type=MCPType.EXCLUDE ), # Exclude analytics GET endpoints RouteMap( methods=["GET"], pattern=r"^/analytics/.*", mcp_type=MCPType.EXCLUDE ) ] # Apply custom mappings mcp = FastMCP.from_openapi( openapi_spec=spec, client=api_client, route_maps=custom_maps ) ``` When a route is mapped to `MCPType.EXCLUDE`, FastMCP will log its presence but won't create any MCP component for it, effectively making it invisible to clients and agents using the MCP server. You can customize this behavior by providing a list of `RouteMap` objects: ```python from fastmcp.server.openapi import FastMCPOpenAPI, RouteMap, MCPType # Custom route mappings custom_mappings = [ # Convert all user-related routes to tools RouteMap( methods=["GET", "POST", "PUT", "DELETE"], pattern=r"^/users.*", mcp_type=MCPType.TOOL ), # Exclude analytics routes RouteMap( methods=["*"], # All methods pattern=r"^/analytics.*", mcp_type=MCPType.EXCLUDE ), ] # Create server with custom mappings mcp = FastMCPOpenAPI( openapi_spec=spec, client=httpx.AsyncClient(), route_maps=custom_mappings, ) ``` #### Route Map Shortcuts FastMCP provides several shortcut functions to create common route maps more easily: ```python from fastmcp.server.openapi import ( ALL_TOOLS, EXCLUDE_ALL, EXCLUDE_PATTERN, PATTERN_AS_TOOLS, ) # Create an MCP server with custom route maps using shortcuts mcp = FastMCP.from_openapi( openapi_spec=spec, client=api_client, route_maps=[ # First exclude all admin endpoints EXCLUDE_PATTERN(r"^/admin/.*"), # Make all /api/v1 endpoints tools PATTERN_AS_TOOLS(r"^/api/v1/.*"), # Make all remaining routes tools ALL_TOOLS(), ] ) ``` Available shortcuts: | Shortcut Function | Description | |------------------|-------------| | `ALL_TOOLS()` | Converts all matching routes to tools | | `EXCLUDE_ALL()` | Excludes all matching routes from being converted to any component | | `PATTERN_AS_TOOLS(pattern)` | Converts routes matching a specific pattern to tools | | `EXCLUDE_PATTERN(pattern)` | Excludes routes matching a specific pattern | These shortcuts are particularly useful for: 1. Converting all remaining unmatched routes to tools (use `ALL_TOOLS()`) 2. Excluding whole sections of your API (use `EXCLUDE_PATTERN("/path/.*")`) 3. Converting routes matching specific patterns to tools (use `PATTERN_AS_TOOLS("/path/.*")`) You can use `EXCLUDE_ALL()` as the last entry in your custom route maps to completely ignore the default route maps. Since custom route maps are applied first and default maps are appended afterward, having `EXCLUDE_ALL()` at the end of your custom maps will match any routes that your earlier custom rules didn't match, preventing the default maps from having any effect. ```python # Create server that only uses custom route maps, ignoring defaults mcp = FastMCP.from_openapi( openapi_spec=spec, client=api_client, route_maps=[ # Routes to keep as tools PATTERN_AS_TOOLS(r"^/api/v1/.*"), # Exclude everything else (ignores default route maps) EXCLUDE_ALL(), ] ) ``` ## How It Works 1. FastMCP parses your OpenAPI spec to extract routes and schemas 2. It applies mapping rules to categorize each route 3. When an MCP client calls a tool or accesses a resource: - FastMCP constructs an HTTP request based on the OpenAPI definition - It sends the request through the provided httpx client - It translates the HTTP response to the appropriate MCP format ### Request Parameter Handling FastMCP carefully handles different types of parameters in OpenAPI requests: #### Query Parameters By default, FastMCP will only include query parameters that have non-empty values. Parameters with `None` values or empty strings (`""`) are automatically filtered out of requests. This ensures that API servers don't receive unnecessary empty parameters that might cause issues. For example, if you call a tool with these parameters: ```python await client.call_tool("search_products", { "category": "electronics", # Will be included "min_price": 100, # Will be included "max_price": None, # Will be excluded "brand": "", # Will be excluded }) ``` The resulting HTTP request will only include `category=electronics&min_price=100`. #### Path Parameters For path parameters, which are typically required by REST APIs, FastMCP filters out `None` values and checks that all required path parameters are provided. If a required path parameter is missing or `None`, an error will be raised. ```python # This will work await client.call_tool("get_product", {"product_id": 123}) # This will raise ValueError: "Missing required path parameters: {'product_id'}" await client.call_tool("get_product", {"product_id": None}) ``` ## Example: Custom Authentication If your API requires authentication, you can set headers on the client: ```python import httpx from fastmcp import FastMCP # Create a client with authentication api_client = httpx.AsyncClient( base_url="https://api.example.com", headers={"Authorization": "Bearer YOUR_TOKEN"} ) # Create an MCP server from your OpenAPI spec mcp = FastMCP.from_openapi(openapi_spec=spec, client=api_client) ```