Skip to content

propertyNames.$ref not converted by _replace_ref_with_defs #3303

@tailaiw

Description

@tailaiw

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working. Reports of errors, unexpected behavior, or broken functionality.openapiRelated to OpenAPI integration, parsing, or code generation features.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions