Description
When using FastMCP.from_fastapi() with a FastAPI app whose response model contains dict[StrEnum, Model], Pydantic generates a propertyNames keyword with a $ref to the enum schema. _replace_ref_with_defs converts additionalProperties.$ref from #/components/schemas/ to #/$defs/, but does not handle propertyNames, leaving a dangling reference.
This causes MCP clients (e.g. Cursor) to fail resolving the reference, preventing all tools from loading.
Example Code
import asyncio
from enum import StrEnum
from fastapi import FastAPI
from pydantic import BaseModel
from fastmcp import FastMCP, Client
class Category(StrEnum):
BOOKS = "Books"
ELECTRONICS = "Electronics"
class ItemInfo(BaseModel):
count: int
class InventoryResponse(BaseModel):
items: dict[Category, ItemInfo]
api = FastAPI()
@api.get("/inventory", response_model=InventoryResponse)
def get_inventory() -> InventoryResponse:
return InventoryResponse(items={Category.BOOKS: ItemInfo(count=5)})
mcp = FastMCP.from_fastapi(app=api)
async def demo():
async with Client(mcp) as client:
tools = await client.list_tools()
for tool in tools:
schema = tool.outputSchema or {}
# additionalProperties.$ref is correctly #/$defs/ItemInfo
# but propertyNames.$ref is still #/components/schemas/Category
print(schema)
if __name__ == "__main__":
asyncio.run(demo())
Output (trimmed):
{
"properties": {
"items": {
"additionalProperties": {"$ref": "#/$defs/ItemInfo"},
"propertyNames": {"$ref": "#/components/schemas/Category"},
"type": "object"
}
},
"$defs": {
"Category": {"type": "string", "enum": ["Books", "Electronics"]},
"ItemInfo": {"properties": {"count": {"type": "integer"}}, "type": "object"}
}
}
Version Information
FastMCP version: 3.0.1
MCP version: 1.26.0
Python version: 3.12.4
Platform: macOS-26.2-arm64-arm-64bit
Also confirmed on main (schemas.py at bb057f2).
Description
When using
FastMCP.from_fastapi()with a FastAPI app whose response model containsdict[StrEnum, Model], Pydantic generates apropertyNameskeyword with a$refto the enum schema._replace_ref_with_defsconvertsadditionalProperties.$reffrom#/components/schemas/to#/$defs/, but does not handlepropertyNames, leaving a dangling reference.This causes MCP clients (e.g. Cursor) to fail resolving the reference, preventing all tools from loading.
Example Code
Output (trimmed):
{ "properties": { "items": { "additionalProperties": {"$ref": "#/$defs/ItemInfo"}, "propertyNames": {"$ref": "#/components/schemas/Category"}, "type": "object" } }, "$defs": { "Category": {"type": "string", "enum": ["Books", "Electronics"]}, "ItemInfo": {"properties": {"count": {"type": "integer"}}, "type": "object"} } }Version Information
Also confirmed on
main(schemas.pyatbb057f2).