Resolved

FastMCP 2.x AttributeError - no state attribute on server object

Python
FastMCP
Backend
Debugging
Server
State Management
Migration
FastAPI

FastMCP server fails to start with AttributeError when accessing server.state in lifespan context manager | Pattern copied from FastAPI documentation causes crash in FastMCP 2.x

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.state is 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 _client to store the client object, replacing the non-existent server.state attribute.
  • Used Python’s global keyword 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 _client variable.
  • 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 _client variable directly, ensuring compatibility with FastMCP 2.x.

Key Changes Summary

  • Storage Location: Shifted from server.state["client"] to a module-level _client variable.
  • Scope Management: Utilized Python’s global keyword 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.