Spaces:
Running
Running
Jeremiah Lowin commited on
Commit ·
926df22
1
Parent(s): c084231
Note that OpenAPI components automatically load tags
Browse files
docs/integrations/openapi.mdx
CHANGED
|
@@ -332,6 +332,38 @@ mcp = FastMCP.from_openapi(
|
|
| 332 |
)
|
| 333 |
```
|
| 334 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 335 |
### Advanced Customization
|
| 336 |
|
| 337 |
<VersionBadge version="2.5.0" />
|
|
|
|
| 332 |
)
|
| 333 |
```
|
| 334 |
|
| 335 |
+
#### OpenAPI Tags in Client Meta
|
| 336 |
+
|
| 337 |
+
FastMCP automatically includes OpenAPI tags from your specification in the component's metadata. These tags are available to MCP clients through the `_meta` field, allowing clients to filter and organize components based on the original OpenAPI tagging:
|
| 338 |
+
|
| 339 |
+
<CodeGroup>
|
| 340 |
+
```json {5} OpenAPI spec with tags
|
| 341 |
+
{
|
| 342 |
+
"paths": {
|
| 343 |
+
"/users": {
|
| 344 |
+
"get": {
|
| 345 |
+
"tags": ["users", "public"],
|
| 346 |
+
"operationId": "list_users",
|
| 347 |
+
"summary": "List all users"
|
| 348 |
+
}
|
| 349 |
+
}
|
| 350 |
+
}
|
| 351 |
+
}
|
| 352 |
+
```
|
| 353 |
+
```python {6-8} Access OpenAPI tags in MCP client
|
| 354 |
+
async with client:
|
| 355 |
+
tools = await client.list_tools()
|
| 356 |
+
for tool in tools:
|
| 357 |
+
if hasattr(tool, '_meta') and tool._meta:
|
| 358 |
+
# OpenAPI tags are now available!
|
| 359 |
+
openapi_tags = tool._meta.get('tags', [])
|
| 360 |
+
if 'users' in openapi_tags:
|
| 361 |
+
print(f"Found user-related tool: {tool.name}")
|
| 362 |
+
```
|
| 363 |
+
</CodeGroup>
|
| 364 |
+
|
| 365 |
+
This makes it easy for clients to understand and organize API endpoints based on their original OpenAPI categorization.
|
| 366 |
+
|
| 367 |
### Advanced Customization
|
| 368 |
|
| 369 |
<VersionBadge version="2.5.0" />
|
tests/server/openapi/test_basic_functionality.py
CHANGED
|
@@ -97,7 +97,7 @@ class TestTools:
|
|
| 97 |
|
| 98 |
assert tools[0].model_dump() == dict(
|
| 99 |
name="create_user_users_post",
|
| 100 |
-
meta=
|
| 101 |
title=None,
|
| 102 |
annotations=None,
|
| 103 |
description=IsStr(regex=r"^Create a new user\..*$", regex_flags=re.DOTALL),
|
|
@@ -122,7 +122,7 @@ class TestTools:
|
|
| 122 |
)
|
| 123 |
assert tools[1].model_dump() == dict(
|
| 124 |
name="update_user_name_users",
|
| 125 |
-
meta=
|
| 126 |
title=None,
|
| 127 |
annotations=None,
|
| 128 |
description=IsStr(
|
|
|
|
| 97 |
|
| 98 |
assert tools[0].model_dump() == dict(
|
| 99 |
name="create_user_users_post",
|
| 100 |
+
meta={"tags": ["users", "create"]},
|
| 101 |
title=None,
|
| 102 |
annotations=None,
|
| 103 |
description=IsStr(regex=r"^Create a new user\..*$", regex_flags=re.DOTALL),
|
|
|
|
| 122 |
)
|
| 123 |
assert tools[1].model_dump() == dict(
|
| 124 |
name="update_user_name_users",
|
| 125 |
+
meta={"tags": ["users", "update"]},
|
| 126 |
title=None,
|
| 127 |
annotations=None,
|
| 128 |
description=IsStr(
|