Skip to content

[v1] FastMCP Settings lifespan remains unresolved #3294

Description

@igorkorsunsky

Description

MCP v1.29.0 leaves the generic FastMCP Settings model incomplete after import. With pydantic-settings 2.15.0, constructing a server now emits the intentional incomplete-field warning added by pydantic-settings PR #901:

IncompleteFieldDefinitionWarning: Field 'lifespan' has an incomplete definition: its annotation contains an unresolved forward reference, so settings sources may fail to correctly resolve its value. Call model_rebuild() on the model where the field is defined, once all the referenced types are defined.

Minimal reproduction

Environment:

  • Python 3.13.5
  • mcp==1.29.0
  • pydantic==2.13.4
  • pydantic-settings==2.15.0
from mcp.server.fastmcp import FastMCP

FastMCP("test")

Promoting warnings to errors makes the construction fail.

The underlying model state is observable without constructing a server:

from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.server import Settings

field = Settings.model_fields["lifespan"]
assert Settings.__pydantic_complete__ is False
assert field._complete is False
print(field.annotation)
# ForwardRef('Callable[[FastMCP[LifespanResultT]], AbstractAsyncContextManager[LifespanResultT]] | None')

Settings is defined before FastMCP in mcp.server.fastmcp.server, so its lifespan annotation remains unresolved after the module finishes importing.

Verified workaround

Calling the public rebuild hook after the module has imported resolves the field and removes the warning without changing lifespan behavior:

from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.server import Settings

Settings.model_rebuild()
FastMCP("test")

After rebuilding, Settings.__pydantic_complete__ and the field's _complete flag are true, and the annotation is no longer a ForwardRef.

Could the v1 FastMCP module rebuild Settings after FastMCP is defined, or otherwise avoid leaving the forward reference unresolved?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions