diff --git a/docs/docs.json b/docs/docs.json
index af88bb341..00c7d7f95 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -335,10 +335,18 @@
"python-sdk/fastmcp-client-elicitation",
"python-sdk/fastmcp-client-logging",
"python-sdk/fastmcp-client-messages",
+ {
+ "group": "mixins",
+ "pages": [
+ "python-sdk/fastmcp-client-mixins-__init__",
+ "python-sdk/fastmcp-client-mixins-prompts",
+ "python-sdk/fastmcp-client-mixins-resources",
+ "python-sdk/fastmcp-client-mixins-task_management",
+ "python-sdk/fastmcp-client-mixins-tools"
+ ]
+ },
"python-sdk/fastmcp-client-oauth_callback",
"python-sdk/fastmcp-client-progress",
- "python-sdk/fastmcp-client-prompts",
- "python-sdk/fastmcp-client-resources",
"python-sdk/fastmcp-client-roots",
{
"group": "sampling",
@@ -354,10 +362,8 @@
}
]
},
- "python-sdk/fastmcp-client-task_management",
"python-sdk/fastmcp-client-tasks",
"python-sdk/fastmcp-client-telemetry",
- "python-sdk/fastmcp-client-tools_client",
{
"group": "transports",
"pages": [
@@ -460,6 +466,15 @@
"python-sdk/fastmcp-server-middleware-tool_injection"
]
},
+ {
+ "group": "mixins",
+ "pages": [
+ "python-sdk/fastmcp-server-mixins-__init__",
+ "python-sdk/fastmcp-server-mixins-lifespan",
+ "python-sdk/fastmcp-server-mixins-mcp_operations",
+ "python-sdk/fastmcp-server-mixins-transport"
+ ]
+ },
{
"group": "openapi",
"pages": [
diff --git a/docs/python-sdk/fastmcp-client-client.mdx b/docs/python-sdk/fastmcp-client-client.mdx
index 7a913c6e8..ee92061f8 100644
--- a/docs/python-sdk/fastmcp-client-client.mdx
+++ b/docs/python-sdk/fastmcp-client-client.mdx
@@ -7,7 +7,7 @@ sidebarTitle: client
## Classes
-### `ClientSessionState`
+### `ClientSessionState`
Holds all session-related state for a Client instance.
@@ -16,13 +16,13 @@ This allows clean separation of configuration (which is copied) from
session state (which should be fresh for each new client instance).
-### `CallToolResult`
+### `CallToolResult`
Parsed result from a tool call.
-### `Client`
+### `Client`
MCP client that delegates connection management to a Transport instance.
@@ -85,7 +85,7 @@ async with client:
**Methods:**
-#### `session`
+#### `session`
```python
session(self) -> ClientSession
@@ -94,7 +94,7 @@ session(self) -> ClientSession
Get the current active session. Raises RuntimeError if not connected.
-#### `initialize_result`
+#### `initialize_result`
```python
initialize_result(self) -> mcp.types.InitializeResult | None
@@ -103,7 +103,7 @@ initialize_result(self) -> mcp.types.InitializeResult | None
Get the result of the initialization request.
-#### `set_roots`
+#### `set_roots`
```python
set_roots(self, roots: RootsList | RootsHandler) -> None
@@ -112,7 +112,7 @@ set_roots(self, roots: RootsList | RootsHandler) -> None
Set the roots for the client. This does not automatically call `send_roots_list_changed`.
-#### `set_sampling_callback`
+#### `set_sampling_callback`
```python
set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabilities: mcp.types.SamplingCapability | None = None) -> None
@@ -121,7 +121,7 @@ set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabil
Set the sampling callback for the client.
-#### `set_elicitation_callback`
+#### `set_elicitation_callback`
```python
set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
@@ -130,7 +130,7 @@ set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
Set the elicitation callback for the client.
-#### `is_connected`
+#### `is_connected`
```python
is_connected(self) -> bool
@@ -139,7 +139,7 @@ is_connected(self) -> bool
Check if the client is currently connected.
-#### `new`
+#### `new`
```python
new(self) -> Client[ClientTransportT]
@@ -155,7 +155,7 @@ share state with the original client.
- A new Client instance with the same configuration but disconnected state.
-#### `initialize`
+#### `initialize`
```python
initialize(self, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.InitializeResult
@@ -183,13 +183,13 @@ capabilities, protocol version, and optional instructions.
- `RuntimeError`: If the client is not connected or initialization times out.
-#### `close`
+#### `close`
```python
close(self)
```
-#### `ping`
+#### `ping`
```python
ping(self) -> bool
@@ -198,7 +198,7 @@ ping(self) -> bool
Send a ping request.
-#### `cancel`
+#### `cancel`
```python
cancel(self, request_id: str | int, reason: str | None = None) -> None
@@ -207,7 +207,7 @@ cancel(self, request_id: str | int, reason: str | None = None) -> None
Send a cancellation notification for an in-progress request.
-#### `progress`
+#### `progress`
```python
progress(self, progress_token: str | int, progress: float, total: float | None = None, message: str | None = None) -> None
@@ -216,7 +216,7 @@ progress(self, progress_token: str | int, progress: float, total: float | None =
Send a progress notification.
-#### `set_logging_level`
+#### `set_logging_level`
```python
set_logging_level(self, level: mcp.types.LoggingLevel) -> None
@@ -225,7 +225,7 @@ set_logging_level(self, level: mcp.types.LoggingLevel) -> None
Send a logging/setLevel request.
-#### `send_roots_list_changed`
+#### `send_roots_list_changed`
```python
send_roots_list_changed(self) -> None
@@ -234,7 +234,7 @@ send_roots_list_changed(self) -> None
Send a roots/list_changed notification.
-#### `complete_mcp`
+#### `complete_mcp`
```python
complete_mcp(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.CompleteResult
@@ -257,7 +257,7 @@ containing the completion and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `complete`
+#### `complete`
```python
complete(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.Completion
@@ -279,7 +279,7 @@ include with the completion request. Defaults to None.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
diff --git a/docs/python-sdk/fastmcp-client-mixins-__init__.mdx b/docs/python-sdk/fastmcp-client-mixins-__init__.mdx
new file mode 100644
index 000000000..bc0e32a4c
--- /dev/null
+++ b/docs/python-sdk/fastmcp-client-mixins-__init__.mdx
@@ -0,0 +1,9 @@
+---
+title: __init__
+sidebarTitle: __init__
+---
+
+# `fastmcp.client.mixins`
+
+
+Client mixins for FastMCP.
diff --git a/docs/python-sdk/fastmcp-client-prompts.mdx b/docs/python-sdk/fastmcp-client-mixins-prompts.mdx
similarity index 78%
rename from docs/python-sdk/fastmcp-client-prompts.mdx
rename to docs/python-sdk/fastmcp-client-mixins-prompts.mdx
index 73b58b4df..7e9c8e8f6 100644
--- a/docs/python-sdk/fastmcp-client-prompts.mdx
+++ b/docs/python-sdk/fastmcp-client-mixins-prompts.mdx
@@ -3,14 +3,14 @@ title: prompts
sidebarTitle: prompts
---
-# `fastmcp.client.prompts`
+# `fastmcp.client.mixins.prompts`
Prompt-related methods for FastMCP Client.
## Classes
-### `ClientPromptsMixin`
+### `ClientPromptsMixin`
Mixin providing prompt-related methods for Client.
@@ -18,7 +18,7 @@ Mixin providing prompt-related methods for Client.
**Methods:**
-#### `list_prompts_mcp`
+#### `list_prompts_mcp`
```python
list_prompts_mcp(self: Client) -> mcp.types.ListPromptsResult
@@ -38,7 +38,7 @@ containing the list of prompts and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self: Client) -> list[mcp.types.Prompt]
@@ -58,7 +58,7 @@ large result sets incrementally), use list_prompts_mcp() with the cursor paramet
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `get_prompt_mcp`
+#### `get_prompt_mcp`
```python
get_prompt_mcp(self: Client, name: str, arguments: dict[str, Any] | None = None, meta: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
@@ -80,19 +80,19 @@ containing the prompt messages and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self: Client, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
```
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self: Client, name: str, arguments: dict[str, Any] | None = None) -> PromptTask
```
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self: Client, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult | PromptTask
diff --git a/docs/python-sdk/fastmcp-client-resources.mdx b/docs/python-sdk/fastmcp-client-mixins-resources.mdx
similarity index 78%
rename from docs/python-sdk/fastmcp-client-resources.mdx
rename to docs/python-sdk/fastmcp-client-mixins-resources.mdx
index 8dfb84cfa..ab89913e9 100644
--- a/docs/python-sdk/fastmcp-client-resources.mdx
+++ b/docs/python-sdk/fastmcp-client-mixins-resources.mdx
@@ -3,14 +3,14 @@ title: resources
sidebarTitle: resources
---
-# `fastmcp.client.resources`
+# `fastmcp.client.mixins.resources`
Resource-related methods for FastMCP Client.
## Classes
-### `ClientResourcesMixin`
+### `ClientResourcesMixin`
Mixin providing resource-related methods for Client.
@@ -18,7 +18,7 @@ Mixin providing resource-related methods for Client.
**Methods:**
-#### `list_resources_mcp`
+#### `list_resources_mcp`
```python
list_resources_mcp(self: Client) -> mcp.types.ListResourcesResult
@@ -38,7 +38,7 @@ containing the list of resources and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self: Client) -> list[mcp.types.Resource]
@@ -58,7 +58,7 @@ large result sets incrementally), use list_resources_mcp() with the cursor param
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `list_resource_templates_mcp`
+#### `list_resource_templates_mcp`
```python
list_resource_templates_mcp(self: Client) -> mcp.types.ListResourceTemplatesResult
@@ -78,7 +78,7 @@ containing the list of resource templates and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self: Client) -> list[mcp.types.ResourceTemplate]
@@ -99,7 +99,7 @@ cursor parameter.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `read_resource_mcp`
+#### `read_resource_mcp`
```python
read_resource_mcp(self: Client, uri: AnyUrl | str, meta: dict[str, Any] | None = None) -> mcp.types.ReadResourceResult
@@ -120,19 +120,19 @@ containing the resource contents and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self: Client, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents]
```
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self: Client, uri: AnyUrl | str) -> ResourceTask
```
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self: Client, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] | ResourceTask
diff --git a/docs/python-sdk/fastmcp-client-task_management.mdx b/docs/python-sdk/fastmcp-client-mixins-task_management.mdx
similarity index 77%
rename from docs/python-sdk/fastmcp-client-task_management.mdx
rename to docs/python-sdk/fastmcp-client-mixins-task_management.mdx
index f9d4ef18d..e09c38f8f 100644
--- a/docs/python-sdk/fastmcp-client-task_management.mdx
+++ b/docs/python-sdk/fastmcp-client-mixins-task_management.mdx
@@ -3,14 +3,14 @@ title: task_management
sidebarTitle: task_management
---
-# `fastmcp.client.task_management`
+# `fastmcp.client.mixins.task_management`
Task management methods for FastMCP Client.
## Classes
-### `ClientTaskManagementMixin`
+### `ClientTaskManagementMixin`
Mixin providing task management methods for Client.
@@ -18,7 +18,7 @@ Mixin providing task management methods for Client.
**Methods:**
-#### `get_task_status`
+#### `get_task_status`
```python
get_task_status(self: Client, task_id: str) -> GetTaskResult
@@ -39,7 +39,7 @@ Sends a 'tasks/get' MCP protocol request over the existing transport.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `get_task_result`
+#### `get_task_result`
```python
get_task_result(self: Client, task_id: str) -> Any
@@ -61,7 +61,7 @@ Returns the raw result - callers should parse it appropriately.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `list_tasks`
+#### `list_tasks`
```python
list_tasks(self: Client, cursor: str | None = None, limit: int = 50) -> dict[str, Any]
@@ -87,7 +87,7 @@ querying status for locally tracked task IDs.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `cancel_task`
+#### `cancel_task`
```python
cancel_task(self: Client, task_id: str) -> mcp.types.CancelTaskResult
diff --git a/docs/python-sdk/fastmcp-client-tools_client.mdx b/docs/python-sdk/fastmcp-client-mixins-tools.mdx
similarity index 91%
rename from docs/python-sdk/fastmcp-client-tools_client.mdx
rename to docs/python-sdk/fastmcp-client-mixins-tools.mdx
index 681abc997..769b267c2 100644
--- a/docs/python-sdk/fastmcp-client-tools_client.mdx
+++ b/docs/python-sdk/fastmcp-client-mixins-tools.mdx
@@ -1,16 +1,16 @@
---
-title: tools_client
-sidebarTitle: tools_client
+title: tools
+sidebarTitle: tools
---
-# `fastmcp.client.tools_client`
+# `fastmcp.client.mixins.tools`
Tool-related methods for FastMCP Client.
## Classes
-### `ClientToolsMixin`
+### `ClientToolsMixin`
Mixin providing tool-related methods for Client.
@@ -18,7 +18,7 @@ Mixin providing tool-related methods for Client.
**Methods:**
-#### `list_tools_mcp`
+#### `list_tools_mcp`
```python
list_tools_mcp(self: Client) -> mcp.types.ListToolsResult
@@ -38,7 +38,7 @@ containing the list of tools and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self: Client) -> list[mcp.types.Tool]
@@ -58,7 +58,7 @@ large result sets incrementally), use list_tools_mcp() with the cursor parameter
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `call_tool_mcp`
+#### `call_tool_mcp`
```python
call_tool_mcp(self: Client, name: str, arguments: dict[str, Any], progress_handler: ProgressHandler | None = None, timeout: datetime.timedelta | float | int | None = None, meta: dict[str, Any] | None = None) -> mcp.types.CallToolResult
@@ -88,19 +88,19 @@ containing the tool result and any additional metadata.
- `McpError`: If the tool call requests results in a TimeoutError | JSONRPCError
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self: Client, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult
```
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self: Client, name: str, arguments: dict[str, Any] | None = None) -> ToolTask
```
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self: Client, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult | ToolTask
diff --git a/docs/python-sdk/fastmcp-server-mixins-__init__.mdx b/docs/python-sdk/fastmcp-server-mixins-__init__.mdx
new file mode 100644
index 000000000..d35f9fc06
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-mixins-__init__.mdx
@@ -0,0 +1,9 @@
+---
+title: __init__
+sidebarTitle: __init__
+---
+
+# `fastmcp.server.mixins`
+
+
+Server mixins for FastMCP.
diff --git a/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx b/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx
new file mode 100644
index 000000000..2374febb0
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx
@@ -0,0 +1,30 @@
+---
+title: lifespan
+sidebarTitle: lifespan
+---
+
+# `fastmcp.server.mixins.lifespan`
+
+
+Lifespan and Docket task infrastructure for FastMCP Server.
+
+## Classes
+
+### `LifespanMixin`
+
+
+Mixin providing lifespan and Docket task infrastructure for FastMCP.
+
+
+**Methods:**
+
+#### `docket`
+
+```python
+docket(self: FastMCP) -> Docket | None
+```
+
+Get the Docket instance if Docket support is enabled.
+
+Returns None if Docket is not enabled or server hasn't been started yet.
+
diff --git a/docs/python-sdk/fastmcp-server-mixins-mcp_operations.mdx b/docs/python-sdk/fastmcp-server-mixins-mcp_operations.mdx
new file mode 100644
index 000000000..9b35c14bb
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-mixins-mcp_operations.mdx
@@ -0,0 +1,23 @@
+---
+title: mcp_operations
+sidebarTitle: mcp_operations
+---
+
+# `fastmcp.server.mixins.mcp_operations`
+
+
+MCP protocol handler setup and wire-format handlers for FastMCP Server.
+
+## Classes
+
+### `MCPOperationsMixin`
+
+
+Mixin providing MCP protocol handler setup and wire-format handlers.
+
+Note: Methods registered with SDK decorators (e.g., _list_tools_mcp, _call_tool_mcp)
+cannot use `self: FastMCP` type hints because the SDK's `get_type_hints()` fails
+to resolve FastMCP at runtime (it's only available under TYPE_CHECKING). When
+type hints fail to resolve, the SDK falls back to calling handlers with no arguments.
+These methods use untyped `self` to avoid this issue.
+
diff --git a/docs/python-sdk/fastmcp-server-mixins-transport.mdx b/docs/python-sdk/fastmcp-server-mixins-transport.mdx
new file mode 100644
index 000000000..ed61e5a5d
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-mixins-transport.mdx
@@ -0,0 +1,131 @@
+---
+title: transport
+sidebarTitle: transport
+---
+
+# `fastmcp.server.mixins.transport`
+
+
+Transport-related methods for FastMCP Server.
+
+## Classes
+
+### `TransportMixin`
+
+
+Mixin providing transport-related methods for FastMCP.
+
+Includes HTTP/stdio/SSE transport handling and custom HTTP routes.
+
+
+**Methods:**
+
+#### `run_async`
+
+```python
+run_async(self: FastMCP, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None
+```
+
+Run the FastMCP server asynchronously.
+
+**Args:**
+- `transport`: Transport protocol to use ("stdio", "http", "sse", or "streamable-http")
+- `show_banner`: Whether to display the server banner. If None, uses the
+FASTMCP_SHOW_SERVER_BANNER setting (default\: True).
+
+
+#### `run`
+
+```python
+run(self: FastMCP, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None
+```
+
+Run the FastMCP server. Note this is a synchronous function.
+
+**Args:**
+- `transport`: Transport protocol to use ("http", "stdio", "sse", or "streamable-http")
+- `show_banner`: Whether to display the server banner. If None, uses the
+FASTMCP_SHOW_SERVER_BANNER setting (default\: True).
+
+
+#### `custom_route`
+
+```python
+custom_route(self: FastMCP, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True) -> Callable[[Callable[[Request], Awaitable[Response]]], Callable[[Request], Awaitable[Response]]]
+```
+
+Decorator to register a custom HTTP route on the FastMCP server.
+
+Allows adding arbitrary HTTP endpoints outside the standard MCP protocol,
+which can be useful for OAuth callbacks, health checks, or admin APIs.
+The handler function must be an async function that accepts a Starlette
+Request and returns a Response.
+
+**Args:**
+- `path`: URL path for the route (e.g., "/auth/callback")
+- `methods`: List of HTTP methods to support (e.g., ["GET", "POST"])
+- `name`: Optional name for the route (to reference this route with
+Starlette's reverse URL lookup feature)
+- `include_in_schema`: Whether to include in OpenAPI schema, defaults to True
+
+
+#### `run_stdio_async`
+
+```python
+run_stdio_async(self: FastMCP, show_banner: bool = True, log_level: str | None = None, stateless: bool = False) -> None
+```
+
+Run the server using stdio transport.
+
+**Args:**
+- `show_banner`: Whether to display the server banner
+- `log_level`: Log level for the server
+- `stateless`: Whether to run in stateless mode (no session initialization)
+
+
+#### `run_http_async`
+
+```python
+run_http_async(self: FastMCP, show_banner: bool = True, transport: Literal['http', 'streamable-http', 'sse'] = 'http', host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, stateless: bool | None = None) -> None
+```
+
+Run the server using HTTP transport.
+
+**Args:**
+- `transport`: Transport protocol to use - "http" (default), "streamable-http", or "sse"
+- `host`: Host address to bind to (defaults to settings.host)
+- `port`: Port to bind to (defaults to settings.port)
+- `log_level`: Log level for the server (defaults to settings.log_level)
+- `path`: Path for the endpoint (defaults to settings.streamable_http_path or settings.sse_path)
+- `uvicorn_config`: Additional configuration for the Uvicorn server
+- `middleware`: A list of middleware to apply to the app
+- `json_response`: Whether to use JSON response format (defaults to settings.json_response)
+- `stateless_http`: Whether to use stateless HTTP (defaults to settings.stateless_http)
+- `stateless`: Alias for stateless_http for CLI consistency
+
+
+#### `http_app`
+
+```python
+http_app(self: FastMCP, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http', event_store: EventStore | None = None, retry_interval: int | None = None) -> StarletteWithLifespan
+```
+
+Create a Starlette app using the specified HTTP transport.
+
+**Args:**
+- `path`: The path for the HTTP endpoint
+- `middleware`: A list of middleware to apply to the app
+- `json_response`: Whether to use JSON response format
+- `stateless_http`: Whether to use stateless mode (new transport per request)
+- `transport`: Transport protocol to use - "http", "streamable-http", or "sse"
+- `event_store`: Optional event store for SSE polling/resumability. When set,
+enables clients to reconnect and resume receiving events after
+server-initiated disconnections. Only used with streamable-http transport.
+- `retry_interval`: Optional retry interval in milliseconds for SSE polling.
+Controls how quickly clients should reconnect after server-initiated
+disconnections. Requires event_store to be set. Only used with
+streamable-http transport.
+
+**Returns:**
+- A Starlette application configured with the specified transport
+
diff --git a/docs/python-sdk/fastmcp-server-providers-base.mdx b/docs/python-sdk/fastmcp-server-providers-base.mdx
index 6342421d6..730fe973d 100644
--- a/docs/python-sdk/fastmcp-server-providers-base.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-base.mdx
@@ -103,8 +103,8 @@ list_tools(self) -> Sequence[Tool]
List tools with all transforms applied.
-Builds a middleware chain: base → transforms (in order).
-Each transform wraps the previous via call_next.
+Applies transforms sequentially: base → transforms (in order).
+Each transform receives the result from the previous transform.
Components may be marked as disabled but are NOT filtered here -
filtering happens at the server level to allow session transforms to override.
@@ -112,7 +112,7 @@ filtering happens at the server level to allow session transforms to override.
- Transformed sequence of tools (including disabled ones).
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None
@@ -132,7 +132,7 @@ allowing session-level transforms to override provider-level disables.
- The tool if found (may be marked disabled), None if not found.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> Sequence[Resource]
@@ -143,7 +143,7 @@ List resources with all transforms applied.
Components may be marked as disabled but are NOT filtered here.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None
@@ -162,7 +162,7 @@ Note: This method does NOT filter disabled components. The Server
- The resource if found (may be marked disabled), None if not found.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> Sequence[ResourceTemplate]
@@ -173,7 +173,7 @@ List resource templates with all transforms applied.
Components may be marked as disabled but are NOT filtered here.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None
@@ -192,7 +192,7 @@ Note: This method does NOT filter disabled components. The Server
- The template if found (may be marked disabled), None if not found.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> Sequence[Prompt]
@@ -203,7 +203,7 @@ List prompts with all transforms applied.
Components may be marked as disabled but are NOT filtered here.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None
@@ -222,7 +222,7 @@ Note: This method does NOT filter disabled components. The Server
- The prompt if found (may be marked disabled), None if not found.
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -237,7 +237,7 @@ for components with task_config.mode != 'forbidden'.
Used by the server during startup to register functions with Docket.
-#### `lifespan`
+#### `lifespan`
```python
lifespan(self) -> AsyncIterator[None]
@@ -253,7 +253,7 @@ The lifespan scope matches the server's lifespan - code before yield
runs at startup, code after yield runs at shutdown.
-#### `enable`
+#### `enable`
```python
enable(self) -> Self
@@ -281,7 +281,7 @@ VersionSpec(gte="v2")). Unversioned components will not match.
- Self for method chaining.
-#### `disable`
+#### `disable`
```python
disable(self) -> Self
diff --git a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
index 821cbd794..2059f6e17 100644
--- a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
@@ -18,7 +18,7 @@ executed.
## Classes
-### `FastMCPProviderTool`
+### `FastMCPProviderTool`
Tool that delegates execution to a wrapped server's middleware.
@@ -30,7 +30,7 @@ chain is executed.
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, tool: Tool) -> FastMCPProviderTool
@@ -39,7 +39,7 @@ wrap(cls, server: Any, tool: Tool) -> FastMCPProviderTool
Wrap a Tool to delegate execution to the server's middleware.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -51,13 +51,13 @@ This is called when the tool is used within a TransformedTool
forwarding function or other contexts where task_meta is not available.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProviderResource`
+### `FastMCPProviderResource`
Resource that delegates reading to a wrapped server's read_resource().
@@ -68,7 +68,7 @@ When `read()` is called, this resource invokes the wrapped server's
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource
@@ -77,13 +77,13 @@ wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource
Wrap a Resource to delegate reading to the server's middleware.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProviderPrompt`
+### `FastMCPProviderPrompt`
Prompt that delegates rendering to a wrapped server's render_prompt().
@@ -94,7 +94,7 @@ When `render()` is called, this prompt invokes the wrapped server's
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt
@@ -103,7 +103,7 @@ wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt
Wrap a Prompt to delegate rendering to the server's middleware.
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any] | None = None) -> PromptResult
@@ -115,13 +115,13 @@ This is called when the prompt is used within a transformed context
or other contexts where task_meta is not available.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProviderResourceTemplate`
+### `FastMCPProviderResourceTemplate`
Resource template that creates FastMCPProviderResources.
@@ -133,7 +133,7 @@ when read.
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTemplate
@@ -142,7 +142,7 @@ wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTem
Wrap a ResourceTemplate to create FastMCPProviderResources.
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any]) -> Resource
@@ -155,7 +155,7 @@ We use `_original_uri_template` with `params` to construct the internal
URI that the nested server understands.
-#### `read`
+#### `read`
```python
read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult
@@ -167,7 +167,7 @@ Reads the resource via the wrapped server and returns the ResourceResult.
This method is called by Docket during background task execution.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -176,7 +176,7 @@ register_with_docket(self, docket: Docket) -> None
No-op: the child's actual template is registered via get_tasks().
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution
@@ -188,13 +188,13 @@ The child's FunctionResourceTemplate.fn is registered (via get_tasks),
and it expects splatted **kwargs, so we splat params here.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProvider`
+### `FastMCPProvider`
Provider that wraps a FastMCP server.
@@ -210,7 +210,7 @@ This ensures middleware runs when components are executed.
**Methods:**
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -224,7 +224,7 @@ server's transforms applied, then applies this provider's transforms
for correct registration keys.
-#### `lifespan`
+#### `lifespan`
```python
lifespan(self) -> AsyncIterator[None]
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index 4fdca2448..353023918 100644
--- a/docs/python-sdk/fastmcp-server-server.mdx
+++ b/docs/python-sdk/fastmcp-server-server.mdx
@@ -10,7 +10,7 @@ FastMCP - A more ergonomic interface for MCP servers.
## Functions
-### `default_lifespan`
+### `default_lifespan`
```python
default_lifespan(server: FastMCP[LifespanResultT]) -> AsyncIterator[Any]
@@ -26,7 +26,7 @@ Default lifespan context manager that does nothing.
- An empty dictionary as the lifespan result.
-### `create_proxy`
+### `create_proxy`
```python
create_proxy(target: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
@@ -54,104 +54,65 @@ use `FastMCPProxy` or `ProxyProvider` directly from `fastmcp.server.providers.pr
## Classes
-### `StateValue`
+### `StateValue`
Wrapper for stored context state values.
-### `FastMCP`
+### `FastMCP`
**Methods:**
-#### `settings`
+#### `settings`
```python
settings(self) -> Settings
```
-#### `name`
+#### `name`
```python
name(self) -> str
```
-#### `instructions`
+#### `instructions`
```python
instructions(self) -> str | None
```
-#### `instructions`
+#### `instructions`
```python
instructions(self, value: str | None) -> None
```
-#### `version`
+#### `version`
```python
version(self) -> str | None
```
-#### `website_url`
+#### `website_url`
```python
website_url(self) -> str | None
```
-#### `icons`
+#### `icons`
```python
icons(self) -> list[mcp.types.Icon]
```
-#### `docket`
-
-```python
-docket(self) -> Docket | None
-```
-
-Get the Docket instance if Docket support is enabled.
-
-Returns None if Docket is not enabled or server hasn't been started yet.
-
-
-#### `run_async`
-
-```python
-run_async(self, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None
-```
-
-Run the FastMCP server asynchronously.
-
-**Args:**
-- `transport`: Transport protocol to use ("stdio", "sse", or "streamable-http")
-- `show_banner`: Whether to display the server banner. If None, uses the
-FASTMCP_SHOW_SERVER_BANNER setting (default\: True).
-
-
-#### `run`
-
-```python
-run(self, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None
-```
-
-Run the FastMCP server. Note this is a synchronous function.
-
-**Args:**
-- `transport`: Transport protocol to use ("http", "stdio", "sse", or "streamable-http")
-- `show_banner`: Whether to display the server banner. If None, uses the
-FASTMCP_SHOW_SERVER_BANNER setting (default\: True).
-
-
-#### `add_middleware`
+#### `add_middleware`
```python
add_middleware(self, middleware: Middleware) -> None
```
-#### `add_provider`
+#### `add_provider`
```python
add_provider(self, provider: Provider) -> None
@@ -171,7 +132,7 @@ always take precedence over providers.
- Prompts become "namespace_promptname"
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -183,7 +144,7 @@ Overrides AggregateProvider.get_tasks() to apply server-level transforms
after aggregation. AggregateProvider handles provider-level namespacing.
-#### `add_transform`
+#### `add_transform`
```python
add_transform(self, transform: Transform) -> None
@@ -198,7 +159,7 @@ They transform tools, resources, and prompts from ALL providers.
- `transform`: The transform to add.
-#### `add_tool_transformation`
+#### `add_tool_transformation`
```python
add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None
@@ -210,7 +171,7 @@ Add a tool transformation.
Use ``add_transform(ToolTransform({...}))`` instead.
-#### `remove_tool_transformation`
+#### `remove_tool_transformation`
```python
remove_tool_transformation(self, _tool_name: str) -> None
@@ -222,7 +183,7 @@ Remove a tool transformation.
Tool transformations are now immutable. Use enable/disable controls instead.
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> Sequence[Tool]
@@ -235,7 +196,7 @@ and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None
@@ -255,7 +216,7 @@ session transforms can override provider-level disables.
- The tool if found and enabled, None otherwise.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> Sequence[Resource]
@@ -268,7 +229,7 @@ and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None
@@ -287,7 +248,7 @@ transforms (including session-level) have been applied.
- The resource if found and enabled, None otherwise.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> Sequence[ResourceTemplate]
@@ -300,7 +261,7 @@ auth filtering, and middleware execution. Returns all versions (no deduplication
Protocol handlers deduplicate for MCP wire format.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None
@@ -319,7 +280,7 @@ all transforms (including session-level) have been applied.
- The template if found and enabled, None otherwise.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> Sequence[Prompt]
@@ -332,7 +293,7 @@ and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None
@@ -351,19 +312,19 @@ transforms (including session-level) have been applied.
- The prompt if found and enabled, None otherwise.
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult
```
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult
```
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult | mcp.types.CreateTaskResult
@@ -393,19 +354,19 @@ return ToolResult.
- `ValidationError`: If arguments fail validation
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str) -> ResourceResult
```
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str) -> mcp.types.CreateTaskResult
```
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str) -> ResourceResult | mcp.types.CreateTaskResult
@@ -434,19 +395,19 @@ return ResourceResult.
- `ResourceError`: If resource read fails
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult
```
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult
```
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult | mcp.types.CreateTaskResult
@@ -476,28 +437,7 @@ return PromptResult.
- `PromptError`: If prompt rendering fails
-#### `custom_route`
-
-```python
-custom_route(self, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True) -> Callable[[Callable[[Request], Awaitable[Response]]], Callable[[Request], Awaitable[Response]]]
-```
-
-Decorator to register a custom HTTP route on the FastMCP server.
-
-Allows adding arbitrary HTTP endpoints outside the standard MCP protocol,
-which can be useful for OAuth callbacks, health checks, or admin APIs.
-The handler function must be an async function that accepts a Starlette
-Request and returns a Response.
-
-**Args:**
-- `path`: URL path for the route (e.g., "/auth/callback")
-- `methods`: List of HTTP methods to support (e.g., ["GET", "POST"])
-- `name`: Optional name for the route (to reference this route with
-Starlette's reverse URL lookup feature)
-- `include_in_schema`: Whether to include in OpenAPI schema, defaults to True
-
-
-#### `add_tool`
+#### `add_tool`
```python
add_tool(self, tool: Tool | Callable[..., Any]) -> Tool
@@ -515,7 +455,7 @@ with the Context type annotation. See the @tool decorator for examples.
- The tool instance that was added to the server.
-#### `remove_tool`
+#### `remove_tool`
```python
remove_tool(self, name: str, version: str | None = None) -> None
@@ -531,19 +471,19 @@ Remove tool(s) from the server.
- `NotFoundError`: If no matching tool is found.
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: AnyFunction) -> FunctionTool
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool]
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool]
@@ -599,7 +539,7 @@ server.tool(my_function, name="custom_name")
```
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource | Callable[..., Any]) -> Resource | ResourceTemplate
@@ -614,7 +554,7 @@ Add a resource to the server.
- The resource instance that was added to the server.
-#### `add_template`
+#### `add_template`
```python
add_template(self, template: ResourceTemplate) -> ResourceTemplate
@@ -629,7 +569,7 @@ Add a resource template to the server.
- The template instance that was added to the server.
-#### `resource`
+#### `resource`
```python
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate | AnyFunction]
@@ -688,7 +628,7 @@ async def get_weather(city: str) -> str:
```
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt
@@ -703,19 +643,19 @@ Add a prompt to the server.
- The prompt instance that was added to the server.
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt]
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt]
@@ -792,68 +732,7 @@ Decorator to register a prompt.
```
-#### `run_stdio_async`
-
-```python
-run_stdio_async(self, show_banner: bool = True, log_level: str | None = None, stateless: bool = False) -> None
-```
-
-Run the server using stdio transport.
-
-**Args:**
-- `show_banner`: Whether to display the server banner
-- `log_level`: Log level for the server
-- `stateless`: Whether to run in stateless mode (no session initialization)
-
-
-#### `run_http_async`
-
-```python
-run_http_async(self, show_banner: bool = True, transport: Literal['http', 'streamable-http', 'sse'] = 'http', host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, stateless: bool | None = None) -> None
-```
-
-Run the server using HTTP transport.
-
-**Args:**
-- `transport`: Transport protocol to use - either "streamable-http" (default) or "sse"
-- `host`: Host address to bind to (defaults to settings.host)
-- `port`: Port to bind to (defaults to settings.port)
-- `log_level`: Log level for the server (defaults to settings.log_level)
-- `path`: Path for the endpoint (defaults to settings.streamable_http_path or settings.sse_path)
-- `uvicorn_config`: Additional configuration for the Uvicorn server
-- `middleware`: A list of middleware to apply to the app
-- `json_response`: Whether to use JSON response format (defaults to settings.json_response)
-- `stateless_http`: Whether to use stateless HTTP (defaults to settings.stateless_http)
-- `stateless`: Alias for stateless_http for CLI consistency
-
-
-#### `http_app`
-
-```python
-http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http', event_store: EventStore | None = None, retry_interval: int | None = None) -> StarletteWithLifespan
-```
-
-Create a Starlette app using the specified HTTP transport.
-
-**Args:**
-- `path`: The path for the HTTP endpoint
-- `middleware`: A list of middleware to apply to the app
-- `json_response`: Whether to use JSON response format
-- `stateless_http`: Whether to use stateless mode (new transport per request)
-- `transport`: Transport protocol to use - "http", "streamable-http", or "sse"
-- `event_store`: Optional event store for SSE polling/resumability. When set,
-enables clients to reconnect and resume receiving events after
-server-initiated disconnections. Only used with streamable-http transport.
-- `retry_interval`: Optional retry interval in milliseconds for SSE polling.
-Controls how quickly clients should reconnect after server-initiated
-disconnections. Requires event_store to be set. Only used with
-streamable-http transport.
-
-**Returns:**
-- A Starlette application configured with the specified transport
-
-
-#### `mount`
+#### `mount`
```python
mount(self, server: FastMCP[LifespanResultT], namespace: str | None = None, as_proxy: bool | None = None, tool_names: dict[str, str] | None = None, prefix: str | None = None) -> None
@@ -900,7 +779,7 @@ mounted server.
- `prefix`: Deprecated. Use namespace instead.
-#### `import_server`
+#### `import_server`
```python
import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None
@@ -941,7 +820,7 @@ templates, and prompts are imported with their original names.
objects are imported with their original names.
-#### `from_openapi`
+#### `from_openapi`
```python
from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, name: str = 'OpenAPI Server', route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self
@@ -965,7 +844,7 @@ Create a FastMCP server from an OpenAPI specification.
- A FastMCP server with an OpenAPIProvider attached.
-#### `from_fastapi`
+#### `from_fastapi`
```python
from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self
@@ -989,7 +868,7 @@ Create a FastMCP server from a FastAPI application.
- A FastMCP server with an OpenAPIProvider attached.
-#### `as_proxy`
+#### `as_proxy`
```python
as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
@@ -1007,7 +886,7 @@ instance or any value accepted as the `transport` argument of
`fastmcp.client.Client` constructor.
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
diff --git a/docs/python-sdk/fastmcp-server-transforms-__init__.mdx b/docs/python-sdk/fastmcp-server-transforms-__init__.mdx
index 6b7e5db17..74857381e 100644
--- a/docs/python-sdk/fastmcp-server-transforms-__init__.mdx
+++ b/docs/python-sdk/fastmcp-server-transforms-__init__.mdx
@@ -8,9 +8,9 @@ sidebarTitle: __init__
Transform system for component transformations.
-Transforms modify components (tools, resources, prompts) using a middleware pattern.
-Each transform wraps the next in the chain via `call_next`, allowing transforms to
-intercept, modify, or replace component queries.
+Transforms modify components (tools, resources, prompts). List operations use a pure
+function pattern where transforms receive sequences and return transformed sequences.
+Get operations use a middleware pattern with `call_next` to chain lookups.
Unlike middleware (which operates on requests), transforms are observable by the
system for task registration, tag filtering, and component introspection.
@@ -28,61 +28,58 @@ Example:
## Classes
-### `GetToolNext`
+### `GetToolNext`
Protocol for get_tool call_next functions.
-### `GetResourceNext`
+### `GetResourceNext`
Protocol for get_resource call_next functions.
-### `GetResourceTemplateNext`
+### `GetResourceTemplateNext`
Protocol for get_resource_template call_next functions.
-### `GetPromptNext`
+### `GetPromptNext`
Protocol for get_prompt call_next functions.
-### `Transform`
+### `Transform`
Base class for component transformations.
-Transforms use a middleware pattern with `call_next` to chain operations.
-Each transform can intercept, modify, or pass through component queries.
-
-For list operations, call `call_next()` to get components from downstream,
-then transform the result. For get operations, optionally transform the
-name/uri before calling `call_next`, then transform the result.
+List operations use a pure function pattern: transforms receive sequences
+and return transformed sequences. Get operations use a middleware pattern
+with `call_next` to chain lookups.
**Methods:**
-#### `list_tools`
+#### `list_tools`
```python
-list_tools(self, call_next: ListToolsNext) -> Sequence[Tool]
+list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
```
List tools with transformation applied.
**Args:**
-- `call_next`: Callable to get tools from downstream transforms/provider.
+- `tools`: Sequence of tools to transform.
**Returns:**
- Transformed sequence of tools.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
@@ -99,22 +96,22 @@ Get a tool by name.
- The tool if found, None otherwise.
-#### `list_resources`
+#### `list_resources`
```python
-list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource]
+list_resources(self, resources: Sequence[Resource]) -> Sequence[Resource]
```
List resources with transformation applied.
**Args:**
-- `call_next`: Callable to get resources from downstream transforms/provider.
+- `resources`: Sequence of resources to transform.
**Returns:**
- Transformed sequence of resources.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None
@@ -131,22 +128,22 @@ Get a resource by URI.
- The resource if found, None otherwise.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
-list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate]
+list_resource_templates(self, templates: Sequence[ResourceTemplate]) -> Sequence[ResourceTemplate]
```
List resource templates with transformation applied.
**Args:**
-- `call_next`: Callable to get templates from downstream transforms/provider.
+- `templates`: Sequence of resource templates to transform.
**Returns:**
- Transformed sequence of resource templates.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None
@@ -163,22 +160,22 @@ Get a resource template by URI.
- The resource template if found, None otherwise.
-#### `list_prompts`
+#### `list_prompts`
```python
-list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt]
+list_prompts(self, prompts: Sequence[Prompt]) -> Sequence[Prompt]
```
List prompts with transformation applied.
**Args:**
-- `call_next`: Callable to get prompts from downstream transforms/provider.
+- `prompts`: Sequence of prompts to transform.
**Returns:**
- Transformed sequence of prompts.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None
diff --git a/docs/python-sdk/fastmcp-server-transforms-enabled.mdx b/docs/python-sdk/fastmcp-server-transforms-enabled.mdx
index ebf95d5b1..a3b3f3b8d 100644
--- a/docs/python-sdk/fastmcp-server-transforms-enabled.mdx
+++ b/docs/python-sdk/fastmcp-server-transforms-enabled.mdx
@@ -15,7 +15,7 @@ Final filtering happens at the Provider level.
## Functions
-### `is_enabled`
+### `is_enabled`
```python
is_enabled(component: FastMCPComponent) -> bool
@@ -37,7 +37,7 @@ Returns False if enabled mark is False.
- True if component should be enabled/visible to clients.
-### `get_visibility_rules`
+### `get_visibility_rules`
```python
get_visibility_rules(context: Context) -> list[dict[str, Any]]
@@ -47,7 +47,7 @@ get_visibility_rules(context: Context) -> list[dict[str, Any]]
Load visibility rule dicts from session state.
-### `save_visibility_rules`
+### `save_visibility_rules`
```python
save_visibility_rules(context: Context, rules: list[dict[str, Any]]) -> None
@@ -64,7 +64,7 @@ If None, sends notifications for all types (safe default).
If provided, only sends notifications for specified types.
-### `create_enabled_transforms`
+### `create_enabled_transforms`
```python
create_enabled_transforms(rules: list[dict[str, Any]]) -> list[Enabled]
@@ -74,7 +74,7 @@ create_enabled_transforms(rules: list[dict[str, Any]]) -> list[Enabled]
Convert rule dicts to Enabled transforms.
-### `get_session_transforms`
+### `get_session_transforms`
```python
get_session_transforms(context: Context) -> list[Enabled]
@@ -84,7 +84,7 @@ get_session_transforms(context: Context) -> list[Enabled]
Get session-specific Enabled transforms from state store.
-### `enable_components`
+### `enable_components`
```python
enable_components(context: Context) -> None
@@ -110,7 +110,7 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `match_all`: If True, matches all components regardless of other criteria.
-### `disable_components`
+### `disable_components`
```python
disable_components(context: Context) -> None
@@ -136,7 +136,7 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `match_all`: If True, matches all components regardless of other criteria.
-### `reset_components`
+### `reset_components`
```python
reset_components(context: Context) -> None
@@ -154,7 +154,7 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `context`: The context for this session.
-### `apply_session_transforms`
+### `apply_session_transforms`
```python
apply_session_transforms(components: Sequence[ComponentT]) -> Sequence[ComponentT]
@@ -176,7 +176,7 @@ global transforms due to mark-based semantics (later marks win).
## Classes
-### `Enabled`
+### `Enabled`
Sets enabled state on matching components.
@@ -188,16 +188,16 @@ Final filtering happens at the Provider level after all transforms run.
**Methods:**
-#### `list_tools`
+#### `list_tools`
```python
-list_tools(self, call_next: ListToolsNext) -> Sequence[Tool]
+list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
```
Mark tools by enabled state.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
@@ -206,16 +206,16 @@ get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
Mark tool if found.
-#### `list_resources`
+#### `list_resources`
```python
-list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource]
+list_resources(self, resources: Sequence[Resource]) -> Sequence[Resource]
```
Mark resources by enabled state.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None
@@ -224,16 +224,16 @@ get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None
Mark resource if found.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
-list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate]
+list_resource_templates(self, templates: Sequence[ResourceTemplate]) -> Sequence[ResourceTemplate]
```
Mark resource templates by enabled state.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None
@@ -242,16 +242,16 @@ get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> Res
Mark resource template if found.
-#### `list_prompts`
+#### `list_prompts`
```python
-list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt]
+list_prompts(self, prompts: Sequence[Prompt]) -> Sequence[Prompt]
```
Mark prompts by enabled state.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None
diff --git a/docs/python-sdk/fastmcp-server-transforms-namespace.mdx b/docs/python-sdk/fastmcp-server-transforms-namespace.mdx
index 0260e3a2e..bb39cd653 100644
--- a/docs/python-sdk/fastmcp-server-transforms-namespace.mdx
+++ b/docs/python-sdk/fastmcp-server-transforms-namespace.mdx
@@ -10,7 +10,7 @@ Namespace transform for prefixing component names.
## Classes
-### `Namespace`
+### `Namespace`
Prefixes component names with a namespace.
@@ -23,16 +23,16 @@ Prefixes component names with a namespace.
**Methods:**
-#### `list_tools`
+#### `list_tools`
```python
-list_tools(self, call_next: ListToolsNext) -> Sequence[Tool]
+list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
```
Prefix tool names with namespace.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
@@ -41,16 +41,16 @@ get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
Get tool by namespaced name.
-#### `list_resources`
+#### `list_resources`
```python
-list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource]
+list_resources(self, resources: Sequence[Resource]) -> Sequence[Resource]
```
Add namespace path segment to resource URIs.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None
@@ -59,16 +59,16 @@ get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None
Get resource by namespaced URI.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
-list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate]
+list_resource_templates(self, templates: Sequence[ResourceTemplate]) -> Sequence[ResourceTemplate]
```
Add namespace path segment to template URIs.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None
@@ -77,16 +77,16 @@ get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> Res
Get resource template by namespaced URI.
-#### `list_prompts`
+#### `list_prompts`
```python
-list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt]
+list_prompts(self, prompts: Sequence[Prompt]) -> Sequence[Prompt]
```
Prefix prompt names with namespace.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None
diff --git a/docs/python-sdk/fastmcp-server-transforms-tool_transform.mdx b/docs/python-sdk/fastmcp-server-transforms-tool_transform.mdx
index 417e18f77..1b01b38f7 100644
--- a/docs/python-sdk/fastmcp-server-transforms-tool_transform.mdx
+++ b/docs/python-sdk/fastmcp-server-transforms-tool_transform.mdx
@@ -24,13 +24,13 @@ hidden arguments, and other transformations at the transform level.
#### `list_tools`
```python
-list_tools(self, call_next: ListToolsNext) -> Sequence[Tool]
+list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
```
Apply transforms to matching tools.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
diff --git a/docs/python-sdk/fastmcp-server-transforms-version_filter.mdx b/docs/python-sdk/fastmcp-server-transforms-version_filter.mdx
index 7a2e43431..d0665eb97 100644
--- a/docs/python-sdk/fastmcp-server-transforms-version_filter.mdx
+++ b/docs/python-sdk/fastmcp-server-transforms-version_filter.mdx
@@ -10,7 +10,7 @@ Version filter transform for filtering components by version range.
## Classes
-### `VersionFilter`
+### `VersionFilter`
Filters components by version range.
@@ -36,49 +36,49 @@ Works with any version string - PEP 440 (1.0, 2.0) or dates (2025-01-01).
**Methods:**
-#### `list_tools`
+#### `list_tools`
```python
-list_tools(self, call_next: ListToolsNext) -> Sequence[Tool]
+list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
```
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
```
-#### `list_resources`
+#### `list_resources`
```python
-list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource]
+list_resources(self, resources: Sequence[Resource]) -> Sequence[Resource]
```
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None
```
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
-list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate]
+list_resource_templates(self, templates: Sequence[ResourceTemplate]) -> Sequence[ResourceTemplate]
```
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None
```
-#### `list_prompts`
+#### `list_prompts`
```python
-list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt]
+list_prompts(self, prompts: Sequence[Prompt]) -> Sequence[Prompt]
```
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None
diff --git a/docs/python-sdk/fastmcp-utilities-tests.mdx b/docs/python-sdk/fastmcp-utilities-tests.mdx
index e59e40d46..d065a03d9 100644
--- a/docs/python-sdk/fastmcp-utilities-tests.mdx
+++ b/docs/python-sdk/fastmcp-utilities-tests.mdx
@@ -7,7 +7,7 @@ sidebarTitle: tests
## Functions
-### `temporary_settings`
+### `temporary_settings`
```python
temporary_settings(**kwargs: Any)
@@ -20,7 +20,7 @@ Temporarily override FastMCP setting values.
- `**kwargs`: The settings to override, including nested settings.
-### `run_server_in_process`
+### `run_server_in_process`
```python
run_server_in_process(server_fn: Callable[..., None], *args: Any, **kwargs: Any) -> Generator[str, None, None]
@@ -43,7 +43,7 @@ not pickleable, so we need a function that creates and runs one.
- The server URL.
-### `run_server_async`
+### `run_server_async`
```python
run_server_async(server: FastMCP, port: int | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http', path: str = '/mcp', host: str = '127.0.0.1') -> AsyncGenerator[str, None]
@@ -64,19 +64,9 @@ sleeps, and cleanup issues.
- `host`: Host to bind to (default\: "127.0.0.1")
-### `caplog_for_fastmcp`
-
-```python
-caplog_for_fastmcp(caplog: LogCaptureFixture) -> Generator[LogCaptureFixture, None, None]
-```
-
-
-Context manager to capture logs from FastMCP loggers even when propagation is disabled.
-
-
## Classes
-### `HeadlessOAuth`
+### `HeadlessOAuth`
OAuth provider that bypasses browser interaction for testing.
@@ -87,7 +77,7 @@ instead of opening a browser and running a callback server. Useful for automated
**Methods:**
-#### `redirect_handler`
+#### `redirect_handler`
```python
redirect_handler(self, authorization_url: str) -> None
@@ -96,7 +86,7 @@ redirect_handler(self, authorization_url: str) -> None
Make HTTP request to authorization URL and store response for callback handler.
-#### `callback_handler`
+#### `callback_handler`
```python
callback_handler(self) -> tuple[str, str | None]