From d35b867b10b2e4b74d9b682c9ebd6b68ddaa5cca Mon Sep 17 00:00:00 2001
From: "marvin-context-protocol[bot]"
<225465937+marvin-context-protocol[bot]@users.noreply.github.com>
Date: Tue, 9 Dec 2025 21:07:20 -0500
Subject: [PATCH] chore: Update SDK documentation (#2517)
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
---
docs/docs.json | 21 +-
docs/python-sdk/fastmcp-cli-cli.mdx | 12 +-
docs/python-sdk/fastmcp-cli-tasks.mdx | 41 +++
docs/python-sdk/fastmcp-client-auth-oauth.mdx | 18 +-
docs/python-sdk/fastmcp-client-client.mdx | 238 ++++++++++++++----
.../python-sdk/fastmcp-client-elicitation.mdx | 2 +-
docs/python-sdk/fastmcp-client-messages.mdx | 28 +--
docs/python-sdk/fastmcp-client-tasks.mdx | 219 ++++++++++++++++
docs/python-sdk/fastmcp-client-transports.mdx | 66 +++--
docs/python-sdk/fastmcp-dependencies.mdx | 14 ++
docs/python-sdk/fastmcp-prompts-prompt.mdx | 12 +-
.../python-sdk/fastmcp-resources-resource.mdx | 26 +-
.../python-sdk/fastmcp-resources-template.mdx | 42 ++--
docs/python-sdk/fastmcp-server-auth-auth.mdx | 80 ++++--
.../fastmcp-server-auth-oauth_proxy.mdx | 72 ++----
docs/python-sdk/fastmcp-server-context.mdx | 80 +++---
.../fastmcp-server-dependencies.mdx | 216 +++++++++++++++-
.../python-sdk/fastmcp-server-elicitation.mdx | 75 +++++-
.../python-sdk/fastmcp-server-event_store.mdx | 78 ++++++
docs/python-sdk/fastmcp-server-http.mdx | 23 +-
docs/python-sdk/fastmcp-server-low_level.mdx | 10 +-
.../fastmcp-server-middleware-middleware.mdx | 2 +-
docs/python-sdk/fastmcp-server-proxy.mdx | 74 +++---
docs/python-sdk/fastmcp-server-server.mdx | 129 +++++-----
.../fastmcp-server-tasks-__init__.mdx | 12 +
.../fastmcp-server-tasks-capabilities.mdx | 24 ++
.../fastmcp-server-tasks-config.mdx | 66 +++++
.../fastmcp-server-tasks-converters.mdx | 77 ++++++
.../fastmcp-server-tasks-handlers.mdx | 78 ++++++
docs/python-sdk/fastmcp-server-tasks-keys.mdx | 91 +++++++
.../fastmcp-server-tasks-protocol.mdx | 88 +++++++
.../fastmcp-server-tasks-subscriptions.mdx | 35 +++
docs/python-sdk/fastmcp-settings.mdx | 28 +--
docs/python-sdk/fastmcp-tools-tool.mdx | 45 ++--
docs/python-sdk/fastmcp-utilities-tests.mdx | 16 +-
docs/python-sdk/fastmcp-utilities-types.mdx | 18 +-
36 files changed, 1740 insertions(+), 416 deletions(-)
create mode 100644 docs/python-sdk/fastmcp-cli-tasks.mdx
create mode 100644 docs/python-sdk/fastmcp-client-tasks.mdx
create mode 100644 docs/python-sdk/fastmcp-dependencies.mdx
create mode 100644 docs/python-sdk/fastmcp-server-event_store.mdx
create mode 100644 docs/python-sdk/fastmcp-server-tasks-__init__.mdx
create mode 100644 docs/python-sdk/fastmcp-server-tasks-capabilities.mdx
create mode 100644 docs/python-sdk/fastmcp-server-tasks-config.mdx
create mode 100644 docs/python-sdk/fastmcp-server-tasks-converters.mdx
create mode 100644 docs/python-sdk/fastmcp-server-tasks-handlers.mdx
create mode 100644 docs/python-sdk/fastmcp-server-tasks-keys.mdx
create mode 100644 docs/python-sdk/fastmcp-server-tasks-protocol.mdx
create mode 100644 docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx
diff --git a/docs/docs.json b/docs/docs.json
index 8c9cbebbd..889e8f37b 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -276,6 +276,7 @@
"anchor": "Python SDK",
"icon": "python",
"pages": [
+ "python-sdk/fastmcp-dependencies",
"python-sdk/fastmcp-exceptions",
"python-sdk/fastmcp-mcp_config",
"python-sdk/fastmcp-settings",
@@ -296,7 +297,8 @@
"python-sdk/fastmcp-cli-install-shared"
]
},
- "python-sdk/fastmcp-cli-run"
+ "python-sdk/fastmcp-cli-run",
+ "python-sdk/fastmcp-cli-tasks"
]
},
{
@@ -319,6 +321,7 @@
"python-sdk/fastmcp-client-progress",
"python-sdk/fastmcp-client-roots",
"python-sdk/fastmcp-client-sampling",
+ "python-sdk/fastmcp-client-tasks",
"python-sdk/fastmcp-client-transports"
]
},
@@ -380,6 +383,7 @@
"python-sdk/fastmcp-server-context",
"python-sdk/fastmcp-server-dependencies",
"python-sdk/fastmcp-server-elicitation",
+ "python-sdk/fastmcp-server-event_store",
"python-sdk/fastmcp-server-http",
"python-sdk/fastmcp-server-low_level",
{
@@ -405,7 +409,20 @@
]
},
"python-sdk/fastmcp-server-proxy",
- "python-sdk/fastmcp-server-server"
+ "python-sdk/fastmcp-server-server",
+ {
+ "group": "tasks",
+ "pages": [
+ "python-sdk/fastmcp-server-tasks-__init__",
+ "python-sdk/fastmcp-server-tasks-capabilities",
+ "python-sdk/fastmcp-server-tasks-config",
+ "python-sdk/fastmcp-server-tasks-converters",
+ "python-sdk/fastmcp-server-tasks-handlers",
+ "python-sdk/fastmcp-server-tasks-keys",
+ "python-sdk/fastmcp-server-tasks-protocol",
+ "python-sdk/fastmcp-server-tasks-subscriptions"
+ ]
+ }
]
},
{
diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx
index 79cb794db..6dbb1a74b 100644
--- a/docs/python-sdk/fastmcp-cli-cli.mdx
+++ b/docs/python-sdk/fastmcp-cli-cli.mdx
@@ -10,7 +10,7 @@ FastMCP CLI tools using Cyclopts.
## Functions
-### `with_argv`
+### `with_argv`
```python
with_argv(args: list[str] | None)
@@ -27,7 +27,7 @@ Args are provided without the script name, so we preserve sys.argv[0]
and replace the rest.
-### `version`
+### `version`
```python
version()
@@ -37,7 +37,7 @@ version()
Display version information and platform details.
-### `dev`
+### `dev`
```python
dev(server_spec: str | None = None) -> None
@@ -50,7 +50,7 @@ Run an MCP server with the MCP Inspector for development.
- `server_spec`: Python file to run, optionally with \:object suffix, or None to auto-detect fastmcp.json
-### `run`
+### `run`
```python
run(server_spec: str | None = None, *server_args: str) -> None
@@ -74,7 +74,7 @@ fastmcp run server.py -- --config config.json --debug
- `server_spec`: Python file, object specification (file\:obj), config file, URL, or None to auto-detect
-### `inspect`
+### `inspect`
```python
inspect(server_spec: str | None = None) -> None
@@ -105,7 +105,7 @@ fastmcp inspect # auto-detect fastmcp.json
- `server_spec`: Python file to inspect, optionally with \:object suffix, or fastmcp.json
-### `prepare`
+### `prepare`
```python
prepare(config_path: Annotated[str | None, cyclopts.Parameter(help='Path to fastmcp.json configuration file')] = None, output_dir: Annotated[str | None, cyclopts.Parameter(help='Directory to create the persistent environment in')] = None, skip_source: Annotated[bool, cyclopts.Parameter(help='Skip source preparation (e.g., git clone)')] = False) -> None
diff --git a/docs/python-sdk/fastmcp-cli-tasks.mdx b/docs/python-sdk/fastmcp-cli-tasks.mdx
new file mode 100644
index 000000000..b1ac931aa
--- /dev/null
+++ b/docs/python-sdk/fastmcp-cli-tasks.mdx
@@ -0,0 +1,41 @@
+---
+title: tasks
+sidebarTitle: tasks
+---
+
+# `fastmcp.cli.tasks`
+
+
+FastMCP tasks CLI for Docket task management.
+
+## Functions
+
+### `check_distributed_backend`
+
+```python
+check_distributed_backend() -> None
+```
+
+
+Check if Docket is configured with a distributed backend.
+
+The CLI worker runs as a separate process, so it needs Redis/Valkey
+to coordinate with the main server process.
+
+**Raises:**
+- `SystemExit`: If using memory\:// URL
+
+
+### `worker`
+
+```python
+worker(server_spec: Annotated[str | None, cyclopts.Parameter(help='Python file to run, optionally with :object suffix, or None to auto-detect fastmcp.json')] = None) -> None
+```
+
+
+Start an additional worker to process background tasks.
+
+Connects to your Docket backend and processes tasks in parallel with
+any other running workers. Configure via environment variables
+(FASTMCP_DOCKET_*).
+
diff --git a/docs/python-sdk/fastmcp-client-auth-oauth.mdx b/docs/python-sdk/fastmcp-client-auth-oauth.mdx
index 40d890ddf..aca8c2e25 100644
--- a/docs/python-sdk/fastmcp-client-auth-oauth.mdx
+++ b/docs/python-sdk/fastmcp-client-auth-oauth.mdx
@@ -7,7 +7,7 @@ sidebarTitle: oauth
## Functions
-### `check_if_auth_required`
+### `check_if_auth_required`
```python
check_if_auth_required(mcp_url: str, httpx_kwargs: dict[str, Any] | None = None) -> bool
@@ -22,47 +22,47 @@ Check if the MCP endpoint requires authentication by making a test request.
## Classes
-### `ClientNotFoundError`
+### `ClientNotFoundError`
Raised when OAuth client credentials are not found on the server.
-### `TokenStorageAdapter`
+### `TokenStorageAdapter`
**Methods:**
-#### `clear`
+#### `clear`
```python
clear(self) -> None
```
-#### `get_tokens`
+#### `get_tokens`
```python
get_tokens(self) -> OAuthToken | None
```
-#### `set_tokens`
+#### `set_tokens`
```python
set_tokens(self, tokens: OAuthToken) -> None
```
-#### `get_client_info`
+#### `get_client_info`
```python
get_client_info(self) -> OAuthClientInformationFull | None
```
-#### `set_client_info`
+#### `set_client_info`
```python
set_client_info(self, client_info: OAuthClientInformationFull) -> None
```
-### `OAuth`
+### `OAuth`
OAuth client provider for MCP servers with browser-based authentication.
diff --git a/docs/python-sdk/fastmcp-client-client.mdx b/docs/python-sdk/fastmcp-client-client.mdx
index cbb1599f9..2f2a5fdc9 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,7 +16,13 @@ This allows clean separation of configuration (which is copied) from
session state (which should be fresh for each new client instance).
-### `Client`
+### `CallToolResult`
+
+
+Parsed result from a tool call.
+
+
+### `Client`
MCP client that delegates connection management to a Transport instance.
@@ -79,7 +85,7 @@ async with client:
**Methods:**
-#### `session`
+#### `session`
```python
session(self) -> ClientSession
@@ -88,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
@@ -97,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
@@ -106,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: ClientSamplingHandler) -> None
@@ -115,7 +121,7 @@ set_sampling_callback(self, sampling_callback: ClientSamplingHandler) -> None
Set the sampling callback for the client.
-#### `set_elicitation_callback`
+#### `set_elicitation_callback`
```python
set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
@@ -124,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
@@ -133,7 +139,7 @@ is_connected(self) -> bool
Check if the client is currently connected.
-#### `new`
+#### `new`
```python
new(self) -> Client[ClientTransportT]
@@ -149,13 +155,7 @@ share state with the original client.
- A new Client instance with the same configuration but disconnected state.
-#### `close`
-
-```python
-close(self)
-```
-
-#### `initialize`
+#### `initialize`
```python
initialize(self, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.InitializeResult
@@ -183,7 +183,13 @@ capabilities, protocol version, and optional instructions.
- `RuntimeError`: If the client is not connected or initialization times out.
-#### `ping`
+#### `close`
+
+```python
+close(self)
+```
+
+#### `ping`
```python
ping(self) -> bool
@@ -192,7 +198,7 @@ ping(self) -> bool
Send a ping request.
-#### `cancel`
+#### `cancel`
```python
cancel(self, request_id: str | int, reason: str | None = None) -> None
@@ -201,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
@@ -210,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
@@ -219,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
@@ -228,7 +234,7 @@ send_roots_list_changed(self) -> None
Send a roots/list_changed notification.
-#### `list_resources_mcp`
+#### `list_resources_mcp`
```python
list_resources_mcp(self) -> mcp.types.ListResourcesResult
@@ -244,7 +250,7 @@ containing the list of resources and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> list[mcp.types.Resource]
@@ -259,7 +265,7 @@ Retrieve a list of resources available on the server.
- `RuntimeError`: If called while the client is not connected.
-#### `list_resource_templates_mcp`
+#### `list_resource_templates_mcp`
```python
list_resource_templates_mcp(self) -> mcp.types.ListResourceTemplatesResult
@@ -275,7 +281,7 @@ containing the list of resource templates and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> list[mcp.types.ResourceTemplate]
@@ -290,16 +296,17 @@ Retrieve a list of resource templates available on the server.
- `RuntimeError`: If called while the client is not connected.
-#### `read_resource_mcp`
+#### `read_resource_mcp`
```python
-read_resource_mcp(self, uri: AnyUrl | str) -> mcp.types.ReadResourceResult
+read_resource_mcp(self, uri: AnyUrl | str, meta: dict[str, Any] | None = None) -> mcp.types.ReadResourceResult
```
Send a resources/read request and return the complete MCP protocol result.
**Args:**
- `uri`: The URI of the resource to read. Can be a string or an AnyUrl object.
+- `meta`: Request metadata (e.g., for SEP-1686 tasks). Defaults to None.
**Returns:**
- mcp.types.ReadResourceResult: The complete response object from the protocol,
@@ -309,26 +316,41 @@ containing the resource contents and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents]
```
+#### `read_resource`
+
+```python
+read_resource(self, uri: AnyUrl | str) -> ResourceTask
+```
+
+#### `read_resource`
+
+```python
+read_resource(self, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] | ResourceTask
+```
+
Read the contents of a resource or resolved template.
**Args:**
- `uri`: The URI of the resource to read. Can be a string or an AnyUrl object.
+- `task`: If True, execute as background task (SEP-1686). Defaults to False.
+- `task_id`: Optional client-provided task ID (auto-generated if not provided).
+- `ttl`: Time to keep results available in milliseconds (default 60s).
**Returns:**
-- list\[mcp.types.TextResourceContents | mcp.types.BlobResourceContents]: A list of content
-objects, typically containing either text or binary data.
+- list\[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] | ResourceTask:
+A list of content objects if task=False, or a ResourceTask object if task=True.
**Raises:**
- `RuntimeError`: If called while the client is not connected.
-#### `list_prompts_mcp`
+#### `list_prompts_mcp`
```python
list_prompts_mcp(self) -> mcp.types.ListPromptsResult
@@ -344,7 +366,7 @@ containing the list of prompts and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> list[mcp.types.Prompt]
@@ -359,10 +381,10 @@ Retrieve a list of prompts available on the server.
- `RuntimeError`: If called while the client is not connected.
-#### `get_prompt_mcp`
+#### `get_prompt_mcp`
```python
-get_prompt_mcp(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
+get_prompt_mcp(self, name: str, arguments: dict[str, Any] | None = None, meta: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
```
Send a prompts/get request and return the complete MCP protocol result.
@@ -370,6 +392,7 @@ Send a prompts/get request and return the complete MCP protocol result.
**Args:**
- `name`: The name of the prompt to retrieve.
- `arguments`: Arguments to pass to the prompt. Defaults to None.
+- `meta`: Request metadata (e.g., for SEP-1686 tasks). Defaults to None.
**Returns:**
- mcp.types.GetPromptResult: The complete response object from the protocol,
@@ -379,27 +402,42 @@ containing the prompt messages and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
```
+#### `get_prompt`
+
+```python
+get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptTask
+```
+
+#### `get_prompt`
+
+```python
+get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult | PromptTask
+```
+
Retrieve a rendered prompt message list from the server.
**Args:**
- `name`: The name of the prompt to retrieve.
- `arguments`: Arguments to pass to the prompt. Defaults to None.
+- `task`: If True, execute as background task (SEP-1686). Defaults to False.
+- `task_id`: Optional client-provided task ID (auto-generated if not provided).
+- `ttl`: Time to keep results available in milliseconds (default 60s).
**Returns:**
-- mcp.types.GetPromptResult: The complete response object from the protocol,
-containing the prompt messages and any additional metadata.
+- mcp.types.GetPromptResult | PromptTask: The complete response object if task=False,
+or a PromptTask object if task=True.
**Raises:**
- `RuntimeError`: If called while the client is not connected.
-#### `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
@@ -421,7 +459,7 @@ containing the completion and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `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
@@ -442,7 +480,7 @@ include with the completion request. Defaults to None.
- `RuntimeError`: If called while the client is not connected.
-#### `list_tools_mcp`
+#### `list_tools_mcp`
```python
list_tools_mcp(self) -> mcp.types.ListToolsResult
@@ -458,7 +496,7 @@ containing the list of tools and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> list[mcp.types.Tool]
@@ -473,7 +511,7 @@ Retrieve a list of tools available on the server.
- `RuntimeError`: If called while the client is not connected.
-#### `call_tool_mcp`
+#### `call_tool_mcp`
```python
call_tool_mcp(self, 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
@@ -502,10 +540,22 @@ containing the tool result and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `call_tool`
+#### `call_tool`
```python
-call_tool(self, name: str, arguments: dict[str, Any] | None = None, timeout: datetime.timedelta | float | int | None = None, progress_handler: ProgressHandler | None = None, raise_on_error: bool = True, meta: dict[str, Any] | None = None) -> CallToolResult
+call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult
+```
+
+#### `call_tool`
+
+```python
+call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolTask
+```
+
+#### `call_tool`
+
+```python
+call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult | ToolTask
```
Call a tool on the server.
@@ -517,15 +567,18 @@ Unlike call_tool_mcp, this method raises a ToolError if the tool call results in
- `arguments`: Arguments to pass to the tool. Defaults to None.
- `timeout`: The timeout for the tool call. Defaults to None.
- `progress_handler`: The progress handler to use for the tool call. Defaults to None.
-- `raise_on_error`: Whether to raise a ToolError if the tool call results in an error. Defaults to True.
+- `raise_on_error`: Whether to raise an exception if the tool call results in an error. Defaults to True.
- `meta`: Additional metadata to include with the request.
This is useful for passing contextual information (like user IDs, trace IDs, or preferences)
that shouldn't be tool arguments but may influence server-side processing. The server
can access this via `context.request_context.meta`. Defaults to None.
+- `task`: If True, execute as background task (SEP-1686). Defaults to False.
+- `task_id`: Optional client-provided task ID (auto-generated if not provided).
+- `ttl`: Time to keep results available in milliseconds (default 60s).
**Returns:**
--
-The content returned by the tool. If the tool returns structured
+- CallToolResult | ToolTask: The content returned by the tool if task=False,
+or a ToolTask object if task=True. If the tool returns structured
outputs, they are returned as a dataclass (if an output schema
is available) or a dictionary; otherwise, a list of content
blocks is returned. Note: to receive both structured and
@@ -537,10 +590,95 @@ raw result object.
- `RuntimeError`: If called while the client is not connected.
-#### `generate_name`
+#### `get_task_status`
+
+```python
+get_task_status(self, task_id: str) -> GetTaskResult
+```
+
+Query the status of a background task.
+
+Sends a 'tasks/get' MCP protocol request over the existing transport.
+
+**Args:**
+- `task_id`: The task ID returned from call_tool_as_task
+
+**Returns:**
+- Status information including taskId, status, pollInterval, etc.
+
+**Raises:**
+- `RuntimeError`: If client not connected
+
+
+#### `get_task_result`
+
+```python
+get_task_result(self, task_id: str) -> Any
+```
+
+Retrieve the raw result of a completed background task.
+
+Sends a 'tasks/result' MCP protocol request over the existing transport.
+Returns the raw result - callers should parse it appropriately.
+
+**Args:**
+- `task_id`: The task ID returned from call_tool_as_task
+
+**Returns:**
+- The raw result (could be tool, prompt, or resource result)
+
+**Raises:**
+- `RuntimeError`: If client not connected, task not found, or task failed
+
+
+#### `list_tasks`
+
+```python
+list_tasks(self, cursor: str | None = None, limit: int = 50) -> dict[str, Any]
+```
+
+List background tasks.
+
+Sends a 'tasks/list' MCP protocol request to the server. If the server
+returns an empty list (indicating client-side tracking), falls back to
+querying status for locally tracked task IDs.
+
+**Args:**
+- `cursor`: Optional pagination cursor
+- `limit`: Maximum number of tasks to return (default 50)
+
+**Returns:**
+- Response with structure:
+- tasks: List of task status dicts with taskId, status, etc.
+- nextCursor: Optional cursor for next page
+
+**Raises:**
+- `RuntimeError`: If client not connected
+
+
+#### `cancel_task`
+
+```python
+cancel_task(self, task_id: str) -> mcp.types.CancelTaskResult
+```
+
+Cancel a task, transitioning it to cancelled state.
+
+Sends a 'tasks/cancel' MCP protocol request. Task will halt execution
+and transition to cancelled state.
+
+**Args:**
+- `task_id`: The task ID to cancel
+
+**Returns:**
+- The task status showing cancelled state
+
+**Raises:**
+- `RuntimeError`: If task doesn't exist
+
+
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
```
-
-### `CallToolResult`
diff --git a/docs/python-sdk/fastmcp-client-elicitation.mdx b/docs/python-sdk/fastmcp-client-elicitation.mdx
index 838f6314d..ccd3ac700 100644
--- a/docs/python-sdk/fastmcp-client-elicitation.mdx
+++ b/docs/python-sdk/fastmcp-client-elicitation.mdx
@@ -7,7 +7,7 @@ sidebarTitle: elicitation
## Functions
-### `create_elicitation_callback`
+### `create_elicitation_callback`
```python
create_elicitation_callback(elicitation_handler: ElicitationHandler) -> ElicitationFnT
diff --git a/docs/python-sdk/fastmcp-client-messages.mdx b/docs/python-sdk/fastmcp-client-messages.mdx
index ef1b87436..78c5ebd6d 100644
--- a/docs/python-sdk/fastmcp-client-messages.mdx
+++ b/docs/python-sdk/fastmcp-client-messages.mdx
@@ -22,85 +22,85 @@ requests, notifications, and exceptions. Users can override any of the hooks
dispatch(self, message: Message) -> None
```
-#### `on_message`
+#### `on_message`
```python
on_message(self, message: Message) -> None
```
-#### `on_request`
+#### `on_request`
```python
on_request(self, message: RequestResponder[mcp.types.ServerRequest, mcp.types.ClientResult]) -> None
```
-#### `on_ping`
+#### `on_ping`
```python
on_ping(self, message: mcp.types.PingRequest) -> None
```
-#### `on_list_roots`
+#### `on_list_roots`
```python
on_list_roots(self, message: mcp.types.ListRootsRequest) -> None
```
-#### `on_create_message`
+#### `on_create_message`
```python
on_create_message(self, message: mcp.types.CreateMessageRequest) -> None
```
-#### `on_notification`
+#### `on_notification`
```python
on_notification(self, message: mcp.types.ServerNotification) -> None
```
-#### `on_exception`
+#### `on_exception`
```python
on_exception(self, message: Exception) -> None
```
-#### `on_progress`
+#### `on_progress`
```python
on_progress(self, message: mcp.types.ProgressNotification) -> None
```
-#### `on_logging_message`
+#### `on_logging_message`
```python
on_logging_message(self, message: mcp.types.LoggingMessageNotification) -> None
```
-#### `on_tool_list_changed`
+#### `on_tool_list_changed`
```python
on_tool_list_changed(self, message: mcp.types.ToolListChangedNotification) -> None
```
-#### `on_resource_list_changed`
+#### `on_resource_list_changed`
```python
on_resource_list_changed(self, message: mcp.types.ResourceListChangedNotification) -> None
```
-#### `on_prompt_list_changed`
+#### `on_prompt_list_changed`
```python
on_prompt_list_changed(self, message: mcp.types.PromptListChangedNotification) -> None
```
-#### `on_resource_updated`
+#### `on_resource_updated`
```python
on_resource_updated(self, message: mcp.types.ResourceUpdatedNotification) -> None
```
-#### `on_cancelled`
+#### `on_cancelled`
```python
on_cancelled(self, message: mcp.types.CancelledNotification) -> None
diff --git a/docs/python-sdk/fastmcp-client-tasks.mdx b/docs/python-sdk/fastmcp-client-tasks.mdx
new file mode 100644
index 000000000..8e8e60578
--- /dev/null
+++ b/docs/python-sdk/fastmcp-client-tasks.mdx
@@ -0,0 +1,219 @@
+---
+title: tasks
+sidebarTitle: tasks
+---
+
+# `fastmcp.client.tasks`
+
+
+SEP-1686 client Task classes.
+
+## Classes
+
+### `TaskNotificationHandler`
+
+
+MessageHandler that routes task status notifications to Task objects.
+
+
+**Methods:**
+
+#### `dispatch`
+
+```python
+dispatch(self, message: Message) -> None
+```
+
+Dispatch messages, including task status notifications.
+
+
+### `Task`
+
+
+Abstract base class for MCP background tasks (SEP-1686).
+
+Provides a uniform API whether the server accepts background execution
+or executes synchronously (graceful degradation per SEP-1686).
+
+
+**Methods:**
+
+#### `task_id`
+
+```python
+task_id(self) -> str
+```
+
+Get the task ID.
+
+
+#### `returned_immediately`
+
+```python
+returned_immediately(self) -> bool
+```
+
+Check if server executed the task immediately.
+
+**Returns:**
+- True if server executed synchronously (graceful degradation or no task support)
+- False if server accepted background execution
+
+
+#### `on_status_change`
+
+```python
+on_status_change(self, callback: Callable[[GetTaskResult], None | Awaitable[None]]) -> None
+```
+
+Register callback for status change notifications.
+
+The callback will be invoked when a notifications/tasks/status is received
+for this task (optional server feature per SEP-1686 lines 436-444).
+
+Supports both sync and async callbacks (auto-detected).
+
+**Args:**
+- `callback`: Function to call with GetTaskResult when status changes.
+ Can return None (sync) or Awaitable[None] (async).
+
+
+#### `status`
+
+```python
+status(self) -> GetTaskResult
+```
+
+Get current task status.
+
+If server executed immediately, returns synthetic completed status.
+Otherwise queries the server for current status.
+
+
+#### `result`
+
+```python
+result(self) -> TaskResultT
+```
+
+Wait for and return the task result.
+
+Must be implemented by subclasses to return the appropriate result type.
+
+
+#### `wait`
+
+```python
+wait(self) -> GetTaskResult
+```
+
+Wait for task to reach a specific state or complete.
+
+Uses event-based waiting when notifications are available (fast),
+with fallback to polling (reliable). Optimally wakes up immediately
+on status changes when server sends notifications/tasks/status.
+
+**Args:**
+- `state`: Desired state ('submitted', 'working', 'completed', 'failed').
+ If None, waits for any terminal state (completed/failed)
+- `timeout`: Maximum time to wait in seconds
+
+**Returns:**
+- Final task status
+
+**Raises:**
+- `TimeoutError`: If desired state not reached within timeout
+
+
+#### `cancel`
+
+```python
+cancel(self) -> None
+```
+
+Cancel this task, transitioning it to cancelled state.
+
+Sends a tasks/cancel protocol request. The server will attempt to halt
+execution and move the task to cancelled state.
+
+Note: If server executed immediately (graceful degradation), this is a no-op
+as there's no server-side task to cancel.
+
+
+### `ToolTask`
+
+
+Represents a tool call that may execute in background or immediately.
+
+Provides a uniform API whether the server accepts background execution
+or executes synchronously (graceful degradation per SEP-1686).
+
+
+**Methods:**
+
+#### `result`
+
+```python
+result(self) -> CallToolResult
+```
+
+Wait for and return the tool result.
+
+If server executed immediately, returns the immediate result.
+Otherwise waits for background task to complete and retrieves result.
+
+**Returns:**
+- The parsed tool result (same as call_tool returns)
+
+
+### `PromptTask`
+
+
+Represents a prompt call that may execute in background or immediately.
+
+Provides a uniform API whether the server accepts background execution
+or executes synchronously (graceful degradation per SEP-1686).
+
+
+**Methods:**
+
+#### `result`
+
+```python
+result(self) -> mcp.types.GetPromptResult
+```
+
+Wait for and return the prompt result.
+
+If server executed immediately, returns the immediate result.
+Otherwise waits for background task to complete and retrieves result.
+
+**Returns:**
+- The prompt result with messages and description
+
+
+### `ResourceTask`
+
+
+Represents a resource read that may execute in background or immediately.
+
+Provides a uniform API whether the server accepts background execution
+or executes synchronously (graceful degradation per SEP-1686).
+
+
+**Methods:**
+
+#### `result`
+
+```python
+result(self) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents]
+```
+
+Wait for and return the resource contents.
+
+If server executed immediately, returns the immediate result.
+Otherwise waits for background task to complete and retrieves result.
+
+**Returns:**
+- list\[ReadResourceContents]: The resource contents
+
diff --git a/docs/python-sdk/fastmcp-client-transports.mdx b/docs/python-sdk/fastmcp-client-transports.mdx
index acc5aca73..8246d767c 100644
--- a/docs/python-sdk/fastmcp-client-transports.mdx
+++ b/docs/python-sdk/fastmcp-client-transports.mdx
@@ -7,7 +7,7 @@ sidebarTitle: transports
## Functions
-### `infer_transport`
+### `infer_transport`
```python
infer_transport(transport: ClientTransport | FastMCP | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str) -> ClientTransport
@@ -57,13 +57,13 @@ transport = infer_transport(config)
## Classes
-### `SessionKwargs`
+### `SessionKwargs`
Keyword arguments for the MCP ClientSession constructor.
-### `ClientTransport`
+### `ClientTransport`
Abstract base class for different MCP client transport mechanisms.
@@ -74,7 +74,7 @@ to an MCP server, and providing a ClientSession within an async context.
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
@@ -93,7 +93,7 @@ within this context.
constructor (e.g., callbacks, timeouts).
-#### `close`
+#### `close`
```python
close(self)
@@ -102,7 +102,7 @@ close(self)
Close the transport.
-### `WSTransport`
+### `WSTransport`
Transport implementation that connects to an MCP server via WebSockets.
@@ -110,13 +110,13 @@ Transport implementation that connects to an MCP server via WebSockets.
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
```
-### `SSETransport`
+### `SSETransport`
Transport implementation that connects to an MCP server via Server-Sent Events.
@@ -124,13 +124,13 @@ Transport implementation that connects to an MCP server via Server-Sent Events.
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
```
-### `StreamableHttpTransport`
+### `StreamableHttpTransport`
Transport implementation that connects to an MCP server via Streamable HTTP Requests.
@@ -138,13 +138,25 @@ Transport implementation that connects to an MCP server via Streamable HTTP Requ
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
```
-### `StdioTransport`
+#### `get_session_id`
+
+```python
+get_session_id(self) -> str | None
+```
+
+#### `close`
+
+```python
+close(self)
+```
+
+### `StdioTransport`
Base transport for connecting to an MCP server via subprocess with stdio.
@@ -155,67 +167,67 @@ transports like Python, Node, Uvx, etc.
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
```
-#### `connect`
+#### `connect`
```python
connect(self, **session_kwargs: Unpack[SessionKwargs]) -> ClientSession | None
```
-#### `disconnect`
+#### `disconnect`
```python
disconnect(self)
```
-#### `close`
+#### `close`
```python
close(self)
```
-### `PythonStdioTransport`
+### `PythonStdioTransport`
Transport for running Python scripts.
-### `FastMCPStdioTransport`
+### `FastMCPStdioTransport`
Transport for running FastMCP servers using the FastMCP CLI.
-### `NodeStdioTransport`
+### `NodeStdioTransport`
Transport for running Node.js scripts.
-### `UvStdioTransport`
+### `UvStdioTransport`
Transport for running commands via the uv tool.
-### `UvxStdioTransport`
+### `UvxStdioTransport`
Transport for running commands via the uvx tool.
-### `NpxStdioTransport`
+### `NpxStdioTransport`
Transport for running commands via the npx tool.
-### `FastMCPTransport`
+### `FastMCPTransport`
In-memory transport for FastMCP servers.
@@ -228,13 +240,13 @@ tests or scenarios where client and server run in the same runtime.
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
```
-### `MCPConfigTransport`
+### `MCPConfigTransport`
Transport for connecting to one or more MCP servers defined in an MCPConfig.
@@ -287,13 +299,13 @@ async with client:
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
```
-#### `close`
+#### `close`
```python
close(self)
diff --git a/docs/python-sdk/fastmcp-dependencies.mdx b/docs/python-sdk/fastmcp-dependencies.mdx
new file mode 100644
index 000000000..d53c37027
--- /dev/null
+++ b/docs/python-sdk/fastmcp-dependencies.mdx
@@ -0,0 +1,14 @@
+---
+title: dependencies
+sidebarTitle: dependencies
+---
+
+# `fastmcp.dependencies`
+
+
+Dependency injection exports for FastMCP.
+
+This module re-exports dependency injection symbols from Docket and FastMCP
+to provide a clean, centralized import location for all dependency-related
+functionality.
+
diff --git a/docs/python-sdk/fastmcp-prompts-prompt.mdx b/docs/python-sdk/fastmcp-prompts-prompt.mdx
index b93053e5d..fbcd6ff5a 100644
--- a/docs/python-sdk/fastmcp-prompts-prompt.mdx
+++ b/docs/python-sdk/fastmcp-prompts-prompt.mdx
@@ -60,7 +60,7 @@ Convert the prompt to an MCP prompt.
#### `from_function`
```python
-from_function(fn: Callable[..., PromptResult | Awaitable[PromptResult]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, enabled: bool | None = None, meta: dict[str, Any] | None = None) -> FunctionPrompt
+from_function(fn: Callable[..., PromptResult | Awaitable[PromptResult]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, enabled: bool | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt
```
Create a Prompt from a function.
@@ -72,7 +72,7 @@ The function can return:
- A sequence of any of the above
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any] | None = None) -> list[PromptMessage]
@@ -84,7 +84,7 @@ This method is not implemented in the base Prompt class and must be
implemented by subclasses.
-### `FunctionPrompt`
+### `FunctionPrompt`
A prompt that is a function.
@@ -92,10 +92,10 @@ A prompt that is a function.
**Methods:**
-#### `from_function`
+#### `from_function`
```python
-from_function(cls, fn: Callable[..., PromptResult | Awaitable[PromptResult]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, enabled: bool | None = None, meta: dict[str, Any] | None = None) -> FunctionPrompt
+from_function(cls, fn: Callable[..., PromptResult | Awaitable[PromptResult]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, enabled: bool | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt
```
Create a Prompt from a function.
@@ -107,7 +107,7 @@ The function can return:
- A sequence of any of the above
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any] | None = None) -> list[PromptMessage]
diff --git a/docs/python-sdk/fastmcp-resources-resource.mdx b/docs/python-sdk/fastmcp-resources-resource.mdx
index 3018841d4..7ed4f805d 100644
--- a/docs/python-sdk/fastmcp-resources-resource.mdx
+++ b/docs/python-sdk/fastmcp-resources-resource.mdx
@@ -18,25 +18,25 @@ Base class for all resources.
**Methods:**
-#### `enable`
+#### `enable`
```python
enable(self) -> None
```
-#### `disable`
+#### `disable`
```python
disable(self) -> None
```
-#### `from_function`
+#### `from_function`
```python
-from_function(fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None) -> FunctionResource
+from_function(fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResource
```
-#### `set_default_mime_type`
+#### `set_default_mime_type`
```python
set_default_mime_type(cls, mime_type: str | None) -> str
@@ -45,7 +45,7 @@ set_default_mime_type(cls, mime_type: str | None) -> str
Set default MIME type if not provided.
-#### `set_default_name`
+#### `set_default_name`
```python
set_default_name(self) -> Self
@@ -54,7 +54,7 @@ set_default_name(self) -> Self
Set default name from URI if not provided.
-#### `read`
+#### `read`
```python
read(self) -> str | bytes
@@ -66,7 +66,7 @@ This method is not implemented in the base Resource class and must be
implemented by subclasses.
-#### `to_mcp_resource`
+#### `to_mcp_resource`
```python
to_mcp_resource(self, **overrides: Any) -> MCPResource
@@ -75,7 +75,7 @@ to_mcp_resource(self, **overrides: Any) -> MCPResource
Convert the resource to an MCPResource.
-#### `key`
+#### `key`
```python
key(self) -> str
@@ -87,7 +87,7 @@ keys having a certain value, as the same tool loaded from different
hierarchies of servers may have different keys.
-### `FunctionResource`
+### `FunctionResource`
A resource that defers data loading by wrapping a function.
@@ -104,16 +104,16 @@ The function can return:
**Methods:**
-#### `from_function`
+#### `from_function`
```python
-from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None) -> FunctionResource
+from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResource
```
Create a FunctionResource from a function.
-#### `read`
+#### `read`
```python
read(self) -> str | bytes
diff --git a/docs/python-sdk/fastmcp-resources-template.mdx b/docs/python-sdk/fastmcp-resources-template.mdx
index 8ff3ff26a..1effd3bc6 100644
--- a/docs/python-sdk/fastmcp-resources-template.mdx
+++ b/docs/python-sdk/fastmcp-resources-template.mdx
@@ -10,7 +10,7 @@ Resource template functionality.
## Functions
-### `extract_query_params`
+### `extract_query_params`
```python
extract_query_params(uri_template: str) -> set[str]
@@ -20,7 +20,7 @@ extract_query_params(uri_template: str) -> set[str]
Extract query parameter names from RFC 6570 `{?param1,param2}` syntax.
-### `build_regex`
+### `build_regex`
```python
build_regex(template: str) -> re.Pattern
@@ -35,7 +35,7 @@ Supports:
- `{?var1,var2}` - query parameters (ignored in path matching)
-### `match_uri_template`
+### `match_uri_template`
```python
match_uri_template(uri: str, uri_template: str) -> dict[str, str] | None
@@ -51,7 +51,7 @@ Supports RFC 6570 URI templates:
## Classes
-### `ResourceTemplate`
+### `ResourceTemplate`
A template for dynamically creating resources.
@@ -59,22 +59,22 @@ A template for dynamically creating resources.
**Methods:**
-#### `enable`
+#### `enable`
```python
enable(self) -> None
```
-#### `disable`
+#### `disable`
```python
disable(self) -> None
```
-#### `from_function`
+#### `from_function`
```python
-from_function(fn: Callable[..., Any], uri_template: str, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None) -> FunctionResourceTemplate
+from_function(fn: Callable[..., Any], uri_template: str, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResourceTemplate
```
#### `set_default_mime_type`
@@ -112,8 +112,11 @@ create_resource(self, uri: str, params: dict[str, Any]) -> Resource
Create a resource from the template with the given parameters.
+The base implementation does not support background tasks.
+Use FunctionResourceTemplate for task support.
-#### `to_mcp_template`
+
+#### `to_mcp_template`
```python
to_mcp_template(self, **overrides: Any) -> MCPResourceTemplate
@@ -122,7 +125,7 @@ to_mcp_template(self, **overrides: Any) -> MCPResourceTemplate
Convert the resource template to an MCPResourceTemplate.
-#### `from_mcp_template`
+#### `from_mcp_template`
```python
from_mcp_template(cls, mcp_template: MCPResourceTemplate) -> ResourceTemplate
@@ -131,7 +134,7 @@ from_mcp_template(cls, mcp_template: MCPResourceTemplate) -> ResourceTemplate
Creates a FastMCP ResourceTemplate from a raw MCP ResourceTemplate object.
-#### `key`
+#### `key`
```python
key(self) -> str
@@ -143,7 +146,7 @@ keys having a certain value, as the same tool loaded from different
hierarchies of servers may have different keys.
-### `FunctionResourceTemplate`
+### `FunctionResourceTemplate`
A template for dynamically creating resources.
@@ -151,7 +154,16 @@ A template for dynamically creating resources.
**Methods:**
-#### `read`
+#### `create_resource`
+
+```python
+create_resource(self, uri: str, params: dict[str, Any]) -> Resource
+```
+
+Create a resource from the template with the given parameters.
+
+
+#### `read`
```python
read(self, arguments: dict[str, Any]) -> str | bytes
@@ -160,10 +172,10 @@ read(self, arguments: dict[str, Any]) -> str | bytes
Read the resource content.
-#### `from_function`
+#### `from_function`
```python
-from_function(cls, fn: Callable[..., Any], uri_template: str, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None) -> FunctionResourceTemplate
+from_function(cls, fn: Callable[..., Any], uri_template: str, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResourceTemplate
```
Create a template from a function.
diff --git a/docs/python-sdk/fastmcp-server-auth-auth.mdx b/docs/python-sdk/fastmcp-server-auth-auth.mdx
index b5002a805..fab057df0 100644
--- a/docs/python-sdk/fastmcp-server-auth-auth.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-auth.mdx
@@ -7,13 +7,42 @@ sidebarTitle: auth
## Classes
-### `AccessToken`
+### `AccessToken`
AccessToken that includes all JWT claims.
-### `AuthProvider`
+### `TokenHandler`
+
+
+TokenHandler that returns OAuth 2.1 compliant error responses.
+
+The MCP SDK returns `unauthorized_client` for client authentication failures.
+However, per RFC 6749 Section 5.2, authentication failures should return
+`invalid_client` with HTTP 401, not `unauthorized_client`.
+
+This distinction matters: `unauthorized_client` means "client exists but
+can't do this", while `invalid_client` means "client doesn't exist or
+credentials are wrong". Claude's OAuth client uses this to decide whether
+to re-register.
+
+This handler transforms 401 responses with `unauthorized_client` to use
+`invalid_client` instead, making the error semantics correct per OAuth spec.
+
+
+**Methods:**
+
+#### `handle`
+
+```python
+handle(self, request: Any)
+```
+
+Wrap SDK handle() and transform auth error responses.
+
+
+### `AuthProvider`
Base class for all FastMCP authentication providers.
@@ -26,7 +55,7 @@ custom authentication routes.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -43,7 +72,7 @@ All auth providers must implement token verification.
- AccessToken object if valid, None if invalid or expired
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self, mcp_path: str | None = None) -> list[Route]
@@ -67,7 +96,7 @@ provider does not create the actual MCP endpoint route.
- List of all routes for this provider (excluding the MCP endpoint itself)
-#### `get_well_known_routes`
+#### `get_well_known_routes`
```python
get_well_known_routes(self, mcp_path: str | None = None) -> list[Route]
@@ -95,7 +124,7 @@ This is used to construct path-scoped well-known URLs.
- List of well-known discovery routes (typically mounted at root level)
-#### `get_middleware`
+#### `get_middleware`
```python
get_middleware(self) -> list
@@ -107,7 +136,7 @@ Get HTTP application-level middleware for this auth provider.
- List of Starlette Middleware instances to apply to the HTTP app
-### `TokenVerifier`
+### `TokenVerifier`
Base class for token verifiers (Resource Servers).
@@ -118,7 +147,7 @@ Token verifiers typically don't provide authentication routes by default.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -127,7 +156,7 @@ verify_token(self, token: str) -> AccessToken | None
Verify a bearer token and return access info if valid.
-### `RemoteAuthProvider`
+### `RemoteAuthProvider`
Authentication provider for resource servers that verify tokens from known authorization servers.
@@ -144,7 +173,7 @@ the authorization servers that issue valid tokens.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -153,7 +182,7 @@ verify_token(self, token: str) -> AccessToken | None
Verify token using the configured token verifier.
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self, mcp_path: str | None = None) -> list[Route]
@@ -164,7 +193,7 @@ Get routes for this provider.
Creates protected resource metadata routes (RFC 9728).
-### `OAuthProvider`
+### `OAuthProvider`
OAuth Authorization Server provider.
@@ -175,7 +204,7 @@ authorization flows, token issuance, and token verification.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -193,7 +222,7 @@ to our existing load_access_token method.
- AccessToken object if valid, None if invalid or expired
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self, mcp_path: str | None = None) -> list[Route]
@@ -208,3 +237,26 @@ This method creates the full set of OAuth routes including:
**Returns:**
- List of OAuth routes
+
+#### `get_well_known_routes`
+
+```python
+get_well_known_routes(self, mcp_path: str | None = None) -> list[Route]
+```
+
+Get well-known discovery routes with RFC 8414 path-aware support.
+
+Overrides the base implementation to support path-aware authorization
+server metadata discovery per RFC 8414. If issuer_url has a path component,
+the authorization server metadata route is adjusted to include that path.
+
+For example, if issuer_url is "http://example.com/api", the discovery
+endpoint will be at "/.well-known/oauth-authorization-server/api" instead
+of just "/.well-known/oauth-authorization-server".
+
+**Args:**
+- `mcp_path`: The path where the MCP endpoint is mounted (e.g., "/mcp")
+
+**Returns:**
+- List of well-known discovery routes
+
diff --git a/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx b/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx
index 2ce8efee2..c8de4bb4e 100644
--- a/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx
@@ -26,7 +26,7 @@ production use with enterprise identity providers.
## Functions
-### `create_consent_html`
+### `create_consent_html`
```python
create_consent_html(client_id: str, redirect_uri: str, scopes: list[str], txn_id: str, csrf_token: str, client_name: str | None = None, title: str = 'Application Access Request', server_name: str | None = None, server_icon_url: str | None = None, server_website_url: str | None = None, client_website_url: str | None = None, csp_policy: str | None = None) -> str
@@ -42,7 +42,7 @@ If empty string "", disables CSP entirely (no meta tag is rendered).
If a non-empty string, uses that as the CSP policy value.
-### `create_error_html`
+### `create_error_html`
```python
create_error_html(error_title: str, error_message: str, error_details: dict[str, str] | None = None, server_name: str | None = None, server_icon_url: str | None = None) -> str
@@ -64,7 +64,7 @@ Create a styled HTML error page for OAuth errors.
## Classes
-### `OAuthTransaction`
+### `OAuthTransaction`
OAuth transaction state for consent flow.
@@ -73,7 +73,7 @@ Stored server-side to track active authorization flows with client context.
Includes CSRF tokens for consent protection per MCP security best practices.
-### `ClientCode`
+### `ClientCode`
Client authorization code with PKCE and upstream tokens.
@@ -82,7 +82,7 @@ Stored server-side after upstream IdP callback. Contains the upstream
tokens bound to the client's PKCE challenge for secure token exchange.
-### `UpstreamTokenSet`
+### `UpstreamTokenSet`
Stored upstream OAuth tokens from identity provider.
@@ -92,7 +92,7 @@ and stored in plaintext within this model. Encryption is handled transparently
at the storage layer via FernetEncryptionWrapper. Tokens are never exposed to MCP clients.
-### `JTIMapping`
+### `JTIMapping`
Maps FastMCP token JTI to upstream token ID.
@@ -101,7 +101,7 @@ This allows stateless JWT validation while still being able to look up
the corresponding upstream token when tools need to access upstream APIs.
-### `RefreshTokenMetadata`
+### `RefreshTokenMetadata`
Metadata for a refresh token, stored keyed by token hash.
@@ -110,7 +110,7 @@ We store only metadata (not the token itself) for security - if storage
is compromised, attackers get hashes they can't reverse into usable tokens.
-### `ProxyDCRClient`
+### `ProxyDCRClient`
Client for DCR proxy with configurable redirect URI validation.
@@ -140,7 +140,7 @@ arise from accepting arbitrary redirect URIs.
**Methods:**
-#### `validate_redirect_uri`
+#### `validate_redirect_uri`
```python
validate_redirect_uri(self, redirect_uri: AnyUrl | None) -> AnyUrl
@@ -154,39 +154,7 @@ This is essential for cached token scenarios where the client may
reconnect with a different port.
-### `TokenHandler`
-
-
-TokenHandler that returns OAuth 2.1 compliant error responses.
-
-The MCP SDK always returns HTTP 400 for all client authentication issues.
-However, OAuth 2.1 Section 5.3 and the MCP specification require that
-invalid or expired tokens MUST receive a HTTP 401 response.
-
-This handler extends the base MCP SDK TokenHandler to transform client
-authentication failures into OAuth 2.1 compliant responses:
-- Changes 'unauthorized_client' to 'invalid_client' error code
-- Returns HTTP 401 status code instead of 400 for client auth failures
-
-Per OAuth 2.1 Section 5.3: "The authorization server MAY return an HTTP 401
-(Unauthorized) status code to indicate which HTTP authentication schemes
-are supported."
-
-Per MCP spec: "Invalid or expired tokens MUST receive a HTTP 401 response."
-
-
-**Methods:**
-
-#### `response`
-
-```python
-response(self, obj: TokenSuccessResponse | TokenErrorResponse)
-```
-
-Override response method to provide OAuth 2.1 compliant error handling.
-
-
-### `OAuthProxy`
+### `OAuthProxy`
OAuth provider that presents a DCR-compliant interface while proxying to non-DCR IDPs.
@@ -300,7 +268,7 @@ Handles provider-specific requirements:
**Methods:**
-#### `get_client`
+#### `get_client`
```python
get_client(self, client_id: str) -> OAuthClientInformationFull | None
@@ -312,7 +280,7 @@ provided to the DCR client during registration, not the upstream client ID.
For unregistered clients, returns None (which will raise an error in the SDK).
-#### `register_client`
+#### `register_client`
```python
register_client(self, client_info: OAuthClientInformationFull) -> None
@@ -326,7 +294,7 @@ redirect URI will likely be localhost or unknown to the proxied IDP. The
proxied IDP only knows about this server's fixed redirect URI.
-#### `authorize`
+#### `authorize`
```python
authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str
@@ -343,7 +311,7 @@ If consent is disabled (require_authorization_consent=False), skip the consent s
and redirect directly to the upstream IdP.
-#### `load_authorization_code`
+#### `load_authorization_code`
```python
load_authorization_code(self, client: OAuthClientInformationFull, authorization_code: str) -> AuthorizationCode | None
@@ -355,7 +323,7 @@ Look up our client code and return authorization code object
with PKCE challenge for validation.
-#### `exchange_authorization_code`
+#### `exchange_authorization_code`
```python
exchange_authorization_code(self, client: OAuthClientInformationFull, authorization_code: AuthorizationCode) -> OAuthToken
@@ -373,7 +341,7 @@ Implements the token factory pattern:
PKCE validation is handled by the MCP framework before this method is called.
-#### `load_refresh_token`
+#### `load_refresh_token`
```python
load_refresh_token(self, client: OAuthClientInformationFull, refresh_token: str) -> RefreshToken | None
@@ -385,7 +353,7 @@ Looks up by token hash and reconstructs the RefreshToken object.
Validates that the token belongs to the requesting client.
-#### `exchange_refresh_token`
+#### `exchange_refresh_token`
```python
exchange_refresh_token(self, client: OAuthClientInformationFull, refresh_token: RefreshToken, scopes: list[str]) -> OAuthToken
@@ -402,7 +370,7 @@ Implements two-tier refresh:
6. Keep same FastMCP refresh token (unless upstream rotates)
-#### `load_access_token`
+#### `load_access_token`
```python
load_access_token(self, token: str) -> AccessToken | None
@@ -421,7 +389,7 @@ The FastMCP JWT is a reference token - all authorization data comes
from validating the upstream token via the TokenVerifier.
-#### `revoke_token`
+#### `revoke_token`
```python
revoke_token(self, token: AccessToken | RefreshToken) -> None
@@ -434,7 +402,7 @@ For all tokens, attempts upstream revocation if endpoint is configured.
Access token JTI mappings expire via TTL.
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self, mcp_path: str | None = None) -> list[Route]
diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx
index ee9772830..fa3a35f2f 100644
--- a/docs/python-sdk/fastmcp-server-context.mdx
+++ b/docs/python-sdk/fastmcp-server-context.mdx
@@ -7,7 +7,7 @@ sidebarTitle: context
## Functions
-### `set_context`
+### `set_context`
```python
set_context(context: Context) -> Generator[Context, None, None]
@@ -15,7 +15,7 @@ set_context(context: Context) -> Generator[Context, None, None]
## Classes
-### `LogData`
+### `LogData`
Data object for passing log arguments to client-side handlers.
@@ -24,7 +24,7 @@ This provides an interface to match the Python standard library logging,
for compatibility with structured logging.
-### `Context`
+### `Context`
Context object providing access to MCP capabilities.
@@ -72,7 +72,7 @@ The context is optional - tools that don't need it can omit the parameter.
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -81,7 +81,7 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-#### `request_context`
+#### `request_context`
```python
request_context(self) -> RequestContext[ServerSession, Any, Request] | None
@@ -110,7 +110,7 @@ async def on_request(self, context, call_next):
```
-#### `report_progress`
+#### `report_progress`
```python
report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None
@@ -123,7 +123,7 @@ Report progress for the current operation.
- `total`: Optional total value e.g. 100
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> list[MCPResource]
@@ -135,7 +135,7 @@ List all available resources from the server.
- List of Resource objects available on the server
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> list[MCPPrompt]
@@ -147,7 +147,7 @@ List all available prompts from the server.
- List of Prompt objects available on the server
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult
@@ -163,7 +163,7 @@ Get a prompt by name with optional arguments.
- The prompt result
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str | AnyUrl) -> list[ReadResourceContents]
@@ -178,7 +178,7 @@ Read a resource by URI.
- The resource content as either text or bytes
-#### `log`
+#### `log`
```python
log(self, message: str, level: LoggingLevel | None = None, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -196,7 +196,7 @@ Messages sent to Clients are also logged to the `fastmcp.server.context.to_clien
- `extra`: Optional mapping for additional arguments
-#### `client_id`
+#### `client_id`
```python
client_id(self) -> str | None
@@ -205,7 +205,7 @@ client_id(self) -> str | None
Get the client ID if available.
-#### `request_id`
+#### `request_id`
```python
request_id(self) -> str
@@ -216,7 +216,7 @@ Get the unique ID for this request.
Raises RuntimeError if MCP request context is not available.
-#### `session_id`
+#### `session_id`
```python
session_id(self) -> str
@@ -233,7 +233,7 @@ the same client session.
- for other transports.
-#### `session`
+#### `session`
```python
session(self) -> ServerSession
@@ -244,7 +244,7 @@ Access to the underlying session for advanced usage.
Raises RuntimeError if MCP request context is not available.
-#### `debug`
+#### `debug`
```python
debug(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -255,7 +255,7 @@ Send a `DEBUG`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `info`
+#### `info`
```python
info(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -266,7 +266,7 @@ Send a `INFO`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `warning`
+#### `warning`
```python
warning(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -277,7 +277,7 @@ Send a `WARNING`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `error`
+#### `error`
```python
error(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -288,7 +288,7 @@ Send a `ERROR`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `list_roots`
+#### `list_roots`
```python
list_roots(self) -> list[Root]
@@ -297,7 +297,7 @@ list_roots(self) -> list[Root]
List the roots available to the server, as indicated by the client.
-#### `send_tool_list_changed`
+#### `send_tool_list_changed`
```python
send_tool_list_changed(self) -> None
@@ -306,7 +306,7 @@ send_tool_list_changed(self) -> None
Send a tool list changed notification to the client.
-#### `send_resource_list_changed`
+#### `send_resource_list_changed`
```python
send_resource_list_changed(self) -> None
@@ -315,7 +315,7 @@ send_resource_list_changed(self) -> None
Send a resource list changed notification to the client.
-#### `send_prompt_list_changed`
+#### `send_prompt_list_changed`
```python
send_prompt_list_changed(self) -> None
@@ -324,10 +324,28 @@ send_prompt_list_changed(self) -> None
Send a prompt list changed notification to the client.
-#### `sample`
+#### `close_sse_stream`
```python
-sample(self, messages: str | Sequence[str | SamplingMessage], system_prompt: str | None = None, include_context: IncludeContext | None = None, temperature: float | None = None, max_tokens: int | None = None, model_preferences: ModelPreferences | str | list[str] | None = None) -> TextContent | ImageContent | AudioContent
+close_sse_stream(self) -> None
+```
+
+Close the current response stream to trigger client reconnection.
+
+When using StreamableHTTP transport with an EventStore configured, this
+method gracefully closes the HTTP connection for the current request.
+The client will automatically reconnect (after `retry_interval` milliseconds)
+and resume receiving events from where it left off via the EventStore.
+
+This is useful for long-running operations to avoid load balancer timeouts.
+Instead of holding a connection open for minutes, you can periodically close
+and let the client reconnect.
+
+
+#### `sample`
+
+```python
+sample(self, messages: str | Sequence[str | SamplingMessage], system_prompt: str | None = None, include_context: IncludeContext | None = None, temperature: float | None = None, max_tokens: int | None = None, model_preferences: ModelPreferences | str | list[str] | None = None) -> SamplingMessageContentBlock | list[SamplingMessageContentBlock]
```
Send a sampling request to the client and await the response.
@@ -337,25 +355,25 @@ completion from the client. The client must be appropriately configured,
or the request will error.
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: None) -> AcceptedElicitation[dict[str, Any]] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: type[T]) -> AcceptedElicitation[T] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: list[str]) -> AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: type[T] | list[str] | None = None) -> AcceptedElicitation[T] | AcceptedElicitation[dict[str, Any]] | AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation
@@ -384,7 +402,7 @@ type or dataclass or BaseModel. If it is a primitive type, an
object schema with a single "value" field will be generated.
-#### `set_state`
+#### `set_state`
```python
set_state(self, key: str, value: Any) -> None
@@ -393,7 +411,7 @@ set_state(self, key: str, value: Any) -> None
Set a value in the context state.
-#### `get_state`
+#### `get_state`
```python
get_state(self, key: str) -> Any
diff --git a/docs/python-sdk/fastmcp-server-dependencies.mdx b/docs/python-sdk/fastmcp-server-dependencies.mdx
index 9092633d9..19636c2ce 100644
--- a/docs/python-sdk/fastmcp-server-dependencies.mdx
+++ b/docs/python-sdk/fastmcp-server-dependencies.mdx
@@ -7,19 +7,155 @@ sidebarTitle: dependencies
## Functions
-### `get_context`
+### `without_injected_parameters`
+
+```python
+without_injected_parameters(fn: Callable[..., Any]) -> Callable[..., Any]
+```
+
+
+Create a wrapper function without injected parameters.
+
+Returns a wrapper that excludes Context and Docket dependency parameters,
+making it safe to use with Pydantic TypeAdapter for schema generation and
+validation. The wrapper internally handles all dependency resolution and
+Context injection when called.
+
+**Args:**
+- `fn`: Original function with Context and/or dependencies
+
+**Returns:**
+- Async wrapper function without injected parameters
+
+
+### `resolve_dependencies`
+
+```python
+resolve_dependencies(fn: Callable[..., Any], arguments: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None]
+```
+
+
+Resolve dependencies and inject Context for a FastMCP function.
+
+This function:
+1. Filters out any dependency parameter names from user arguments (security)
+2. Resolves Docket dependencies
+3. Injects Context if needed
+4. Merges everything together
+
+The filtering prevents external callers from overriding injected parameters by
+providing values for dependency parameter names. This is a security feature.
+
+**Args:**
+- `fn`: The function to resolve dependencies for
+- `arguments`: User arguments (may contain keys that match dependency names,
+ which will be filtered out)
+
+
+### `get_context`
```python
get_context() -> Context
```
-### `get_http_request`
+### `CurrentContext`
+
+```python
+CurrentContext() -> Context
+```
+
+
+Get the current FastMCP Context instance.
+
+This dependency provides access to the active FastMCP Context for the
+current MCP operation (tool/resource/prompt call).
+
+**Returns:**
+- A dependency that resolves to the active Context instance
+
+**Raises:**
+- `RuntimeError`: If no active context found (during resolution)
+
+
+### `CurrentDocket`
+
+```python
+CurrentDocket() -> Docket
+```
+
+
+Get the current Docket instance managed by FastMCP.
+
+This dependency provides access to the Docket instance that FastMCP
+automatically creates for background task scheduling.
+
+**Returns:**
+- A dependency that resolves to the active Docket instance
+
+**Raises:**
+- `RuntimeError`: If not within a FastMCP server context
+
+
+### `CurrentWorker`
+
+```python
+CurrentWorker() -> Worker
+```
+
+
+Get the current Docket Worker instance managed by FastMCP.
+
+This dependency provides access to the Worker instance that FastMCP
+automatically creates for background task processing.
+
+**Returns:**
+- A dependency that resolves to the active Worker instance
+
+**Raises:**
+- `RuntimeError`: If not within a FastMCP server context
+
+
+### `CurrentFastMCP`
+
+```python
+CurrentFastMCP()
+```
+
+
+Get the current FastMCP server instance.
+
+This dependency provides access to the active FastMCP server.
+
+**Returns:**
+- A dependency that resolves to the active FastMCP server
+
+**Raises:**
+- `RuntimeError`: If no server in context (during resolution)
+
+
+### `get_server`
+
+```python
+get_server()
+```
+
+
+Get the current FastMCP server instance directly.
+
+**Returns:**
+- The active FastMCP server
+
+**Raises:**
+- `RuntimeError`: If no server in context
+
+
+### `get_http_request`
```python
get_http_request() -> Request
```
-### `get_http_headers`
+### `get_http_headers`
```python
get_http_headers(include_all: bool = False) -> dict[str, str]
@@ -35,7 +171,7 @@ By default, strips problematic headers like `content-length` that cause issues i
If `include_all` is True, all headers are returned.
-### `get_access_token`
+### `get_access_token`
```python
get_access_token() -> AccessToken | None
@@ -52,3 +188,75 @@ request is available.
**Returns:**
- The access token if an authenticated user is available, None otherwise.
+
+## Classes
+
+### `InMemoryProgress`
+
+
+In-memory progress tracker for immediate tool execution.
+
+Provides the same interface as Progress but stores state in memory
+instead of Redis. Useful for testing and immediate execution where
+progress doesn't need to be observable across processes.
+
+
+**Methods:**
+
+#### `current`
+
+```python
+current(self) -> int | None
+```
+
+#### `total`
+
+```python
+total(self) -> int
+```
+
+#### `message`
+
+```python
+message(self) -> str | None
+```
+
+#### `set_total`
+
+```python
+set_total(self, total: int) -> None
+```
+
+Set the total/target value for progress tracking.
+
+
+#### `increment`
+
+```python
+increment(self, amount: int = 1) -> None
+```
+
+Atomically increment the current progress value.
+
+
+#### `set_message`
+
+```python
+set_message(self, message: str | None) -> None
+```
+
+Update the progress status message.
+
+
+### `Progress`
+
+
+FastMCP Progress dependency that works in both server and worker contexts.
+
+Extends Docket's Progress to handle two execution modes:
+- In Docket worker: Uses the execution's progress (standard Docket behavior)
+- In FastMCP server: Uses in-memory progress (not observable remotely)
+
+This allows tools to use Progress() regardless of whether they're called
+immediately or as background tasks.
+
diff --git a/docs/python-sdk/fastmcp-server-elicitation.mdx b/docs/python-sdk/fastmcp-server-elicitation.mdx
index c21fc533d..04a9be73a 100644
--- a/docs/python-sdk/fastmcp-server-elicitation.mdx
+++ b/docs/python-sdk/fastmcp-server-elicitation.mdx
@@ -7,7 +7,45 @@ sidebarTitle: elicitation
## Functions
-### `get_elicitation_schema`
+### `parse_elicit_response_type`
+
+```python
+parse_elicit_response_type(response_type: Any) -> ElicitConfig
+```
+
+
+Parse response_type into schema and handling configuration.
+
+Supports multiple syntaxes:
+- None: Empty object schema, expect empty response
+- dict: {"low": {"title": "..."}} -> single-select titled enum
+- list patterns:
+ - [["a", "b"]] -> multi-select untitled
+ - [{"low": {...}}] -> multi-select titled
+ - ["a", "b"] -> single-select untitled
+- list\[X] type annotation: multi-select with type
+- Scalar types (bool, int, float, str, Literal, Enum): single value
+- Other types (dataclass, BaseModel): use directly
+
+
+### `handle_elicit_accept`
+
+```python
+handle_elicit_accept(config: ElicitConfig, content: Any) -> AcceptedElicitation[Any]
+```
+
+
+Handle an accepted elicitation response.
+
+**Args:**
+- `config`: The elicitation configuration from parse_elicit_response_type
+- `content`: The response content from the client
+
+**Returns:**
+- AcceptedElicitation with the extracted/validated data
+
+
+### `get_elicitation_schema`
```python
get_elicitation_schema(response_type: type[T]) -> dict[str, Any]
@@ -20,7 +58,7 @@ Get the schema for an elicitation response.
- `response_type`: The type of the response
-### `validate_elicitation_json_schema`
+### `validate_elicitation_json_schema`
```python
validate_elicitation_json_schema(schema: dict[str, Any]) -> None
@@ -45,7 +83,7 @@ This ensures the schema is compatible with MCP elicitation requirements:
## Classes
-### `ElicitationJsonSchema`
+### `ElicitationJsonSchema`
Custom JSON schema generator for MCP elicitation that always inlines enums.
@@ -57,31 +95,46 @@ Optionally adds enumNames for better UI display when available.
**Methods:**
-#### `generate_inner`
+#### `generate_inner`
```python
generate_inner(self, schema: core_schema.CoreSchema) -> JsonSchemaValue
```
-Override to prevent ref generation for enums.
+Override to prevent ref generation for enums and handle list schemas.
-#### `enum_schema`
+#### `list_schema`
+
+```python
+list_schema(self, schema: core_schema.ListSchema) -> JsonSchemaValue
+```
+
+Generate schema for list types, detecting enum items for multi-select.
+
+
+#### `enum_schema`
```python
enum_schema(self, schema: core_schema.EnumSchema) -> JsonSchemaValue
```
-Generate inline enum schema with optional enumNames for better UI.
+Generate inline enum schema.
-If enum members have a _display_name_ attribute or custom __str__,
-we'll include enumNames for better UI representation.
+Always generates enum pattern: {"enum": [value, ...]}
+Titled enums are handled separately via dict-based syntax in ctx.elicit().
-### `AcceptedElicitation`
+### `AcceptedElicitation`
Result when user accepts the elicitation.
-### `ScalarElicitationType`
+### `ScalarElicitationType`
+
+### `ElicitConfig`
+
+
+Configuration for an elicitation request.
+
diff --git a/docs/python-sdk/fastmcp-server-event_store.mdx b/docs/python-sdk/fastmcp-server-event_store.mdx
new file mode 100644
index 000000000..9ff70bc56
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-event_store.mdx
@@ -0,0 +1,78 @@
+---
+title: event_store
+sidebarTitle: event_store
+---
+
+# `fastmcp.server.event_store`
+
+
+EventStore implementation backed by AsyncKeyValue.
+
+This module provides an EventStore implementation that enables SSE polling/resumability
+for Streamable HTTP transports. Events are stored using the key_value package's
+AsyncKeyValue protocol, allowing users to configure any compatible backend
+(in-memory, Redis, etc.) following the same pattern as ResponseCachingMiddleware.
+
+
+## Classes
+
+### `EventEntry`
+
+
+Stored event entry.
+
+
+### `StreamEventList`
+
+
+List of event IDs for a stream.
+
+
+### `EventStore`
+
+
+EventStore implementation backed by AsyncKeyValue.
+
+Enables SSE polling/resumability by storing events that can be replayed
+when clients reconnect. Works with any AsyncKeyValue backend (memory, Redis, etc.)
+following the same pattern as ResponseCachingMiddleware and OAuthProxy.
+
+**Args:**
+- `storage`: AsyncKeyValue backend. Defaults to MemoryStore.
+- `max_events_per_stream`: Maximum events to retain per stream. Default 100.
+- `ttl`: Event TTL in seconds. Default 3600 (1 hour). Set to None for no expiration.
+
+
+**Methods:**
+
+#### `store_event`
+
+```python
+store_event(self, stream_id: StreamId, message: JSONRPCMessage | None) -> EventId
+```
+
+Store an event and return its ID.
+
+**Args:**
+- `stream_id`: ID of the stream the event belongs to
+- `message`: The JSON-RPC message to store, or None for priming events
+
+**Returns:**
+- The generated event ID for the stored event
+
+
+#### `replay_events_after`
+
+```python
+replay_events_after(self, last_event_id: EventId, send_callback: EventCallback) -> StreamId | None
+```
+
+Replay events that occurred after the specified event ID.
+
+**Args:**
+- `last_event_id`: The ID of the last event the client received
+- `send_callback`: A callback function to send events to the client
+
+**Returns:**
+- The stream ID of the replayed events, or None if the event ID was not found
+
diff --git a/docs/python-sdk/fastmcp-server-http.mdx b/docs/python-sdk/fastmcp-server-http.mdx
index 40ae6fb9b..8aaf2c934 100644
--- a/docs/python-sdk/fastmcp-server-http.mdx
+++ b/docs/python-sdk/fastmcp-server-http.mdx
@@ -7,13 +7,13 @@ sidebarTitle: http
## Functions
-### `set_http_request`
+### `set_http_request`
```python
set_http_request(request: Request) -> Generator[Request, None, None]
```
-### `create_base_app`
+### `create_base_app`
```python
create_base_app(routes: list[BaseRoute], middleware: list[Middleware], debug: bool = False, lifespan: Callable | None = None) -> StarletteWithLifespan
@@ -32,7 +32,7 @@ Create a base Starlette app with common middleware and routes.
- A Starlette application
-### `create_sse_app`
+### `create_sse_app`
```python
create_sse_app(server: FastMCP[LifespanResultT], message_path: str, sse_path: str, auth: AuthProvider | None = None, debug: bool = False, routes: list[BaseRoute] | None = None, middleware: list[Middleware] | None = None) -> StarletteWithLifespan
@@ -54,10 +54,10 @@ Returns:
A Starlette application with RequestContextMiddleware
-### `create_streamable_http_app`
+### `create_streamable_http_app`
```python
-create_streamable_http_app(server: FastMCP[LifespanResultT], streamable_http_path: str, event_store: EventStore | None = None, auth: AuthProvider | None = None, json_response: bool = False, stateless_http: bool = False, debug: bool = False, routes: list[BaseRoute] | None = None, middleware: list[Middleware] | None = None) -> StarletteWithLifespan
+create_streamable_http_app(server: FastMCP[LifespanResultT], streamable_http_path: str, event_store: EventStore | None = None, retry_interval: int | None = None, auth: AuthProvider | None = None, json_response: bool = False, stateless_http: bool = False, debug: bool = False, routes: list[BaseRoute] | None = None, middleware: list[Middleware] | None = None) -> StarletteWithLifespan
```
@@ -66,7 +66,10 @@ Return an instance of the StreamableHTTP server app.
**Args:**
- `server`: The FastMCP server instance
- `streamable_http_path`: Path for StreamableHTTP connections
-- `event_store`: Optional event store for session management
+- `event_store`: Optional event store for SSE polling/resumability
+- `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. Defaults to SDK default.
- `auth`: Optional authentication provider (AuthProvider)
- `json_response`: Whether to use JSON response format
- `stateless_http`: Whether to use stateless mode (new transport per request)
@@ -80,23 +83,23 @@ Return an instance of the StreamableHTTP server app.
## Classes
-### `StreamableHTTPASGIApp`
+### `StreamableHTTPASGIApp`
ASGI application wrapper for Streamable HTTP server transport.
-### `StarletteWithLifespan`
+### `StarletteWithLifespan`
**Methods:**
-#### `lifespan`
+#### `lifespan`
```python
lifespan(self) -> Lifespan[Starlette]
```
-### `RequestContextMiddleware`
+### `RequestContextMiddleware`
Middleware that stores each request in a ContextVar
diff --git a/docs/python-sdk/fastmcp-server-low_level.mdx b/docs/python-sdk/fastmcp-server-low_level.mdx
index fd3dcaeec..9b18bc5be 100644
--- a/docs/python-sdk/fastmcp-server-low_level.mdx
+++ b/docs/python-sdk/fastmcp-server-low_level.mdx
@@ -15,7 +15,7 @@ ServerSession that routes initialization requests through FastMCP middleware.
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -24,11 +24,11 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-### `LowLevelServer`
+### `LowLevelServer`
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -37,13 +37,13 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-#### `create_initialization_options`
+#### `create_initialization_options`
```python
create_initialization_options(self, notification_options: NotificationOptions | None = None, experimental_capabilities: dict[str, dict[str, Any]] | None = None, **kwargs: Any) -> InitializationOptions
```
-#### `run`
+#### `run`
```python
run(self, read_stream: MemoryObjectReceiveStream[SessionMessage | Exception], write_stream: MemoryObjectSendStream[SessionMessage], initialization_options: InitializationOptions, raise_exceptions: bool = False, stateless: bool = False)
diff --git a/docs/python-sdk/fastmcp-server-middleware-middleware.mdx b/docs/python-sdk/fastmcp-server-middleware-middleware.mdx
index 4d23d9364..baeffa691 100644
--- a/docs/python-sdk/fastmcp-server-middleware-middleware.mdx
+++ b/docs/python-sdk/fastmcp-server-middleware-middleware.mdx
@@ -66,7 +66,7 @@ on_notification(self, context: MiddlewareContext[mt.Notification[Any, Any]], cal
#### `on_initialize`
```python
-on_initialize(self, context: MiddlewareContext[mt.InitializeRequest], call_next: CallNext[mt.InitializeRequest, None]) -> None
+on_initialize(self, context: MiddlewareContext[mt.InitializeRequest], call_next: CallNext[mt.InitializeRequest, mt.InitializeResult | None]) -> mt.InitializeResult | None
```
#### `on_call_tool`
diff --git a/docs/python-sdk/fastmcp-server-proxy.mdx b/docs/python-sdk/fastmcp-server-proxy.mdx
index da1447345..9abe6e123 100644
--- a/docs/python-sdk/fastmcp-server-proxy.mdx
+++ b/docs/python-sdk/fastmcp-server-proxy.mdx
@@ -7,7 +7,7 @@ sidebarTitle: proxy
## Functions
-### `default_proxy_roots_handler`
+### `default_proxy_roots_handler`
```python
default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanContextT]) -> RootsList
@@ -19,13 +19,13 @@ A handler that forwards the list roots request from the remote server to the pro
## Classes
-### `ProxyManagerMixin`
+### `ProxyManagerMixin`
A mixin for proxy managers to provide a unified client retrieval method.
-### `ProxyToolManager`
+### `ProxyToolManager`
A ToolManager that sources its tools from a remote client in addition to local and mounted tools.
@@ -33,7 +33,7 @@ A ToolManager that sources its tools from a remote client in addition to local a
**Methods:**
-#### `get_tools`
+#### `get_tools`
```python
get_tools(self) -> dict[str, Tool]
@@ -42,7 +42,7 @@ get_tools(self) -> dict[str, Tool]
Gets the unfiltered tool inventory including local, mounted, and proxy tools.
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> list[Tool]
@@ -51,7 +51,7 @@ list_tools(self) -> list[Tool]
Gets the filtered list of tools including local, mounted, and proxy tools.
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult
@@ -60,7 +60,7 @@ call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult
Calls a tool, trying local/mounted first, then proxy if not found.
-### `ProxyResourceManager`
+### `ProxyResourceManager`
A ResourceManager that sources its resources from a remote client in addition to local and mounted resources.
@@ -68,7 +68,7 @@ A ResourceManager that sources its resources from a remote client in addition to
**Methods:**
-#### `get_resources`
+#### `get_resources`
```python
get_resources(self) -> dict[str, Resource]
@@ -77,7 +77,7 @@ get_resources(self) -> dict[str, Resource]
Gets the unfiltered resource inventory including local, mounted, and proxy resources.
-#### `get_resource_templates`
+#### `get_resource_templates`
```python
get_resource_templates(self) -> dict[str, ResourceTemplate]
@@ -86,7 +86,7 @@ get_resource_templates(self) -> dict[str, ResourceTemplate]
Gets the unfiltered template inventory including local, mounted, and proxy templates.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> list[Resource]
@@ -95,7 +95,7 @@ list_resources(self) -> list[Resource]
Gets the filtered list of resources including local, mounted, and proxy resources.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> list[ResourceTemplate]
@@ -104,7 +104,7 @@ list_resource_templates(self) -> list[ResourceTemplate]
Gets the filtered list of templates including local, mounted, and proxy templates.
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: AnyUrl | str) -> str | bytes
@@ -113,7 +113,7 @@ read_resource(self, uri: AnyUrl | str) -> str | bytes
Reads a resource, trying local/mounted first, then proxy if not found.
-### `ProxyPromptManager`
+### `ProxyPromptManager`
A PromptManager that sources its prompts from a remote client in addition to local and mounted prompts.
@@ -121,7 +121,7 @@ A PromptManager that sources its prompts from a remote client in addition to loc
**Methods:**
-#### `get_prompts`
+#### `get_prompts`
```python
get_prompts(self) -> dict[str, Prompt]
@@ -130,7 +130,7 @@ get_prompts(self) -> dict[str, Prompt]
Gets the unfiltered prompt inventory including local, mounted, and proxy prompts.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> list[Prompt]
@@ -139,7 +139,7 @@ list_prompts(self) -> list[Prompt]
Gets the filtered list of prompts including local, mounted, and proxy prompts.
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult
@@ -148,7 +148,7 @@ render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPr
Renders a prompt, trying local/mounted first, then proxy if not found.
-### `ProxyTool`
+### `ProxyTool`
A Tool that represents and executes a tool on a remote server.
@@ -156,7 +156,7 @@ A Tool that represents and executes a tool on a remote server.
**Methods:**
-#### `from_mcp_tool`
+#### `from_mcp_tool`
```python
from_mcp_tool(cls, client: Client, mcp_tool: mcp.types.Tool) -> ProxyTool
@@ -165,7 +165,7 @@ from_mcp_tool(cls, client: Client, mcp_tool: mcp.types.Tool) -> ProxyTool
Factory method to create a ProxyTool from a raw MCP tool schema.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResult
@@ -174,7 +174,7 @@ run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResu
Executes the tool by making a call through the client.
-### `ProxyResource`
+### `ProxyResource`
A Resource that represents and reads a resource from a remote server.
@@ -182,7 +182,7 @@ A Resource that represents and reads a resource from a remote server.
**Methods:**
-#### `from_mcp_resource`
+#### `from_mcp_resource`
```python
from_mcp_resource(cls, client: Client, mcp_resource: mcp.types.Resource) -> ProxyResource
@@ -191,7 +191,7 @@ from_mcp_resource(cls, client: Client, mcp_resource: mcp.types.Resource) -> Prox
Factory method to create a ProxyResource from a raw MCP resource schema.
-#### `read`
+#### `read`
```python
read(self) -> str | bytes
@@ -200,7 +200,7 @@ read(self) -> str | bytes
Read the resource content from the remote server.
-### `ProxyTemplate`
+### `ProxyTemplate`
A ResourceTemplate that represents and creates resources from a remote server template.
@@ -208,7 +208,7 @@ A ResourceTemplate that represents and creates resources from a remote server te
**Methods:**
-#### `from_mcp_template`
+#### `from_mcp_template`
```python
from_mcp_template(cls, client: Client, mcp_template: mcp.types.ResourceTemplate) -> ProxyTemplate
@@ -217,7 +217,7 @@ from_mcp_template(cls, client: Client, mcp_template: mcp.types.ResourceTemplate)
Factory method to create a ProxyTemplate from a raw MCP template schema.
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any], context: Context | None = None) -> ProxyResource
@@ -226,7 +226,7 @@ create_resource(self, uri: str, params: dict[str, Any], context: Context | None
Create a resource from the template by calling the remote server.
-### `ProxyPrompt`
+### `ProxyPrompt`
A Prompt that represents and renders a prompt from a remote server.
@@ -234,7 +234,7 @@ A Prompt that represents and renders a prompt from a remote server.
**Methods:**
-#### `from_mcp_prompt`
+#### `from_mcp_prompt`
```python
from_mcp_prompt(cls, client: Client, mcp_prompt: mcp.types.Prompt) -> ProxyPrompt
@@ -243,7 +243,7 @@ from_mcp_prompt(cls, client: Client, mcp_prompt: mcp.types.Prompt) -> ProxyPromp
Factory method to create a ProxyPrompt from a raw MCP prompt schema.
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any]) -> list[PromptMessage]
@@ -252,14 +252,14 @@ render(self, arguments: dict[str, Any]) -> list[PromptMessage]
Render the prompt by making a call through the client.
-### `FastMCPProxy`
+### `FastMCPProxy`
A FastMCP server that acts as a proxy to a remote MCP-compliant server.
It uses specialized managers that fulfill requests via a client factory.
-### `ProxyClient`
+### `ProxyClient`
A proxy client that forwards advanced interactions between a remote MCP server and the proxy's connected clients.
@@ -268,7 +268,7 @@ Supports forwarding roots, sampling, elicitation, logging, and progress.
**Methods:**
-#### `default_sampling_handler`
+#### `default_sampling_handler`
```python
default_sampling_handler(cls, messages: list[mcp.types.SamplingMessage], params: mcp.types.CreateMessageRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> mcp.types.CreateMessageResult
@@ -277,7 +277,7 @@ default_sampling_handler(cls, messages: list[mcp.types.SamplingMessage], params:
A handler that forwards the sampling request from the remote server to the proxy's connected clients and relays the response back to the remote server.
-#### `default_elicitation_handler`
+#### `default_elicitation_handler`
```python
default_elicitation_handler(cls, message: str, response_type: type, params: mcp.types.ElicitRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> ElicitResult
@@ -286,7 +286,7 @@ default_elicitation_handler(cls, message: str, response_type: type, params: mcp.
A handler that forwards the elicitation request from the remote server to the proxy's connected clients and relays the response back to the remote server.
-#### `default_log_handler`
+#### `default_log_handler`
```python
default_log_handler(cls, message: LogMessage) -> None
@@ -295,7 +295,7 @@ default_log_handler(cls, message: LogMessage) -> None
A handler that forwards the log notification from the remote server to the proxy's connected clients.
-#### `default_progress_handler`
+#### `default_progress_handler`
```python
default_progress_handler(cls, progress: float, total: float | None, message: str | None) -> None
@@ -304,7 +304,7 @@ default_progress_handler(cls, progress: float, total: float | None, message: str
A handler that forwards the progress notification from the remote server to the proxy's connected clients.
-### `StatefulProxyClient`
+### `StatefulProxyClient`
A proxy client that provides a stateful client factory for the proxy server.
@@ -318,7 +318,7 @@ Note that it is essential to ensure that the proxy server itself is also statefu
**Methods:**
-#### `clear`
+#### `clear`
```python
clear(self)
@@ -327,7 +327,7 @@ clear(self)
Clear all cached clients and force disconnect them.
-#### `new_stateful`
+#### `new_stateful`
```python
new_stateful(self) -> Client[ClientTransportT]
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index 79ac12f81..8ab3dbc75 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.
-### `add_resource_prefix`
+### `add_resource_prefix`
```python
add_resource_prefix(uri: str, prefix: str) -> str
@@ -58,7 +58,7 @@ add_resource_prefix("resource:///absolute/path", "prefix")
- `ValueError`: If the URI doesn't match the expected protocol\://path format
-### `remove_resource_prefix`
+### `remove_resource_prefix`
```python
remove_resource_prefix(uri: str, prefix: str) -> str
@@ -90,7 +90,7 @@ remove_resource_prefix("resource://prefix//absolute/path", "prefix")
- `ValueError`: If the URI doesn't match the expected protocol\://path format
-### `has_resource_prefix`
+### `has_resource_prefix`
```python
has_resource_prefix(uri: str, prefix: str) -> bool
@@ -124,53 +124,64 @@ False
## Classes
-### `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]
```
-#### `run_async`
+#### `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 = True, **transport_kwargs: Any) -> None
@@ -182,7 +193,7 @@ Run the FastMCP server asynchronously.
- `transport`: Transport protocol to use ("stdio", "sse", or "streamable-http")
-#### `run`
+#### `run`
```python
run(self, transport: Transport | None = None, show_banner: bool = True, **transport_kwargs: Any) -> None
@@ -194,13 +205,13 @@ Run the FastMCP server. Note this is a synchronous function.
- `transport`: Transport protocol to use ("stdio", "sse", or "streamable-http")
-#### `add_middleware`
+#### `add_middleware`
```python
add_middleware(self, middleware: Middleware) -> None
```
-#### `get_tools`
+#### `get_tools`
```python
get_tools(self) -> dict[str, Tool]
@@ -209,13 +220,13 @@ get_tools(self) -> dict[str, Tool]
Get all tools (unfiltered), including mounted servers, indexed by key.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, key: str) -> Tool
```
-#### `get_resources`
+#### `get_resources`
```python
get_resources(self) -> dict[str, Resource]
@@ -224,13 +235,13 @@ get_resources(self) -> dict[str, Resource]
Get all resources (unfiltered), including mounted servers, indexed by key.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, key: str) -> Resource
```
-#### `get_resource_templates`
+#### `get_resource_templates`
```python
get_resource_templates(self) -> dict[str, ResourceTemplate]
@@ -239,7 +250,7 @@ get_resource_templates(self) -> dict[str, ResourceTemplate]
Get all resource templates (unfiltered), including mounted servers, indexed by key.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, key: str) -> ResourceTemplate
@@ -248,7 +259,7 @@ get_resource_template(self, key: str) -> ResourceTemplate
Get a registered resource template by key.
-#### `get_prompts`
+#### `get_prompts`
```python
get_prompts(self) -> dict[str, Prompt]
@@ -257,13 +268,13 @@ get_prompts(self) -> dict[str, Prompt]
Get all prompts (unfiltered), including mounted servers, indexed by key.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, key: str) -> Prompt
```
-#### `custom_route`
+#### `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]]]
@@ -284,7 +295,7 @@ 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) -> Tool
@@ -302,7 +313,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) -> None
@@ -317,7 +328,7 @@ Remove a tool from the server.
- `NotFoundError`: If the tool is not found
-#### `add_tool_transformation`
+#### `add_tool_transformation`
```python
add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None
@@ -326,7 +337,7 @@ add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfi
Add a tool transformation.
-#### `remove_tool_transformation`
+#### `remove_tool_transformation`
```python
remove_tool_transformation(self, tool_name: str) -> None
@@ -335,19 +346,19 @@ remove_tool_transformation(self, tool_name: str) -> None
Remove a tool transformation.
-#### `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
@@ -405,7 +416,7 @@ server.tool(my_function, name="custom_name")
```
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource) -> Resource
@@ -420,7 +431,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
@@ -435,7 +446,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]
@@ -495,7 +506,7 @@ async def get_weather(city: str) -> str:
```
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt) -> Prompt
@@ -510,19 +521,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
@@ -600,7 +611,7 @@ Decorator to register a prompt.
```
-#### `run_stdio_async`
+#### `run_stdio_async`
```python
run_stdio_async(self, show_banner: bool = True, log_level: str | None = None) -> None
@@ -613,7 +624,7 @@ Run the server using stdio transport.
- `log_level`: Log level for the server
-#### `run_http_async`
+#### `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) -> None
@@ -633,10 +644,10 @@ Run the server using HTTP transport.
- `stateless_http`: Whether to use stateless HTTP (defaults to settings.stateless_http)
-#### `http_app`
+#### `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') -> StarletteWithLifespan
+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.
@@ -644,13 +655,22 @@ 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
-- `transport`: Transport protocol to use - either "streamable-http" (default) or "sse"
+- `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], prefix: str | None = None, as_proxy: bool | None = None) -> None
@@ -699,15 +719,12 @@ the server's objects are accessible with their original names.
- `as_proxy`: Whether to treat the mounted server as a proxy. If None (default),
automatically determined based on whether the server has a custom lifespan
(True if it has a custom lifespan, False otherwise).
-- `tool_separator`: Deprecated. Separator character for tool names.
-- `resource_separator`: Deprecated. Separator character for resource URIs.
-- `prompt_separator`: Deprecated. Separator character for prompt names.
-#### `import_server`
+#### `import_server`
```python
-import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None, tool_separator: str | None = None, resource_separator: str | None = None, prompt_separator: str | None = None) -> None
+import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None
```
Import the MCP objects from another FastMCP server into this one,
@@ -739,13 +756,9 @@ templates, and prompts are imported with their original names.
- `server`: The FastMCP server to import
- `prefix`: Optional prefix to use for the imported server's objects. If None,
objects are imported with their original names.
-- `tool_separator`: Deprecated. Separator for tool names.
-- `resource_separator`: Deprecated and ignored. Prefix is now
-applied using the protocol\://prefix/path format
-- `prompt_separator`: Deprecated. Separator for prompt names.
-#### `from_openapi`
+#### `from_openapi`
```python
from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, 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, **settings: Any) -> FastMCPOpenAPI
@@ -754,7 +767,7 @@ from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, route
Create a FastMCP server from an OpenAPI specification.
-#### `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, **settings: Any) -> FastMCPOpenAPI
@@ -763,7 +776,7 @@ from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap]
Create a FastMCP server from a FastAPI application.
-#### `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
@@ -777,10 +790,10 @@ 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
```
-### `MountedServer`
+### `MountedServer`
diff --git a/docs/python-sdk/fastmcp-server-tasks-__init__.mdx b/docs/python-sdk/fastmcp-server-tasks-__init__.mdx
new file mode 100644
index 000000000..9c9f5e88e
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-tasks-__init__.mdx
@@ -0,0 +1,12 @@
+---
+title: __init__
+sidebarTitle: __init__
+---
+
+# `fastmcp.server.tasks`
+
+
+MCP SEP-1686 background tasks support.
+
+This module implements protocol-level background task execution for MCP servers.
+
diff --git a/docs/python-sdk/fastmcp-server-tasks-capabilities.mdx b/docs/python-sdk/fastmcp-server-tasks-capabilities.mdx
new file mode 100644
index 000000000..6b8c78e3e
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-tasks-capabilities.mdx
@@ -0,0 +1,24 @@
+---
+title: capabilities
+sidebarTitle: capabilities
+---
+
+# `fastmcp.server.tasks.capabilities`
+
+
+SEP-1686 task capabilities declaration.
+
+## Functions
+
+### `get_task_capabilities`
+
+```python
+get_task_capabilities() -> dict[str, Any]
+```
+
+
+Return the SEP-1686 task capabilities structure.
+
+This is the standard capabilities map advertised to clients,
+declaring support for list, cancel, and request operations.
+
diff --git a/docs/python-sdk/fastmcp-server-tasks-config.mdx b/docs/python-sdk/fastmcp-server-tasks-config.mdx
new file mode 100644
index 000000000..cac8b9254
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-tasks-config.mdx
@@ -0,0 +1,66 @@
+---
+title: config
+sidebarTitle: config
+---
+
+# `fastmcp.server.tasks.config`
+
+
+TaskConfig for MCP SEP-1686 background task execution modes.
+
+This module defines the configuration for how tools, resources, and prompts
+handle task-augmented execution as specified in SEP-1686.
+
+
+## Classes
+
+### `TaskConfig`
+
+
+Configuration for MCP background task execution (SEP-1686).
+
+Controls how a component handles task-augmented requests:
+
+- "forbidden": Component does not support task execution. Clients must not
+ request task augmentation; server returns -32601 if they do.
+- "optional": Component supports both synchronous and task execution.
+ Client may request task augmentation or call normally.
+- "required": Component requires task execution. Clients must request task
+ augmentation; server returns -32601 if they don't.
+
+
+**Methods:**
+
+#### `from_bool`
+
+```python
+from_bool(cls, value: bool) -> TaskConfig
+```
+
+Convert boolean task flag to TaskConfig.
+
+**Args:**
+- `value`: True for "optional" mode, False for "forbidden" mode.
+
+**Returns:**
+- TaskConfig with appropriate mode.
+
+
+#### `validate_function`
+
+```python
+validate_function(self, fn: Callable[..., Any], name: str) -> None
+```
+
+Validate that function is compatible with this task config.
+
+Task execution requires async functions. Raises ValueError if mode
+is "optional" or "required" but function is synchronous.
+
+**Args:**
+- `fn`: The function to validate (handles callable classes and staticmethods).
+- `name`: Name for error messages.
+
+**Raises:**
+- `ValueError`: If task execution is enabled but function is sync.
+
diff --git a/docs/python-sdk/fastmcp-server-tasks-converters.mdx b/docs/python-sdk/fastmcp-server-tasks-converters.mdx
new file mode 100644
index 000000000..94118c394
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-tasks-converters.mdx
@@ -0,0 +1,77 @@
+---
+title: converters
+sidebarTitle: converters
+---
+
+# `fastmcp.server.tasks.converters`
+
+
+SEP-1686 task result converters.
+
+Converts raw task return values to MCP result types.
+
+
+## Functions
+
+### `convert_tool_result`
+
+```python
+convert_tool_result(server: FastMCP, raw_value: Any, tool_name: str, client_task_id: str) -> mcp.types.CallToolResult
+```
+
+
+Convert raw tool return value to MCP CallToolResult.
+
+Replicates the serialization logic from tool.run() to properly handle
+output_schema, structured content, etc.
+
+**Args:**
+- `server`: FastMCP server instance
+- `raw_value`: The raw return value from user's tool function
+- `tool_name`: Name of the tool (to get output_schema and serializer)
+- `client_task_id`: Client task ID for related-task metadata
+
+**Returns:**
+- CallToolResult with properly formatted content and structured content
+
+
+### `convert_prompt_result`
+
+```python
+convert_prompt_result(server: FastMCP, raw_value: Any, prompt_name: str, client_task_id: str) -> mcp.types.GetPromptResult
+```
+
+
+Convert raw prompt return value to MCP GetPromptResult.
+
+The user function returns raw values (strings, dicts, lists) that need
+to be converted to PromptMessage objects.
+
+**Args:**
+- `server`: FastMCP server instance
+- `raw_value`: The raw return value from user's prompt function
+- `prompt_name`: Name of the prompt
+- `client_task_id`: Client task ID for related-task metadata
+
+**Returns:**
+- GetPromptResult with properly formatted messages
+
+
+### `convert_resource_result`
+
+```python
+convert_resource_result(server: FastMCP, raw_value: Any, uri: str, client_task_id: str) -> dict[str, Any]
+```
+
+
+Convert raw resource return value to MCP resource contents dict.
+
+**Args:**
+- `server`: FastMCP server instance
+- `raw_value`: The raw return value from user's resource function (str or bytes)
+- `uri`: Resource URI (for the contents response)
+- `client_task_id`: Client task ID for related-task metadata
+
+**Returns:**
+- Dict with 'contents' key containing list of resource contents
+
diff --git a/docs/python-sdk/fastmcp-server-tasks-handlers.mdx b/docs/python-sdk/fastmcp-server-tasks-handlers.mdx
new file mode 100644
index 000000000..423f3bdea
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-tasks-handlers.mdx
@@ -0,0 +1,78 @@
+---
+title: handlers
+sidebarTitle: handlers
+---
+
+# `fastmcp.server.tasks.handlers`
+
+
+SEP-1686 task execution handlers.
+
+Handles queuing tool/prompt/resource executions to Docket as background tasks.
+
+
+## Functions
+
+### `handle_tool_as_task`
+
+```python
+handle_tool_as_task(server: FastMCP, tool_name: str, arguments: dict[str, Any], task_meta: dict[str, Any]) -> mcp.types.CallToolResult
+```
+
+
+Handle tool execution as background task (SEP-1686).
+
+Queues the user's actual function to Docket (preserving signature for DI),
+stores raw return values, converts to MCP types on retrieval.
+
+**Args:**
+- `server`: FastMCP server instance
+- `tool_name`: Name of the tool to execute
+- `arguments`: Tool arguments
+- `task_meta`: Task metadata from request (contains ttl)
+
+**Returns:**
+- Task stub with task metadata in _meta
+
+
+### `handle_prompt_as_task`
+
+```python
+handle_prompt_as_task(server: FastMCP, prompt_name: str, arguments: dict[str, Any] | None, task_meta: dict[str, Any]) -> mcp.types.GetPromptResult
+```
+
+
+Handle prompt execution as background task (SEP-1686).
+
+Queues the user's actual function to Docket (preserving signature for DI).
+
+**Args:**
+- `server`: FastMCP server instance
+- `prompt_name`: Name of the prompt to execute
+- `arguments`: Prompt arguments
+- `task_meta`: Task metadata from request (contains ttl)
+
+**Returns:**
+- Task stub with task metadata in _meta
+
+
+### `handle_resource_as_task`
+
+```python
+handle_resource_as_task(server: FastMCP, uri: str, resource, task_meta: dict[str, Any]) -> mcp.types.ServerResult
+```
+
+
+Handle resource read as background task (SEP-1686).
+
+Queues the user's actual function to Docket.
+
+**Args:**
+- `server`: FastMCP server instance
+- `uri`: Resource URI
+- `resource`: Resource or ResourceTemplate object
+- `task_meta`: Task metadata from request (contains ttl)
+
+**Returns:**
+- ServerResult with ReadResourceResult stub
+
diff --git a/docs/python-sdk/fastmcp-server-tasks-keys.mdx b/docs/python-sdk/fastmcp-server-tasks-keys.mdx
new file mode 100644
index 000000000..8094a28a7
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-tasks-keys.mdx
@@ -0,0 +1,91 @@
+---
+title: keys
+sidebarTitle: keys
+---
+
+# `fastmcp.server.tasks.keys`
+
+
+Task key management for SEP-1686 background tasks.
+
+Task keys encode security scoping and metadata in the Docket key format:
+ {session_id}:{client_task_id}:{task_type}:{component_identifier}
+
+This format provides:
+- Session-based security scoping (prevents cross-session access)
+- Task type identification (tool/prompt/resource)
+- Component identification (name or URI for result conversion)
+
+
+## Functions
+
+### `build_task_key`
+
+```python
+build_task_key(session_id: str, client_task_id: str, task_type: str, component_identifier: str) -> str
+```
+
+
+Build Docket task key with embedded metadata.
+
+Format: {session_id}:{client_task_id}:{task_type}:{component_identifier}
+
+The component_identifier is URI-encoded to handle special characters (colons, slashes, etc.).
+
+**Args:**
+- `session_id`: Session ID for security scoping
+- `client_task_id`: Client-provided task ID
+- `task_type`: Type of task ("tool", "prompt", "resource")
+- `component_identifier`: Tool name, prompt name, or resource URI
+
+**Returns:**
+- Encoded task key for Docket
+
+**Examples:**
+
+>>> build_task_key("session123", "task456", "tool", "my_tool")
+'session123:task456:tool:my_tool'
+>>> build_task_key("session123", "task456", "resource", "file://data.txt")
+'session123:task456:resource:file%3A%2F%2Fdata.txt'
+
+
+### `parse_task_key`
+
+```python
+parse_task_key(task_key: str) -> dict[str, str]
+```
+
+
+Parse Docket task key to extract metadata.
+
+**Args:**
+- `task_key`: Encoded task key from Docket
+
+**Returns:**
+- Dict with keys: session_id, client_task_id, task_type, component_identifier
+
+**Examples:**
+
+>>> parse_task_key("session123:task456:tool:my_tool")
+{'session_id': 'session123', 'client_task_id': 'task456',
+ 'task_type': 'tool', 'component_identifier': 'my_tool'}
+>>> parse_task_key("session123:task456:resource:file%3A%2F%2Fdata.txt")
+{'session_id': 'session123', 'client_task_id': 'task456',
+ 'task_type': 'resource', 'component_identifier': 'file://data.txt'}
+
+
+### `get_client_task_id_from_key`
+
+```python
+get_client_task_id_from_key(task_key: str) -> str
+```
+
+
+Extract just the client task ID from a task key.
+
+**Args:**
+- `task_key`: Full encoded task key
+
+**Returns:**
+- Client-provided task ID (second segment)
+
diff --git a/docs/python-sdk/fastmcp-server-tasks-protocol.mdx b/docs/python-sdk/fastmcp-server-tasks-protocol.mdx
new file mode 100644
index 000000000..6d355b824
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-tasks-protocol.mdx
@@ -0,0 +1,88 @@
+---
+title: protocol
+sidebarTitle: protocol
+---
+
+# `fastmcp.server.tasks.protocol`
+
+
+SEP-1686 task protocol handlers.
+
+Implements MCP task protocol methods: tasks/get, tasks/result, tasks/list, tasks/cancel, tasks/delete.
+
+
+## Functions
+
+### `tasks_get_handler`
+
+```python
+tasks_get_handler(server: FastMCP, params: dict[str, Any]) -> GetTaskResult
+```
+
+
+Handle MCP 'tasks/get' request (SEP-1686).
+
+**Args:**
+- `server`: FastMCP server instance
+- `params`: Request params containing taskId
+
+**Returns:**
+- Task status response with spec-compliant fields
+
+
+### `tasks_result_handler`
+
+```python
+tasks_result_handler(server: FastMCP, params: dict[str, Any]) -> Any
+```
+
+
+Handle MCP 'tasks/result' request (SEP-1686).
+
+Converts raw task return values to MCP types based on task type.
+
+**Args:**
+- `server`: FastMCP server instance
+- `params`: Request params containing taskId
+
+**Returns:**
+- MCP result (CallToolResult, GetPromptResult, or ReadResourceResult)
+
+
+### `tasks_list_handler`
+
+```python
+tasks_list_handler(server: FastMCP, params: dict[str, Any]) -> ListTasksResult
+```
+
+
+Handle MCP 'tasks/list' request (SEP-1686).
+
+Note: With client-side tracking, this returns minimal info.
+
+**Args:**
+- `server`: FastMCP server instance
+- `params`: Request params (cursor, limit)
+
+**Returns:**
+- Response with tasks list and pagination
+
+
+### `tasks_cancel_handler`
+
+```python
+tasks_cancel_handler(server: FastMCP, params: dict[str, Any]) -> CancelTaskResult
+```
+
+
+Handle MCP 'tasks/cancel' request (SEP-1686).
+
+Cancels a running task, transitioning it to cancelled state.
+
+**Args:**
+- `server`: FastMCP server instance
+- `params`: Request params containing taskId
+
+**Returns:**
+- Task status response showing cancelled state
+
diff --git a/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx b/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx
new file mode 100644
index 000000000..78f06cf81
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx
@@ -0,0 +1,35 @@
+---
+title: subscriptions
+sidebarTitle: subscriptions
+---
+
+# `fastmcp.server.tasks.subscriptions`
+
+
+Task subscription helpers for sending MCP notifications (SEP-1686).
+
+Subscribes to Docket execution state changes and sends notifications/tasks/status
+to clients when their tasks change state.
+
+
+## Functions
+
+### `subscribe_to_task_updates`
+
+```python
+subscribe_to_task_updates(task_id: str, task_key: str, session: ServerSession, docket: Docket) -> None
+```
+
+
+Subscribe to Docket execution events and send MCP notifications.
+
+Per SEP-1686 lines 436-444, servers MAY send notifications/tasks/status
+when task state changes. This is an optional optimization that reduces
+client polling frequency.
+
+**Args:**
+- `task_id`: Client-visible task ID (server-generated UUID)
+- `task_key`: Internal Docket execution key (includes session, type, component)
+- `session`: MCP ServerSession for sending notifications
+- `docket`: Docket instance for subscribing to execution events
+
diff --git a/docs/python-sdk/fastmcp-settings.mdx b/docs/python-sdk/fastmcp-settings.mdx
index bb11611e9..398896549 100644
--- a/docs/python-sdk/fastmcp-settings.mdx
+++ b/docs/python-sdk/fastmcp-settings.mdx
@@ -7,9 +7,15 @@ sidebarTitle: settings
## Classes
-### `ExperimentalSettings`
+### `DocketSettings`
-### `Settings`
+
+Docket worker configuration.
+
+
+### `ExperimentalSettings`
+
+### `Settings`
FastMCP settings.
@@ -17,7 +23,7 @@ FastMCP settings.
**Methods:**
-#### `get_setting`
+#### `get_setting`
```python
get_setting(self, attr: str) -> Any
@@ -27,7 +33,7 @@ Get a setting. If the setting contains one or more `__`, it will be
treated as a nested setting.
-#### `set_setting`
+#### `set_setting`
```python
set_setting(self, attr: str, value: Any) -> None
@@ -37,23 +43,13 @@ Set a setting. If the setting contains one or more `__`, it will be
treated as a nested setting.
-#### `settings`
-
-```python
-settings(self) -> Self
-```
-
-This property is for backwards compatibility with FastMCP < 2.8.0,
-which accessed fastmcp.settings.settings
-
-
-#### `normalize_log_level`
+#### `normalize_log_level`
```python
normalize_log_level(cls, v)
```
-#### `server_auth_class`
+#### `server_auth_class`
```python
server_auth_class(self) -> AuthProvider | None
diff --git a/docs/python-sdk/fastmcp-tools-tool.mdx b/docs/python-sdk/fastmcp-tools-tool.mdx
index c6f3931a9..d6fc3accc 100644
--- a/docs/python-sdk/fastmcp-tools-tool.mdx
+++ b/docs/python-sdk/fastmcp-tools-tool.mdx
@@ -7,7 +7,7 @@ sidebarTitle: tool
## Functions
-### `default_serializer`
+### `default_serializer`
```python
default_serializer(data: Any) -> str
@@ -15,17 +15,17 @@ default_serializer(data: Any) -> str
## Classes
-### `ToolResult`
+### `ToolResult`
**Methods:**
-#### `to_mcp_result`
+#### `to_mcp_result`
```python
to_mcp_result(self) -> list[ContentBlock] | tuple[list[ContentBlock], dict[str, Any]] | CallToolResult
```
-### `Tool`
+### `Tool`
Internal tool registration info.
@@ -33,19 +33,19 @@ Internal tool registration info.
**Methods:**
-#### `enable`
+#### `enable`
```python
enable(self) -> None
```
-#### `disable`
+#### `disable`
```python
disable(self) -> None
```
-#### `to_mcp_tool`
+#### `to_mcp_tool`
```python
to_mcp_tool(self, **overrides: Any) -> MCPTool
@@ -54,16 +54,16 @@ to_mcp_tool(self, **overrides: Any) -> MCPTool
Convert the FastMCP tool to an MCP tool.
-#### `from_function`
+#### `from_function`
```python
-from_function(fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None) -> FunctionTool
+from_function(fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None, task: bool | TaskConfig | None = None) -> FunctionTool
```
Create a Tool from a function.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -78,26 +78,37 @@ implemented by subclasses.
(list of ContentBlocks, dict of structured output).
-#### `from_tool`
+#### `from_tool`
```python
from_tool(cls, tool: Tool) -> TransformedTool
```
-### `FunctionTool`
+### `FunctionTool`
**Methods:**
-#### `from_function`
+#### `to_mcp_tool`
```python
-from_function(cls, fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None) -> FunctionTool
+to_mcp_tool(self, **overrides: Any) -> MCPTool
+```
+
+Convert the FastMCP tool to an MCP tool.
+
+Extends the base implementation to add task execution mode if enabled.
+
+
+#### `from_function`
+
+```python
+from_function(cls, fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None, task: bool | TaskConfig | None = None) -> FunctionTool
```
Create a Tool from a function.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -106,11 +117,11 @@ run(self, arguments: dict[str, Any]) -> ToolResult
Run the tool with arguments.
-### `ParsedFunction`
+### `ParsedFunction`
**Methods:**
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any], exclude_args: list[str] | None = None, validate: bool = True, wrap_non_object_output_schema: bool = True) -> ParsedFunction
diff --git a/docs/python-sdk/fastmcp-utilities-tests.mdx b/docs/python-sdk/fastmcp-utilities-tests.mdx
index a33f1122b..e59e40d46 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,10 +64,10 @@ sleeps, and cleanup issues.
- `host`: Host to bind to (default\: "127.0.0.1")
-### `caplog_for_fastmcp`
+### `caplog_for_fastmcp`
```python
-caplog_for_fastmcp(caplog)
+caplog_for_fastmcp(caplog: LogCaptureFixture) -> Generator[LogCaptureFixture, None, None]
```
@@ -76,7 +76,7 @@ Context manager to capture logs from FastMCP loggers even when propagation is di
## Classes
-### `HeadlessOAuth`
+### `HeadlessOAuth`
OAuth provider that bypasses browser interaction for testing.
@@ -87,7 +87,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 +96,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]
diff --git a/docs/python-sdk/fastmcp-utilities-types.mdx b/docs/python-sdk/fastmcp-utilities-types.mdx
index 0026885eb..93fc7bc40 100644
--- a/docs/python-sdk/fastmcp-utilities-types.mdx
+++ b/docs/python-sdk/fastmcp-utilities-types.mdx
@@ -77,7 +77,7 @@ This is used to exclude parameters from type adapter processing when they can't
The excluded parameters are removed from the function's __annotations__ dictionary.
-### `replace_type`
+### `replace_type`
```python
replace_type(type_, type_map: dict[type, type])
@@ -112,7 +112,7 @@ list[list[str]]
Base model for FastMCP models.
-### `Image`
+### `Image`
Helper class for returning images from tools.
@@ -120,7 +120,7 @@ Helper class for returning images from tools.
**Methods:**
-#### `to_image_content`
+#### `to_image_content`
```python
to_image_content(self, mime_type: str | None = None, annotations: Annotations | None = None) -> mcp.types.ImageContent
@@ -129,7 +129,7 @@ to_image_content(self, mime_type: str | None = None, annotations: Annotations |
Convert to MCP ImageContent.
-#### `to_data_uri`
+#### `to_data_uri`
```python
to_data_uri(self, mime_type: str | None = None) -> str
@@ -138,7 +138,7 @@ to_data_uri(self, mime_type: str | None = None) -> str
Get image as a data URI.
-### `Audio`
+### `Audio`
Helper class for returning audio from tools.
@@ -146,13 +146,13 @@ Helper class for returning audio from tools.
**Methods:**
-#### `to_audio_content`
+#### `to_audio_content`
```python
to_audio_content(self, mime_type: str | None = None, annotations: Annotations | None = None) -> mcp.types.AudioContent
```
-### `File`
+### `File`
Helper class for returning file data from tools.
@@ -160,10 +160,10 @@ Helper class for returning file data from tools.
**Methods:**
-#### `to_resource_content`
+#### `to_resource_content`
```python
to_resource_content(self, mime_type: str | None = None, annotations: Annotations | None = None) -> mcp.types.EmbeddedResource
```
-### `ContextSamplingFallbackProtocol`
+### `ContextSamplingFallbackProtocol`