File size: 4,696 Bytes
0332908
 
 
51ea945
0332908
 
c36510a
 
 
0332908
51ea945
0332908
51ea945
 
 
9d6fa16
51ea945
 
0332908
51ea945
 
0332908
51ea945
 
0332908
51ea945
 
 
0332908
51ea945
0332908
51ea945
0332908
51ea945
 
 
 
 
0332908
 
51ea945
0332908
51ea945
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0332908
51ea945
0332908
51ea945
0332908
51ea945
 
0332908
51ea945
 
 
 
 
 
 
0332908
51ea945
 
 
 
 
 
0332908
 
51ea945
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0332908
 
 
 
51ea945
0332908
51ea945
0332908
51ea945
 
0332908
51ea945
 
 
 
 
 
 
 
 
 
 
 
 
0332908
 
 
 
51ea945
 
 
 
 
 
0332908
51ea945
 
0332908
51ea945
 
 
 
 
 
 
 
 
 
 
 
0332908
51ea945
 
 
0332908
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
---
title: OpenAPI Integration
sidebarTitle: OpenAPI
description: Generate MCP servers from OpenAPI specs
icon: code-branch
---
import { VersionBadge } from '/snippets/version-badge.mdx'

<VersionBadge version="2.0.0" />

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()
```

## 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".*\{.*\}.*", 
             route_type=RouteType.RESOURCE_TEMPLATE),
    
    # GET without path parameters -> Resource
    RouteMap(methods=["GET"], pattern=r".*", 
             route_type=RouteType.RESOURCE),
    
    # All other methods -> Tool
    RouteMap(methods=["POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"],
             pattern=r".*", route_type=RouteType.TOOL),
]
```

### 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, RouteType

# Custom mapping rules
custom_maps = [
    # Force all analytics endpoints to be Tools
    RouteMap(methods=["GET"], 
             pattern=r"^/analytics/.*", 
             route_type=RouteType.TOOL)
]

# Apply custom mappings
mcp = await FastMCP.from_openapi(
    openapi_spec=spec,
    client=api_client,
    route_maps=custom_maps
)
```

## 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

## Complete Example

```python
import asyncio
import httpx
from fastmcp import FastMCP

# Sample OpenAPI spec for a Pet Store API
petstore_spec = {
    "openapi": "3.0.0",
    "paths": {
        "/pets": {
            "get": {
                "operationId": "listPets",
                "summary": "List all pets"
            },
            "post": {
                "operationId": "createPet",
                "summary": "Create a new pet"
            }
        },
        "/pets/{petId}": {
            "get": {
                "operationId": "getPet",
                "summary": "Get a pet by ID",
                "parameters": [
                    {
                        "name": "petId",
                        "in": "path",
                        "required": True,
                        "schema": {"type": "string"}
                    }
                ]
            }
        }
    }
}

async def main():
    # Client for the Pet Store API
    client = httpx.AsyncClient(base_url="https://petstore.example.com/api")
    
    # Create the MCP server
    mcp = await FastMCP.from_openapi(
        openapi_spec=petstore_spec,
        client=client,
        name="PetStore"
    )
    
    # List what components were created
    tools = await mcp.list_tools()
    resources = await mcp.list_resources()
    templates = await mcp.list_resource_templates()
    
    print(f"Tools: {len(tools)}")          # Should include createPet
    print(f"Resources: {len(resources)}")  # Should include listPets
    print(f"Templates: {len(templates)}")  # Should include getPet
    
    # Start the MCP server
    mcp.run()

if __name__ == "__main__":
    asyncio.run(main())
```