diff --git a/docs/docs.json b/docs/docs.json
index f8158e5c7..456d6b263 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -368,6 +368,7 @@
"group": "fastmcp.cli",
"pages": [
"python-sdk/fastmcp-cli-__init__",
+ "python-sdk/fastmcp-cli-apps_dev",
"python-sdk/fastmcp-cli-auth",
"python-sdk/fastmcp-cli-cimd",
"python-sdk/fastmcp-cli-cli",
diff --git a/docs/python-sdk/fastmcp-cli-apps_dev.mdx b/docs/python-sdk/fastmcp-cli-apps_dev.mdx
new file mode 100644
index 000000000..49cbed7fc
--- /dev/null
+++ b/docs/python-sdk/fastmcp-cli-apps_dev.mdx
@@ -0,0 +1,47 @@
+---
+title: apps_dev
+sidebarTitle: apps_dev
+---
+
+# `fastmcp.cli.apps_dev`
+
+
+Dev server for previewing FastMCPApp UIs locally.
+
+Starts the user's MCP server on a configurable port, then starts a lightweight
+Starlette dev server that:
+
+ - Serves a Prefab-based tool picker at GET /
+ - Proxies /mcp to the user's server (avoids browser CORS restrictions)
+ - Serves the AppBridge host page at GET /launch
+
+The host page uses @modelcontextprotocol/ext-apps to connect to the MCP server
+and render the selected UI tool inside an iframe.
+
+Startup sequence
+----------------
+1. Download ext-apps app-bridge.js from npm and patch its bare
+ ``@modelcontextprotocol/sdk/…`` imports to use concrete esm.sh URLs.
+2. Detect the exact Zod v4 module URL that esm.sh serves for that SDK version
+ and build an import-map entry that redirects the broken ``v4.mjs`` (which
+ only re-exports ``{z, default}``) to ``v4/classic/index.mjs`` (which
+ correctly exports every named Zod v4 function). Import maps apply to the
+ full module graph in the document, including cross-origin esm.sh modules.
+3. Serve both the patched JS and the import-map JSON from the dev server.
+
+
+## Functions
+
+### `run_dev_apps`
+
+```python
+run_dev_apps(server_spec: str) -> None
+```
+
+
+Start the full dev environment for a FastMCPApp server.
+
+Starts the user's MCP server on *mcp_port*, starts the Prefab dev UI
+on *dev_port* (with an /mcp proxy to the user's server), then opens
+the browser.
+
diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx
index 60804a298..b8bf7e0de 100644
--- a/docs/python-sdk/fastmcp-cli-cli.mdx
+++ b/docs/python-sdk/fastmcp-cli-cli.mdx
@@ -50,7 +50,23 @@ 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`
+### `apps`
+
+```python
+apps(server_spec: str) -> None
+```
+
+
+Preview a FastMCPApp UI in the browser.
+
+Starts the MCP server from SERVER_SPEC on --mcp-port, launches a local
+dev UI on --dev-port with a tool picker and AppBridge host, then opens
+the browser automatically.
+
+Requires fastmcp[apps] to be installed (prefab-ui).
+
+
+### `run`
```python
run(server_spec: str | None = None, *server_args: str) -> None
@@ -75,7 +91,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
@@ -106,7 +122,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-install-claude_code.mdx b/docs/python-sdk/fastmcp-cli-install-claude_code.mdx
index 0a3393077..675faafc4 100644
--- a/docs/python-sdk/fastmcp-cli-install-claude_code.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-claude_code.mdx
@@ -57,7 +57,7 @@ Install FastMCP server in Claude Code.
- True if installation was successful, False otherwise
-### `claude_code_command`
+### `claude_code_command`
```python
claude_code_command(server_spec: str) -> None
diff --git a/docs/python-sdk/fastmcp-cli-install-gemini_cli.mdx b/docs/python-sdk/fastmcp-cli-install-gemini_cli.mdx
index 9cb51f0f4..d80716460 100644
--- a/docs/python-sdk/fastmcp-cli-install-gemini_cli.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-gemini_cli.mdx
@@ -54,7 +54,7 @@ Install FastMCP server in Gemini CLI.
- True if installation was successful, False otherwise
-### `gemini_cli_command`
+### `gemini_cli_command`
```python
gemini_cli_command(server_spec: str) -> None
diff --git a/docs/python-sdk/fastmcp-cli-install-shared.mdx b/docs/python-sdk/fastmcp-cli-install-shared.mdx
index a1fe2119c..b51b0a424 100644
--- a/docs/python-sdk/fastmcp-cli-install-shared.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-shared.mdx
@@ -10,7 +10,19 @@ Shared utilities for install commands.
## Functions
-### `parse_env_var`
+### `validate_server_name`
+
+```python
+validate_server_name(name: str) -> str
+```
+
+
+Validate that a server name is safe for use as a subprocess argument.
+
+Raises SystemExit if the name contains shell metacharacters.
+
+
+### `parse_env_var`
```python
parse_env_var(env_var: str) -> tuple[str, str]
@@ -20,7 +32,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]
@@ -32,7 +44,7 @@ Process common arguments shared by all install commands.
Handles both fastmcp.json config files and traditional file.py:object syntax.
-### `open_deeplink`
+### `open_deeplink`
```python
open_deeplink(url: str) -> bool
diff --git a/docs/python-sdk/fastmcp-client-client.mdx b/docs/python-sdk/fastmcp-client-client.mdx
index 6c3ac689a..efbf56f08 100644
--- a/docs/python-sdk/fastmcp-client-client.mdx
+++ b/docs/python-sdk/fastmcp-client-client.mdx
@@ -7,7 +7,7 @@ sidebarTitle: client
## Classes
-### `ClientSessionState`
+### `ClientSessionState`
Holds all session-related state for a Client instance.
@@ -16,13 +16,13 @@ This allows clean separation of configuration (which is copied) from
session state (which should be fresh for each new client instance).
-### `CallToolResult`
+### `CallToolResult`
Parsed result from a tool call.
-### `Client`
+### `Client`
MCP client that delegates connection management to a Transport instance.
@@ -85,7 +85,7 @@ async with client:
**Methods:**
-#### `session`
+#### `session`
```python
session(self) -> ClientSession
@@ -94,7 +94,7 @@ session(self) -> ClientSession
Get the current active session. Raises RuntimeError if not connected.
-#### `initialize_result`
+#### `initialize_result`
```python
initialize_result(self) -> mcp.types.InitializeResult | None
@@ -103,7 +103,7 @@ initialize_result(self) -> mcp.types.InitializeResult | None
Get the result of the initialization request.
-#### `set_roots`
+#### `set_roots`
```python
set_roots(self, roots: RootsList | RootsHandler) -> None
@@ -112,7 +112,7 @@ set_roots(self, roots: RootsList | RootsHandler) -> None
Set the roots for the client. This does not automatically call `send_roots_list_changed`.
-#### `set_sampling_callback`
+#### `set_sampling_callback`
```python
set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabilities: mcp.types.SamplingCapability | None = None) -> None
@@ -121,7 +121,7 @@ set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabil
Set the sampling callback for the client.
-#### `set_elicitation_callback`
+#### `set_elicitation_callback`
```python
set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
@@ -130,7 +130,7 @@ set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
Set the elicitation callback for the client.
-#### `is_connected`
+#### `is_connected`
```python
is_connected(self) -> bool
@@ -139,7 +139,7 @@ is_connected(self) -> bool
Check if the client is currently connected.
-#### `new`
+#### `new`
```python
new(self) -> Client[ClientTransportT]
@@ -155,7 +155,7 @@ share state with the original client.
- A new Client instance with the same configuration but disconnected state.
-#### `initialize`
+#### `initialize`
```python
initialize(self, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.InitializeResult
@@ -183,13 +183,13 @@ capabilities, protocol version, and optional instructions.
- `RuntimeError`: If the client is not connected or initialization times out.
-#### `close`
+#### `close`
```python
close(self)
```
-#### `ping`
+#### `ping`
```python
ping(self) -> bool
@@ -198,7 +198,7 @@ ping(self) -> bool
Send a ping request.
-#### `cancel`
+#### `cancel`
```python
cancel(self, request_id: str | int, reason: str | None = None) -> None
@@ -207,7 +207,7 @@ cancel(self, request_id: str | int, reason: str | None = None) -> None
Send a cancellation notification for an in-progress request.
-#### `progress`
+#### `progress`
```python
progress(self, progress_token: str | int, progress: float, total: float | None = None, message: str | None = None) -> None
@@ -216,7 +216,7 @@ progress(self, progress_token: str | int, progress: float, total: float | None =
Send a progress notification.
-#### `set_logging_level`
+#### `set_logging_level`
```python
set_logging_level(self, level: mcp.types.LoggingLevel) -> None
@@ -225,7 +225,7 @@ set_logging_level(self, level: mcp.types.LoggingLevel) -> None
Send a logging/setLevel request.
-#### `send_roots_list_changed`
+#### `send_roots_list_changed`
```python
send_roots_list_changed(self) -> None
@@ -234,7 +234,7 @@ send_roots_list_changed(self) -> None
Send a roots/list_changed notification.
-#### `complete_mcp`
+#### `complete_mcp`
```python
complete_mcp(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.CompleteResult
@@ -257,7 +257,7 @@ containing the completion and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `complete`
+#### `complete`
```python
complete(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.Completion
@@ -279,7 +279,7 @@ include with the completion request. Defaults to None.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
diff --git a/docs/python-sdk/fastmcp-client-transports-http.mdx b/docs/python-sdk/fastmcp-client-transports-http.mdx
index a3375240e..6f819138c 100644
--- a/docs/python-sdk/fastmcp-client-transports-http.mdx
+++ b/docs/python-sdk/fastmcp-client-transports-http.mdx
@@ -10,7 +10,7 @@ Streamable HTTP transport for FastMCP Client.
## Classes
-### `StreamableHttpTransport`
+### `StreamableHttpTransport`
Transport implementation that connects to an MCP server via Streamable HTTP Requests.
@@ -18,19 +18,19 @@ Transport implementation that connects to an MCP server via Streamable HTTP Requ
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
```
-#### `get_session_id`
+#### `get_session_id`
```python
get_session_id(self) -> str | None
```
-#### `close`
+#### `close`
```python
close(self)
diff --git a/docs/python-sdk/fastmcp-client-transports-sse.mdx b/docs/python-sdk/fastmcp-client-transports-sse.mdx
index 59c145401..a65dace46 100644
--- a/docs/python-sdk/fastmcp-client-transports-sse.mdx
+++ b/docs/python-sdk/fastmcp-client-transports-sse.mdx
@@ -10,7 +10,7 @@ Server-Sent Events (SSE) transport for FastMCP Client.
## Classes
-### `SSETransport`
+### `SSETransport`
Transport implementation that connects to an MCP server via Server-Sent Events.
@@ -18,7 +18,7 @@ Transport implementation that connects to an MCP server via Server-Sent Events.
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
diff --git a/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx b/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx
index 0553029eb..9dc66b06a 100644
--- a/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx
+++ b/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx
@@ -47,7 +47,7 @@ leave that limit uncapped.
run(self, code: str) -> Any
```
-### `Search`
+### `Search`
Discovery tool factory that searches the catalog by query.
@@ -64,7 +64,7 @@ Defaults to BM25 ranking.
The LLM can override this per call. ``None`` means no limit.
-### `GetSchemas`
+### `GetSchemas`
Discovery tool factory that returns schemas for tools by name.
@@ -78,7 +78,7 @@ types, and required markers.
``"full"`` returns the complete JSON schema.
-### `GetTags`
+### `GetTags`
Discovery tool factory that lists tool tags from the catalog.
@@ -93,7 +93,7 @@ without tags appear under ``"untagged"``.
``"full"`` lists all tools under each tag.
-### `ListTools`
+### `ListTools`
Discovery tool factory that lists all tools in the catalog.
@@ -106,7 +106,7 @@ Discovery tool factory that lists all tools in the catalog.
``"full"`` returns the complete JSON schema.
-### `CodeMode`
+### `CodeMode`
Transform that collapses all tools into discovery + execute meta-tools.
@@ -123,13 +123,13 @@ environment with ``call_tool(name, params)`` in scope.
**Methods:**
-#### `transform_tools`
+#### `transform_tools`
```python
transform_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
```
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
diff --git a/docs/python-sdk/fastmcp-resources-template.mdx b/docs/python-sdk/fastmcp-resources-template.mdx
index 29766c944..06d8ef8ed 100644
--- a/docs/python-sdk/fastmcp-resources-template.mdx
+++ b/docs/python-sdk/fastmcp-resources-template.mdx
@@ -23,7 +23,7 @@ Extract query parameter names from RFC 6570 `{?param1,param2}` syntax.
### `build_regex`
```python
-build_regex(template: str) -> re.Pattern
+build_regex(template: str) -> re.Pattern[str] | None
```
@@ -34,8 +34,11 @@ Supports:
- `{var*}` - wildcard path parameter (captures multiple segments)
- `{?var1,var2}` - query parameters (ignored in path matching)
+Returns None if the template produces an invalid regex (e.g. parameter
+names with hyphens, leading digits, or duplicates from a remote server).
-### `match_uri_template`
+
+### `match_uri_template`
```python
match_uri_template(uri: str, uri_template: str) -> dict[str, str] | None
@@ -51,7 +54,7 @@ Supports RFC 6570 URI templates:
## Classes
-### `ResourceTemplate`
+### `ResourceTemplate`
A template for dynamically creating resources.
@@ -59,13 +62,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: AuthCheck | list[AuthCheck] | None = None) -> FunctionResourceTemplate
```
-#### `set_default_mime_type`
+#### `set_default_mime_type`
```python
set_default_mime_type(cls, mime_type: str | None) -> str
@@ -74,7 +77,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 +86,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 +95,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 +111,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 +123,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 +132,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 +141,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 +150,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 +159,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 +175,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 +189,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 +198,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 +207,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 +219,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 +237,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: AuthCheck | list[AuthCheck] | None = None) -> FunctionResourceTemplate
diff --git a/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx b/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx
index b30f3090b..9ca0d77ad 100644
--- a/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx
@@ -15,7 +15,7 @@ This maintains proper OAuth 2.0 token audience boundaries.
## Functions
-### `derive_jwt_key`
+### `derive_jwt_key`
```python
derive_jwt_key() -> bytes
@@ -27,7 +27,7 @@ Derive JWT signing key from a high-entropy or low-entropy key material and serve
## Classes
-### `JWTIssuer`
+### `JWTIssuer`
Issues and validates FastMCP-signed JWT tokens using HS256.
@@ -39,7 +39,7 @@ a key derived from the upstream client secret.
**Methods:**
-#### `issue_access_token`
+#### `issue_access_token`
```python
issue_access_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int = 3600, upstream_claims: dict[str, Any] | None = None) -> str
@@ -62,7 +62,7 @@ which contains actual user identity and authorization data.
- 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, upstream_claims: dict[str, Any] | None = None) -> str
@@ -85,18 +85,20 @@ token which contains actual user identity and authorization data.
- Signed JWT token
-#### `verify_token`
+#### `verify_token`
```python
-verify_token(self, token: str) -> dict[str, Any]
+verify_token(self, token: str, expected_token_use: str = 'access') -> dict[str, Any]
```
Verify and decode a FastMCP token.
-Validates JWT signature, expiration, issuer, and audience.
+Validates JWT signature, expiration, issuer, audience, and token type.
**Args:**
- `token`: JWT token to verify
+- `expected_token_use`: Expected token type ("access" or "refresh").
+Defaults to "access", which rejects refresh tokens.
**Returns:**
- Decoded token payload
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 8ac1885b2..d675dd066 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
@@ -182,7 +182,7 @@ For unregistered clients, returns None (which will raise an error in the SDK).
CIMD clients (URL-based client IDs) are looked up and cached automatically.
-#### `register_client`
+#### `register_client`
```python
register_client(self, client_info: OAuthClientInformationFull) -> None
@@ -196,7 +196,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
@@ -214,7 +214,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
@@ -226,7 +226,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
@@ -244,7 +244,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
@@ -256,7 +256,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
@@ -273,7 +273,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
@@ -292,7 +292,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
@@ -305,7 +305,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-oidc_proxy.mdx b/docs/python-sdk/fastmcp-server-auth-oidc_proxy.mdx
index a941099ae..a9160db17 100644
--- a/docs/python-sdk/fastmcp-server-auth-oidc_proxy.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-oidc_proxy.mdx
@@ -19,7 +19,7 @@ This implementation is based on:
## Classes
-### `OIDCConfiguration`
+### `OIDCConfiguration`
OIDC Configuration.
@@ -27,7 +27,7 @@ OIDC Configuration.
**Methods:**
-#### `get_oidc_configuration`
+#### `get_oidc_configuration`
```python
get_oidc_configuration(cls, config_url: AnyHttpUrl) -> Self
@@ -41,7 +41,7 @@ Get the OIDC configuration for the specified config URL.
- `timeout_seconds`: HTTP request timeout in seconds
-### `OIDCProxy`
+### `OIDCProxy`
OAuth provider that wraps OAuthProxy to provide configuration via an OIDC configuration URL.
@@ -52,7 +52,7 @@ that is OIDC compliant.
**Methods:**
-#### `get_oidc_configuration`
+#### `get_oidc_configuration`
```python
get_oidc_configuration(self, config_url: AnyHttpUrl, strict: bool | None, timeout_seconds: int | None) -> OIDCConfiguration
@@ -66,7 +66,7 @@ Gets the OIDC configuration for the specified configuration URL.
- `timeout_seconds`: HTTP request timeout in seconds
-#### `get_token_verifier`
+#### `get_token_verifier`
```python
get_token_verifier(self) -> TokenVerifier
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx b/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx
index 140ddd193..350d3f2e6 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx
@@ -31,7 +31,7 @@ Example:
## Classes
-### `Auth0Provider`
+### `Auth0Provider`
An Auth0 provider implementation for FastMCP.
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx b/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx
index fc8b111f6..c8d9ea795 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx
@@ -31,7 +31,7 @@ Example:
## Classes
-### `AWSCognitoTokenVerifier`
+### `AWSCognitoTokenVerifier`
Token verifier that filters claims to Cognito-specific subset.
@@ -39,7 +39,7 @@ Token verifier that filters claims to Cognito-specific subset.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -48,7 +48,7 @@ verify_token(self, token: str) -> AccessToken | None
Verify token and filter claims to Cognito-specific subset.
-### `AWSCognitoProvider`
+### `AWSCognitoProvider`
Complete AWS Cognito OAuth provider for FastMCP.
@@ -66,7 +66,7 @@ Features:
**Methods:**
-#### `get_token_verifier`
+#### `get_token_verifier`
```python
get_token_verifier(self) -> AWSCognitoTokenVerifier
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx
index 4d3140c4a..77ef582c9 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
@@ -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-discord.mdx b/docs/python-sdk/fastmcp-server-auth-providers-discord.mdx
index d35dbf459..57d3b743b 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-discord.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-discord.mdx
@@ -29,7 +29,7 @@ Example:
## Classes
-### `DiscordTokenVerifier`
+### `DiscordTokenVerifier`
Token verifier for Discord OAuth tokens.
@@ -40,7 +40,7 @@ by calling Discord's tokeninfo API to check if they're valid and get user info.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -49,7 +49,7 @@ verify_token(self, token: str) -> AccessToken | None
Verify Discord OAuth token by calling Discord's tokeninfo API.
-### `DiscordProvider`
+### `DiscordProvider`
Complete Discord OAuth provider for FastMCP.
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-github.mdx b/docs/python-sdk/fastmcp-server-auth-providers-github.mdx
index 66a808136..03bd4e4c3 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-github.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-github.mdx
@@ -29,7 +29,7 @@ Example:
## Classes
-### `GitHubTokenVerifier`
+### `GitHubTokenVerifier`
Token verifier for GitHub OAuth tokens.
@@ -40,7 +40,7 @@ by calling GitHub's API to check if they're valid and get user info.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -49,7 +49,7 @@ verify_token(self, token: str) -> AccessToken | None
Verify GitHub OAuth token by calling GitHub API.
-### `GitHubProvider`
+### `GitHubProvider`
Complete GitHub OAuth provider for FastMCP.
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-google.mdx b/docs/python-sdk/fastmcp-server-auth-providers-google.mdx
index 880488438..b9568dbf9 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-google.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-google.mdx
@@ -29,7 +29,7 @@ Example:
## Classes
-### `GoogleTokenVerifier`
+### `GoogleTokenVerifier`
Token verifier for Google OAuth tokens.
@@ -40,7 +40,7 @@ by calling Google's tokeninfo API to check if they're valid and get user info.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -49,7 +49,7 @@ verify_token(self, token: str) -> AccessToken | None
Verify Google OAuth token by calling Google's tokeninfo API.
-### `GoogleProvider`
+### `GoogleProvider`
Complete Google OAuth provider for FastMCP.
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx b/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx
index b88c7c49e..9f1be4fc1 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx
@@ -87,7 +87,7 @@ Example:
## Classes
-### `OCIProvider`
+### `OCIProvider`
An OCI IAM Domain provider implementation for FastMCP.
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx
index 36dec25f5..32cb93e4c 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx
@@ -18,7 +18,7 @@ Choose based on your WorkOS setup and authentication requirements.
## Classes
-### `WorkOSTokenVerifier`
+### `WorkOSTokenVerifier`
Token verifier for WorkOS OAuth tokens.
@@ -29,7 +29,7 @@ the /oauth2/userinfo endpoint to check validity and get user info.
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -38,7 +38,7 @@ verify_token(self, token: str) -> AccessToken | None
Verify WorkOS OAuth token by calling userinfo endpoint.
-### `WorkOSProvider`
+### `WorkOSProvider`
Complete WorkOS OAuth provider for FastMCP.
@@ -59,7 +59,7 @@ Setup Requirements:
4. Note your Client ID and Client Secret
-### `AuthKitProvider`
+### `AuthKitProvider`
AuthKit metadata provider for DCR (Dynamic Client Registration).
@@ -85,7 +85,7 @@ https://workos.com/docs/authkit/mcp/integrating/token-verification
**Methods:**
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self, mcp_path: str | None = None) -> list[Route]
diff --git a/docs/python-sdk/fastmcp-server-low_level.mdx b/docs/python-sdk/fastmcp-server-low_level.mdx
index 7886475a8..7456a5940 100644
--- a/docs/python-sdk/fastmcp-server-low_level.mdx
+++ b/docs/python-sdk/fastmcp-server-low_level.mdx
@@ -15,7 +15,7 @@ ServerSession that routes initialization requests through FastMCP middleware.
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -24,7 +24,7 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-#### `client_supports_extension`
+#### `client_supports_extension`
```python
client_supports_extension(self, extension_id: str) -> bool
@@ -36,11 +36,11 @@ Inspects the ``extensions`` extra field on ``ClientCapabilities``
sent by the client during initialization.
-### `LowLevelServer`
+### `LowLevelServer`
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -49,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
@@ -68,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)
@@ -77,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]]]
@@ -92,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-mixins-lifespan.mdx b/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx
index 9d0eec22e..fe786652c 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-mixins-transport.mdx b/docs/python-sdk/fastmcp-server-mixins-transport.mdx
index c5cc4e2fd..ad4e0b60e 100644
--- a/docs/python-sdk/fastmcp-server-mixins-transport.mdx
+++ b/docs/python-sdk/fastmcp-server-mixins-transport.mdx
@@ -10,7 +10,7 @@ Transport-related methods for FastMCP Server.
## Classes
-### `TransportMixin`
+### `TransportMixin`
Mixin providing transport-related methods for FastMCP.
@@ -20,7 +20,7 @@ Includes HTTP/stdio/SSE transport handling and custom HTTP routes.
**Methods:**
-#### `run_async`
+#### `run_async`
```python
run_async(self: FastMCP, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None
@@ -34,7 +34,7 @@ Run the FastMCP server asynchronously.
FASTMCP_SHOW_SERVER_BANNER setting (default\: True).
-#### `run`
+#### `run`
```python
run(self: FastMCP, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None
@@ -48,7 +48,7 @@ Run the FastMCP server. Note this is a synchronous function.
FASTMCP_SHOW_SERVER_BANNER setting (default\: True).
-#### `custom_route`
+#### `custom_route`
```python
custom_route(self: FastMCP, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True) -> Callable[[Callable[[Request], Awaitable[Response]]], Callable[[Request], Awaitable[Response]]]
@@ -69,7 +69,7 @@ Starlette's reverse URL lookup feature)
- `include_in_schema`: Whether to include in OpenAPI schema, defaults to True
-#### `run_stdio_async`
+#### `run_stdio_async`
```python
run_stdio_async(self: FastMCP, show_banner: bool = True, log_level: str | None = None, stateless: bool = False) -> None
@@ -83,7 +83,7 @@ Run the server using stdio transport.
- `stateless`: Whether to run in stateless mode (no session initialization)
-#### `run_http_async`
+#### `run_http_async`
```python
run_http_async(self: FastMCP, show_banner: bool = True, transport: Literal['http', 'streamable-http', 'sse'] = 'http', host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, stateless: bool | None = None) -> None
@@ -104,7 +104,7 @@ Run the server using HTTP transport.
- `stateless`: Alias for stateless_http for CLI consistency
-#### `http_app`
+#### `http_app`
```python
http_app(self: FastMCP, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http', event_store: EventStore | None = None, retry_interval: int | None = None) -> StarletteWithLifespan
diff --git a/docs/python-sdk/fastmcp-server-providers-proxy.mdx b/docs/python-sdk/fastmcp-server-providers-proxy.mdx
index 96d9a5a9f..d612a9f37 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
@@ -67,7 +67,7 @@ Forward progress notification from remote server to proxy's connected clients.
## Classes
-### `ProxyTool`
+### `ProxyTool`
A Tool that represents and executes a tool on a remote server.
@@ -75,7 +75,7 @@ A Tool that represents and executes a tool on a remote server.
**Methods:**
-#### `model_copy`
+#### `model_copy`
```python
model_copy(self, **kwargs: Any) -> ProxyTool
@@ -84,7 +84,7 @@ model_copy(self, **kwargs: Any) -> ProxyTool
Override to preserve _backend_name when name changes.
-#### `from_mcp_tool`
+#### `from_mcp_tool`
```python
from_mcp_tool(cls, client_factory: ClientFactoryT, mcp_tool: mcp.types.Tool) -> ProxyTool
@@ -93,7 +93,7 @@ from_mcp_tool(cls, client_factory: ClientFactoryT, mcp_tool: mcp.types.Tool) ->
Factory method to create a ProxyTool from a raw MCP tool schema.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResult
@@ -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.
@@ -242,10 +242,20 @@ component instances that forward execution to the remote server.
All components returned by this provider have task_config.mode="forbidden"
because tasks cannot be executed through a proxy.
+Component lists (tools, resources, templates, prompts) are cached so that
+individual lookups (e.g. during ``call_tool``) can resolve from the cache
+instead of opening a new backend connection. The cache stores the
+backend's raw component metadata and is shared across all sessions;
+per-session visibility and auth filtering are applied after cache lookup
+by the server layer. The cache is refreshed whenever a ``list_*`` call
+is made, and entries expire after ``cache_ttl`` seconds (default 300).
+Set ``cache_ttl=0`` to disable caching. Disabling is recommended for
+backends whose component lists change dynamically.
+
**Methods:**
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -258,7 +268,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 +277,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 +285,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 +306,7 @@ it to detect (and correct) staleness.
**Methods:**
-#### `clear`
+#### `clear`
```python
clear(self)
@@ -305,7 +315,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-sampling-sampling_tool.mdx b/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx
index cac91d36e..2a3590003 100644
--- a/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx
+++ b/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx
@@ -10,7 +10,7 @@ SamplingTool for use during LLM sampling requests.
## Classes
-### `SamplingTool`
+### `SamplingTool`
A tool that can be used during LLM sampling.
@@ -37,7 +37,7 @@ Create a SamplingTool explicitly when you need custom name/description:
**Methods:**
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any] | None = None) -> Any
@@ -52,7 +52,7 @@ Execute the tool with the given arguments.
- The result of executing the tool function.
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any]) -> SamplingTool
@@ -79,7 +79,7 @@ concurrently. Defaults to False.
- `ValueError`: If the function is a lambda without a name override.
-#### `from_callable_tool`
+#### `from_callable_tool`
```python
from_callable_tool(cls, tool: FunctionTool | TransformedTool) -> SamplingTool
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index dbfdf6e1c..deff347ad 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
@@ -228,7 +228,7 @@ requested, falls back to the next-highest enabled version.
- The tool if found and enabled, None otherwise.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> Sequence[Resource]
@@ -241,7 +241,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
@@ -263,7 +263,7 @@ requested, falls back to the next-highest enabled version.
- The resource if found and enabled, None otherwise.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> Sequence[ResourceTemplate]
@@ -276,7 +276,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
@@ -298,7 +298,7 @@ requested, falls back to the next-highest enabled version.
- The template if found and enabled, None otherwise.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> Sequence[Prompt]
@@ -311,7 +311,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
@@ -333,19 +333,19 @@ requested, falls back to the next-highest enabled version.
- 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
@@ -375,19 +375,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
@@ -416,19 +416,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
@@ -458,7 +458,7 @@ return PromptResult.
- `PromptError`: If prompt rendering fails
-#### `add_tool`
+#### `add_tool`
```python
add_tool(self, tool: Tool | Callable[..., Any]) -> Tool
@@ -476,7 +476,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
@@ -495,19 +495,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]
@@ -563,7 +563,7 @@ server.tool(my_function, name="custom_name")
```
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource | Callable[..., Any]) -> Resource | ResourceTemplate
@@ -578,7 +578,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
@@ -593,7 +593,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]
@@ -652,7 +652,7 @@ async def get_weather(city: str) -> str:
```
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt
@@ -667,19 +667,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]
@@ -756,7 +756,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
@@ -803,7 +803,7 @@ mounted server.
- `prefix`: Deprecated. Use namespace instead.
-#### `import_server`
+#### `import_server`
```python
import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None
@@ -844,7 +844,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
@@ -873,7 +873,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
@@ -897,7 +897,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
@@ -915,7 +915,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-requests.mdx b/docs/python-sdk/fastmcp-server-tasks-requests.mdx
index 5cde802fc..a8b31a13d 100644
--- a/docs/python-sdk/fastmcp-server-tasks-requests.mdx
+++ b/docs/python-sdk/fastmcp-server-tasks-requests.mdx
@@ -52,7 +52,7 @@ Converts raw task return values to MCP types based on task type.
- MCP result (CallToolResult, GetPromptResult, or ReadResourceResult)
-### `tasks_list_handler`
+### `tasks_list_handler`
```python
tasks_list_handler(server: FastMCP, params: dict[str, Any]) -> ListTasksResult
@@ -71,7 +71,7 @@ Note: With client-side tracking, this returns minimal info.
- Response with tasks list and pagination
-### `tasks_cancel_handler`
+### `tasks_cancel_handler`
```python
tasks_cancel_handler(server: FastMCP, params: dict[str, Any]) -> CancelTaskResult
diff --git a/docs/python-sdk/fastmcp-server-transforms-prompts_as_tools.mdx b/docs/python-sdk/fastmcp-server-transforms-prompts_as_tools.mdx
index f1656c263..dc3b659d0 100644
--- a/docs/python-sdk/fastmcp-server-transforms-prompts_as_tools.mdx
+++ b/docs/python-sdk/fastmcp-server-transforms-prompts_as_tools.mdx
@@ -11,6 +11,10 @@ Transform that exposes prompts as tools.
This transform generates tools for listing and getting prompts, enabling
clients that only support tools to access prompt functionality.
+The generated tools route through `ctx.fastmcp` at runtime, so all server
+middleware (auth, visibility, rate limiting, etc.) applies to prompt
+operations exactly as it would for direct `prompts/get` calls.
+
Example:
```python
from fastmcp import FastMCP
@@ -24,23 +28,26 @@ Example:
## Classes
-### `PromptsAsTools`
+### `PromptsAsTools`
Transform that adds tools for listing and getting prompts.
Generates two tools:
-- `list_prompts`: Lists all prompts from the provider
+- `list_prompts`: Lists all prompts
- `get_prompt`: Gets a specific prompt with optional arguments
-The transform captures a provider reference at construction and queries it
-for prompts when the generated tools are called. When used with FastMCP,
-the provider's auth and visibility filtering is automatically applied.
+The generated tools route through the server at runtime, so auth,
+middleware, and visibility apply automatically.
+
+This transform should be applied to a FastMCP server instance, not
+a raw Provider, because the generated tools need the server's
+middleware chain for auth and visibility filtering.
**Methods:**
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
@@ -49,7 +56,7 @@ list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
Add prompt tools to the tool list.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
diff --git a/docs/python-sdk/fastmcp-server-transforms-resources_as_tools.mdx b/docs/python-sdk/fastmcp-server-transforms-resources_as_tools.mdx
index 3b46e875c..50f0a0c95 100644
--- a/docs/python-sdk/fastmcp-server-transforms-resources_as_tools.mdx
+++ b/docs/python-sdk/fastmcp-server-transforms-resources_as_tools.mdx
@@ -11,6 +11,10 @@ Transform that exposes resources as tools.
This transform generates tools for listing and reading resources, enabling
clients that only support tools to access resource functionality.
+The generated tools route through `ctx.fastmcp` at runtime, so all server
+middleware (auth, visibility, rate limiting, etc.) applies to resource
+operations exactly as it would for direct `resources/read` calls.
+
Example:
```python
from fastmcp import FastMCP
@@ -24,23 +28,26 @@ Example:
## Classes
-### `ResourcesAsTools`
+### `ResourcesAsTools`
Transform that adds tools for listing and reading resources.
Generates two tools:
-- `list_resources`: Lists all resources and templates from the provider
+- `list_resources`: Lists all resources and templates
- `read_resource`: Reads a resource by URI
-The transform captures a provider reference at construction and queries it
-for resources when the generated tools are called. When used with FastMCP,
-the provider's auth and visibility filtering is automatically applied.
+The generated tools route through the server at runtime, so auth,
+middleware, and visibility apply automatically.
+
+This transform should be applied to a FastMCP server instance, not
+a raw Provider, because the generated tools need the server's
+middleware chain for auth and visibility filtering.
**Methods:**
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
@@ -49,7 +56,7 @@ list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
Add resource tools to the tool list.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
diff --git a/docs/python-sdk/fastmcp-settings.mdx b/docs/python-sdk/fastmcp-settings.mdx
index eeb1156f8..f9b0cf26a 100644
--- a/docs/python-sdk/fastmcp-settings.mdx
+++ b/docs/python-sdk/fastmcp-settings.mdx
@@ -7,13 +7,13 @@ sidebarTitle: settings
## Classes
-### `DocketSettings`
+### `DocketSettings`
Docket worker configuration.
-### `Settings`
+### `Settings`
FastMCP settings.
@@ -21,7 +21,7 @@ FastMCP settings.
**Methods:**
-#### `get_setting`
+#### `get_setting`
```python
get_setting(self, attr: str) -> Any
@@ -31,7 +31,7 @@ Get a setting. If the setting contains one or more `__`, it will be
treated as a nested setting.
-#### `set_setting`
+#### `set_setting`
```python
set_setting(self, attr: str, value: Any) -> None
@@ -41,7 +41,7 @@ Set a setting. If the setting contains one or more `__`, it will be
treated as a nested setting.
-#### `normalize_log_level`
+#### `normalize_log_level`
```python
normalize_log_level(cls, v)
diff --git a/docs/python-sdk/fastmcp-tools-tool.mdx b/docs/python-sdk/fastmcp-tools-tool.mdx
index d3bb86176..8b7a0abd2 100644
--- a/docs/python-sdk/fastmcp-tools-tool.mdx
+++ b/docs/python-sdk/fastmcp-tools-tool.mdx
@@ -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-json_schema.mdx b/docs/python-sdk/fastmcp-utilities-json_schema.mdx
index e08643cb9..a8b51f1d0 100644
--- a/docs/python-sdk/fastmcp-utilities-json_schema.mdx
+++ b/docs/python-sdk/fastmcp-utilities-json_schema.mdx
@@ -7,7 +7,7 @@ sidebarTitle: json_schema
## Functions
-### `dereference_refs`
+### `dereference_refs`
```python
dereference_refs(schema: dict[str, Any]) -> dict[str, Any]
@@ -27,6 +27,11 @@ For self-referencing/circular schemas where full dereferencing is not possible,
this function falls back to resolving only the root-level $ref while preserving
$defs for nested references.
+Only local ``$ref`` values (those starting with ``#``) are resolved.
+Remote URIs (``http://``, ``file://``, etc.) are stripped before
+resolution to prevent SSRF / local-file-inclusion attacks when proxying
+schemas from untrusted servers.
+
**Args:**
- `schema`: JSON schema dict that may contain $ref references
@@ -35,7 +40,7 @@ $defs for nested references.
- when no longer needed
-### `resolve_root_ref`
+### `resolve_root_ref`
```python
resolve_root_ref(schema: dict[str, Any]) -> dict[str, Any]
@@ -57,7 +62,7 @@ the referenced definition while preserving $defs for nested references.
- if no resolution is needed
-### `compress_schema`
+### `compress_schema`
```python
compress_schema(schema: dict[str, Any], prune_params: list[str] | None = None, prune_additional_properties: bool = False, prune_titles: bool = False, dereference: bool = False) -> dict[str, Any]
diff --git a/docs/python-sdk/fastmcp-utilities-skills.mdx b/docs/python-sdk/fastmcp-utilities-skills.mdx
index ccb0c83b8..807d07782 100644
--- a/docs/python-sdk/fastmcp-utilities-skills.mdx
+++ b/docs/python-sdk/fastmcp-utilities-skills.mdx
@@ -75,7 +75,7 @@ Creates a subdirectory named after the skill containing all files.
- `FileExistsError`: If skill directory exists and overwrite=False
-### `sync_skills`
+### `sync_skills`
```python
sync_skills(client: Client, target_dir: str | Path) -> list[Path]