Jeremiah Lowin commited on
Commit
2cbf3b1
·
1 Parent(s): 7e21d4d

Treat all openapi routes as tools

Browse files
docs/servers/openapi.mdx CHANGED
@@ -41,17 +41,9 @@ That's it! Your entire API is now available as an MCP server. Clients can discov
41
 
42
  ## Route Mapping
43
 
 
44
 
45
-
46
- FastMCP analyzes your API specification and automatically creates MCP components based on HTTP semantics and REST conventions. By default, the following rules are used to determine what MCP component to create for each route:
47
-
48
- | OpenAPI Route | Example | MCP Component |
49
- |---------------|---------|---------------|
50
- | `GET` with path params | `GET /users/{id}` | **Resource Template** |
51
- | `GET` without path params | `GET /stats` | **Resource** |
52
- | `POST`, `PUT`, `PATCH`, `DELETE`, etc. | `POST /users` | **Tool** |
53
-
54
- Interally, FastMCP uses an ordered list of `RouteMap` objects to determine how to map OpenAPI routes to various MCP component types.
55
 
56
  Each `RouteMap` specifies a combination of methods, patterns, and tags, as well as a corresponding MCP component type. Each OpenAPI route is checked against each `RouteMap` in order, and the first one that matches every criteria is used to determine its converted MCP type. A special type, `EXCLUDE`, can be used to exclude routes from the MCP server entirely.
57
 
@@ -60,33 +52,14 @@ Each `RouteMap` specifies a combination of methods, patterns, and tags, as well
60
  - **Tags**: A set of OpenAPI tags that must all be present. An empty set (`{}`) means no tag filtering, so the route matches regardless of its tags.
61
  - **MCP type**: What MCP component type to create (`TOOL`, `RESOURCE`, `RESOURCE_TEMPLATE`, or `EXCLUDE`)
62
 
63
- To illustrate this in practice, here are FastMCP's default rules as a list of `RouteMap` objects:
64
 
65
  ```python
66
  from fastmcp.server.openapi import RouteMap, MCPType
67
 
68
  DEFAULT_ROUTE_MAPPINGS = [
69
-
70
- # GET with path parameters → ResourceTemplate
71
- RouteMap(
72
- methods=["GET"],
73
- pattern=r".*\{.*\}.*",
74
- mcp_type=MCPType.RESOURCE_TEMPLATE
75
- ),
76
-
77
- # GET without path parameters → Resource
78
- RouteMap(
79
- methods=["GET"],
80
- pattern=r".*",
81
- mcp_type=MCPType.RESOURCE
82
- ),
83
-
84
- # All other methods → Tool
85
- RouteMap(
86
- methods=["*"],
87
- pattern=r".*",
88
- mcp_type=MCPType.TOOL
89
- ),
90
  ]
91
  ```
92
 
@@ -94,20 +67,28 @@ DEFAULT_ROUTE_MAPPINGS = [
94
 
95
  When creating your FastMCP server, you can customize routing behavior by providing your own list of `RouteMap` objects. Your custom maps are processed before the default route maps, and routes will be assigned to the first matching custom map.
96
 
97
- For example, the following simple rule will treat every OpenAPI route as a tool:
98
 
99
- ```python {7}
100
  from fastmcp import FastMCP
101
  from fastmcp.server.openapi import RouteMap, MCPType
102
 
 
 
 
 
 
 
 
 
103
  mcp = FastMCP.from_openapi(
104
  ...,
105
- route_maps=[
106
- RouteMap(mcp_type=MCPType.TOOL),
107
- ],
108
  )
109
  ```
110
 
 
 
111
  Here is a more complete example that uses custom route maps to convert all `GET` endpoints under `/analytics/` to tools while excluding all admin endpoints and all routes tagged "internal". All other routes will be handled by the default rules:
112
 
113
  ```python
 
41
 
42
  ## Route Mapping
43
 
44
+ By default, FastMCP converts **every endpoint** in your OpenAPI specification into an MCP **Tool**. This provides a simple, predictable starting point that ensures all your API's functionality is immediately available to the vast majority of LLM clients which only support MCP tools.
45
 
46
+ While this is a pragmatic default for maximum compatibility, you can easily customize this behavior. Interally, FastMCP uses an ordered list of `RouteMap` objects to determine how to map OpenAPI routes to various MCP component types.
 
 
 
 
 
 
 
 
 
47
 
48
  Each `RouteMap` specifies a combination of methods, patterns, and tags, as well as a corresponding MCP component type. Each OpenAPI route is checked against each `RouteMap` in order, and the first one that matches every criteria is used to determine its converted MCP type. A special type, `EXCLUDE`, can be used to exclude routes from the MCP server entirely.
49
 
 
52
  - **Tags**: A set of OpenAPI tags that must all be present. An empty set (`{}`) means no tag filtering, so the route matches regardless of its tags.
53
  - **MCP type**: What MCP component type to create (`TOOL`, `RESOURCE`, `RESOURCE_TEMPLATE`, or `EXCLUDE`)
54
 
55
+ Here is FastMCP's default rule:
56
 
57
  ```python
58
  from fastmcp.server.openapi import RouteMap, MCPType
59
 
60
  DEFAULT_ROUTE_MAPPINGS = [
61
+ # All routes become tools
62
+ RouteMap(mcp_type=MCPType.TOOL),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  ]
64
  ```
65
 
 
67
 
68
  When creating your FastMCP server, you can customize routing behavior by providing your own list of `RouteMap` objects. Your custom maps are processed before the default route maps, and routes will be assigned to the first matching custom map.
69
 
70
+ For example, prior to FastMCP 2.8.0, GET requests were automatically mapped to `Resource` and `ResourceTemplate` components based on whether they had path parameters. (This was changed solely for client compatibility reasons.) You can restore this behavior by providing custom route maps:
71
 
72
+ ```python {2, 5-10}
73
  from fastmcp import FastMCP
74
  from fastmcp.server.openapi import RouteMap, MCPType
75
 
76
+ # Restore pre-2.8.0 semantic mapping
77
+ semantic_maps = [
78
+ # GET requests with path parameters become ResourceTemplates
79
+ RouteMap(methods=["GET"], pattern=r".*\{.*\}.*", mcp_type=MCPType.RESOURCE_TEMPLATE),
80
+ # All other GET requests become Resources
81
+ RouteMap(methods=["GET"], pattern=r".*", mcp_type=MCPType.RESOURCE),
82
+ ]
83
+
84
  mcp = FastMCP.from_openapi(
85
  ...,
86
+ route_maps=semantic_maps,
 
 
87
  )
88
  ```
89
 
90
+ With these maps, `GET` requests are handled semantically, and all other methods (`POST`, `PUT`, etc.) will fall through to the default rule and become `Tool`s.
91
+
92
  Here is a more complete example that uses custom route maps to convert all `GET` endpoints under `/analytics/` to tools while excluding all admin endpoints and all routes tagged "internal". All other routes will be handled by the default rules:
93
 
94
  ```python
src/fastmcp/server/openapi.py CHANGED
@@ -155,16 +155,10 @@ class RouteMap:
155
  self.route_type = self.mcp_type
156
 
157
 
158
- # Default route mappings as a list, where order determines priority
 
159
  DEFAULT_ROUTE_MAPPINGS = [
160
- # GET requests with path parameters go to ResourceTemplate
161
- RouteMap(
162
- methods=["GET"], pattern=r".*\{.*\}.*", mcp_type=MCPType.RESOURCE_TEMPLATE
163
- ),
164
- # GET requests without path parameters go to Resource
165
- RouteMap(methods=["GET"], pattern=r".*", mcp_type=MCPType.RESOURCE),
166
- # All other HTTP methods go to Tool
167
- RouteMap(methods="*", pattern=r".*", mcp_type=MCPType.TOOL),
168
  ]
169
 
170
 
 
155
  self.route_type = self.mcp_type
156
 
157
 
158
+ # Default route mapping: all routes become tools.
159
+ # Users can provide custom route_maps to override this behavior.
160
  DEFAULT_ROUTE_MAPPINGS = [
161
+ RouteMap(mcp_type=MCPType.TOOL),
 
 
 
 
 
 
 
162
  ]
163
 
164
 
src/fastmcp/server/server.py CHANGED
@@ -1551,28 +1551,11 @@ class FastMCP(Generic[LifespanResultT]):
1551
  route_map_fn: OpenAPIRouteMapFn | None = None,
1552
  mcp_component_fn: OpenAPIComponentFn | None = None,
1553
  mcp_names: dict[str, str] | None = None,
1554
- all_routes_as_tools: bool = False,
1555
  **settings: Any,
1556
  ) -> FastMCPOpenAPI:
1557
  """
1558
  Create a FastMCP server from an OpenAPI specification.
1559
  """
1560
- from .openapi import FastMCPOpenAPI, MCPType, RouteMap
1561
-
1562
- # Deprecated since 2.5.0
1563
- if all_routes_as_tools:
1564
- warnings.warn(
1565
- "The 'all_routes_as_tools' parameter is deprecated and will be removed in a future version. "
1566
- 'Use \'route_maps=[RouteMap(methods="*", pattern=r".*", mcp_type=MCPType.TOOL)]\' instead.',
1567
- DeprecationWarning,
1568
- stacklevel=2,
1569
- )
1570
-
1571
- if all_routes_as_tools and route_maps:
1572
- raise ValueError("Cannot specify both all_routes_as_tools and route_maps")
1573
-
1574
- elif all_routes_as_tools:
1575
- route_maps = [RouteMap(methods="*", pattern=r".*", mcp_type=MCPType.TOOL)]
1576
 
1577
  return FastMCPOpenAPI(
1578
  openapi_spec=openapi_spec,
@@ -1593,7 +1576,6 @@ class FastMCP(Generic[LifespanResultT]):
1593
  route_map_fn: OpenAPIRouteMapFn | None = None,
1594
  mcp_component_fn: OpenAPIComponentFn | None = None,
1595
  mcp_names: dict[str, str] | None = None,
1596
- all_routes_as_tools: bool = False,
1597
  httpx_client_kwargs: dict[str, Any] | None = None,
1598
  **settings: Any,
1599
  ) -> FastMCPOpenAPI:
@@ -1601,22 +1583,7 @@ class FastMCP(Generic[LifespanResultT]):
1601
  Create a FastMCP server from a FastAPI application.
1602
  """
1603
 
1604
- from .openapi import FastMCPOpenAPI, MCPType, RouteMap
1605
-
1606
- # Deprecated since 2.5.0
1607
- if all_routes_as_tools:
1608
- warnings.warn(
1609
- "The 'all_routes_as_tools' parameter is deprecated and will be removed in a future version. "
1610
- 'Use \'route_maps=[RouteMap(methods="*", pattern=r".*", mcp_type=MCPType.TOOL)]\' instead.',
1611
- DeprecationWarning,
1612
- stacklevel=2,
1613
- )
1614
-
1615
- if all_routes_as_tools and route_maps:
1616
- raise ValueError("Cannot specify both all_routes_as_tools and route_maps")
1617
-
1618
- elif all_routes_as_tools:
1619
- route_maps = [RouteMap(methods="*", pattern=r".*", mcp_type=MCPType.TOOL)]
1620
 
1621
  if httpx_client_kwargs is None:
1622
  httpx_client_kwargs = {}
 
1551
  route_map_fn: OpenAPIRouteMapFn | None = None,
1552
  mcp_component_fn: OpenAPIComponentFn | None = None,
1553
  mcp_names: dict[str, str] | None = None,
 
1554
  **settings: Any,
1555
  ) -> FastMCPOpenAPI:
1556
  """
1557
  Create a FastMCP server from an OpenAPI specification.
1558
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1559
 
1560
  return FastMCPOpenAPI(
1561
  openapi_spec=openapi_spec,
 
1576
  route_map_fn: OpenAPIRouteMapFn | None = None,
1577
  mcp_component_fn: OpenAPIComponentFn | None = None,
1578
  mcp_names: dict[str, str] | None = None,
 
1579
  httpx_client_kwargs: dict[str, Any] | None = None,
1580
  **settings: Any,
1581
  ) -> FastMCPOpenAPI:
 
1583
  Create a FastMCP server from a FastAPI application.
1584
  """
1585
 
1586
+ from .openapi import FastMCPOpenAPI
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1587
 
1588
  if httpx_client_kwargs is None:
1589
  httpx_client_kwargs = {}