From 902b63f67652f0ce2cc102d68384024bc7707de2 Mon Sep 17 00:00:00 2001
From: "marvin-context-protocol[bot]"
<225465937+marvin-context-protocol[bot]@users.noreply.github.com>
Date: Mon, 2 Mar 2026 17:27:38 -0500
Subject: [PATCH] chore: Update SDK documentation (#3313)
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
---
docs/docs.json | 55 ++++-
docs/python-sdk/fastmcp-cli-cli.mdx | 7 +-
docs/python-sdk/fastmcp-cli-run.mdx | 33 ++-
docs/python-sdk/fastmcp-client-client.mdx | 34 +--
.../fastmcp-client-transports-config.mdx | 2 +-
docs/python-sdk/fastmcp-dependencies.mdx | 7 +-
.../fastmcp-experimental-__init__.mdx | 8 +
...fastmcp-experimental-sampling-__init__.mdx | 8 +
...fastmcp-experimental-sampling-handlers.mdx | 8 +
...stmcp-experimental-transforms-__init__.mdx | 8 +
...tmcp-experimental-transforms-code_mode.mdx | 121 ++++++++++
docs/python-sdk/fastmcp-resources-types.mdx | 24 +-
docs/python-sdk/fastmcp-server-auth-auth.mdx | 67 +++++-
.../fastmcp-server-auth-providers-azure.mdx | 14 +-
...stmcp-server-auth-providers-propelauth.mdx | 69 ++++++
docs/python-sdk/fastmcp-server-context.mdx | 94 ++++----
.../fastmcp-server-dependencies.mdx | 134 +++++++----
...astmcp-server-middleware-authorization.mdx | 12 +-
.../fastmcp-server-mixins-lifespan.mdx | 4 +-
...viders-local_provider-decorators-tools.mdx | 10 +-
.../fastmcp-server-providers-proxy.mdx | 56 ++---
docs/python-sdk/fastmcp-server-server.mdx | 98 ++++----
.../fastmcp-server-transforms-catalog.mdx | 220 ++++++++++++++++++
...tmcp-server-transforms-search-__init__.mdx | 23 ++
.../fastmcp-server-transforms-search-base.mdx | 105 +++++++++
.../fastmcp-server-transforms-search-bm25.mdx | 20 ++
...fastmcp-server-transforms-search-regex.mdx | 20 ++
.../fastmcp-tools-function_parsing.mdx | 4 +-
.../fastmcp-tools-function_tool.mdx | 18 +-
docs/python-sdk/fastmcp-tools-tool.mdx | 24 +-
.../fastmcp-utilities-openapi-schemas.mdx | 2 +-
31 files changed, 1042 insertions(+), 267 deletions(-)
create mode 100644 docs/python-sdk/fastmcp-experimental-__init__.mdx
create mode 100644 docs/python-sdk/fastmcp-experimental-sampling-__init__.mdx
create mode 100644 docs/python-sdk/fastmcp-experimental-sampling-handlers.mdx
create mode 100644 docs/python-sdk/fastmcp-experimental-transforms-__init__.mdx
create mode 100644 docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx
create mode 100644 docs/python-sdk/fastmcp-server-auth-providers-propelauth.mdx
create mode 100644 docs/python-sdk/fastmcp-server-transforms-catalog.mdx
create mode 100644 docs/python-sdk/fastmcp-server-transforms-search-__init__.mdx
create mode 100644 docs/python-sdk/fastmcp-server-transforms-search-base.mdx
create mode 100644 docs/python-sdk/fastmcp-server-transforms-search-bm25.mdx
create mode 100644 docs/python-sdk/fastmcp-server-transforms-search-regex.mdx
diff --git a/docs/docs.json b/docs/docs.json
index 08e99918c..1a72acf86 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -93,12 +93,12 @@
"collapsed": true,
"group": "Upgrade",
"icon": "up",
- "tag": "NEW",
"pages": [
"getting-started/upgrading/from-fastmcp-2",
"getting-started/upgrading/from-mcp-sdk",
"getting-started/upgrading/from-low-level-sdk"
- ]
+ ],
+ "tag": "NEW"
}
]
},
@@ -120,7 +120,6 @@
{
"collapsed": true,
"group": "Features",
- "tag": "NEW",
"icon": "stars",
"pages": [
"servers/tasks",
@@ -136,12 +135,12 @@
"servers/storage-backends",
"servers/telemetry",
"servers/versioning"
- ]
+ ],
+ "tag": "NEW"
},
{
"collapsed": true,
"group": "Providers",
- "tag": "NEW",
"icon": "layer-group",
"pages": [
"servers/providers/overview",
@@ -151,12 +150,12 @@
"servers/providers/skills",
"servers/providers/custom",
"servers/providers/mounting"
- ]
+ ],
+ "tag": "NEW"
},
{
"collapsed": true,
"group": "Transforms",
- "tag": "NEW",
"icon": "wand-magic-sparkles",
"pages": [
"servers/transforms/transforms",
@@ -167,7 +166,8 @@
"servers/transforms/tool-search",
"servers/transforms/resources-as-tools",
"servers/transforms/prompts-as-tools"
- ]
+ ],
+ "tag": "NEW"
},
{
"collapsed": true,
@@ -216,12 +216,12 @@
{
"collapsed": true,
"group": "CLI",
- "tag": "NEW",
"icon": "terminal",
"pages": [
"clients/cli",
"clients/generate-cli"
- ]
+ ],
+ "tag": "NEW"
},
{
"collapsed": true,
@@ -250,13 +250,13 @@
{
"collapsed": true,
"group": "Authentication",
- "tag": "NEW",
"icon": "key",
"pages": [
"clients/auth/oauth",
"clients/auth/cimd",
"clients/auth/bearer"
- ]
+ ],
+ "tag": "NEW"
}
]
},
@@ -434,6 +434,26 @@
}
]
},
+ {
+ "group": "fastmcp.experimental",
+ "pages": [
+ "python-sdk/fastmcp-experimental-__init__",
+ {
+ "group": "sampling",
+ "pages": [
+ "python-sdk/fastmcp-experimental-sampling-__init__",
+ "python-sdk/fastmcp-experimental-sampling-handlers"
+ ]
+ },
+ {
+ "group": "transforms",
+ "pages": [
+ "python-sdk/fastmcp-experimental-transforms-__init__",
+ "python-sdk/fastmcp-experimental-transforms-code_mode"
+ ]
+ }
+ ]
+ },
{
"group": "fastmcp.prompts",
"pages": [
@@ -493,6 +513,7 @@
"python-sdk/fastmcp-server-auth-providers-introspection",
"python-sdk/fastmcp-server-auth-providers-jwt",
"python-sdk/fastmcp-server-auth-providers-oci",
+ "python-sdk/fastmcp-server-auth-providers-propelauth",
"python-sdk/fastmcp-server-auth-providers-scalekit",
"python-sdk/fastmcp-server-auth-providers-supabase",
"python-sdk/fastmcp-server-auth-providers-workos"
@@ -622,9 +643,19 @@
"group": "transforms",
"pages": [
"python-sdk/fastmcp-server-transforms-__init__",
+ "python-sdk/fastmcp-server-transforms-catalog",
"python-sdk/fastmcp-server-transforms-namespace",
"python-sdk/fastmcp-server-transforms-prompts_as_tools",
"python-sdk/fastmcp-server-transforms-resources_as_tools",
+ {
+ "group": "search",
+ "pages": [
+ "python-sdk/fastmcp-server-transforms-search-__init__",
+ "python-sdk/fastmcp-server-transforms-search-base",
+ "python-sdk/fastmcp-server-transforms-search-bm25",
+ "python-sdk/fastmcp-server-transforms-search-regex"
+ ]
+ },
"python-sdk/fastmcp-server-transforms-tool_transform",
"python-sdk/fastmcp-server-transforms-version_filter",
"python-sdk/fastmcp-server-transforms-visibility"
diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx
index 4b7054fcf..60804a298 100644
--- a/docs/python-sdk/fastmcp-cli-cli.mdx
+++ b/docs/python-sdk/fastmcp-cli-cli.mdx
@@ -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
@@ -66,6 +66,7 @@ The server can be specified in several ways:
4. MCPConfig file: "mcp.json" - runs as a proxy server for the MCP Servers in the MCPConfig file
5. FastMCP config: "fastmcp.json" - runs server using FastMCP configuration
6. No argument: looks for fastmcp.json in current directory
+7. Module mode: "-m my_module" - runs the module directly via python -m
Server arguments can be passed after -- :
fastmcp run server.py -- --config config.json --debug
@@ -74,7 +75,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 +106,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-run.mdx b/docs/python-sdk/fastmcp-cli-run.mdx
index 52df74f4c..0b341c459 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,26 @@ Run a MCP server or connect to a remote one.
- `stateless`: Whether to run in stateless mode (no session)
-### `run_v1_server_async`
+### `run_module_command`
+
+```python
+run_module_command(module_name: str) -> None
+```
+
+
+Run a Python module directly using ``python -m ``.
+
+When ``-m`` is used, the module manages its own server startup.
+No server-object discovery or transport overrides are applied.
+
+**Args:**
+- `module_name`: Dotted module name (e.g. ``my_package``).
+- `env_command_builder`: An optional callable that wraps a command list
+with environment setup (e.g. ``UVEnvironment.build_command``).
+- `extra_args`: Extra arguments forwarded after the module name.
+
+
+### `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 +120,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-client.mdx b/docs/python-sdk/fastmcp-client-client.mdx
index 7b72fa3f7..6c3ac689a 100644
--- a/docs/python-sdk/fastmcp-client-client.mdx
+++ b/docs/python-sdk/fastmcp-client-client.mdx
@@ -85,7 +85,7 @@ async with client:
**Methods:**
-#### `session`
+#### `session`
```python
session(self) -> ClientSession
@@ -94,7 +94,7 @@ session(self) -> ClientSession
Get the current active session. Raises RuntimeError if not connected.
-#### `initialize_result`
+#### `initialize_result`
```python
initialize_result(self) -> mcp.types.InitializeResult | None
@@ -103,7 +103,7 @@ initialize_result(self) -> mcp.types.InitializeResult | None
Get the result of the initialization request.
-#### `set_roots`
+#### `set_roots`
```python
set_roots(self, roots: RootsList | RootsHandler) -> None
@@ -112,7 +112,7 @@ set_roots(self, roots: RootsList | RootsHandler) -> None
Set the roots for the client. This does not automatically call `send_roots_list_changed`.
-#### `set_sampling_callback`
+#### `set_sampling_callback`
```python
set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabilities: mcp.types.SamplingCapability | None = None) -> None
@@ -121,7 +121,7 @@ set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabil
Set the sampling callback for the client.
-#### `set_elicitation_callback`
+#### `set_elicitation_callback`
```python
set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
@@ -130,7 +130,7 @@ set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
Set the elicitation callback for the client.
-#### `is_connected`
+#### `is_connected`
```python
is_connected(self) -> bool
@@ -139,7 +139,7 @@ is_connected(self) -> bool
Check if the client is currently connected.
-#### `new`
+#### `new`
```python
new(self) -> Client[ClientTransportT]
@@ -155,7 +155,7 @@ share state with the original client.
- A new Client instance with the same configuration but disconnected state.
-#### `initialize`
+#### `initialize`
```python
initialize(self, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.InitializeResult
@@ -183,13 +183,13 @@ capabilities, protocol version, and optional instructions.
- `RuntimeError`: If the client is not connected or initialization times out.
-#### `close`
+#### `close`
```python
close(self)
```
-#### `ping`
+#### `ping`
```python
ping(self) -> bool
@@ -198,7 +198,7 @@ ping(self) -> bool
Send a ping request.
-#### `cancel`
+#### `cancel`
```python
cancel(self, request_id: str | int, reason: str | None = None) -> None
@@ -207,7 +207,7 @@ cancel(self, request_id: str | int, reason: str | None = None) -> None
Send a cancellation notification for an in-progress request.
-#### `progress`
+#### `progress`
```python
progress(self, progress_token: str | int, progress: float, total: float | None = None, message: str | None = None) -> None
@@ -216,7 +216,7 @@ progress(self, progress_token: str | int, progress: float, total: float | None =
Send a progress notification.
-#### `set_logging_level`
+#### `set_logging_level`
```python
set_logging_level(self, level: mcp.types.LoggingLevel) -> None
@@ -225,7 +225,7 @@ set_logging_level(self, level: mcp.types.LoggingLevel) -> None
Send a logging/setLevel request.
-#### `send_roots_list_changed`
+#### `send_roots_list_changed`
```python
send_roots_list_changed(self) -> None
@@ -234,7 +234,7 @@ send_roots_list_changed(self) -> None
Send a roots/list_changed notification.
-#### `complete_mcp`
+#### `complete_mcp`
```python
complete_mcp(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.CompleteResult
@@ -257,7 +257,7 @@ containing the completion and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `complete`
+#### `complete`
```python
complete(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.Completion
@@ -279,7 +279,7 @@ include with the completion request. Defaults to None.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
diff --git a/docs/python-sdk/fastmcp-client-transports-config.mdx b/docs/python-sdk/fastmcp-client-transports-config.mdx
index 09f03a3d5..7ad10e0df 100644
--- a/docs/python-sdk/fastmcp-client-transports-config.mdx
+++ b/docs/python-sdk/fastmcp-client-transports-config.mdx
@@ -65,7 +65,7 @@ async with client:
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
```
-#### `close`
+#### `close`
```python
close(self)
diff --git a/docs/python-sdk/fastmcp-dependencies.mdx b/docs/python-sdk/fastmcp-dependencies.mdx
index e803029c3..f27566ef3 100644
--- a/docs/python-sdk/fastmcp-dependencies.mdx
+++ b/docs/python-sdk/fastmcp-dependencies.mdx
@@ -8,11 +8,10 @@ sidebarTitle: dependencies
Dependency injection exports for FastMCP.
-This module re-exports dependency injection symbols from Docket and FastMCP
-to provide a clean, centralized import location for all dependency-related
-functionality.
+This module re-exports dependency injection symbols to provide a clean,
+centralized import location for all dependency-related functionality.
DI features (Depends, CurrentContext, CurrentFastMCP) work without pydocket
-using a vendored DI engine. Only task-related dependencies (CurrentDocket,
+using the uncalled-for DI engine. Only task-related dependencies (CurrentDocket,
CurrentWorker) and background task execution require fastmcp[tasks].
diff --git a/docs/python-sdk/fastmcp-experimental-__init__.mdx b/docs/python-sdk/fastmcp-experimental-__init__.mdx
new file mode 100644
index 000000000..04ef31f33
--- /dev/null
+++ b/docs/python-sdk/fastmcp-experimental-__init__.mdx
@@ -0,0 +1,8 @@
+---
+title: __init__
+sidebarTitle: __init__
+---
+
+# `fastmcp.experimental`
+
+*This module is empty or contains only private/internal implementations.*
diff --git a/docs/python-sdk/fastmcp-experimental-sampling-__init__.mdx b/docs/python-sdk/fastmcp-experimental-sampling-__init__.mdx
new file mode 100644
index 000000000..f37691267
--- /dev/null
+++ b/docs/python-sdk/fastmcp-experimental-sampling-__init__.mdx
@@ -0,0 +1,8 @@
+---
+title: __init__
+sidebarTitle: __init__
+---
+
+# `fastmcp.experimental.sampling`
+
+*This module is empty or contains only private/internal implementations.*
diff --git a/docs/python-sdk/fastmcp-experimental-sampling-handlers.mdx b/docs/python-sdk/fastmcp-experimental-sampling-handlers.mdx
new file mode 100644
index 000000000..9220684bb
--- /dev/null
+++ b/docs/python-sdk/fastmcp-experimental-sampling-handlers.mdx
@@ -0,0 +1,8 @@
+---
+title: handlers
+sidebarTitle: handlers
+---
+
+# `fastmcp.experimental.sampling.handlers`
+
+*This module is empty or contains only private/internal implementations.*
diff --git a/docs/python-sdk/fastmcp-experimental-transforms-__init__.mdx b/docs/python-sdk/fastmcp-experimental-transforms-__init__.mdx
new file mode 100644
index 000000000..a33a00679
--- /dev/null
+++ b/docs/python-sdk/fastmcp-experimental-transforms-__init__.mdx
@@ -0,0 +1,8 @@
+---
+title: __init__
+sidebarTitle: __init__
+---
+
+# `fastmcp.experimental.transforms`
+
+*This module is empty or contains only private/internal implementations.*
diff --git a/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx b/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx
new file mode 100644
index 000000000..6ef971e8e
--- /dev/null
+++ b/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx
@@ -0,0 +1,121 @@
+---
+title: code_mode
+sidebarTitle: code_mode
+---
+
+# `fastmcp.experimental.transforms.code_mode`
+
+## Classes
+
+### `SandboxProvider`
+
+
+Interface for executing LLM-generated Python code in a sandbox.
+
+WARNING: The ``code`` parameter passed to ``run`` contains untrusted,
+LLM-generated Python. Implementations MUST execute it in an isolated
+sandbox — never with plain ``exec()``. Use ``MontySandboxProvider``
+(backed by ``pydantic-monty``) for production workloads.
+
+
+**Methods:**
+
+#### `run`
+
+```python
+run(self, code: str) -> Any
+```
+
+### `MontySandboxProvider`
+
+
+Sandbox provider backed by `pydantic-monty`.
+
+**Args:**
+- `limits`: Resource limits for sandbox execution. Supported keys\:
+``max_duration_secs`` (float), ``max_allocations`` (int),
+``max_memory`` (int), ``max_recursion_depth`` (int),
+``gc_interval`` (int). All are optional; omit a key to
+leave that limit uncapped.
+
+
+**Methods:**
+
+#### `run`
+
+```python
+run(self, code: str) -> Any
+```
+
+### `Search`
+
+
+Discovery tool factory that searches the catalog by query.
+
+**Args:**
+- `search_fn`: Async callable ``(tools, query) -> matching_tools``.
+Defaults to BM25 ranking.
+- `name`: Name of the synthetic tool exposed to the LLM.
+- `default_detail`: Default detail level for search results.
+``"brief"`` returns tool names and descriptions only.
+``"detailed"`` returns compact markdown with parameter schemas.
+``"full"`` returns complete JSON tool definitions.
+
+
+### `GetSchemas`
+
+
+Discovery tool factory that returns schemas for tools by name.
+
+**Args:**
+- `name`: Name of the synthetic tool exposed to the LLM.
+- `default_detail`: Default detail level for schema results.
+``"brief"`` returns tool names and descriptions only.
+``"detailed"`` renders compact markdown with parameter names,
+types, and required markers.
+``"full"`` returns the complete JSON schema.
+
+
+### `GetTags`
+
+
+Discovery tool factory that lists tool tags from the catalog.
+
+Reads ``tool.tags`` from the catalog and groups tools by tag. Tools
+without tags appear under ``"untagged"``.
+
+**Args:**
+- `name`: Name of the synthetic tool exposed to the LLM.
+- `default_detail`: Default detail level.
+``"brief"`` returns tag names with tool counts.
+``"full"`` lists all tools under each tag.
+
+
+### `CodeMode`
+
+
+Transform that collapses all tools into discovery + execute meta-tools.
+
+Discovery tools are composable via the ``discovery_tools`` parameter.
+Each is a callable that receives catalog access and returns a ``Tool``.
+By default, ``Search`` and ``GetSchemas`` are included for
+progressive disclosure: search finds candidates, get_schema retrieves
+parameter details, and execute runs code.
+
+The ``execute`` tool is always present and provides a sandboxed Python
+environment with ``call_tool(name, params)`` in scope.
+
+
+**Methods:**
+
+#### `transform_tools`
+
+```python
+transform_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
+```
+
+#### `get_tool`
+
+```python
+get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
+```
diff --git a/docs/python-sdk/fastmcp-resources-types.mdx b/docs/python-sdk/fastmcp-resources-types.mdx
index 01f866ab8..d19b24eb2 100644
--- a/docs/python-sdk/fastmcp-resources-types.mdx
+++ b/docs/python-sdk/fastmcp-resources-types.mdx
@@ -27,7 +27,7 @@ read(self) -> ResourceResult
Read the text content.
-### `BinaryResource`
+### `BinaryResource`
A resource that reads from bytes.
@@ -35,7 +35,7 @@ A resource that reads from bytes.
**Methods:**
-#### `read`
+#### `read`
```python
read(self) -> ResourceResult
@@ -44,7 +44,7 @@ read(self) -> ResourceResult
Read the binary content.
-### `FileResource`
+### `FileResource`
A resource that reads from a file.
@@ -54,7 +54,7 @@ Set is_binary=True to read file as binary data instead of text.
**Methods:**
-#### `validate_absolute_path`
+#### `validate_absolute_path`
```python
validate_absolute_path(cls, path: Path) -> Path
@@ -63,7 +63,7 @@ validate_absolute_path(cls, path: Path) -> Path
Ensure path is absolute.
-#### `set_binary_from_mime_type`
+#### `set_binary_from_mime_type`
```python
set_binary_from_mime_type(cls, is_binary: bool, info: ValidationInfo) -> bool
@@ -72,7 +72,7 @@ set_binary_from_mime_type(cls, is_binary: bool, info: ValidationInfo) -> bool
Set is_binary based on mime_type if not explicitly set.
-#### `read`
+#### `read`
```python
read(self) -> ResourceResult
@@ -81,7 +81,7 @@ read(self) -> ResourceResult
Read the file content.
-### `HttpResource`
+### `HttpResource`
A resource that reads from an HTTP endpoint.
@@ -89,7 +89,7 @@ A resource that reads from an HTTP endpoint.
**Methods:**
-#### `read`
+#### `read`
```python
read(self) -> ResourceResult
@@ -98,7 +98,7 @@ read(self) -> ResourceResult
Read the HTTP content.
-### `DirectoryResource`
+### `DirectoryResource`
A resource that lists files in a directory.
@@ -106,7 +106,7 @@ A resource that lists files in a directory.
**Methods:**
-#### `validate_absolute_path`
+#### `validate_absolute_path`
```python
validate_absolute_path(cls, path: Path) -> Path
@@ -115,7 +115,7 @@ validate_absolute_path(cls, path: Path) -> Path
Ensure path is absolute.
-#### `list_files`
+#### `list_files`
```python
list_files(self) -> list[Path]
@@ -124,7 +124,7 @@ list_files(self) -> list[Path]
List files in the directory.
-#### `read`
+#### `read`
```python
read(self) -> ResourceResult
diff --git a/docs/python-sdk/fastmcp-server-auth-auth.mdx b/docs/python-sdk/fastmcp-server-auth-auth.mdx
index d2a0728aa..2186df875 100644
--- a/docs/python-sdk/fastmcp-server-auth-auth.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-auth.mdx
@@ -254,7 +254,66 @@ Get routes for this provider.
Creates protected resource metadata routes (RFC 9728).
-### `OAuthProvider`
+### `MultiAuth`
+
+
+Composes an optional auth server with additional token verifiers.
+
+Use this when a single server needs to accept tokens from multiple sources.
+For example, an OAuth proxy for interactive clients combined with a JWT
+verifier for machine-to-machine tokens.
+
+Token verification tries the server first (if present), then each verifier
+in order, returning the first successful result. Routes and OAuth metadata
+come from the server; verifiers contribute only token verification.
+
+
+**Methods:**
+
+#### `verify_token`
+
+```python
+verify_token(self, token: str) -> AccessToken | None
+```
+
+Verify a token by trying the server, then each verifier in order.
+
+Each source is tried independently. If a source raises an exception,
+it is logged and treated as a non-match so that remaining sources
+still get a chance to verify the token.
+
+
+#### `set_mcp_path`
+
+```python
+set_mcp_path(self, mcp_path: str | None) -> None
+```
+
+Propagate MCP path to the server and all verifiers.
+
+
+#### `get_routes`
+
+```python
+get_routes(self, mcp_path: str | None = None) -> list[Route]
+```
+
+Delegate route creation to the server.
+
+
+#### `get_well_known_routes`
+
+```python
+get_well_known_routes(self, mcp_path: str | None = None) -> list[Route]
+```
+
+Delegate well-known route creation to the server.
+
+This ensures that server-specific well-known route logic (e.g.,
+OAuthProvider's RFC 8414 path-aware discovery) is preserved.
+
+
+### `OAuthProvider`
OAuth Authorization Server provider.
@@ -265,7 +324,7 @@ authorization flows, token issuance, and token verification.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -283,7 +342,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]
@@ -299,7 +358,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-providers-azure.mdx b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx
index 7d2988de7..3a5ca0868 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx
@@ -14,7 +14,7 @@ using the OAuth Proxy pattern for non-DCR OAuth flows.
## Functions
-### `EntraOBOToken`
+### `EntraOBOToken`
```python
EntraOBOToken(scopes: list[str]) -> str
@@ -43,7 +43,7 @@ or OBO exchange fails
## Classes
-### `AzureProvider`
+### `AzureProvider`
Azure (Microsoft Entra) OAuth provider for FastMCP.
@@ -78,7 +78,7 @@ Setup:
**Methods:**
-#### `authorize`
+#### `authorize`
```python
authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str
@@ -98,7 +98,7 @@ scopes to determine the resource/audience instead of a separate parameter.
- Authorization URL to redirect the user to Azure AD
-#### `get_obo_credential`
+#### `get_obo_credential`
```python
get_obo_credential(self, user_assertion: str) -> OnBehalfOfCredential
@@ -120,7 +120,7 @@ calls multiple tools with the same scopes.
- `ImportError`: If azure-identity is not installed (requires fastmcp[azure]).
-#### `close_obo_credentials`
+#### `close_obo_credentials`
```python
close_obo_credentials(self) -> None
@@ -129,7 +129,7 @@ close_obo_credentials(self) -> None
Close all cached OBO credentials.
-### `AzureJWTVerifier`
+### `AzureJWTVerifier`
JWT verifier pre-configured for Azure AD / Microsoft Entra ID.
@@ -166,7 +166,7 @@ Example::
**Methods:**
-#### `scopes_supported`
+#### `scopes_supported`
```python
scopes_supported(self) -> list[str]
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-propelauth.mdx b/docs/python-sdk/fastmcp-server-auth-providers-propelauth.mdx
new file mode 100644
index 000000000..3b31b00d8
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-auth-providers-propelauth.mdx
@@ -0,0 +1,69 @@
+---
+title: propelauth
+sidebarTitle: propelauth
+---
+
+# `fastmcp.server.auth.providers.propelauth`
+
+
+PropelAuth authentication provider for FastMCP.
+
+Example:
+ ```python
+ from fastmcp import FastMCP
+ from fastmcp.server.auth.providers.propelauth import PropelAuthProvider
+
+ auth = PropelAuthProvider(
+ auth_url="https://auth.yourdomain.com",
+ introspection_client_id="your-client-id",
+ introspection_client_secret="your-client-secret",
+ base_url="https://your-fastmcp-server.com",
+ required_scopes=["read:user_data"],
+ )
+
+ mcp = FastMCP("My App", auth=auth)
+ ```
+
+
+## Classes
+
+### `PropelAuthTokenIntrospectionOverrides`
+
+### `PropelAuthProvider`
+
+
+PropelAuth resource server provider using OAuth 2.1 token introspection.
+
+This provider validates access tokens via PropelAuth's introspection endpoint
+and forwards authorization server metadata for OAuth discovery.
+
+For detailed setup instructions, see:
+https://docs.propelauth.com/mcp-authentication/overview
+
+
+**Methods:**
+
+#### `get_routes`
+
+```python
+get_routes(self, mcp_path: str | None = None) -> list[Route]
+```
+
+Get routes for this provider.
+
+Includes the standard routes from the RemoteAuthProvider (protected resource metadata routes (RFC 9728)),
+and creates an authorization server metadata route that forwards to PropelAuth's route
+
+**Args:**
+- `mcp_path`: The path where the MCP endpoint is mounted (e.g., "/mcp")
+This is used to advertise the resource URL in metadata.
+
+
+#### `verify_token`
+
+```python
+verify_token(self, token: str) -> AccessToken | None
+```
+
+Verify token and check the ``aud`` claim against the configured resource.
+
diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx
index 6c73ede2e..58a916faf 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.
@@ -99,7 +99,7 @@ The context is optional - tools that don't need it can omit the parameter.
**Methods:**
-#### `is_background_task`
+#### `is_background_task`
```python
is_background_task(self) -> bool
@@ -112,7 +112,7 @@ task-aware implementations that can pause the task and wait for
client input.
-#### `task_id`
+#### `task_id`
```python
task_id(self) -> str | None
@@ -123,7 +123,7 @@ Get the background task ID if running in a background task.
Returns None if not running in a background task context.
-#### `origin_request_id`
+#### `origin_request_id`
```python
origin_request_id(self) -> str | None
@@ -136,7 +136,7 @@ In background task mode, this is the request_id captured when the task
was submitted, if one was available.
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -145,7 +145,7 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-#### `request_context`
+#### `request_context`
```python
request_context(self) -> RequestContext[ServerSession, Any, Request] | None
@@ -174,7 +174,7 @@ async def on_request(self, context, call_next):
```
-#### `lifespan_context`
+#### `lifespan_context`
```python
lifespan_context(self) -> dict[str, Any]
@@ -201,7 +201,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
@@ -218,7 +218,7 @@ Works in both foreground (MCP progress notifications) and background
- `message`: Optional status message describing current progress
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> list[SDKResource]
@@ -230,7 +230,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]
@@ -242,7 +242,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
@@ -258,7 +258,7 @@ Get a prompt by name with optional arguments.
- The prompt result
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str | AnyUrl) -> ResourceResult
@@ -273,7 +273,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
@@ -291,7 +291,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
@@ -303,7 +303,7 @@ Returns the transport type used to run this server: "stdio", "sse",
or "streamable-http". Returns None if called outside of a server context.
-#### `client_supports_extension`
+#### `client_supports_extension`
```python
client_supports_extension(self, extension_id: str) -> bool
@@ -328,7 +328,7 @@ Example::
return "text-only client"
-#### `client_id`
+#### `client_id`
```python
client_id(self) -> str | None
@@ -337,7 +337,7 @@ client_id(self) -> str | None
Get the client ID if available.
-#### `request_id`
+#### `request_id`
```python
request_id(self) -> str
@@ -348,7 +348,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
@@ -365,7 +365,7 @@ the same client session.
- for other transports.
-#### `session`
+#### `session`
```python
session(self) -> ServerSession
@@ -379,7 +379,7 @@ 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
@@ -390,7 +390,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
@@ -401,7 +401,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
@@ -412,7 +412,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
@@ -423,7 +423,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]
@@ -432,7 +432,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
@@ -444,7 +444,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
@@ -462,7 +462,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
@@ -505,7 +505,7 @@ regardless of this setting.
- - .text: The text content (if any)
-#### `sample`
+#### `sample`
```python
sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ResultT]
@@ -514,7 +514,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]
@@ -523,7 +523,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]
@@ -571,43 +571,43 @@ regardless of this setting.
- - .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
@@ -636,7 +636,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
@@ -657,7 +657,7 @@ requests.
The key is automatically prefixed with the session identifier.
-#### `get_state`
+#### `get_state`
```python
get_state(self, key: str) -> Any
@@ -671,7 +671,7 @@ then falls back to the session-scoped state store.
Returns None if the key is not found.
-#### `delete_state`
+#### `delete_state`
```python
delete_state(self, key: str) -> None
@@ -682,7 +682,7 @@ Delete a value from the state store.
Removes from both request-scoped and session-scoped stores.
-#### `enable_components`
+#### `enable_components`
```python
enable_components(self) -> None
@@ -706,7 +706,7 @@ ResourceListChangedNotification, and PromptListChangedNotification.
- `match_all`: If True, matches all components regardless of other criteria.
-#### `disable_components`
+#### `disable_components`
```python
disable_components(self) -> None
@@ -730,7 +730,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 b2313dd7d..60439e182 100644
--- a/docs/python-sdk/fastmcp-server-dependencies.mdx
+++ b/docs/python-sdk/fastmcp-server-dependencies.mdx
@@ -9,13 +9,13 @@ sidebarTitle: dependencies
Dependency injection for FastMCP.
DI features (Depends, CurrentContext, CurrentFastMCP) work without pydocket
-using a vendored DI engine. Only task-related dependencies (CurrentDocket,
+using the uncalled-for DI engine. Only task-related dependencies (CurrentDocket,
CurrentWorker) and background task execution require fastmcp[tasks].
## Functions
-### `get_task_context`
+### `get_task_context`
```python
get_task_context() -> TaskContextInfo | None
@@ -31,7 +31,7 @@ Returns None if not running in a task context (e.g., foreground execution).
- TaskContextInfo with task_id and session_id, or None if not in a task.
-### `register_task_session`
+### `register_task_session`
```python
register_task_session(session_id: str, session: ServerSession) -> None
@@ -49,7 +49,7 @@ client disconnects.
- `session`: The ServerSession instance
-### `get_task_session`
+### `get_task_session`
```python
get_task_session(session_id: str) -> ServerSession | None
@@ -65,7 +65,7 @@ Get a registered session by ID if still alive.
- The ServerSession if found and alive, None otherwise
-### `is_docket_available`
+### `is_docket_available`
```python
is_docket_available() -> bool
@@ -75,7 +75,7 @@ is_docket_available() -> bool
Check if pydocket is installed.
-### `require_docket`
+### `require_docket`
```python
require_docket(feature: str) -> None
@@ -89,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]
@@ -115,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
@@ -125,7 +125,7 @@ get_context() -> Context
Get the current FastMCP Context instance directly.
-### `get_server`
+### `get_server`
```python
get_server() -> FastMCP
@@ -141,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
@@ -153,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, include: set[str] | None = None) -> dict[str, str]
@@ -174,7 +174,7 @@ normally be excluded. This is useful for proxy transports that need to forward
authorization headers to upstream MCP servers.
-### `get_access_token`
+### `get_access_token`
```python
get_access_token() -> AccessToken | None
@@ -193,7 +193,7 @@ token snapshot stored in Redis at task submission time.
- 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]
@@ -218,7 +218,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]
@@ -244,7 +244,7 @@ time, so all injection goes through the unified DI system.
which will be filtered out)
-### `CurrentContext`
+### `CurrentContext`
```python
CurrentContext() -> Context
@@ -263,7 +263,7 @@ current MCP operation (tool/resource/prompt call).
- `RuntimeError`: If no active context found (during resolution)
-### `OptionalCurrentContext`
+### `OptionalCurrentContext`
```python
OptionalCurrentContext() -> Context | None
@@ -273,7 +273,7 @@ OptionalCurrentContext() -> Context | None
Get the current FastMCP Context, or None when no context is active.
-### `CurrentDocket`
+### `CurrentDocket`
```python
CurrentDocket() -> Docket
@@ -293,7 +293,7 @@ automatically creates for background task scheduling.
- `ImportError`: If fastmcp[tasks] not installed
-### `CurrentWorker`
+### `CurrentWorker`
```python
CurrentWorker() -> Worker
@@ -313,7 +313,7 @@ automatically creates for background task processing.
- `ImportError`: If fastmcp[tasks] not installed
-### `CurrentFastMCP`
+### `CurrentFastMCP`
```python
CurrentFastMCP() -> FastMCP
@@ -331,7 +331,7 @@ This dependency provides access to the active FastMCP server.
- `RuntimeError`: If no server in context (during resolution)
-### `CurrentRequest`
+### `CurrentRequest`
```python
CurrentRequest() -> Request
@@ -351,7 +351,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]
@@ -369,7 +369,7 @@ transport.
- A dependency that resolves to a dictionary of header name -> value
-### `CurrentAccessToken`
+### `CurrentAccessToken`
```python
CurrentAccessToken() -> AccessToken
@@ -388,7 +388,7 @@ authenticated request. Raises an error if no authentication is present.
- `RuntimeError`: If no authenticated user (use get_access_token() for optional)
-### `TokenClaim`
+### `TokenClaim`
```python
TokenClaim(name: str) -> str
@@ -413,7 +413,7 @@ without needing the full token object.
## Classes
-### `TaskContextInfo`
+### `TaskContextInfo`
Information about the current background task context.
@@ -422,7 +422,7 @@ Returned by ``get_task_context()`` when running inside a Docket worker.
Contains identifiers needed to communicate with the MCP session.
-### `ProgressLike`
+### `ProgressLike`
Protocol for progress tracking interface.
@@ -433,7 +433,7 @@ and Docket's Progress (worker context).
**Methods:**
-#### `current`
+#### `current`
```python
current(self) -> int | None
@@ -442,7 +442,7 @@ current(self) -> int | None
Current progress value.
-#### `total`
+#### `total`
```python
total(self) -> int
@@ -451,7 +451,7 @@ total(self) -> int
Total/target progress value.
-#### `message`
+#### `message`
```python
message(self) -> str | None
@@ -460,7 +460,7 @@ message(self) -> str | None
Current progress message.
-#### `set_total`
+#### `set_total`
```python
set_total(self, total: int) -> None
@@ -469,7 +469,7 @@ set_total(self, total: int) -> None
Set the total/target value for progress tracking.
-#### `increment`
+#### `increment`
```python
increment(self, amount: int = 1) -> None
@@ -478,7 +478,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
@@ -487,7 +487,7 @@ set_message(self, message: str | None) -> None
Update the progress status message.
-### `InMemoryProgress`
+### `InMemoryProgress`
In-memory progress tracker for immediate tool execution.
@@ -499,25 +499,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
@@ -526,7 +526,7 @@ set_total(self, total: int) -> None
Set the total/target value for progress tracking.
-#### `increment`
+#### `increment`
```python
increment(self, amount: int = 1) -> None
@@ -535,7 +535,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
@@ -544,7 +544,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.
@@ -558,3 +558,59 @@ This allows tools to use Progress() regardless of whether they're called
immediately or as background tasks, and regardless of whether pydocket
is installed.
+
+**Methods:**
+
+#### `current`
+
+```python
+current(self) -> int | None
+```
+
+Current progress value.
+
+
+#### `total`
+
+```python
+total(self) -> int
+```
+
+Total/target progress value.
+
+
+#### `message`
+
+```python
+message(self) -> str | None
+```
+
+Current progress message.
+
+
+#### `set_total`
+
+```python
+set_total(self, total: int) -> None
+```
+
+Set the total/target value for progress tracking.
+
+
+#### `increment`
+
+```python
+increment(self, amount: int = 1) -> None
+```
+
+Atomically increment the current progress value.
+
+
+#### `set_message`
+
+```python
+set_message(self, message: str | None) -> None
+```
+
+Update the progress status message.
+
diff --git a/docs/python-sdk/fastmcp-server-middleware-authorization.mdx b/docs/python-sdk/fastmcp-server-middleware-authorization.mdx
index abc9ff6ae..5bf859a09 100644
--- a/docs/python-sdk/fastmcp-server-middleware-authorization.mdx
+++ b/docs/python-sdk/fastmcp-server-middleware-authorization.mdx
@@ -61,7 +61,7 @@ on_list_tools(self, context: MiddlewareContext[mt.ListToolsRequest], call_next:
Filter tools/list response based on auth checks.
-#### `on_call_tool`
+#### `on_call_tool`
```python
on_call_tool(self, context: MiddlewareContext[mt.CallToolRequestParams], call_next: CallNext[mt.CallToolRequestParams, ToolResult]) -> ToolResult
@@ -70,7 +70,7 @@ on_call_tool(self, context: MiddlewareContext[mt.CallToolRequestParams], call_ne
Check auth before tool execution.
-#### `on_list_resources`
+#### `on_list_resources`
```python
on_list_resources(self, context: MiddlewareContext[mt.ListResourcesRequest], call_next: CallNext[mt.ListResourcesRequest, Sequence[Resource]]) -> Sequence[Resource]
@@ -79,7 +79,7 @@ on_list_resources(self, context: MiddlewareContext[mt.ListResourcesRequest], cal
Filter resources/list response based on auth checks.
-#### `on_read_resource`
+#### `on_read_resource`
```python
on_read_resource(self, context: MiddlewareContext[mt.ReadResourceRequestParams], call_next: CallNext[mt.ReadResourceRequestParams, ResourceResult]) -> ResourceResult
@@ -88,7 +88,7 @@ on_read_resource(self, context: MiddlewareContext[mt.ReadResourceRequestParams],
Check auth before resource read.
-#### `on_list_resource_templates`
+#### `on_list_resource_templates`
```python
on_list_resource_templates(self, context: MiddlewareContext[mt.ListResourceTemplatesRequest], call_next: CallNext[mt.ListResourceTemplatesRequest, Sequence[ResourceTemplate]]) -> Sequence[ResourceTemplate]
@@ -97,7 +97,7 @@ on_list_resource_templates(self, context: MiddlewareContext[mt.ListResourceTempl
Filter resource templates/list response based on auth checks.
-#### `on_list_prompts`
+#### `on_list_prompts`
```python
on_list_prompts(self, context: MiddlewareContext[mt.ListPromptsRequest], call_next: CallNext[mt.ListPromptsRequest, Sequence[Prompt]]) -> Sequence[Prompt]
@@ -106,7 +106,7 @@ on_list_prompts(self, context: MiddlewareContext[mt.ListPromptsRequest], call_ne
Filter prompts/list response based on auth checks.
-#### `on_get_prompt`
+#### `on_get_prompt`
```python
on_get_prompt(self, context: MiddlewareContext[mt.GetPromptRequestParams], call_next: CallNext[mt.GetPromptRequestParams, PromptResult]) -> PromptResult
diff --git a/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx b/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx
index 0028ea080..9d0eec22e 100644
--- a/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx
+++ b/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx
@@ -10,7 +10,7 @@ Lifespan and Docket task infrastructure for FastMCP Server.
## Classes
-### `LifespanMixin`
+### `LifespanMixin`
Mixin providing lifespan and Docket task infrastructure for FastMCP.
@@ -18,7 +18,7 @@ Mixin providing lifespan and Docket task infrastructure for FastMCP.
**Methods:**
-#### `docket`
+#### `docket`
```python
docket(self: FastMCP) -> Docket | None
diff --git a/docs/python-sdk/fastmcp-server-providers-local_provider-decorators-tools.mdx b/docs/python-sdk/fastmcp-server-providers-local_provider-decorators-tools.mdx
index d3cf4daa2..efeae3661 100644
--- a/docs/python-sdk/fastmcp-server-providers-local_provider-decorators-tools.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-local_provider-decorators-tools.mdx
@@ -14,7 +14,7 @@ registration functionality to LocalProvider.
## Classes
-### `ToolDecoratorMixin`
+### `ToolDecoratorMixin`
Mixin class providing tool decorator functionality for LocalProvider.
@@ -26,7 +26,7 @@ This mixin contains all methods related to:
**Methods:**
-#### `add_tool`
+#### `add_tool`
```python
add_tool(self: LocalProvider, tool: Tool | Callable[..., Any]) -> Tool
@@ -37,19 +37,19 @@ Add a tool to this provider's storage.
Accepts either a Tool object or a decorated function with __fastmcp__ metadata.
-#### `tool`
+#### `tool`
```python
tool(self: LocalProvider, name_or_fn: F) -> F
```
-#### `tool`
+#### `tool`
```python
tool(self: LocalProvider, name_or_fn: str | None = None) -> Callable[[F], F]
```
-#### `tool`
+#### `tool`
```python
tool(self: LocalProvider, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool]
diff --git a/docs/python-sdk/fastmcp-server-providers-proxy.mdx b/docs/python-sdk/fastmcp-server-providers-proxy.mdx
index b661d2386..4c64d8566 100644
--- a/docs/python-sdk/fastmcp-server-providers-proxy.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-proxy.mdx
@@ -15,7 +15,7 @@ classes that forward execution to remote servers.
## Functions
-### `default_proxy_roots_handler`
+### `default_proxy_roots_handler`
```python
default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanContextT]) -> RootsList
@@ -25,7 +25,7 @@ default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanConte
Forward list roots request from remote server to proxy's connected clients.
-### `default_proxy_sampling_handler`
+### `default_proxy_sampling_handler`
```python
default_proxy_sampling_handler(messages: list[mcp.types.SamplingMessage], params: mcp.types.CreateMessageRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> mcp.types.CreateMessageResult
@@ -35,7 +35,7 @@ default_proxy_sampling_handler(messages: list[mcp.types.SamplingMessage], params
Forward sampling request from remote server to proxy's connected clients.
-### `default_proxy_elicitation_handler`
+### `default_proxy_elicitation_handler`
```python
default_proxy_elicitation_handler(message: str, response_type: type, params: mcp.types.ElicitRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> ElicitResult
@@ -45,7 +45,7 @@ default_proxy_elicitation_handler(message: str, response_type: type, params: mcp
Forward elicitation request from remote server to proxy's connected clients.
-### `default_proxy_log_handler`
+### `default_proxy_log_handler`
```python
default_proxy_log_handler(message: LogMessage) -> None
@@ -55,7 +55,7 @@ default_proxy_log_handler(message: LogMessage) -> None
Forward log notification from remote server to proxy's connected clients.
-### `default_proxy_progress_handler`
+### `default_proxy_progress_handler`
```python
default_proxy_progress_handler(progress: float, total: float | None, message: str | None) -> None
@@ -102,13 +102,13 @@ run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResu
Executes the tool by making a call through the client.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `ProxyResource`
+### `ProxyResource`
A Resource that represents and reads a resource from a remote server.
@@ -116,7 +116,7 @@ A Resource that represents and reads a resource from a remote server.
**Methods:**
-#### `model_copy`
+#### `model_copy`
```python
model_copy(self, **kwargs: Any) -> ProxyResource
@@ -125,7 +125,7 @@ model_copy(self, **kwargs: Any) -> ProxyResource
Override to preserve _backend_uri when uri changes.
-#### `from_mcp_resource`
+#### `from_mcp_resource`
```python
from_mcp_resource(cls, client_factory: ClientFactoryT, mcp_resource: mcp.types.Resource) -> ProxyResource
@@ -134,7 +134,7 @@ from_mcp_resource(cls, client_factory: ClientFactoryT, mcp_resource: mcp.types.R
Factory method to create a ProxyResource from a raw MCP resource schema.
-#### `read`
+#### `read`
```python
read(self) -> ResourceResult
@@ -143,13 +143,13 @@ read(self) -> ResourceResult
Read the resource content from the remote server.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `ProxyTemplate`
+### `ProxyTemplate`
A ResourceTemplate that represents and creates resources from a remote server template.
@@ -157,7 +157,7 @@ A ResourceTemplate that represents and creates resources from a remote server te
**Methods:**
-#### `model_copy`
+#### `model_copy`
```python
model_copy(self, **kwargs: Any) -> ProxyTemplate
@@ -166,7 +166,7 @@ model_copy(self, **kwargs: Any) -> ProxyTemplate
Override to preserve _backend_uri_template when uri_template changes.
-#### `from_mcp_template`
+#### `from_mcp_template`
```python
from_mcp_template(cls, client_factory: ClientFactoryT, mcp_template: mcp.types.ResourceTemplate) -> ProxyTemplate
@@ -175,7 +175,7 @@ from_mcp_template(cls, client_factory: ClientFactoryT, mcp_template: mcp.types.R
Factory method to create a ProxyTemplate from a raw MCP template schema.
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any], context: Context | None = None) -> ProxyResource
@@ -184,13 +184,13 @@ create_resource(self, uri: str, params: dict[str, Any], context: Context | None
Create a resource from the template by calling the remote server.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `ProxyPrompt`
+### `ProxyPrompt`
A Prompt that represents and renders a prompt from a remote server.
@@ -198,7 +198,7 @@ A Prompt that represents and renders a prompt from a remote server.
**Methods:**
-#### `model_copy`
+#### `model_copy`
```python
model_copy(self, **kwargs: Any) -> ProxyPrompt
@@ -207,7 +207,7 @@ model_copy(self, **kwargs: Any) -> ProxyPrompt
Override to preserve _backend_name when name changes.
-#### `from_mcp_prompt`
+#### `from_mcp_prompt`
```python
from_mcp_prompt(cls, client_factory: ClientFactoryT, mcp_prompt: mcp.types.Prompt) -> ProxyPrompt
@@ -216,7 +216,7 @@ from_mcp_prompt(cls, client_factory: ClientFactoryT, mcp_prompt: mcp.types.Promp
Factory method to create a ProxyPrompt from a raw MCP prompt schema.
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any]) -> PromptResult
@@ -225,13 +225,13 @@ render(self, arguments: dict[str, Any]) -> PromptResult
Render the prompt by making a call through the client.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `ProxyProvider`
+### `ProxyProvider`
Provider that proxies to a remote MCP server via a client factory.
@@ -245,7 +245,7 @@ because tasks cannot be executed through a proxy.
**Methods:**
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -258,7 +258,7 @@ server lifespan initialization, which would open the client before any
context is set. All Proxy* components have task_config.mode="forbidden".
-### `FastMCPProxy`
+### `FastMCPProxy`
A FastMCP server that acts as a proxy to a remote MCP-compliant server.
@@ -267,7 +267,7 @@ This is a convenience wrapper that creates a FastMCP server with a
ProxyProvider. For more control, use FastMCP with add_provider(ProxyProvider(...)).
-### `ProxyClient`
+### `ProxyClient`
A proxy client that forwards advanced interactions between a remote MCP server and the proxy's connected clients.
@@ -275,7 +275,7 @@ A proxy client that forwards advanced interactions between a remote MCP server a
Supports forwarding roots, sampling, elicitation, logging, and progress.
-### `StatefulProxyClient`
+### `StatefulProxyClient`
A proxy client that provides a stateful client factory for the proxy server.
@@ -296,7 +296,7 @@ it to detect (and correct) staleness.
**Methods:**
-#### `clear`
+#### `clear`
```python
clear(self)
@@ -305,7 +305,7 @@ clear(self)
Clear all cached clients and force disconnect them.
-#### `new_stateful`
+#### `new_stateful`
```python
new_stateful(self) -> Client[ClientTransportT]
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index d3a7de773..dbd0ad15a 100644
--- a/docs/python-sdk/fastmcp-server-server.mdx
+++ b/docs/python-sdk/fastmcp-server-server.mdx
@@ -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
@@ -64,43 +64,43 @@ Wrapper for stored context state values.
**Methods:**
-#### `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]
```
-#### `local_provider`
+#### `local_provider`
```python
local_provider(self) -> LocalProvider
@@ -115,13 +115,13 @@ Use this to remove components:
mcp.local_provider.remove_prompt("my_prompt")
-#### `add_middleware`
+#### `add_middleware`
```python
add_middleware(self, middleware: Middleware) -> None
```
-#### `add_provider`
+#### `add_provider`
```python
add_provider(self, provider: Provider) -> None
@@ -141,7 +141,7 @@ always take precedence over providers.
- Prompts become "namespace_promptname"
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -153,7 +153,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
@@ -168,7 +168,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
@@ -180,7 +180,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
@@ -192,7 +192,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]
@@ -205,7 +205,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
@@ -225,7 +225,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]
@@ -238,7 +238,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
@@ -257,7 +257,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]
@@ -270,7 +270,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
@@ -289,7 +289,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]
@@ -302,7 +302,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
@@ -321,19 +321,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
@@ -363,19 +363,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
@@ -404,19 +404,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
@@ -446,7 +446,7 @@ return PromptResult.
- `PromptError`: If prompt rendering fails
-#### `add_tool`
+#### `add_tool`
```python
add_tool(self, tool: Tool | Callable[..., Any]) -> Tool
@@ -464,7 +464,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
@@ -483,19 +483,19 @@ Remove tool(s) from the server.
- `NotFoundError`: If no matching tool is found.
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: F) -> F
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | None = None) -> Callable[[F], F]
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool]
@@ -551,7 +551,7 @@ server.tool(my_function, name="custom_name")
```
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource | Callable[..., Any]) -> Resource | ResourceTemplate
@@ -566,7 +566,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
@@ -581,7 +581,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[[F], F]
@@ -640,7 +640,7 @@ async def get_weather(city: str) -> str:
```
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt
@@ -655,19 +655,19 @@ Add a prompt to the server.
- The prompt instance that was added to the server.
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: F) -> F
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | None = None) -> Callable[[F], F]
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt]
@@ -744,7 +744,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
@@ -791,7 +791,7 @@ mounted server.
- `prefix`: Deprecated. Use namespace instead.
-#### `import_server`
+#### `import_server`
```python
import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None
@@ -832,7 +832,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 | None = None, 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, validate_output: bool = True, **settings: Any) -> Self
@@ -861,7 +861,7 @@ response structure while still returning structured JSON.
- 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, **settings: Any) -> Self
@@ -885,7 +885,7 @@ Use this to configure timeout and other client settings.
- 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
@@ -903,7 +903,7 @@ instance or any value accepted as the `transport` argument of
`fastmcp.client.Client` constructor.
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
diff --git a/docs/python-sdk/fastmcp-server-transforms-catalog.mdx b/docs/python-sdk/fastmcp-server-transforms-catalog.mdx
new file mode 100644
index 000000000..1dd2cfe4a
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-transforms-catalog.mdx
@@ -0,0 +1,220 @@
+---
+title: catalog
+sidebarTitle: catalog
+---
+
+# `fastmcp.server.transforms.catalog`
+
+
+Base class for transforms that need to read the real component catalog.
+
+Some transforms replace ``list_tools()`` output with synthetic components
+(e.g. a search interface) while still needing access to the *real*
+(auth-filtered) catalog at call time. ``CatalogTransform`` provides the
+bypass machinery so subclasses can call ``get_tool_catalog()`` without
+triggering their own replacement logic.
+
+Re-entrancy problem
+-------------------
+
+When a synthetic tool handler calls ``get_tool_catalog()``, that calls
+``ctx.fastmcp.list_tools()`` which re-enters the transform pipeline —
+including *this* transform's ``list_tools()``. If the subclass overrides
+``list_tools()`` directly, the re-entrant call would hit the subclass's
+replacement logic again (returning synthetic tools instead of the real
+catalog). A ``super()`` call can't prevent this because Python can't
+short-circuit a method after ``super()`` returns.
+
+Solution: ``CatalogTransform`` owns ``list_tools()`` and uses a
+per-instance ``ContextVar`` to detect re-entrant calls. During bypass,
+it passes through to the base ``Transform.list_tools()`` (a no-op).
+Otherwise, it delegates to ``transform_tools()`` — the subclass hook
+where replacement logic lives. Same pattern for resources, prompts,
+and resource templates.
+
+This is *not* the same as the ``Provider._list_tools()`` convention
+(which produces raw components with no arguments). ``transform_tools()``
+receives the current catalog and returns a transformed version. The
+distinct name avoids confusion between the two patterns.
+
+Usage::
+
+ class MyTransform(CatalogTransform):
+ async def transform_tools(self, tools):
+ return [self._make_search_tool()]
+
+ def _make_search_tool(self):
+ async def search(ctx: Context = None):
+ real_tools = await self.get_tool_catalog(ctx)
+ ...
+ return Tool.from_function(fn=search, name="search")
+
+
+## Classes
+
+### `CatalogTransform`
+
+
+Transform that needs access to the real component catalog.
+
+Subclasses override ``transform_tools()`` / ``transform_resources()``
+/ ``transform_prompts()`` / ``transform_resource_templates()``
+instead of the ``list_*()`` methods. The base class owns
+``list_*()`` and handles re-entrant bypass automatically — subclasses
+never see re-entrant calls from ``get_*_catalog()``.
+
+The ``get_*_catalog()`` methods fetch the real (auth-filtered) catalog
+by temporarily setting a bypass flag so that this transform's
+``list_*()`` passes through without calling the subclass hook.
+
+
+**Methods:**
+
+#### `list_tools`
+
+```python
+list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
+```
+
+#### `list_resources`
+
+```python
+list_resources(self, resources: Sequence[Resource]) -> Sequence[Resource]
+```
+
+#### `list_resource_templates`
+
+```python
+list_resource_templates(self, templates: Sequence[ResourceTemplate]) -> Sequence[ResourceTemplate]
+```
+
+#### `list_prompts`
+
+```python
+list_prompts(self, prompts: Sequence[Prompt]) -> Sequence[Prompt]
+```
+
+#### `transform_tools`
+
+```python
+transform_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
+```
+
+Transform the tool catalog.
+
+Override this method to replace, filter, or augment the tool listing.
+The default implementation passes through unchanged.
+
+Do NOT override ``list_tools()`` directly — the base class uses it
+to handle re-entrant bypass when ``get_tool_catalog()`` reads the
+real catalog.
+
+
+#### `transform_resources`
+
+```python
+transform_resources(self, resources: Sequence[Resource]) -> Sequence[Resource]
+```
+
+Transform the resource catalog.
+
+Override this method to replace, filter, or augment the resource listing.
+The default implementation passes through unchanged.
+
+Do NOT override ``list_resources()`` directly — the base class uses it
+to handle re-entrant bypass when ``get_resource_catalog()`` reads the
+real catalog.
+
+
+#### `transform_resource_templates`
+
+```python
+transform_resource_templates(self, templates: Sequence[ResourceTemplate]) -> Sequence[ResourceTemplate]
+```
+
+Transform the resource template catalog.
+
+Override this method to replace, filter, or augment the template listing.
+The default implementation passes through unchanged.
+
+Do NOT override ``list_resource_templates()`` directly — the base class
+uses it to handle re-entrant bypass when
+``get_resource_template_catalog()`` reads the real catalog.
+
+
+#### `transform_prompts`
+
+```python
+transform_prompts(self, prompts: Sequence[Prompt]) -> Sequence[Prompt]
+```
+
+Transform the prompt catalog.
+
+Override this method to replace, filter, or augment the prompt listing.
+The default implementation passes through unchanged.
+
+Do NOT override ``list_prompts()`` directly — the base class uses it
+to handle re-entrant bypass when ``get_prompt_catalog()`` reads the
+real catalog.
+
+
+#### `get_tool_catalog`
+
+```python
+get_tool_catalog(self, ctx: Context) -> Sequence[Tool]
+```
+
+Fetch the real tool catalog, bypassing this transform.
+
+**Args:**
+- `ctx`: The current request context.
+- `run_middleware`: Whether to run middleware on the inner call.
+Defaults to True because this is typically called from a
+tool handler where list_tools middleware has not yet run.
+
+
+#### `get_resource_catalog`
+
+```python
+get_resource_catalog(self, ctx: Context) -> Sequence[Resource]
+```
+
+Fetch the real resource catalog, bypassing this transform.
+
+**Args:**
+- `ctx`: The current request context.
+- `run_middleware`: Whether to run middleware on the inner call.
+Defaults to True because this is typically called from a
+tool handler where list_resources middleware has not yet run.
+
+
+#### `get_prompt_catalog`
+
+```python
+get_prompt_catalog(self, ctx: Context) -> Sequence[Prompt]
+```
+
+Fetch the real prompt catalog, bypassing this transform.
+
+**Args:**
+- `ctx`: The current request context.
+- `run_middleware`: Whether to run middleware on the inner call.
+Defaults to True because this is typically called from a
+tool handler where list_prompts middleware has not yet run.
+
+
+#### `get_resource_template_catalog`
+
+```python
+get_resource_template_catalog(self, ctx: Context) -> Sequence[ResourceTemplate]
+```
+
+Fetch the real resource template catalog, bypassing this transform.
+
+**Args:**
+- `ctx`: The current request context.
+- `run_middleware`: Whether to run middleware on the inner call.
+Defaults to True because this is typically called from a
+tool handler where list_resource_templates middleware has
+not yet run.
+
diff --git a/docs/python-sdk/fastmcp-server-transforms-search-__init__.mdx b/docs/python-sdk/fastmcp-server-transforms-search-__init__.mdx
new file mode 100644
index 000000000..80b71d226
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-transforms-search-__init__.mdx
@@ -0,0 +1,23 @@
+---
+title: __init__
+sidebarTitle: __init__
+---
+
+# `fastmcp.server.transforms.search`
+
+
+Search transforms for tool discovery.
+
+Search transforms collapse a large tool catalog into a search interface,
+letting LLMs discover tools on demand instead of seeing the full list.
+
+Example:
+ ```python
+ from fastmcp import FastMCP
+ from fastmcp.server.transforms.search import RegexSearchTransform
+
+ mcp = FastMCP("Server")
+ mcp.add_transform(RegexSearchTransform())
+ # list_tools now returns only search_tools + call_tool
+ ```
+
diff --git a/docs/python-sdk/fastmcp-server-transforms-search-base.mdx b/docs/python-sdk/fastmcp-server-transforms-search-base.mdx
new file mode 100644
index 000000000..7ecd3b5f2
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-transforms-search-base.mdx
@@ -0,0 +1,105 @@
+---
+title: base
+sidebarTitle: base
+---
+
+# `fastmcp.server.transforms.search.base`
+
+
+Base class for search transforms.
+
+Search transforms replace ``list_tools()`` output with a small set of
+synthetic tools — a search tool and a call-tool proxy — so LLMs can
+discover tools on demand instead of receiving the full catalog.
+
+All concrete search transforms (``RegexSearchTransform``,
+``BM25SearchTransform``, etc.) inherit from ``BaseSearchTransform`` and
+implement ``_make_search_tool()`` and ``_search()`` to provide their
+specific search strategy.
+
+Example::
+
+ from fastmcp import FastMCP
+ from fastmcp.server.transforms.search import RegexSearchTransform
+
+ mcp = FastMCP("Server")
+
+ @mcp.tool
+ def add(a: int, b: int) -> int: ...
+
+ @mcp.tool
+ def multiply(x: float, y: float) -> float: ...
+
+ # Clients now see only ``search_tools`` and ``call_tool``.
+ # The original tools are discoverable via search.
+ mcp.add_transform(RegexSearchTransform())
+
+
+## Functions
+
+### `serialize_tools_for_output_json`
+
+```python
+serialize_tools_for_output_json(tools: Sequence[Tool]) -> list[dict[str, Any]]
+```
+
+
+Serialize tools to the same dict format as ``list_tools`` output.
+
+
+### `serialize_tools_for_output_markdown`
+
+```python
+serialize_tools_for_output_markdown(tools: Sequence[Tool]) -> str
+```
+
+
+Serialize tools to compact markdown, using ~65-70% fewer tokens than JSON.
+
+
+## Classes
+
+### `BaseSearchTransform`
+
+
+Replace the tool listing with a search interface.
+
+When this transform is active, ``list_tools()`` returns only:
+
+* Any tools listed in ``always_visible`` (pinned).
+* A **search tool** that finds tools matching a query.
+* A **call_tool** proxy that executes tools discovered via search.
+
+Hidden tools remain callable — ``get_tool()`` delegates unknown
+names downstream, so direct calls and the call-tool proxy both work.
+
+Search results respect the full auth pipeline: middleware, visibility
+transforms, and component-level auth checks all apply.
+
+**Args:**
+- `max_results`: Maximum number of tools returned per search.
+- `always_visible`: Tool names that stay in the ``list_tools``
+output alongside the synthetic search/call tools.
+- `search_tool_name`: Name of the generated search tool.
+- `call_tool_name`: Name of the generated call-tool proxy.
+
+
+**Methods:**
+
+#### `transform_tools`
+
+```python
+transform_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
+```
+
+Replace the catalog with pinned + synthetic search/call tools.
+
+
+#### `get_tool`
+
+```python
+get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
+```
+
+Intercept synthetic tool names; delegate everything else.
+
diff --git a/docs/python-sdk/fastmcp-server-transforms-search-bm25.mdx b/docs/python-sdk/fastmcp-server-transforms-search-bm25.mdx
new file mode 100644
index 000000000..d5264f46a
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-transforms-search-bm25.mdx
@@ -0,0 +1,20 @@
+---
+title: bm25
+sidebarTitle: bm25
+---
+
+# `fastmcp.server.transforms.search.bm25`
+
+
+BM25-based search transform.
+
+## Classes
+
+### `BM25SearchTransform`
+
+
+Search transform using BM25 Okapi relevance ranking.
+
+Maintains an in-memory index that is lazily rebuilt when the tool
+catalog changes (detected via a hash of tool names).
+
diff --git a/docs/python-sdk/fastmcp-server-transforms-search-regex.mdx b/docs/python-sdk/fastmcp-server-transforms-search-regex.mdx
new file mode 100644
index 000000000..e36c8d25e
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-transforms-search-regex.mdx
@@ -0,0 +1,20 @@
+---
+title: regex
+sidebarTitle: regex
+---
+
+# `fastmcp.server.transforms.search.regex`
+
+
+Regex-based search transform.
+
+## Classes
+
+### `RegexSearchTransform`
+
+
+Search transform using regex pattern matching.
+
+Tools are matched against their name, description, and parameter
+information using ``re.search`` with ``re.IGNORECASE``.
+
diff --git a/docs/python-sdk/fastmcp-tools-function_parsing.mdx b/docs/python-sdk/fastmcp-tools-function_parsing.mdx
index 284b6cdbe..f9cd7f28e 100644
--- a/docs/python-sdk/fastmcp-tools-function_parsing.mdx
+++ b/docs/python-sdk/fastmcp-tools-function_parsing.mdx
@@ -10,11 +10,11 @@ Function introspection and schema generation for FastMCP tools.
## Classes
-### `ParsedFunction`
+### `ParsedFunction`
**Methods:**
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any], exclude_args: list[str] | None = None, validate: bool = True, wrap_non_object_output_schema: bool = True) -> ParsedFunction
diff --git a/docs/python-sdk/fastmcp-tools-function_tool.mdx b/docs/python-sdk/fastmcp-tools-function_tool.mdx
index 97d0d967f..d25c6ecf8 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 1fe8e4c9d..0394bf4a5 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 | Callable[..., Any]) -> TransformedTool
```
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
diff --git a/docs/python-sdk/fastmcp-utilities-openapi-schemas.mdx b/docs/python-sdk/fastmcp-utilities-openapi-schemas.mdx
index 406f1fac0..fad88ee5f 100644
--- a/docs/python-sdk/fastmcp-utilities-openapi-schemas.mdx
+++ b/docs/python-sdk/fastmcp-utilities-openapi-schemas.mdx
@@ -20,7 +20,7 @@ clean_schema_for_display(schema: JsonSchema | None) -> JsonSchema | None
Clean up a schema dictionary for display by removing internal/complex fields.
-### `extract_output_schema_from_responses`
+### `extract_output_schema_from_responses`
```python
extract_output_schema_from_responses(responses: dict[str, ResponseInfo], schema_definitions: dict[str, Any] | None = None, openapi_version: str | None = None) -> dict[str, Any] | None