diff --git a/docs/docs.json b/docs/docs.json
index de6369d10..b7f26ab6b 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -301,6 +301,8 @@
"pages": [
"python-sdk/fastmcp-cli-__init__",
"python-sdk/fastmcp-cli-cli",
+ "python-sdk/fastmcp-cli-client",
+ "python-sdk/fastmcp-cli-discovery",
{
"group": "install",
"pages": [
@@ -311,7 +313,8 @@
"python-sdk/fastmcp-cli-install-gemini_cli",
"python-sdk/fastmcp-cli-install-goose",
"python-sdk/fastmcp-cli-install-mcp_json",
- "python-sdk/fastmcp-cli-install-shared"
+ "python-sdk/fastmcp-cli-install-shared",
+ "python-sdk/fastmcp-cli-install-stdio"
]
},
"python-sdk/fastmcp-cli-run",
@@ -400,6 +403,7 @@
"group": "fastmcp.server",
"pages": [
"python-sdk/fastmcp-server-__init__",
+ "python-sdk/fastmcp-server-apps",
{
"group": "auth",
"pages": [
@@ -547,6 +551,7 @@
"python-sdk/fastmcp-server-tasks-__init__",
"python-sdk/fastmcp-server-tasks-capabilities",
"python-sdk/fastmcp-server-tasks-config",
+ "python-sdk/fastmcp-server-tasks-elicitation",
"python-sdk/fastmcp-server-tasks-handlers",
"python-sdk/fastmcp-server-tasks-keys",
"python-sdk/fastmcp-server-tasks-requests",
diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx
index 759a4324d..df21e8105 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-client.mdx b/docs/python-sdk/fastmcp-cli-client.mdx
new file mode 100644
index 000000000..e256d90bc
--- /dev/null
+++ b/docs/python-sdk/fastmcp-cli-client.mdx
@@ -0,0 +1,133 @@
+---
+title: client
+sidebarTitle: client
+---
+
+# `fastmcp.cli.client`
+
+
+Client-side CLI commands for querying and invoking MCP servers.
+
+## Functions
+
+### `resolve_server_spec`
+
+```python
+resolve_server_spec(server_spec: str | None) -> str | dict[str, Any] | ClientTransport
+```
+
+
+Turn CLI inputs into something ``Client()`` accepts.
+
+Exactly one of ``server_spec`` or ``command`` should be provided.
+
+Resolution order for ``server_spec``:
+1. URLs (``http://``, ``https://``) — passed through as-is.
+ If ``--transport`` is ``sse``, the URL is rewritten to end with ``/sse``
+ so ``infer_transport`` picks the right transport.
+2. Existing file paths, or strings ending in ``.py``/``.js``/``.json``.
+3. Anything else — name-based resolution via ``resolve_name``.
+
+When ``command`` is provided, the string is shell-split into a
+``StdioTransport(command, args)``.
+
+
+### `coerce_value`
+
+```python
+coerce_value(raw: str, schema: dict[str, Any]) -> Any
+```
+
+
+Coerce a string CLI value according to a JSON-Schema type hint.
+
+
+### `parse_tool_arguments`
+
+```python
+parse_tool_arguments(raw_args: tuple[str, ...], input_json: str | None, input_schema: dict[str, Any]) -> dict[str, Any]
+```
+
+
+Build a tool-call argument dict from CLI inputs.
+
+A single JSON object argument is treated as the full argument dict.
+``--input-json`` provides the base dict; ``key=value`` pairs override.
+Values are coerced using the tool's ``inputSchema``.
+
+
+### `format_tool_signature`
+
+```python
+format_tool_signature(tool: mcp.types.Tool) -> str
+```
+
+
+Build ``name(param: type, ...) -> return_type`` from a tool's JSON schemas.
+
+
+### `list_command`
+
+```python
+list_command(server_spec: Annotated[str | None, cyclopts.Parameter(help='Server URL, Python file, MCPConfig JSON, or .js file')] = None) -> None
+```
+
+
+List tools available on an MCP server.
+
+**Examples:**
+
+fastmcp list http://localhost:8000/mcp
+fastmcp list server.py
+fastmcp list mcp.json --json
+fastmcp list --command 'npx -y @mcp/server' --resources
+fastmcp list http://server/mcp --transport sse
+
+
+### `call_command`
+
+```python
+call_command(server_spec: Annotated[str | None, cyclopts.Parameter(help='Server URL, Python file, MCPConfig JSON, or .js file')] = None, target: Annotated[str, cyclopts.Parameter(help='Tool name, resource URI, or prompt name (with --prompt)')] = '', *arguments: str) -> None
+```
+
+
+Call a tool, read a resource, or get a prompt on an MCP server.
+
+By default the target is treated as a tool name. If the target
+contains ``://`` it is treated as a resource URI. Pass ``--prompt``
+to treat it as a prompt name.
+
+Arguments are passed as key=value pairs. Use --input-json for complex
+or nested arguments.
+
+**Examples:**
+
+fastmcp call server.py greet name=World
+fastmcp call server.py resource://docs/readme
+fastmcp call server.py analyze --prompt data='[1,2,3]'
+fastmcp call http://server/mcp create --input-json '{"tags": ["a","b"]}'
+
+
+### `discover_command`
+
+```python
+discover_command() -> None
+```
+
+
+Discover MCP servers configured in editor and project configs.
+
+Scans Claude Desktop, Claude Code, Cursor, Gemini CLI, Goose, and
+project-level mcp.json files for MCP server definitions.
+
+Discovered server names can be used directly with ``fastmcp list``
+and ``fastmcp call`` instead of specifying a URL or file path.
+
+**Examples:**
+
+fastmcp discover
+fastmcp discover --source claude-code
+fastmcp discover --source cursor --source gemini --json
+fastmcp list weather
+fastmcp call cursor:weather get_forecast city=London
+
diff --git a/docs/python-sdk/fastmcp-cli-discovery.mdx b/docs/python-sdk/fastmcp-cli-discovery.mdx
new file mode 100644
index 000000000..3cc6866bd
--- /dev/null
+++ b/docs/python-sdk/fastmcp-cli-discovery.mdx
@@ -0,0 +1,71 @@
+---
+title: discovery
+sidebarTitle: discovery
+---
+
+# `fastmcp.cli.discovery`
+
+
+Discover MCP servers configured in editor config files.
+
+Scans filesystem-readable config files from editors like Claude Desktop,
+Claude Code, Cursor, Gemini CLI, and Goose, as well as project-level
+``mcp.json`` files. Each discovered server can be resolved by name
+(or ``source:name``) so the CLI can connect without requiring a URL
+or file path.
+
+
+## Functions
+
+### `discover_servers`
+
+```python
+discover_servers(start_dir: Path | None = None) -> list[DiscoveredServer]
+```
+
+
+Run all scanners and return the combined results.
+
+Duplicate names across sources are preserved — callers can
+use :pyattr:`DiscoveredServer.qualified_name` to disambiguate.
+
+
+### `resolve_name`
+
+```python
+resolve_name(name: str, start_dir: Path | None = None) -> ClientTransport
+```
+
+
+Resolve a server name (or ``source:name``) to a transport.
+
+Raises :class:`ValueError` when the name is not found or is ambiguous.
+
+
+## Classes
+
+### `DiscoveredServer`
+
+
+A single MCP server found in an editor or project config.
+
+
+**Methods:**
+
+#### `qualified_name`
+
+```python
+qualified_name(self) -> str
+```
+
+Fully qualified ``source:name`` identifier.
+
+
+#### `transport_summary`
+
+```python
+transport_summary(self) -> str
+```
+
+Human-readable one-liner describing the transport.
+
diff --git a/docs/python-sdk/fastmcp-cli-install-cursor.mdx b/docs/python-sdk/fastmcp-cli-install-cursor.mdx
index 40c0c5c6a..adb8b0bfd 100644
--- a/docs/python-sdk/fastmcp-cli-install-cursor.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-cursor.mdx
@@ -10,7 +10,7 @@ Cursor integration for FastMCP install using Cyclopts.
## Functions
-### `generate_cursor_deeplink`
+### `generate_cursor_deeplink`
```python
generate_cursor_deeplink(server_name: str, server_config: StdioMCPServer) -> str
@@ -27,14 +27,14 @@ Generate a Cursor deeplink for installing the MCP server.
- Deeplink URL that can be clicked to install the server
-### `open_deeplink`
+### `open_deeplink`
```python
open_deeplink(deeplink: str) -> bool
```
-Attempt to open a deeplink URL using the system's default handler.
+Attempt to open a Cursor deeplink URL using the system's default handler.
**Args:**
- `deeplink`: The deeplink URL to open
@@ -43,7 +43,7 @@ Attempt to open a deeplink URL using the system's default handler.
- True if the command succeeded, False otherwise
-### `install_cursor_workspace`
+### `install_cursor_workspace`
```python
install_cursor_workspace(file: Path, server_object: str | None, name: str, workspace_path: Path) -> bool
@@ -68,7 +68,7 @@ Install FastMCP server to workspace-specific Cursor configuration.
- True if installation was successful, False otherwise
-### `install_cursor`
+### `install_cursor`
```python
install_cursor(file: Path, server_object: str | None, name: str) -> bool
@@ -93,7 +93,7 @@ Install FastMCP server in Cursor.
- True if installation was successful, False otherwise
-### `cursor_command`
+### `cursor_command`
```python
cursor_command(server_spec: str) -> None
diff --git a/docs/python-sdk/fastmcp-cli-install-goose.mdx b/docs/python-sdk/fastmcp-cli-install-goose.mdx
new file mode 100644
index 000000000..9db2bdf18
--- /dev/null
+++ b/docs/python-sdk/fastmcp-cli-install-goose.mdx
@@ -0,0 +1,67 @@
+---
+title: goose
+sidebarTitle: goose
+---
+
+# `fastmcp.cli.install.goose`
+
+
+Goose integration for FastMCP install using Cyclopts.
+
+## Functions
+
+### `generate_goose_deeplink`
+
+```python
+generate_goose_deeplink(name: str, command: str, args: list[str]) -> str
+```
+
+
+Generate a Goose deeplink for installing an MCP extension.
+
+**Args:**
+- `name`: Human-readable display name for the extension.
+- `command`: The executable command (e.g. "uv").
+- `args`: Arguments to the command.
+- `description`: Short description shown in Goose.
+
+**Returns:**
+- A goose://extension?... deeplink URL.
+
+
+### `install_goose`
+
+```python
+install_goose(file: Path, server_object: str | None, name: str) -> bool
+```
+
+
+Install FastMCP server in Goose via deeplink.
+
+**Args:**
+- `file`: Path to the server file.
+- `server_object`: Optional server object name (for \:object suffix).
+- `name`: Name for the extension in Goose.
+- `with_packages`: Optional list of additional packages to install.
+- `python_version`: Optional Python version to use.
+
+**Returns:**
+- True if installation was successful, False otherwise.
+
+
+### `goose_command`
+
+```python
+goose_command(server_spec: str) -> None
+```
+
+
+Install an MCP server in Goose.
+
+Uses uvx to run the server. Environment variables are not included
+in the deeplink; use `fastmcp install mcp-json` to generate a full
+config for manual installation.
+
+**Args:**
+- `server_spec`: Python file to install, optionally with \:object suffix
+
diff --git a/docs/python-sdk/fastmcp-cli-install-shared.mdx b/docs/python-sdk/fastmcp-cli-install-shared.mdx
index 337179267..1df969961 100644
--- a/docs/python-sdk/fastmcp-cli-install-shared.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-shared.mdx
@@ -10,7 +10,7 @@ Shared utilities for install commands.
## Functions
-### `parse_env_var`
+### `parse_env_var`
```python
parse_env_var(env_var: str) -> tuple[str, str]
@@ -20,7 +20,7 @@ parse_env_var(env_var: str) -> tuple[str, str]
Parse environment variable string in format KEY=VALUE.
-### `process_common_args`
+### `process_common_args`
```python
process_common_args(server_spec: str, server_name: str | None, with_packages: list[str] | None, env_vars: list[str] | None, env_file: Path | None) -> tuple[Path, str | None, str, list[str], dict[str, str] | None]
@@ -31,3 +31,20 @@ Process common arguments shared by all install commands.
Handles both fastmcp.json config files and traditional file.py:object syntax.
+
+### `open_deeplink`
+
+```python
+open_deeplink(url: str) -> bool
+```
+
+
+Attempt to open a deeplink URL using the system's default handler.
+
+**Args:**
+- `url`: The deeplink URL to open.
+- `expected_scheme`: The URL scheme to validate (e.g. "cursor", "goose").
+
+**Returns:**
+- True if the command succeeded, False otherwise.
+
diff --git a/docs/python-sdk/fastmcp-cli-install-stdio.mdx b/docs/python-sdk/fastmcp-cli-install-stdio.mdx
new file mode 100644
index 000000000..d7d7c28d4
--- /dev/null
+++ b/docs/python-sdk/fastmcp-cli-install-stdio.mdx
@@ -0,0 +1,50 @@
+---
+title: stdio
+sidebarTitle: stdio
+---
+
+# `fastmcp.cli.install.stdio`
+
+
+Stdio command generation for FastMCP install using Cyclopts.
+
+## Functions
+
+### `install_stdio`
+
+```python
+install_stdio(file: Path, server_object: str | None) -> bool
+```
+
+
+Generate the stdio command for running a FastMCP server.
+
+**Args:**
+- `file`: Path to the server file
+- `server_object`: Optional server object name (for \:object suffix)
+- `with_editable`: Optional list of directories to install in editable mode
+- `with_packages`: Optional list of additional packages to install
+- `copy`: If True, copy to clipboard instead of printing to stdout
+- `python_version`: Optional Python version to use
+- `with_requirements`: Optional requirements file to install from
+- `project`: Optional project directory to run within
+
+**Returns:**
+- True if generation was successful, False otherwise
+
+
+### `stdio_command`
+
+```python
+stdio_command(server_spec: str) -> None
+```
+
+
+Generate the stdio command for running a FastMCP server.
+
+Outputs the shell command that an MCP host would use to start this server
+over stdio transport. Useful for manual configuration or debugging.
+
+**Args:**
+- `server_spec`: Python file to run, optionally with \:object suffix
+
diff --git a/docs/python-sdk/fastmcp-cli-run.mdx b/docs/python-sdk/fastmcp-cli-run.mdx
index c3192a611..4141cd3f1 100644
--- a/docs/python-sdk/fastmcp-cli-run.mdx
+++ b/docs/python-sdk/fastmcp-cli-run.mdx
@@ -10,7 +10,7 @@ FastMCP run command implementation with enhanced type hints.
## Functions
-### `is_url`
+### `is_url`
```python
is_url(path: str) -> bool
@@ -20,7 +20,7 @@ is_url(path: str) -> bool
Check if a string is a URL.
-### `create_client_server`
+### `create_client_server`
```python
create_client_server(url: str) -> Any
@@ -36,7 +36,7 @@ Create a FastMCP server from a client URL.
- A FastMCP server instance
-### `create_mcp_config_server`
+### `create_mcp_config_server`
```python
create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None]
@@ -46,7 +46,7 @@ create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None]
Create a FastMCP server from a MCPConfig.
-### `load_mcp_server_config`
+### `load_mcp_server_config`
```python
load_mcp_server_config(config_path: Path) -> MCPServerConfig
@@ -62,7 +62,7 @@ Load a FastMCP configuration from a fastmcp.json file.
- MCPServerConfig object
-### `run_command`
+### `run_command`
```python
run_command(server_spec: str, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, server_args: list[str] | None = None, show_banner: bool = True, use_direct_import: bool = False, skip_source: bool = False, stateless: bool = False) -> None
@@ -85,7 +85,7 @@ Run a MCP server or connect to a remote one.
- `stateless`: Whether to run in stateless mode (no session)
-### `run_v1_server_async`
+### `run_v1_server_async`
```python
run_v1_server_async(server: FastMCP1x, host: str | None = None, port: int | None = None, transport: TransportType | None = None) -> None
@@ -101,7 +101,7 @@ Run a FastMCP 1.x server using async methods.
- `transport`: Transport protocol to use
-### `run_with_reload`
+### `run_with_reload`
```python
run_with_reload(cmd: list[str], reload_dirs: list[Path] | None = None, is_stdio: bool = False) -> None
diff --git a/docs/python-sdk/fastmcp-client-transports-config.mdx b/docs/python-sdk/fastmcp-client-transports-config.mdx
index d19f709f2..2e802df0a 100644
--- a/docs/python-sdk/fastmcp-client-transports-config.mdx
+++ b/docs/python-sdk/fastmcp-client-transports-config.mdx
@@ -19,7 +19,7 @@ object or dictionary matching the MCPConfig schema. It supports two key scenario
2. If the MCPConfig contains multiple servers, it creates a composite client by mounting
all servers on a single FastMCP instance, with each server's name, by default, used as its mounting prefix.
-In the multi-server case, tools are accessible with the prefix pattern `{server_name}_{tool_name}`
+In the multiserver case, tools are accessible with the prefix pattern `{server_name}_{tool_name}`
and resources with the pattern `protocol://{server_name}/path/to/resource`.
This is particularly useful for creating clients that need to interact with multiple specialized
diff --git a/docs/python-sdk/fastmcp-prompts-function_prompt.mdx b/docs/python-sdk/fastmcp-prompts-function_prompt.mdx
index 3c543de88..edc9527f2 100644
--- a/docs/python-sdk/fastmcp-prompts-function_prompt.mdx
+++ b/docs/python-sdk/fastmcp-prompts-function_prompt.mdx
@@ -10,7 +10,7 @@ Standalone @prompt decorator for FastMCP.
## Functions
-### `prompt`
+### `prompt`
```python
prompt(name_or_fn: str | Callable[..., Any] | None = None) -> Any
@@ -25,19 +25,19 @@ using mcp.add_prompt().
## Classes
-### `DecoratedPrompt`
+### `DecoratedPrompt`
Protocol for functions decorated with @prompt.
-### `PromptMeta`
+### `PromptMeta`
Metadata attached to functions by the @prompt decorator.
-### `FunctionPrompt`
+### `FunctionPrompt`
A prompt that is a function.
@@ -45,7 +45,7 @@ A prompt that is a function.
**Methods:**
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any]) -> FunctionPrompt
@@ -66,7 +66,7 @@ The function can return:
- PromptResult: used directly
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any] | None = None) -> PromptResult
@@ -75,7 +75,7 @@ render(self, arguments: dict[str, Any] | None = None) -> PromptResult
Render the prompt with arguments.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -87,7 +87,7 @@ FunctionPrompt registers the underlying function, which has the user's
Depends parameters for docket to resolve.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, arguments: dict[str, Any] | None, **kwargs: Any) -> Execution
diff --git a/docs/python-sdk/fastmcp-prompts-prompt.mdx b/docs/python-sdk/fastmcp-prompts-prompt.mdx
index 1541e9c58..b0e33f1e3 100644
--- a/docs/python-sdk/fastmcp-prompts-prompt.mdx
+++ b/docs/python-sdk/fastmcp-prompts-prompt.mdx
@@ -10,7 +10,7 @@ Base classes for FastMCP prompts.
## Classes
-### `Message`
+### `Message`
Wrapper for prompt message with auto-serialization.
@@ -21,7 +21,7 @@ Accepts any content - strings pass through, other types
**Methods:**
-#### `to_mcp_prompt_message`
+#### `to_mcp_prompt_message`
```python
to_mcp_prompt_message(self) -> PromptMessage
@@ -30,13 +30,13 @@ to_mcp_prompt_message(self) -> PromptMessage
Convert to MCP PromptMessage.
-### `PromptArgument`
+### `PromptArgument`
An argument that can be passed to a prompt.
-### `PromptResult`
+### `PromptResult`
Canonical result type for prompt rendering.
@@ -47,7 +47,7 @@ roles, and metadata at both the message and result level.
**Methods:**
-#### `to_mcp_prompt_result`
+#### `to_mcp_prompt_result`
```python
to_mcp_prompt_result(self) -> GetPromptResult
@@ -56,7 +56,7 @@ to_mcp_prompt_result(self) -> GetPromptResult
Convert to MCP GetPromptResult.
-### `Prompt`
+### `Prompt`
A prompt template that can be rendered with parameters.
@@ -64,7 +64,7 @@ A prompt template that can be rendered with parameters.
**Methods:**
-#### `to_mcp_prompt`
+#### `to_mcp_prompt`
```python
to_mcp_prompt(self, **overrides: Any) -> SDKPrompt
@@ -73,7 +73,7 @@ to_mcp_prompt(self, **overrides: Any) -> SDKPrompt
Convert the prompt to an MCP prompt.
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any]) -> FunctionPrompt
@@ -87,7 +87,7 @@ The function can return:
- PromptResult: used directly
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any] | None = None) -> str | list[Message | str] | PromptResult
@@ -101,7 +101,7 @@ Subclasses must implement this method. Return one of:
- PromptResult: Used directly
-#### `convert_result`
+#### `convert_result`
```python
convert_result(self, raw_value: Any) -> PromptResult
@@ -113,7 +113,7 @@ Convert a raw return value to PromptResult.
- `TypeError`: for unsupported types
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -122,7 +122,7 @@ register_with_docket(self, docket: Docket) -> None
Register this prompt with docket for background execution.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, arguments: dict[str, Any] | None, **kwargs: Any) -> Execution
@@ -138,7 +138,7 @@ Schedule this prompt for background execution via docket.
- `**kwargs`: Additional kwargs passed to docket.add()
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
diff --git a/docs/python-sdk/fastmcp-resources-function_resource.mdx b/docs/python-sdk/fastmcp-resources-function_resource.mdx
index e7d710744..c5de76443 100644
--- a/docs/python-sdk/fastmcp-resources-function_resource.mdx
+++ b/docs/python-sdk/fastmcp-resources-function_resource.mdx
@@ -10,7 +10,7 @@ Standalone @resource decorator for FastMCP.
## Functions
-### `resource`
+### `resource`
```python
resource(uri: str) -> Callable[[F], F]
@@ -25,19 +25,19 @@ using mcp.add_resource().
## Classes
-### `DecoratedResource`
+### `DecoratedResource`
Protocol for functions decorated with @resource.
-### `ResourceMeta`
+### `ResourceMeta`
Metadata attached to functions by the @resource decorator.
-### `FunctionResource`
+### `FunctionResource`
A resource that defers data loading by wrapping a function.
@@ -54,7 +54,7 @@ The function can return:
**Methods:**
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl | None = None) -> FunctionResource
@@ -71,7 +71,7 @@ individual parameters must not be passed.
Cannot be used together with metadata parameter.
-#### `read`
+#### `read`
```python
read(self) -> str | bytes | ResourceResult
@@ -80,7 +80,7 @@ read(self) -> str | bytes | ResourceResult
Read the resource by calling the wrapped function.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
diff --git a/docs/python-sdk/fastmcp-resources-resource.mdx b/docs/python-sdk/fastmcp-resources-resource.mdx
index b064ac47b..2c5972094 100644
--- a/docs/python-sdk/fastmcp-resources-resource.mdx
+++ b/docs/python-sdk/fastmcp-resources-resource.mdx
@@ -10,7 +10,7 @@ Base classes and interfaces for FastMCP resources.
## Classes
-### `ResourceContent`
+### `ResourceContent`
Wrapper for resource content with optional MIME type and metadata.
@@ -21,7 +21,7 @@ other types (dict, list, BaseModel, etc.) are automatically JSON-serialized.
**Methods:**
-#### `to_mcp_resource_contents`
+#### `to_mcp_resource_contents`
```python
to_mcp_resource_contents(self, uri: AnyUrl | str) -> mcp.types.TextResourceContents | mcp.types.BlobResourceContents
@@ -36,7 +36,7 @@ Convert to MCP resource contents type.
- TextResourceContents for str content, BlobResourceContents for bytes
-### `ResourceResult`
+### `ResourceResult`
Canonical result type for resource reads.
@@ -47,7 +47,7 @@ per-item MIME types, and metadata at both the item and result level.
**Methods:**
-#### `to_mcp_result`
+#### `to_mcp_result`
```python
to_mcp_result(self, uri: AnyUrl | str) -> mcp.types.ReadResourceResult
@@ -62,7 +62,7 @@ Convert to MCP ReadResourceResult.
- MCP ReadResourceResult with converted contents
-### `Resource`
+### `Resource`
Base class for all resources.
@@ -70,13 +70,13 @@ Base class for all resources.
**Methods:**
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl) -> FunctionResource
```
-#### `set_default_mime_type`
+#### `set_default_mime_type`
```python
set_default_mime_type(cls, mime_type: str | None) -> str
@@ -85,7 +85,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
@@ -94,7 +94,7 @@ set_default_name(self) -> Self
Set default name from URI if not provided.
-#### `read`
+#### `read`
```python
read(self) -> str | bytes | ResourceResult
@@ -108,7 +108,7 @@ Subclasses implement this to return resource data. Supported return types:
- ResourceResult: Full control over contents and result-level meta
-#### `convert_result`
+#### `convert_result`
```python
convert_result(self, raw_value: Any) -> ResourceResult
@@ -121,10 +121,17 @@ This is used in two contexts:
2. In tasks_result_handler() to convert Docket task results to ResourceResult
Handles ResourceResult passthrough and converts raw values using
-ResourceResult's normalization.
+ResourceResult's normalization. When the raw value is a plain
+string or bytes, the resource's own ``mime_type`` is forwarded so
+that ``ui://`` resources (and others with non-default MIME types)
+don't fall back to ``text/plain``.
+
+The resource's component-level ``meta`` (e.g. ``ui`` metadata for
+MCP Apps CSP/permissions) is propagated to each content item so
+that hosts can read it from the ``resources/read`` response.
-#### `to_mcp_resource`
+#### `to_mcp_resource`
```python
to_mcp_resource(self, **overrides: Any) -> SDKResource
@@ -133,7 +140,7 @@ to_mcp_resource(self, **overrides: Any) -> SDKResource
Convert the resource to an SDKResource.
-#### `key`
+#### `key`
```python
key(self) -> str
@@ -142,7 +149,7 @@ key(self) -> str
The globally unique lookup key for this resource.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -151,7 +158,7 @@ register_with_docket(self, docket: Docket) -> None
Register this resource with docket for background execution.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, **kwargs: Any) -> Execution
@@ -166,7 +173,7 @@ Schedule this resource for background execution via docket.
- `**kwargs`: Additional kwargs passed to docket.add()
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
diff --git a/docs/python-sdk/fastmcp-resources-template.mdx b/docs/python-sdk/fastmcp-resources-template.mdx
index e1b932d88..e55bae102 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,13 +59,13 @@ A template for dynamically creating resources.
**Methods:**
-#### `from_function`
+#### `from_function`
```python
from_function(fn: Callable[..., Any], uri_template: str, name: str | None = None, version: str | int | 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, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None, auth: AuthCheckCallable | list[AuthCheckCallable] | None = None) -> FunctionResourceTemplate
```
-#### `set_default_mime_type`
+#### `set_default_mime_type`
```python
set_default_mime_type(cls, mime_type: str | None) -> str
@@ -74,7 +74,7 @@ set_default_mime_type(cls, mime_type: str | None) -> str
Set default MIME type if not provided.
-#### `matches`
+#### `matches`
```python
matches(self, uri: str) -> dict[str, Any] | None
@@ -83,7 +83,7 @@ matches(self, uri: str) -> dict[str, Any] | None
Check if URI matches template and extract parameters.
-#### `read`
+#### `read`
```python
read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult
@@ -92,7 +92,7 @@ read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult
Read the resource content.
-#### `convert_result`
+#### `convert_result`
```python
convert_result(self, raw_value: Any) -> ResourceResult
@@ -108,7 +108,7 @@ Handles ResourceResult passthrough and converts raw values using
ResourceResult's normalization.
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any]) -> Resource
@@ -120,7 +120,7 @@ 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) -> SDKResourceTemplate
@@ -129,7 +129,7 @@ to_mcp_template(self, **overrides: Any) -> SDKResourceTemplate
Convert the resource template to an SDKResourceTemplate.
-#### `from_mcp_template`
+#### `from_mcp_template`
```python
from_mcp_template(cls, mcp_template: SDKResourceTemplate) -> ResourceTemplate
@@ -138,7 +138,7 @@ from_mcp_template(cls, mcp_template: SDKResourceTemplate) -> ResourceTemplate
Creates a FastMCP ResourceTemplate from a raw MCP ResourceTemplate object.
-#### `key`
+#### `key`
```python
key(self) -> str
@@ -147,7 +147,7 @@ key(self) -> str
The globally unique lookup key for this template.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -156,7 +156,7 @@ register_with_docket(self, docket: Docket) -> None
Register this template with docket for background execution.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution
@@ -172,13 +172,13 @@ Schedule this template for background execution via docket.
- `**kwargs`: Additional kwargs passed to docket.add()
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FunctionResourceTemplate`
+### `FunctionResourceTemplate`
A template for dynamically creating resources.
@@ -186,7 +186,7 @@ A template for dynamically creating resources.
**Methods:**
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any]) -> Resource
@@ -195,7 +195,7 @@ create_resource(self, uri: str, params: dict[str, Any]) -> Resource
Create a resource from the template with the given parameters.
-#### `read`
+#### `read`
```python
read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult
@@ -204,7 +204,7 @@ read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult
Read the resource content.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -216,7 +216,7 @@ FunctionResourceTemplate registers the underlying function, which has the
user's Depends parameters for docket to resolve.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution
@@ -234,7 +234,7 @@ FunctionResourceTemplate splats the params dict since .fn expects **kwargs.
- `**kwargs`: Additional kwargs passed to docket.add()
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any], uri_template: str, name: str | None = None, version: str | int | 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, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None, auth: AuthCheckCallable | list[AuthCheckCallable] | None = None) -> FunctionResourceTemplate
diff --git a/docs/python-sdk/fastmcp-server-apps.mdx b/docs/python-sdk/fastmcp-server-apps.mdx
new file mode 100644
index 000000000..c72052339
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-apps.mdx
@@ -0,0 +1,87 @@
+---
+title: apps
+sidebarTitle: apps
+---
+
+# `fastmcp.server.apps`
+
+
+MCP Apps support — extension negotiation and typed UI metadata models.
+
+Provides constants and Pydantic models for the MCP Apps extension
+(io.modelcontextprotocol/ui), enabling tools and resources to carry
+UI metadata for clients that support interactive app rendering.
+
+
+## Functions
+
+### `ui_to_meta_dict`
+
+```python
+ui_to_meta_dict(ui: ToolUI | ResourceUI | dict[str, Any]) -> dict[str, Any]
+```
+
+
+Convert a UI model or dict to the wire-format dict for ``meta["ui"]``.
+
+
+### `resolve_ui_mime_type`
+
+```python
+resolve_ui_mime_type(uri: str, explicit_mime_type: str | None) -> str | None
+```
+
+
+Return the appropriate MIME type for a resource URI.
+
+For ``ui://`` scheme resources, defaults to ``UI_MIME_TYPE`` when no
+explicit MIME type is provided. This ensures UI resources are correctly
+identified regardless of how they're registered (via FastMCP.resource,
+the standalone @resource decorator, or resource templates).
+
+**Args:**
+- `uri`: The resource URI string
+- `explicit_mime_type`: The MIME type explicitly provided by the user
+
+**Returns:**
+- The resolved MIME type (explicit value, UI default, or None)
+
+
+## Classes
+
+### `ResourceCSP`
+
+
+Content Security Policy for MCP App resources.
+
+Declares which external origins the app is allowed to connect to or
+load resources from. Hosts use these declarations to build the
+``Content-Security-Policy`` header for the sandboxed iframe.
+
+
+### `ResourcePermissions`
+
+
+Iframe sandbox permissions for MCP App resources.
+
+Each field, when set (typically to ``{}``), requests that the host
+grant the corresponding Permission Policy feature to the sandboxed
+iframe. Hosts MAY honour these; apps should use JS feature detection
+as a fallback.
+
+
+### `ToolUI`
+
+
+Typed ``_meta.ui`` for tools — links a tool to its UI resource.
+
+All fields use ``exclude_none`` serialization so only explicitly-set
+values appear on the wire. Aliases match the MCP Apps wire format
+(camelCase).
+
+
+### `ResourceUI`
+
+
+Typed ``_meta.ui`` for resources — rendering hints for UI-capable clients.
+
diff --git a/docs/python-sdk/fastmcp-server-auth-auth.mdx b/docs/python-sdk/fastmcp-server-auth-auth.mdx
index 8f58e8be6..723b5a08f 100644
--- a/docs/python-sdk/fastmcp-server-auth-auth.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-auth.mdx
@@ -164,7 +164,21 @@ Token verifiers typically don't provide authentication routes by default.
**Methods:**
-#### `verify_token`
+#### `scopes_supported`
+
+```python
+scopes_supported(self) -> list[str]
+```
+
+Scopes to advertise in OAuth metadata.
+
+Defaults to required_scopes. Override in subclasses when the
+advertised scopes differ from the validation scopes (e.g., Azure AD
+where tokens contain short-form scopes but clients request full URI
+scopes).
+
+
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -173,7 +187,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.
@@ -190,7 +204,7 @@ the authorization servers that issue valid tokens.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -199,7 +213,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]
@@ -210,7 +224,7 @@ Get routes for this provider.
Creates protected resource metadata routes (RFC 9728).
-### `OAuthProvider`
+### `OAuthProvider`
OAuth Authorization Server provider.
@@ -221,7 +235,7 @@ authorization flows, token issuance, and token verification.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -239,7 +253,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]
@@ -255,7 +269,7 @@ This method creates the full set of OAuth routes including:
- List of OAuth routes
-#### `get_well_known_routes`
+#### `get_well_known_routes`
```python
get_well_known_routes(self, mcp_path: str | None = None) -> list[Route]
diff --git a/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx b/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx
index cbaa6eb04..9b168337e 100644
--- a/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx
@@ -42,7 +42,7 @@ a key derived from the upstream client secret.
#### `issue_access_token`
```python
-issue_access_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int = 3600) -> str
+issue_access_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int = 3600, upstream_claims: dict[str, Any] | None = None) -> str
```
Issue a minimal FastMCP access token.
@@ -56,15 +56,16 @@ which contains actual user identity and authorization data.
- `scopes`: Token scopes
- `jti`: Unique token identifier (maps to upstream token)
- `expires_in`: Token lifetime in seconds
+- `upstream_claims`: Optional claims from upstream IdP token to include
**Returns:**
- Signed JWT token
-#### `issue_refresh_token`
+#### `issue_refresh_token`
```python
-issue_refresh_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int) -> str
+issue_refresh_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int, upstream_claims: dict[str, Any] | None = None) -> str
```
Issue a minimal FastMCP refresh token.
@@ -78,12 +79,13 @@ token which contains actual user identity and authorization data.
- `scopes`: Token scopes
- `jti`: Unique token identifier (maps to upstream token)
- `expires_in`: Token lifetime in seconds (should match upstream refresh expiry)
+- `upstream_claims`: Optional claims from upstream IdP token to include
**Returns:**
- Signed JWT token
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> dict[str, Any]
diff --git a/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx
index 20f839f46..26f80c876 100644
--- a/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx
@@ -26,7 +26,7 @@ production use with enterprise identity providers.
## Classes
-### `OAuthProxy`
+### `OAuthProxy`
OAuth provider that presents a DCR-compliant interface while proxying to non-DCR IDPs.
@@ -140,7 +140,7 @@ Handles provider-specific requirements:
**Methods:**
-#### `set_mcp_path`
+#### `set_mcp_path`
```python
set_mcp_path(self, mcp_path: str | None) -> None
@@ -157,7 +157,7 @@ this specific MCP endpoint.
- `mcp_path`: The path where the MCP endpoint is mounted (e.g., "/mcp")
-#### `jwt_issuer`
+#### `jwt_issuer`
```python
jwt_issuer(self) -> JWTIssuer
@@ -169,7 +169,7 @@ The JWT issuer is created when set_mcp_path() is called (via get_routes()).
This property ensures a clear error if used before initialization.
-#### `get_client`
+#### `get_client`
```python
get_client(self, client_id: str) -> OAuthClientInformationFull | None
@@ -181,7 +181,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
@@ -195,7 +195,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
@@ -213,7 +213,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
@@ -225,7 +225,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
@@ -243,7 +243,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
@@ -255,7 +255,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
@@ -272,7 +272,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
@@ -291,7 +291,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
@@ -304,7 +304,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-auth-providers-azure.mdx b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx
index 411a17550..2e403a611 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx
@@ -49,7 +49,7 @@ Setup:
**Methods:**
-#### `authorize`
+#### `authorize`
```python
authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str
@@ -68,3 +68,55 @@ scopes to determine the resource/audience instead of a separate parameter.
**Returns:**
- Authorization URL to redirect the user to Azure AD
+
+### `AzureJWTVerifier`
+
+
+JWT verifier pre-configured for Azure AD / Microsoft Entra ID.
+
+Auto-configures JWKS URI, issuer, audience, and scope handling from your
+Azure app registration details. Designed for Managed Identity and other
+token-verification-only scenarios where AzureProvider's full OAuth proxy
+isn't needed.
+
+Handles Azure's scope format automatically:
+- Validates tokens using short-form scopes (what Azure puts in ``scp`` claims)
+- Advertises full-URI scopes in OAuth metadata (what clients need to request)
+
+Example::
+
+ from fastmcp.server.auth import RemoteAuthProvider
+ from fastmcp.server.auth.providers.azure import AzureJWTVerifier
+ from pydantic import AnyHttpUrl
+
+ verifier = AzureJWTVerifier(
+ client_id="your-client-id",
+ tenant_id="your-tenant-id",
+ required_scopes=["access_as_user"],
+ )
+
+ auth = RemoteAuthProvider(
+ token_verifier=verifier,
+ authorization_servers=[
+ AnyHttpUrl("https://login.microsoftonline.com/your-tenant-id/v2.0")
+ ],
+ base_url="https://my-server.com",
+ )
+
+
+**Methods:**
+
+#### `scopes_supported`
+
+```python
+scopes_supported(self) -> list[str]
+```
+
+Return scopes with Azure URI prefix for OAuth metadata.
+
+Azure tokens contain short-form scopes (e.g., ``read``) in the ``scp``
+claim, but clients must request full URI scopes (e.g.,
+``api://client-id/read``) from the Azure authorization endpoint. This
+property returns the full-URI form for OAuth metadata while
+``required_scopes`` retains the short form for token validation.
+
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx b/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx
index 9ea8f2701..9dd176f2e 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx
@@ -82,7 +82,7 @@ Use this when:
**Methods:**
-#### `load_access_token`
+#### `load_access_token`
```python
load_access_token(self, token: str) -> AccessToken | None
@@ -97,7 +97,7 @@ Validate a JWT bearer token and return an AccessToken when the token is valid.
- AccessToken | None: An AccessToken populated from token claims if the token is valid; `None` if the token is expired, has an invalid signature or format, fails issuer/audience/scope validation, or any other validation error occurs.
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -115,7 +115,7 @@ to our existing load_access_token method.
- AccessToken object if valid, None if invalid or expired
-### `StaticTokenVerifier`
+### `StaticTokenVerifier`
Simple static token verifier for testing and development.
@@ -136,7 +136,7 @@ WARNING: Never use this in production - tokens are stored in plain text!
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx
index 1edf918c8..060f0c4d5 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_transport`
+### `set_transport`
```python
set_transport(transport: TransportType) -> Token[TransportType | None]
@@ -17,7 +17,7 @@ set_transport(transport: TransportType) -> Token[TransportType | None]
Set the current transport type. Returns token for reset.
-### `reset_transport`
+### `reset_transport`
```python
reset_transport(token: Token[TransportType | None]) -> None
@@ -27,7 +27,7 @@ reset_transport(token: Token[TransportType | None]) -> None
Reset transport to previous value.
-### `set_context`
+### `set_context`
```python
set_context(context: Context) -> Generator[Context, None, None]
@@ -35,7 +35,7 @@ set_context(context: Context) -> Generator[Context, None, None]
## Classes
-### `LogData`
+### `LogData`
Data object for passing log arguments to client-side handlers.
@@ -44,7 +44,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.
@@ -96,7 +96,31 @@ The context is optional - tools that don't need it can omit the parameter.
**Methods:**
-#### `fastmcp`
+#### `is_background_task`
+
+```python
+is_background_task(self) -> bool
+```
+
+True when this context is running in a background task (Docket worker).
+
+When True, certain operations like elicit() and sample() will use
+task-aware implementations that can pause the task and wait for
+client input.
+
+
+#### `task_id`
+
+```python
+task_id(self) -> str | None
+```
+
+Get the background task ID if running in a background task.
+
+Returns None if not running in a background task context.
+
+
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -105,7 +129,7 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-#### `request_context`
+#### `request_context`
```python
request_context(self) -> RequestContext[ServerSession, Any, Request] | None
@@ -134,7 +158,7 @@ async def on_request(self, context, call_next):
```
-#### `lifespan_context`
+#### `lifespan_context`
```python
lifespan_context(self) -> dict[str, Any]
@@ -157,7 +181,7 @@ def my_tool(ctx: Context) -> str:
```
-#### `report_progress`
+#### `report_progress`
```python
report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None
@@ -170,7 +194,7 @@ Report progress for the current operation.
- `total`: Optional total value e.g. 100
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> list[SDKResource]
@@ -182,7 +206,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[SDKPrompt]
@@ -194,7 +218,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
@@ -210,7 +234,7 @@ Get a prompt by name with optional arguments.
- The prompt result
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str | AnyUrl) -> ResourceResult
@@ -225,7 +249,7 @@ Read a resource by URI.
- ResourceResult with contents
-#### `log`
+#### `log`
```python
log(self, message: str, level: LoggingLevel | None = None, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -243,7 +267,7 @@ Messages sent to Clients are also logged to the `fastmcp.server.context.to_clien
- `extra`: Optional mapping for additional arguments
-#### `transport`
+#### `transport`
```python
transport(self) -> TransportType | None
@@ -255,7 +279,32 @@ Returns the transport type used to run this server: "stdio", "sse",
or "streamable-http". Returns None if called outside of a server context.
-#### `client_id`
+#### `client_supports_extension`
+
+```python
+client_supports_extension(self, extension_id: str) -> bool
+```
+
+Check whether the connected client supports a given MCP extension.
+
+Inspects the ``extensions`` extra field on ``ClientCapabilities``
+sent by the client during initialization.
+
+Returns ``False`` when no session is available (e.g., outside a
+request context) or when the client did not advertise the extension.
+
+Example::
+
+ from fastmcp.server.apps import UI_EXTENSION_ID
+
+ @mcp.tool
+ async def my_tool(ctx: Context) -> str:
+ if ctx.client_supports_extension(UI_EXTENSION_ID):
+ return "UI-capable client"
+ return "text-only client"
+
+
+#### `client_id`
```python
client_id(self) -> str | None
@@ -264,7 +313,7 @@ client_id(self) -> str | None
Get the client ID if available.
-#### `request_id`
+#### `request_id`
```python
request_id(self) -> str
@@ -275,7 +324,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
@@ -292,7 +341,7 @@ the same client session.
- for other transports.
-#### `session`
+#### `session`
```python
session(self) -> ServerSession
@@ -300,10 +349,13 @@ session(self) -> ServerSession
Access to the underlying session for advanced usage.
-Raises RuntimeError if MCP request context is not available.
+In request mode: Returns the session from the active request context.
+In background task mode: Returns the session stored at Context creation.
+
+Raises RuntimeError if no session is available.
-#### `debug`
+#### `debug`
```python
debug(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -314,7 +366,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
@@ -325,7 +377,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
@@ -336,7 +388,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
@@ -347,7 +399,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]
@@ -356,7 +408,7 @@ list_roots(self) -> list[Root]
List the roots available to the server, as indicated by the client.
-#### `send_notification`
+#### `send_notification`
```python
send_notification(self, notification: mcp.types.ServerNotificationType) -> None
@@ -368,7 +420,7 @@ Send a notification to the client immediately.
- `notification`: An MCP notification instance (e.g., ToolListChangedNotification())
-#### `close_sse_stream`
+#### `close_sse_stream`
```python
close_sse_stream(self) -> None
@@ -386,7 +438,7 @@ Instead of holding a connection open for minutes, you can periodically close
and let the client reconnect.
-#### `sample_step`
+#### `sample_step`
```python
sample_step(self, messages: str | Sequence[str | SamplingMessage]) -> SampleStep
@@ -423,7 +475,7 @@ Tools can raise ToolError to bypass masking.
- - .text: The text content (if any)
-#### `sample`
+#### `sample`
```python
sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ResultT]
@@ -432,7 +484,7 @@ sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[
Overload: With result_type, returns SamplingResult[ResultT].
-#### `sample`
+#### `sample`
```python
sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[str]
@@ -441,7 +493,7 @@ sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[
Overload: Without result_type, returns SamplingResult[str].
-#### `sample`
+#### `sample`
```python
sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ResultT] | SamplingResult[str]
@@ -483,43 +535,43 @@ Tools can raise ToolError to bypass masking.
- - .history: All messages exchanged during sampling
-#### `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: dict[str, dict[str, str]]) -> AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: list[list[str]]) -> AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: list[dict[str, dict[str, str]]]) -> AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: type[T] | list[str] | dict[str, dict[str, str]] | list[list[str]] | list[dict[str, dict[str, str]]] | None = None) -> AcceptedElicitation[T] | AcceptedElicitation[dict[str, Any]] | AcceptedElicitation[str] | AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation
@@ -548,7 +600,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
@@ -561,7 +613,7 @@ The key is automatically prefixed with the session identifier.
State expires after 1 day to prevent unbounded memory growth.
-#### `get_state`
+#### `get_state`
```python
get_state(self, key: str) -> Any
@@ -572,7 +624,7 @@ Get a value from the session-scoped state store.
Returns None if the key is not found.
-#### `delete_state`
+#### `delete_state`
```python
delete_state(self, key: str) -> None
@@ -581,7 +633,7 @@ delete_state(self, key: str) -> None
Delete a value from the session-scoped state store.
-#### `enable_components`
+#### `enable_components`
```python
enable_components(self) -> None
@@ -605,7 +657,7 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `match_all`: If True, matches all components regardless of other criteria.
-#### `disable_components`
+#### `disable_components`
```python
disable_components(self) -> None
@@ -629,7 +681,7 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `match_all`: If True, matches all components regardless of other criteria.
-#### `reset_visibility`
+#### `reset_visibility`
```python
reset_visibility(self) -> None
diff --git a/docs/python-sdk/fastmcp-server-dependencies.mdx b/docs/python-sdk/fastmcp-server-dependencies.mdx
index 71d7a91f6..d718b2fc3 100644
--- a/docs/python-sdk/fastmcp-server-dependencies.mdx
+++ b/docs/python-sdk/fastmcp-server-dependencies.mdx
@@ -15,7 +15,57 @@ CurrentWorker) and background task execution require fastmcp[tasks].
## Functions
-### `is_docket_available`
+### `get_task_context`
+
+```python
+get_task_context() -> TaskContextInfo | None
+```
+
+
+Get the current task context if running inside a background task worker.
+
+This function extracts task information from the Docket execution context.
+Returns None if not running in a task context (e.g., foreground execution).
+
+**Returns:**
+- TaskContextInfo with task_id and session_id, or None if not in a task.
+
+
+### `register_task_session`
+
+```python
+register_task_session(session_id: str, session: ServerSession) -> None
+```
+
+
+Register a session for Context access in background tasks.
+
+Called automatically when a task is submitted to Docket. The session is
+stored as a weakref so it doesn't prevent garbage collection when the
+client disconnects.
+
+**Args:**
+- `session_id`: The session identifier
+- `session`: The ServerSession instance
+
+
+### `get_task_session`
+
+```python
+get_task_session(session_id: str) -> ServerSession | None
+```
+
+
+Get a registered session by ID if still alive.
+
+**Args:**
+- `session_id`: The session identifier
+
+**Returns:**
+- The ServerSession if found and alive, None otherwise
+
+
+### `is_docket_available`
```python
is_docket_available() -> bool
@@ -25,7 +75,7 @@ is_docket_available() -> bool
Check if pydocket is installed.
-### `require_docket`
+### `require_docket`
```python
require_docket(feature: str) -> None
@@ -39,7 +89,7 @@ Raise ImportError with install instructions if docket not available.
"CurrentDocket()"). Will be included in the error message.
-### `transform_context_annotations`
+### `transform_context_annotations`
```python
transform_context_annotations(fn: Callable[..., Any]) -> Callable[..., Any]
@@ -65,7 +115,7 @@ allows them to have defaults in any order.
- Function with modified signature (same function object, updated __signature__)
-### `get_context`
+### `get_context`
```python
get_context() -> Context
@@ -75,7 +125,7 @@ get_context() -> Context
Get the current FastMCP Context instance directly.
-### `get_server`
+### `get_server`
```python
get_server() -> FastMCP
@@ -91,7 +141,7 @@ Get the current FastMCP server instance directly.
- `RuntimeError`: If no server in context
-### `get_http_request`
+### `get_http_request`
```python
get_http_request() -> Request
@@ -103,7 +153,7 @@ Get the current HTTP request.
Tries MCP SDK's request_ctx first, then falls back to FastMCP's HTTP context.
-### `get_http_headers`
+### `get_http_headers`
```python
get_http_headers(include_all: bool = False) -> dict[str, str]
@@ -119,7 +169,7 @@ By default, strips problematic headers like `content-length` that cause issues
if forwarded to downstream clients. If `include_all` is True, all headers are returned.
-### `get_access_token`
+### `get_access_token`
```python
get_access_token() -> AccessToken | None
@@ -137,7 +187,7 @@ request is available.
- The access token if an authenticated user is available, None otherwise.
-### `without_injected_parameters`
+### `without_injected_parameters`
```python
without_injected_parameters(fn: Callable[..., Any]) -> Callable[..., Any]
@@ -162,7 +212,7 @@ Handles:
- Async wrapper function without injected parameters
-### `resolve_dependencies`
+### `resolve_dependencies`
```python
resolve_dependencies(fn: Callable[..., Any], arguments: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None]
@@ -188,7 +238,7 @@ time, so all injection goes through the unified DI system.
which will be filtered out)
-### `CurrentContext`
+### `CurrentContext`
```python
CurrentContext() -> Context
@@ -207,7 +257,7 @@ current MCP operation (tool/resource/prompt call).
- `RuntimeError`: If no active context found (during resolution)
-### `CurrentDocket`
+### `CurrentDocket`
```python
CurrentDocket() -> Docket
@@ -227,7 +277,7 @@ automatically creates for background task scheduling.
- `ImportError`: If fastmcp[tasks] not installed
-### `CurrentWorker`
+### `CurrentWorker`
```python
CurrentWorker() -> Worker
@@ -247,7 +297,7 @@ automatically creates for background task processing.
- `ImportError`: If fastmcp[tasks] not installed
-### `CurrentFastMCP`
+### `CurrentFastMCP`
```python
CurrentFastMCP() -> FastMCP
@@ -265,7 +315,7 @@ This dependency provides access to the active FastMCP server.
- `RuntimeError`: If no server in context (during resolution)
-### `CurrentRequest`
+### `CurrentRequest`
```python
CurrentRequest() -> Request
@@ -285,7 +335,7 @@ current HTTP request. Only available when running over HTTP transports
- `RuntimeError`: If no HTTP request in context (e.g., STDIO transport)
-### `CurrentHeaders`
+### `CurrentHeaders`
```python
CurrentHeaders() -> dict[str, str]
@@ -302,7 +352,7 @@ safe to use in code that might run over any transport.
- A dependency that resolves to a dictionary of header name -> value
-### `CurrentAccessToken`
+### `CurrentAccessToken`
```python
CurrentAccessToken() -> AccessToken
@@ -323,7 +373,16 @@ authenticated request. Raises an error if no authentication is present.
## Classes
-### `ProgressLike`
+### `TaskContextInfo`
+
+
+Information about the current background task context.
+
+Returned by ``get_task_context()`` when running inside a Docket worker.
+Contains identifiers needed to communicate with the MCP session.
+
+
+### `ProgressLike`
Protocol for progress tracking interface.
@@ -334,7 +393,7 @@ and Docket's Progress (worker context).
**Methods:**
-#### `current`
+#### `current`
```python
current(self) -> int | None
@@ -343,7 +402,7 @@ current(self) -> int | None
Current progress value.
-#### `total`
+#### `total`
```python
total(self) -> int
@@ -352,7 +411,7 @@ total(self) -> int
Total/target progress value.
-#### `message`
+#### `message`
```python
message(self) -> str | None
@@ -361,7 +420,7 @@ message(self) -> str | None
Current progress message.
-#### `set_total`
+#### `set_total`
```python
set_total(self, total: int) -> None
@@ -370,7 +429,7 @@ set_total(self, total: int) -> None
Set the total/target value for progress tracking.
-#### `increment`
+#### `increment`
```python
increment(self, amount: int = 1) -> None
@@ -379,7 +438,7 @@ increment(self, amount: int = 1) -> None
Atomically increment the current progress value.
-#### `set_message`
+#### `set_message`
```python
set_message(self, message: str | None) -> None
@@ -388,7 +447,7 @@ set_message(self, message: str | None) -> None
Update the progress status message.
-### `InMemoryProgress`
+### `InMemoryProgress`
In-memory progress tracker for immediate tool execution.
@@ -400,25 +459,25 @@ progress doesn't need to be observable across processes.
**Methods:**
-#### `current`
+#### `current`
```python
current(self) -> int | None
```
-#### `total`
+#### `total`
```python
total(self) -> int
```
-#### `message`
+#### `message`
```python
message(self) -> str | None
```
-#### `set_total`
+#### `set_total`
```python
set_total(self, total: int) -> None
@@ -427,7 +486,7 @@ set_total(self, total: int) -> None
Set the total/target value for progress tracking.
-#### `increment`
+#### `increment`
```python
increment(self, amount: int = 1) -> None
@@ -436,7 +495,7 @@ increment(self, amount: int = 1) -> None
Atomically increment the current progress value.
-#### `set_message`
+#### `set_message`
```python
set_message(self, message: str | None) -> None
@@ -445,7 +504,7 @@ set_message(self, message: str | None) -> None
Update the progress status message.
-### `Progress`
+### `Progress`
FastMCP Progress dependency that works in both server and worker contexts.
diff --git a/docs/python-sdk/fastmcp-server-low_level.mdx b/docs/python-sdk/fastmcp-server-low_level.mdx
index 4a2212305..07445bac0 100644
--- a/docs/python-sdk/fastmcp-server-low_level.mdx
+++ b/docs/python-sdk/fastmcp-server-low_level.mdx
@@ -7,7 +7,7 @@ sidebarTitle: low_level
## Classes
-### `MiddlewareServerSession`
+### `MiddlewareServerSession`
ServerSession that routes initialization requests through FastMCP middleware.
@@ -15,7 +15,7 @@ ServerSession that routes initialization requests through FastMCP middleware.
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -24,11 +24,23 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-### `LowLevelServer`
+#### `client_supports_extension`
+
+```python
+client_supports_extension(self, extension_id: str) -> bool
+```
+
+Check if the connected client supports a given MCP extension.
+
+Inspects the ``extensions`` extra field on ``ClientCapabilities``
+sent by the client during initialization.
+
+
+### `LowLevelServer`
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -37,13 +49,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
```
-#### `get_capabilities`
+#### `get_capabilities`
```python
get_capabilities(self, notification_options: NotificationOptions, experimental_capabilities: dict[str, dict[str, Any]]) -> mcp.types.ServerCapabilities
@@ -56,7 +68,7 @@ capabilities.experimental.tasks, which is required by the MCP spec and
enables proper task detection by clients like VS Code Copilot 1.107+.
-#### `run`
+#### `run`
```python
run(self, read_stream: MemoryObjectReceiveStream[SessionMessage | Exception], write_stream: MemoryObjectSendStream[SessionMessage], initialization_options: InitializationOptions, raise_exceptions: bool = False, stateless: bool = False)
@@ -65,7 +77,7 @@ run(self, read_stream: MemoryObjectReceiveStream[SessionMessage | Exception], wr
Overrides the run method to use the MiddlewareServerSession.
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self) -> Callable[[Callable[[AnyUrl], Awaitable[mcp.types.ReadResourceResult | mcp.types.CreateTaskResult]]], Callable[[AnyUrl], Awaitable[mcp.types.ReadResourceResult | mcp.types.CreateTaskResult]]]
@@ -80,7 +92,7 @@ This decorator can be removed once the MCP SDK adds native CreateTaskResult supp
for resources.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self) -> Callable[[Callable[[str, dict[str, Any] | None], Awaitable[mcp.types.GetPromptResult | mcp.types.CreateTaskResult]]], Callable[[str, dict[str, Any] | None], Awaitable[mcp.types.GetPromptResult | mcp.types.CreateTaskResult]]]
diff --git a/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx b/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx
index 5339b4a8c..be1218a20 100644
--- a/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx
+++ b/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx
@@ -21,7 +21,7 @@ proper MCP error responses. Also tracks error patterns for monitoring.
**Methods:**
-#### `on_message`
+#### `on_message`
```python
on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any
@@ -30,7 +30,7 @@ on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any
Handle errors for all messages.
-#### `get_error_stats`
+#### `get_error_stats`
```python
get_error_stats(self) -> dict[str, int]
@@ -39,7 +39,7 @@ get_error_stats(self) -> dict[str, int]
Get error statistics for monitoring.
-### `RetryMiddleware`
+### `RetryMiddleware`
Middleware that implements automatic retry logic for failed requests.
@@ -50,7 +50,7 @@ backoff to avoid overwhelming the server or external dependencies.
**Methods:**
-#### `on_request`
+#### `on_request`
```python
on_request(self, context: MiddlewareContext, call_next: CallNext) -> Any
diff --git a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
index 2059f6e17..f4fb6ed28 100644
--- a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
@@ -39,7 +39,7 @@ wrap(cls, server: Any, tool: Tool) -> FastMCPProviderTool
Wrap a Tool to delegate execution to the server's middleware.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -51,13 +51,13 @@ This is called when the tool is used within a TransformedTool
forwarding function or other contexts where task_meta is not available.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProviderResource`
+### `FastMCPProviderResource`
Resource that delegates reading to a wrapped server's read_resource().
@@ -68,7 +68,7 @@ When `read()` is called, this resource invokes the wrapped server's
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource
@@ -77,13 +77,13 @@ wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource
Wrap a Resource to delegate reading to the server's middleware.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProviderPrompt`
+### `FastMCPProviderPrompt`
Prompt that delegates rendering to a wrapped server's render_prompt().
@@ -94,7 +94,7 @@ When `render()` is called, this prompt invokes the wrapped server's
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt
@@ -103,7 +103,7 @@ wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt
Wrap a Prompt to delegate rendering to the server's middleware.
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any] | None = None) -> PromptResult
@@ -115,13 +115,13 @@ This is called when the prompt is used within a transformed context
or other contexts where task_meta is not available.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProviderResourceTemplate`
+### `FastMCPProviderResourceTemplate`
Resource template that creates FastMCPProviderResources.
@@ -133,7 +133,7 @@ when read.
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTemplate
@@ -142,7 +142,7 @@ wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTem
Wrap a ResourceTemplate to create FastMCPProviderResources.
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any]) -> Resource
@@ -155,7 +155,7 @@ We use `_original_uri_template` with `params` to construct the internal
URI that the nested server understands.
-#### `read`
+#### `read`
```python
read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult
@@ -167,7 +167,7 @@ Reads the resource via the wrapped server and returns the ResourceResult.
This method is called by Docket during background task execution.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -176,7 +176,7 @@ register_with_docket(self, docket: Docket) -> None
No-op: the child's actual template is registered via get_tasks().
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution
@@ -188,13 +188,13 @@ The child's FunctionResourceTemplate.fn is registered (via get_tasks),
and it expects splatted **kwargs, so we splat params here.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProvider`
+### `FastMCPProvider`
Provider that wraps a FastMCP server.
@@ -210,7 +210,7 @@ This ensures middleware runs when components are executed.
**Methods:**
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -224,7 +224,7 @@ server's transforms applied, then applies this provider's transforms
for correct registration keys.
-#### `lifespan`
+#### `lifespan`
```python
lifespan(self) -> AsyncIterator[None]
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index 21db24fad..fc85ea732 100644
--- a/docs/python-sdk/fastmcp-server-server.mdx
+++ b/docs/python-sdk/fastmcp-server-server.mdx
@@ -10,7 +10,7 @@ FastMCP - A more ergonomic interface for MCP servers.
## Functions
-### `default_lifespan`
+### `default_lifespan`
```python
default_lifespan(server: FastMCP[LifespanResultT]) -> AsyncIterator[Any]
@@ -26,7 +26,7 @@ Default lifespan context manager that does nothing.
- An empty dictionary as the lifespan result.
-### `create_proxy`
+### `create_proxy`
```python
create_proxy(target: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
@@ -54,65 +54,65 @@ use `FastMCPProxy` or `ProxyProvider` directly from `fastmcp.server.providers.pr
## Classes
-### `StateValue`
+### `StateValue`
Wrapper for stored context state values.
-### `FastMCP`
+### `FastMCP`
**Methods:**
-#### `settings`
+#### `settings`
```python
settings(self) -> Settings
```
-#### `name`
+#### `name`
```python
name(self) -> str
```
-#### `instructions`
+#### `instructions`
```python
instructions(self) -> str | None
```
-#### `instructions`
+#### `instructions`
```python
instructions(self, value: str | None) -> None
```
-#### `version`
+#### `version`
```python
version(self) -> str | None
```
-#### `website_url`
+#### `website_url`
```python
website_url(self) -> str | None
```
-#### `icons`
+#### `icons`
```python
icons(self) -> list[mcp.types.Icon]
```
-#### `add_middleware`
+#### `add_middleware`
```python
add_middleware(self, middleware: Middleware) -> None
```
-#### `add_provider`
+#### `add_provider`
```python
add_provider(self, provider: Provider) -> None
@@ -132,7 +132,7 @@ always take precedence over providers.
- Prompts become "namespace_promptname"
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -144,7 +144,7 @@ Overrides AggregateProvider.get_tasks() to apply server-level transforms
after aggregation. AggregateProvider handles provider-level namespacing.
-#### `add_transform`
+#### `add_transform`
```python
add_transform(self, transform: Transform) -> None
@@ -159,7 +159,7 @@ They transform tools, resources, and prompts from ALL providers.
- `transform`: The transform to add.
-#### `add_tool_transformation`
+#### `add_tool_transformation`
```python
add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None
@@ -171,7 +171,7 @@ Add a tool transformation.
Use ``add_transform(ToolTransform({...}))`` instead.
-#### `remove_tool_transformation`
+#### `remove_tool_transformation`
```python
remove_tool_transformation(self, _tool_name: str) -> None
@@ -183,7 +183,7 @@ Remove a tool transformation.
Tool transformations are now immutable. Use enable/disable controls instead.
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> Sequence[Tool]
@@ -196,7 +196,7 @@ and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None
@@ -216,7 +216,7 @@ session transforms can override provider-level disables.
- The tool if found and enabled, None otherwise.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> Sequence[Resource]
@@ -229,7 +229,7 @@ and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None
@@ -248,7 +248,7 @@ transforms (including session-level) have been applied.
- The resource if found and enabled, None otherwise.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> Sequence[ResourceTemplate]
@@ -261,7 +261,7 @@ auth filtering, and middleware execution. Returns all versions (no deduplication
Protocol handlers deduplicate for MCP wire format.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None
@@ -280,7 +280,7 @@ all transforms (including session-level) have been applied.
- The template if found and enabled, None otherwise.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> Sequence[Prompt]
@@ -293,7 +293,7 @@ and middleware execution. Returns all versions (no deduplication).
Protocol handlers deduplicate for MCP wire format.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None
@@ -312,19 +312,19 @@ transforms (including session-level) have been applied.
- The prompt if found and enabled, None otherwise.
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult
```
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult
```
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult | mcp.types.CreateTaskResult
@@ -354,19 +354,19 @@ return ToolResult.
- `ValidationError`: If arguments fail validation
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str) -> ResourceResult
```
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str) -> mcp.types.CreateTaskResult
```
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str) -> ResourceResult | mcp.types.CreateTaskResult
@@ -395,19 +395,19 @@ return ResourceResult.
- `ResourceError`: If resource read fails
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult
```
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult
```
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult | mcp.types.CreateTaskResult
@@ -437,7 +437,7 @@ return PromptResult.
- `PromptError`: If prompt rendering fails
-#### `add_tool`
+#### `add_tool`
```python
add_tool(self, tool: Tool | Callable[..., Any]) -> Tool
@@ -455,7 +455,7 @@ with the Context type annotation. See the @tool decorator for examples.
- The tool instance that was added to the server.
-#### `remove_tool`
+#### `remove_tool`
```python
remove_tool(self, name: str, version: str | None = None) -> None
@@ -471,19 +471,19 @@ Remove tool(s) from the server.
- `NotFoundError`: If no matching tool is found.
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: AnyFunction) -> FunctionTool
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool]
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool]
@@ -539,7 +539,7 @@ server.tool(my_function, name="custom_name")
```
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource | Callable[..., Any]) -> Resource | ResourceTemplate
@@ -554,7 +554,7 @@ Add a resource to the server.
- The resource instance that was added to the server.
-#### `add_template`
+#### `add_template`
```python
add_template(self, template: ResourceTemplate) -> ResourceTemplate
@@ -569,7 +569,7 @@ Add a resource template to the server.
- The template instance that was added to the server.
-#### `resource`
+#### `resource`
```python
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate | AnyFunction]
@@ -628,7 +628,7 @@ async def get_weather(city: str) -> str:
```
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt
@@ -643,19 +643,19 @@ Add a prompt to the server.
- The prompt instance that was added to the server.
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt]
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt]
@@ -732,7 +732,7 @@ Decorator to register a prompt.
```
-#### `mount`
+#### `mount`
```python
mount(self, server: FastMCP[LifespanResultT], namespace: str | None = None, as_proxy: bool | None = None, tool_names: dict[str, str] | None = None, prefix: str | None = None) -> None
@@ -779,7 +779,7 @@ mounted server.
- `prefix`: Deprecated. Use namespace instead.
-#### `import_server`
+#### `import_server`
```python
import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None
@@ -820,7 +820,7 @@ templates, and prompts are imported with their original names.
objects are imported with their original names.
-#### `from_openapi`
+#### `from_openapi`
```python
from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, name: str = 'OpenAPI Server', route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self
@@ -844,7 +844,7 @@ Create a FastMCP server from an OpenAPI specification.
- A FastMCP server with an OpenAPIProvider attached.
-#### `from_fastapi`
+#### `from_fastapi`
```python
from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self
@@ -868,7 +868,7 @@ Create a FastMCP server from a FastAPI application.
- A FastMCP server with an OpenAPIProvider attached.
-#### `as_proxy`
+#### `as_proxy`
```python
as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
@@ -886,7 +886,7 @@ instance or any value accepted as the `transport` argument of
`fastmcp.client.Client` constructor.
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
diff --git a/docs/python-sdk/fastmcp-server-tasks-config.mdx b/docs/python-sdk/fastmcp-server-tasks-config.mdx
index 2dbbc63dd..cc78f7156 100644
--- a/docs/python-sdk/fastmcp-server-tasks-config.mdx
+++ b/docs/python-sdk/fastmcp-server-tasks-config.mdx
@@ -14,7 +14,7 @@ handle task-augmented execution as specified in SEP-1686.
## Classes
-### `TaskMeta`
+### `TaskMeta`
Metadata for task-augmented execution requests.
@@ -27,7 +27,7 @@ the operation should be submitted as a background task.
- `fn_key`: Docket routing key. Auto-derived from component name if None.
-### `TaskConfig`
+### `TaskConfig`
Configuration for MCP background task execution (SEP-1686).
@@ -44,7 +44,7 @@ Controls how a component handles task-augmented requests:
**Methods:**
-#### `from_bool`
+#### `from_bool`
```python
from_bool(cls, value: bool) -> TaskConfig
@@ -59,7 +59,7 @@ Convert boolean task flag to TaskConfig.
- TaskConfig with appropriate mode.
-#### `supports_tasks`
+#### `supports_tasks`
```python
supports_tasks(self) -> bool
@@ -71,7 +71,7 @@ Check if this component supports task execution.
- True if mode is "optional" or "required", False if "forbidden".
-#### `validate_function`
+#### `validate_function`
```python
validate_function(self, fn: Callable[..., Any], name: str) -> None
diff --git a/docs/python-sdk/fastmcp-server-tasks-elicitation.mdx b/docs/python-sdk/fastmcp-server-tasks-elicitation.mdx
new file mode 100644
index 000000000..1b06baa8e
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-tasks-elicitation.mdx
@@ -0,0 +1,74 @@
+---
+title: elicitation
+sidebarTitle: elicitation
+---
+
+# `fastmcp.server.tasks.elicitation`
+
+
+Background task elicitation support (SEP-1686).
+
+This module provides elicitation capabilities for background tasks running
+in Docket workers. Unlike regular MCP requests, background tasks don't have
+an active request context, so elicitation requires special handling:
+
+1. Set task status to "input_required" via Redis
+2. Send notifications/tasks/updated with elicitation metadata
+3. Wait for client to send input via tasks/sendInput
+4. Resume task execution with the provided input
+
+This uses the public MCP SDK APIs where possible, with minimal use of
+internal APIs for background task coordination.
+
+
+## Functions
+
+### `elicit_for_task`
+
+```python
+elicit_for_task(task_id: str, session: ServerSession, message: str, schema: dict[str, Any], fastmcp: FastMCP) -> mcp.types.ElicitResult
+```
+
+
+Send an elicitation request from a background task.
+
+This function handles the complexity of eliciting user input when running
+in a Docket worker context where there's no active MCP request.
+
+**Args:**
+- `task_id`: The background task ID
+- `session`: The MCP ServerSession for this task
+- `message`: The message to display to the user
+- `schema`: The JSON schema for the expected response
+- `fastmcp`: The FastMCP server instance
+
+**Returns:**
+- ElicitResult containing the user's response
+
+**Raises:**
+- `RuntimeError`: If Docket is not available
+- `McpError`: If the elicitation request fails
+
+
+### `handle_task_input`
+
+```python
+handle_task_input(task_id: str, session_id: str, action: str, content: dict[str, Any] | None, fastmcp: FastMCP) -> bool
+```
+
+
+Handle input sent to a background task via tasks/sendInput.
+
+This is called when a client sends input in response to an elicitation
+request from a background task.
+
+**Args:**
+- `task_id`: The background task ID
+- `session_id`: The MCP session ID
+- `action`: The elicitation action ("accept", "decline", "cancel")
+- `content`: The response content (for "accept" action)
+- `fastmcp`: The FastMCP server instance
+
+**Returns:**
+- True if the input was successfully stored, False otherwise
+
diff --git a/docs/python-sdk/fastmcp-tools-function_tool.mdx b/docs/python-sdk/fastmcp-tools-function_tool.mdx
index 0e4b35333..bd66818a0 100644
--- a/docs/python-sdk/fastmcp-tools-function_tool.mdx
+++ b/docs/python-sdk/fastmcp-tools-function_tool.mdx
@@ -10,7 +10,7 @@ Standalone @tool decorator for FastMCP.
## Functions
-### `tool`
+### `tool`
```python
tool(name_or_fn: str | Callable[..., Any] | None = None) -> Any
@@ -25,23 +25,23 @@ using mcp.add_tool().
## Classes
-### `DecoratedTool`
+### `DecoratedTool`
Protocol for functions decorated with @tool.
-### `ToolMeta`
+### `ToolMeta`
Metadata attached to functions by the @tool decorator.
-### `FunctionTool`
+### `FunctionTool`
**Methods:**
-#### `to_mcp_tool`
+#### `to_mcp_tool`
```python
to_mcp_tool(self, **overrides: Any) -> mcp.types.Tool
@@ -52,7 +52,7 @@ Convert the FastMCP tool to an MCP tool.
Extends the base implementation to add task execution mode if enabled.
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any]) -> FunctionTool
@@ -68,7 +68,7 @@ individual parameters must not be passed.
Cannot be used together with metadata parameter.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -77,7 +77,7 @@ run(self, arguments: dict[str, Any]) -> ToolResult
Run the tool with arguments.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -89,7 +89,7 @@ FunctionTool registers the underlying function, which has the user's
Depends parameters for docket to resolve.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, arguments: dict[str, Any], **kwargs: Any) -> Execution
diff --git a/docs/python-sdk/fastmcp-tools-tool.mdx b/docs/python-sdk/fastmcp-tools-tool.mdx
index 9acb15695..1068a7716 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,7 +33,7 @@ Internal tool registration info.
**Methods:**
-#### `to_mcp_tool`
+#### `to_mcp_tool`
```python
to_mcp_tool(self, **overrides: Any) -> MCPTool
@@ -42,7 +42,7 @@ to_mcp_tool(self, **overrides: Any) -> MCPTool
Convert the FastMCP tool to an MCP tool.
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any]) -> FunctionTool
@@ -51,7 +51,7 @@ from_function(cls, fn: Callable[..., Any]) -> FunctionTool
Create a Tool from a function.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -66,7 +66,7 @@ implemented by subclasses.
(list of ContentBlocks, dict of structured output).
-#### `convert_result`
+#### `convert_result`
```python
convert_result(self, raw_value: Any) -> ToolResult
@@ -78,7 +78,7 @@ Handles ToolResult passthrough and converts raw values using the tool's
attributes (serializer, output_schema) for proper conversion.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -87,7 +87,7 @@ register_with_docket(self, docket: Docket) -> None
Register this tool with docket for background execution.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, arguments: dict[str, Any], **kwargs: Any) -> Execution
@@ -103,13 +103,13 @@ Schedule this tool for background execution via docket.
- `**kwargs`: Additional kwargs passed to docket.add()
-#### `from_tool`
+#### `from_tool`
```python
from_tool(cls, tool: Tool) -> TransformedTool
```
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
diff --git a/docs/python-sdk/fastmcp-tools-tool_transform.mdx b/docs/python-sdk/fastmcp-tools-tool_transform.mdx
index 8506d990e..dba6cf8a6 100644
--- a/docs/python-sdk/fastmcp-tools-tool_transform.mdx
+++ b/docs/python-sdk/fastmcp-tools-tool_transform.mdx
@@ -7,7 +7,7 @@ sidebarTitle: tool_transform
## Functions
-### `forward`
+### `forward`
```python
forward(**kwargs: Any) -> ToolResult
@@ -36,7 +36,7 @@ tool has args `a` and `b`, and an `transform_args` was provided that maps `x` to
- `TypeError`: If provided arguments don't match the transformed schema.
-### `forward_raw`
+### `forward_raw`
```python
forward_raw(**kwargs: Any) -> ToolResult
@@ -62,7 +62,7 @@ y=2)` will call the parent tool with `x=1` and `y=2`.
- `RuntimeError`: If called outside a transformed tool context.
-### `apply_transformations_to_tools`
+### `apply_transformations_to_tools`
```python
apply_transformations_to_tools(tools: dict[str, Tool], transformations: dict[str, ToolTransformConfig]) -> dict[str, Tool]
@@ -78,7 +78,7 @@ but transformations are keyed by tool name (e.g., "my_tool").
## Classes
-### `ArgTransform`
+### `ArgTransform`
Configuration for transforming a parent tool's argument.
@@ -150,7 +150,7 @@ ArgTransform(name="new_name", description="New desc", default=None, type=int)
```
-### `ArgTransformConfig`
+### `ArgTransformConfig`
A model for requesting a single argument transform.
@@ -158,7 +158,7 @@ A model for requesting a single argument transform.
**Methods:**
-#### `to_arg_transform`
+#### `to_arg_transform`
```python
to_arg_transform(self) -> ArgTransform
@@ -167,7 +167,7 @@ to_arg_transform(self) -> ArgTransform
Convert the argument transform to a FastMCP argument transform.
-### `TransformedTool`
+### `TransformedTool`
A tool that is transformed from another tool.
@@ -191,7 +191,7 @@ validation when forward() is called from custom functions.
**Methods:**
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -210,7 +210,7 @@ functions.
- ToolResult object containing content and optional structured output.
-#### `from_tool`
+#### `from_tool`
```python
from_tool(cls, tool: Tool, name: str | None = None, version: str | NotSetT | None = NotSet, title: str | NotSetT | None = NotSet, description: str | NotSetT | None = NotSet, tags: set[str] | None = None, transform_fn: Callable[..., Any] | None = None, transform_args: dict[str, ArgTransform] | None = None, annotations: ToolAnnotations | NotSetT | None = NotSet, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: Callable[[Any], str] | NotSetT | None = NotSet, meta: dict[str, Any] | NotSetT | None = NotSet) -> TransformedTool
@@ -293,7 +293,7 @@ async def custom_output(**kwargs) -> ToolResult:
```
-### `ToolTransformConfig`
+### `ToolTransformConfig`
Provides a way to transform a tool.
@@ -301,7 +301,7 @@ Provides a way to transform a tool.
**Methods:**
-#### `apply`
+#### `apply`
```python
apply(self, tool: Tool) -> TransformedTool
diff --git a/docs/python-sdk/fastmcp-utilities-auth.mdx b/docs/python-sdk/fastmcp-utilities-auth.mdx
index f30966e96..3e8271e9e 100644
--- a/docs/python-sdk/fastmcp-utilities-auth.mdx
+++ b/docs/python-sdk/fastmcp-utilities-auth.mdx
@@ -10,7 +10,49 @@ Authentication utility helpers.
## Functions
-### `parse_scopes`
+### `decode_jwt_header`
+
+```python
+decode_jwt_header(token: str) -> dict[str, Any]
+```
+
+
+Decode JWT header without signature verification.
+
+Useful for extracting the key ID (kid) for JWKS lookup.
+
+**Args:**
+- `token`: JWT token string (header.payload.signature)
+
+**Returns:**
+- Decoded header as a dictionary
+
+**Raises:**
+- `ValueError`: If token is not a valid JWT format
+
+
+### `decode_jwt_payload`
+
+```python
+decode_jwt_payload(token: str) -> dict[str, Any]
+```
+
+
+Decode JWT payload without signature verification.
+
+Use only for tokens received directly from trusted sources (e.g., IdP token endpoints).
+
+**Args:**
+- `token`: JWT token string (header.payload.signature)
+
+**Returns:**
+- Decoded payload as a dictionary
+
+**Raises:**
+- `ValueError`: If token is not a valid JWT format
+
+
+### `parse_scopes`
```python
parse_scopes(value: Any) -> list[str] | None
diff --git a/docs/python-sdk/fastmcp-utilities-lifespan.mdx b/docs/python-sdk/fastmcp-utilities-lifespan.mdx
index 319dbc29c..cf347d794 100644
--- a/docs/python-sdk/fastmcp-utilities-lifespan.mdx
+++ b/docs/python-sdk/fastmcp-utilities-lifespan.mdx
@@ -13,7 +13,7 @@ Lifespan utilities for combining async context manager lifespans.
### `combine_lifespans`
```python
-combine_lifespans(*lifespans: Callable[[AppT], AbstractAsyncContextManager[dict[str, Any] | None]]) -> Callable[[AppT], AbstractAsyncContextManager[dict[str, Any]]]
+combine_lifespans(*lifespans: Callable[[AppT], AbstractAsyncContextManager[Mapping[str, Any] | None]]) -> Callable[[AppT], AbstractAsyncContextManager[dict[str, Any]]]
```
diff --git a/docs/python-sdk/fastmcp-utilities-skills.mdx b/docs/python-sdk/fastmcp-utilities-skills.mdx
index 32aed81ca..ba1c9430f 100644
--- a/docs/python-sdk/fastmcp-utilities-skills.mdx
+++ b/docs/python-sdk/fastmcp-utilities-skills.mdx
@@ -10,7 +10,7 @@ Client utilities for discovering and downloading skills from MCP servers.
## Functions
-### `list_skills`
+### `list_skills`
```python
list_skills(client: Client) -> list[SkillSummary]
@@ -29,7 +29,7 @@ Discovers skills by finding resources with URIs matching the
- List of SkillSummary objects with name, description, and URI
-### `get_skill_manifest`
+### `get_skill_manifest`
```python
get_skill_manifest(client: Client, skill_name: str) -> SkillManifest
@@ -49,7 +49,7 @@ Get the manifest for a specific skill.
- `ValueError`: If manifest cannot be read or parsed
-### `download_skill`
+### `download_skill`
```python
download_skill(client: Client, skill_name: str, target_dir: str | Path) -> Path
@@ -95,19 +95,19 @@ Download all available skills from a server.
## Classes
-### `SkillSummary`
+### `SkillSummary`
Summary information about a skill available on a server.
-### `SkillFile`
+### `SkillFile`
Information about a file within a skill.
-### `SkillManifest`
+### `SkillManifest`
Full manifest of a skill including all files.