Skip to main content
This guide provides migration instructions for breaking changes and major updates when upgrading between FastMCP versions.

v3.0.0

WSTransport Removed

The deprecated WSTransport client transport has been removed. Use StreamableHttpTransport instead.

Provider Architecture

FastMCP v3 introduces a unified provider architecture for sourcing components. All tools, resources, and prompts now flow through providers:
  • LocalProvider stores decorator-registered components (@mcp.tool, etc.)
  • FastMCPProvider wraps another FastMCP server for composition
  • ProxyProvider connects to remote MCP servers
  • TransformingProvider adds namespacing and renaming
See Providers for the complete documentation.

Mount Namespace Parameter

The prefix parameter for mount() has been renamed to namespace:
main.mount(subserver, prefix="api")

Component Enable/Disable

The enabled field and enable()/disable() methods have been removed from component objects. Use server or provider methods instead:
tool = await server.get_tool("my_tool")
tool.disable()
tool.enable()
Components describe capabilities; servers and providers control availability. This ensures mutations work correctly even when components pass through transforming providers. Allowlist mode: Use only=True to restrict visibility to specific components:
# Show ONLY tools with "public" tag
server.enable(tags={"public"}, only=True)
FastMCP(include_tags=..., exclude_tags=...) deprecated: These init parameters emit deprecation warnings. Use the new methods instead:
# Before
mcp = FastMCP("server", exclude_tags={"internal"})

# After
mcp = FastMCP("server")
mcp.disable(tags={"internal"})

Component Lookup Method Parameter Names

The server lookup methods now use semantic parameter names instead of generic key:
  • FastMCP.get_tool(name=...) (was key)
  • FastMCP.get_resource(uri=...) (was key)
  • FastMCP.get_resource_template(uri=...) (was key)
  • FastMCP.get_prompt(name=...) (was key)
If you were passing arguments positionally, no change is needed. If you were using keyword arguments:
tool = await mcp.get_tool(key="my_tool")

Component Listing Methods Return Lists

The get_tools(), get_resources(), get_prompts(), and get_resource_templates() methods now return lists instead of dicts:
tools = await server.get_tools()
if "my_tool" in tools:
    tool = tools["my_tool"]
The dict key was redundant since components already have .name or .uri attributes. Use list comprehensions or next() for lookups.

Prompt Return Types

Prompt functions now use Message instead of mcp.types.PromptMessage. The Message class provides auto-serialization and a simpler API:
from mcp.types import PromptMessage, TextContent

@mcp.prompt
def my_prompt() -> PromptMessage:
    return PromptMessage(
        role="user",
        content=TextContent(type="text", text="Hello")
    )
Key changes:
  • Use Message(content, role="user") instead of PromptMessage(role=..., content=TextContent(...))
  • Message auto-serializes dicts, lists, and Pydantic models to JSON
  • PromptResult now accepts str | list[Message] (no single Message)
  • Returning mcp.types.PromptMessage directly is no longer supported
See Prompts documentation for full details.

Tool Serializer Deprecated

The tool_serializer parameter on FastMCP is deprecated. Return ToolResult from your tools for explicit control over serialization. See Custom Serialization for examples.

Auth Provider Automatic Environment Variable Loading Removed

Auth providers no longer automatically read configuration from environment variables. You can still use environment variables, but you must read them yourself:
# Relied on FASTMCP_SERVER_AUTH_GITHUB_CLIENT_ID, etc.
auth = GitHubProvider()
This applies to all auth providers: GitHubProvider, GoogleProvider, AzureProvider, Auth0Provider, AWSProvider, WorkOSProvider, DescopeProvider, DiscordProvider, ScalekitProvider, SupabaseProvider, OCIProvider, JWTVerifier, and IntrospectionVerifier. The FastMCPSettings class has also been simplified - it no longer includes auth-related settings that were previously loaded from environment variables.

Server Banner Environment Variable Renamed

The environment variable for controlling the server banner has been renamed:
  • Before: FASTMCP_SHOW_CLI_BANNER
  • After: FASTMCP_SHOW_SERVER_BANNER
This change reflects that the setting now applies to all server startup methods, not just the CLI. The banner is now suppressed when running python server.py directly, not just when using fastmcp run.

v2.14.0

OpenAPI Parser Promotion

The experimental OpenAPI parser is now the standard implementation. The legacy parser has been removed. If you were using the legacy parser: No code changes required. The new parser is a drop-in replacement with improved architecture. If you were using the experimental parser: Update your imports from the experimental module to the standard location:
from fastmcp.experimental.server.openapi import FastMCPOpenAPI, RouteMap, MCPType
The experimental imports will continue working temporarily but will show deprecation warnings. The FASTMCP_EXPERIMENTAL_ENABLE_NEW_OPENAPI_PARSER environment variable is no longer needed and can be removed.

Deprecated Features Removed

The following deprecated features have been removed in v2.14.0: BearerAuthProvider (deprecated in v2.11):
from fastmcp.server.auth.providers.bearer import BearerAuthProvider
Context.get_http_request() (deprecated in v2.2.11):
request = context.get_http_request()
Top-level Image import (deprecated in v2.8.1):
from fastmcp import Image
FastMCP dependencies parameter (deprecated in v2.11.4):
mcp = FastMCP("server", dependencies=["requests", "pandas"])
Legacy resource prefix format: The resource_prefix_format parameter and “protocol” format have been removed. Only the “path” format is supported (this was already the default). FastMCPProxy client parameter:
proxy = FastMCPProxy(client=my_client)
output_schema=False:
@mcp.tool(output_schema=False)
def my_tool() -> str:
    return "result"

v2.13.0

OAuth Token Key Management

The OAuth proxy now issues its own JWT tokens to clients instead of forwarding upstream provider tokens. This improves security by maintaining proper token audience boundaries. What changed: The OAuth proxy now implements a token factory pattern - it receives tokens from your OAuth provider (GitHub, Google, etc.), encrypts and stores them, then issues its own FastMCP JWT tokens to clients. This requires cryptographic keys for JWT signing and token encryption. Default behavior (development): By default, FastMCP automatically manages keys based on your platform:
  • Mac/Windows: Keys are auto-managed via system keyring, surviving server restarts with zero configuration. Suitable only for development and local testing.
  • Linux: Keys are ephemeral (random salt at startup, regenerated on each restart).
This works fine for development and testing where re-authentication after restart is acceptable. For production: Production deployments must provide explicit keys and use persistent storage. Add these three things:
auth = GitHubProvider(
    client_id=os.environ["GITHUB_CLIENT_ID"],
    client_secret=os.environ["GITHUB_CLIENT_SECRET"],
    base_url="https://your-server.com",

    # Explicit keys (required for production)
    jwt_signing_key=os.environ["JWT_SIGNING_KEY"],

    # Persistent network storage (required for production)
    client_storage=RedisStore(host="redis.example.com", port=6379)
)
More information: