Issue
The FastMCP 2.x server failed to start due to an AttributeError: 'FastMCP' object has no attribute 'state'. This error occurred when the lifespan context manager attempted to access server.state["client"] during server initialization, preventing the server (name-fastmcp-docs-playground) from booting successfully.
Culprit
The issue arose because the code incorrectly assumed that FastMCP 2.x implements a state attribute on the server object, similar to FastAPI’s app.state mechanism. This pattern was likely adopted from:
- FastAPI documentation, where
app.stateis a standard way to store application-level state. - Older FastMCP 1.x examples, which might have supported this attribute.
- Generic ASGI lifespan patterns, which were not adapted for FastMCP’s architecture.
FastMCP 2.x does not include a state attribute, making the assumption incompatible with its design.
Solution
To resolve the issue, the implementation was refactored to use a module-level global variable instead of server.state. Key changes included:
1. Global Variable Implementation
- Introduced a module-level variable
_clientto store the client object, replacing the non-existentserver.stateattribute. - Used Python’s
globalkeyword to enable access to this variable across functions in the module.
2. Lifespan Context Manager Update
- Modified the lifespan context manager to initialize and manage the global
_clientvariable. - The context manager now creates a client on startup and ensures proper cleanup by closing it when the server yields.
3. Tool Function Access
- Updated tool functions to access the global
_clientvariable directly, ensuring compatibility with FastMCP 2.x.
Key Changes Summary
- Storage Location: Shifted from
server.state["client"]to a module-level_clientvariable. - Scope Management: Utilized Python’s
globalkeyword for module-wide access to the client object. - Compatibility: Maintained FastMCP 2.x compatibility without requiring architectural changes.
- Files Modified: All changes were confined to
fastmcp_docs_server_longer.py, specifically lines 20, 26-31, and 54-57.
This approach eliminated the dependency on FastMCP’s non-existent state attribute while preserving the intended functionality of storing and managing the client object.