diff --git a/docs/python-sdk/fastmcp-client-auth-oauth.mdx b/docs/python-sdk/fastmcp-client-auth-oauth.mdx
index aca8c2e25d..0d94c75132 100644
--- a/docs/python-sdk/fastmcp-client-auth-oauth.mdx
+++ b/docs/python-sdk/fastmcp-client-auth-oauth.mdx
@@ -7,7 +7,7 @@ sidebarTitle: oauth
## Functions
-### `check_if_auth_required`
+### `check_if_auth_required`
```python
check_if_auth_required(mcp_url: str, httpx_kwargs: dict[str, Any] | None = None) -> bool
@@ -22,47 +22,47 @@ Check if the MCP endpoint requires authentication by making a test request.
## Classes
-### `ClientNotFoundError`
+### `ClientNotFoundError`
Raised when OAuth client credentials are not found on the server.
-### `TokenStorageAdapter`
+### `TokenStorageAdapter`
**Methods:**
-#### `clear`
+#### `clear`
```python
clear(self) -> None
```
-#### `get_tokens`
+#### `get_tokens`
```python
get_tokens(self) -> OAuthToken | None
```
-#### `set_tokens`
+#### `set_tokens`
```python
set_tokens(self, tokens: OAuthToken) -> None
```
-#### `get_client_info`
+#### `get_client_info`
```python
get_client_info(self) -> OAuthClientInformationFull | None
```
-#### `set_client_info`
+#### `set_client_info`
```python
set_client_info(self, client_info: OAuthClientInformationFull) -> None
```
-### `OAuth`
+### `OAuth`
OAuth client provider for MCP servers with browser-based authentication.
@@ -73,7 +73,7 @@ a browser for user authorization and running a local callback server.
**Methods:**
-#### `redirect_handler`
+#### `redirect_handler`
```python
redirect_handler(self, authorization_url: str) -> None
@@ -82,7 +82,7 @@ redirect_handler(self, authorization_url: str) -> None
Open browser for authorization, with pre-flight check for invalid client.
-#### `callback_handler`
+#### `callback_handler`
```python
callback_handler(self) -> tuple[str, str | None]
@@ -91,7 +91,7 @@ callback_handler(self) -> tuple[str, str | None]
Handle OAuth callback and return (auth_code, state).
-#### `async_auth_flow`
+#### `async_auth_flow`
```python
async_auth_flow(self, request: httpx.Request) -> AsyncGenerator[httpx.Request, httpx.Response]
diff --git a/docs/python-sdk/fastmcp-prompts-prompt.mdx b/docs/python-sdk/fastmcp-prompts-prompt.mdx
index 8a24524eee..8516742dd0 100644
--- a/docs/python-sdk/fastmcp-prompts-prompt.mdx
+++ b/docs/python-sdk/fastmcp-prompts-prompt.mdx
@@ -8,47 +8,46 @@ sidebarTitle: prompt
Base classes for FastMCP prompts.
-## Functions
+## Classes
-### `Message`
+### `Message`
-```python
-Message(content: str | ContentBlock, role: Role | None = None, **kwargs: Any) -> PromptMessage
-```
+Wrapper for prompt message with auto-serialization.
-A user-friendly constructor for PromptMessage.
+Accepts any content - strings pass through, other types
+(dict, list, BaseModel) are JSON-serialized to text.
-## Classes
+**Methods:**
-### `PromptArgument`
+#### `to_mcp_prompt_message`
+```python
+to_mcp_prompt_message(self) -> PromptMessage
+```
-An argument that can be passed to a prompt.
+Convert to MCP PromptMessage.
-### `PromptResult`
+### `PromptArgument`
-Canonical result type for prompt rendering.
+An argument that can be passed to a prompt.
-This is the internal type that all prompt renders return. It wraps the
-messages with optional description and metadata.
+### `PromptResult`
-**Methods:**
-#### `from_value`
+Canonical result type for prompt rendering.
-```python
-from_value(cls, value: list[PromptMessage] | PromptResult, description: str | None = None, meta: dict[str, Any] | None = None) -> PromptResult
-```
+Provides explicit control over prompt responses: multiple messages,
+roles, and metadata at both the message and result level.
-Convert various types to PromptResult.
+**Methods:**
-#### `to_mcp_prompt_result`
+#### `to_mcp_prompt_result`
```python
to_mcp_prompt_result(self) -> GetPromptResult
@@ -57,7 +56,7 @@ to_mcp_prompt_result(self) -> GetPromptResult
Convert to MCP GetPromptResult.
-### `Prompt`
+### `Prompt`
A prompt template that can be rendered with parameters.
@@ -65,7 +64,7 @@ A prompt template that can be rendered with parameters.
**Methods:**
-#### `to_mcp_prompt`
+#### `to_mcp_prompt`
```python
to_mcp_prompt(self, **overrides: Any) -> SDKPrompt
@@ -74,35 +73,35 @@ to_mcp_prompt(self, **overrides: Any) -> SDKPrompt
Convert the prompt to an MCP prompt.
-#### `from_function`
+#### `from_function`
```python
-from_function(fn: Callable[..., _PromptFnReturn | Awaitable[_PromptFnReturn]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt
+from_function(fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt
```
Create a Prompt from a function.
The function can return:
-- A string (converted to a message)
-- A Message object
-- A dict (converted to a message)
-- A sequence of any of the above
+- str: wrapped as single user Message
+- list\[Message | str]: converted to list\[Message]
+- PromptResult: used directly
-#### `render`
+#### `render`
```python
-render(self, arguments: dict[str, Any] | None = None) -> list[PromptMessage] | PromptResult
+render(self, arguments: dict[str, Any] | None = None) -> str | list[Message | str] | PromptResult
```
Render the prompt with arguments.
-This method is not implemented in the base Prompt class and must be
-implemented by subclasses. The preferred return type is PromptResult,
-but list\[PromptMessage] is still supported for backwards compatibility.
+Subclasses must implement this method. Return one of:
+- str: Wrapped as single user Message
+- list\[Message | str]: Converted to list\[Message]
+- PromptResult: Used directly
-#### `convert_result`
+#### `convert_result`
```python
convert_result(self, raw_value: Any) -> PromptResult
@@ -110,10 +109,11 @@ convert_result(self, raw_value: Any) -> PromptResult
Convert a raw return value to PromptResult.
-Handles PromptResult passthrough and converts raw values to messages.
+**Raises:**
+- `TypeError`: for unsupported types
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -122,7 +122,7 @@ register_with_docket(self, docket: Docket) -> None
Register this prompt with docket for background execution.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, arguments: dict[str, Any] | None, **kwargs: Any) -> Execution
@@ -138,7 +138,7 @@ Schedule this prompt for background execution via docket.
- `**kwargs`: Additional kwargs passed to docket.add()
-### `FunctionPrompt`
+### `FunctionPrompt`
A prompt that is a function.
@@ -146,22 +146,21 @@ A prompt that is a function.
**Methods:**
-#### `from_function`
+#### `from_function`
```python
-from_function(cls, fn: Callable[..., _PromptFnReturn | Awaitable[_PromptFnReturn]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt
+from_function(cls, fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt
```
Create a Prompt from a function.
The function can return:
-- A string (converted to a message)
-- A Message object
-- A dict (converted to a message)
-- A sequence of any of the above
+- str: wrapped as single user Message
+- list\[Message | str]: converted to list\[Message]
+- PromptResult: used directly
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any] | None = None) -> PromptResult
@@ -170,7 +169,7 @@ render(self, arguments: dict[str, Any] | None = None) -> PromptResult
Render the prompt with arguments.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -182,7 +181,7 @@ FunctionPrompt registers the underlying function, which has the user's
Depends parameters for docket to resolve.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, arguments: dict[str, Any] | None, **kwargs: Any) -> Execution
diff --git a/docs/python-sdk/fastmcp-resources-resource.mdx b/docs/python-sdk/fastmcp-resources-resource.mdx
index 8a21b4f6b7..bbd17a04fa 100644
--- a/docs/python-sdk/fastmcp-resources-resource.mdx
+++ b/docs/python-sdk/fastmcp-resources-resource.mdx
@@ -10,58 +10,59 @@ Base classes and interfaces for FastMCP resources.
## Classes
-### `ResourceContent`
+### `ResourceContent`
-Canonical wrapper for resource content.
+Wrapper for resource content with optional MIME type and metadata.
-This is the internal representation for all resource reads. Users can
-return ResourceContent directly for full control, or return simpler types
-(str, bytes, dict) which will be automatically converted.
+Accepts any value for content - strings and bytes pass through directly,
+other types (dict, list, BaseModel, etc.) are automatically JSON-serialized.
**Methods:**
-#### `from_value`
+#### `to_mcp_resource_contents`
```python
-from_value(cls, value: Any, mime_type: str | None = None, meta: dict[str, Any] | None = None) -> ResourceContent
+to_mcp_resource_contents(self, uri: AnyUrl | str) -> mcp.types.TextResourceContents | mcp.types.BlobResourceContents
```
-Convert any value to ResourceContent, handling serialization.
+Convert to MCP resource contents type.
**Args:**
-- `value`: The value to convert. Can be\:
-- ResourceContent\: returned as-is (meta param ignored)
-- str\: text content
-- bytes\: binary content
-- other\: serialized to JSON string
-- `mime_type`: Optional MIME type override. If not provided\:
-- str → "text/plain"
-- bytes → "application/octet-stream"
-- other → "application/json"
-- `meta`: Optional metadata (ignored if value is already ResourceContent)
+- `uri`: The URI of the resource (required by MCP types)
**Returns:**
-- ResourceContent instance
+- TextResourceContents for str content, BlobResourceContents for bytes
+
+### `ResourceResult`
-#### `to_mcp_resource_contents`
+
+Canonical result type for resource reads.
+
+Provides explicit control over resource responses: multiple content items,
+per-item MIME types, and metadata at both the item and result level.
+
+
+**Methods:**
+
+#### `to_mcp_result`
```python
-to_mcp_resource_contents(self, uri: AnyUrl | str) -> mcp.types.TextResourceContents | mcp.types.BlobResourceContents
+to_mcp_result(self, uri: AnyUrl | str) -> mcp.types.ReadResourceResult
```
-Convert to MCP resource contents type.
+Convert to MCP ReadResourceResult.
**Args:**
- `uri`: The URI of the resource (required by MCP types)
**Returns:**
-- TextResourceContents for str content, BlobResourceContents for bytes
+- MCP ReadResourceResult with converted contents
-### `Resource`
+### `Resource`
Base class for all resources.
@@ -69,13 +70,13 @@ Base class for all resources.
**Methods:**
-#### `from_function`
+#### `from_function`
```python
from_function(fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResource
```
-#### `set_default_mime_type`
+#### `set_default_mime_type`
```python
set_default_mime_type(cls, mime_type: str | None) -> str
@@ -84,7 +85,7 @@ set_default_mime_type(cls, mime_type: str | None) -> str
Set default MIME type if not provided.
-#### `set_default_name`
+#### `set_default_name`
```python
set_default_name(self) -> Self
@@ -93,36 +94,37 @@ set_default_name(self) -> Self
Set default name from URI if not provided.
-#### `read`
+#### `read`
```python
-read(self) -> str | bytes | ResourceContent
+read(self) -> str | bytes | ResourceResult
```
Read the resource content.
-This method must be implemented by subclasses. For backwards compatibility,
-subclasses can return str, bytes, or ResourceContent. However, returning
-str or bytes is deprecated - new code should return ResourceContent.
+Subclasses implement this to return resource data. Supported return types:
+ - str: Text content
+ - bytes: Binary content
+ - ResourceResult: Full control over contents and result-level meta
-**Returns:**
-- str | bytes | ResourceContent: The resource content. Returning str
-- or bytes is deprecated; prefer ResourceContent for full control
-- over MIME type and metadata.
-
-#### `convert_result`
+#### `convert_result`
```python
-convert_result(self, raw_value: Any) -> ResourceContent
+convert_result(self, raw_value: Any) -> ResourceResult
```
-Convert a raw return value to ResourceContent.
+Convert a raw result to ResourceResult.
+
+This is used in two contexts:
+1. In _read() to convert user function return values to ResourceResult
+2. In tasks_result_handler() to convert Docket task results to ResourceResult
-Handles ResourceContent passthrough and converts raw values using mime_type.
+Handles ResourceResult passthrough and converts raw values using
+ResourceResult's normalization.
-#### `to_mcp_resource`
+#### `to_mcp_resource`
```python
to_mcp_resource(self, **overrides: Any) -> SDKResource
@@ -131,7 +133,7 @@ to_mcp_resource(self, **overrides: Any) -> SDKResource
Convert the resource to an SDKResource.
-#### `key`
+#### `key`
```python
key(self) -> str
@@ -140,7 +142,7 @@ key(self) -> str
The globally unique lookup key for this resource.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -149,7 +151,7 @@ register_with_docket(self, docket: Docket) -> None
Register this resource with docket for background execution.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, **kwargs: Any) -> Execution
@@ -164,7 +166,7 @@ Schedule this resource for background execution via docket.
- `**kwargs`: Additional kwargs passed to docket.add()
-### `FunctionResource`
+### `FunctionResource`
A resource that defers data loading by wrapping a function.
@@ -181,7 +183,7 @@ The function can return:
**Methods:**
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResource
@@ -190,21 +192,16 @@ from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl, name: str | None =
Create a FunctionResource from a function.
-#### `read`
+#### `read`
```python
-read(self) -> str | bytes | ResourceContent
+read(self) -> str | bytes | ResourceResult
```
Read the resource by calling the wrapped function.
-**Returns:**
-- str | bytes | ResourceContent: The resource content. If the user's
-- function returns str, bytes, dict, etc., it will be wrapped
-- in ResourceContent. Nested Resource reads may return raw types.
-
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
diff --git a/docs/python-sdk/fastmcp-resources-template.mdx b/docs/python-sdk/fastmcp-resources-template.mdx
index e01ab0abbb..e93d9f4be4 100644
--- a/docs/python-sdk/fastmcp-resources-template.mdx
+++ b/docs/python-sdk/fastmcp-resources-template.mdx
@@ -86,7 +86,7 @@ Check if URI matches template and extract parameters.
#### `read`
```python
-read(self, arguments: dict[str, Any]) -> str | bytes
+read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult
```
Read the resource content.
@@ -95,15 +95,20 @@ Read the resource content.
#### `convert_result`
```python
-convert_result(self, raw_value: Any) -> ResourceContent
+convert_result(self, raw_value: Any) -> ResourceResult
```
-Convert a raw return value to ResourceContent.
+Convert a raw result to ResourceResult.
-Handles ResourceContent passthrough and converts raw values using mime_type.
+This is used in two contexts:
+1. In _read() to convert user function return values to ResourceResult
+2. In tasks_result_handler() to convert Docket task results to ResourceResult
+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
@@ -115,7 +120,7 @@ The base implementation does not support background tasks.
Use FunctionResourceTemplate for task support.
-#### `to_mcp_template`
+#### `to_mcp_template`
```python
to_mcp_template(self, **overrides: Any) -> SDKResourceTemplate
@@ -124,7 +129,7 @@ to_mcp_template(self, **overrides: Any) -> SDKResourceTemplate
Convert the resource template to an SDKResourceTemplate.
-#### `from_mcp_template`
+#### `from_mcp_template`
```python
from_mcp_template(cls, mcp_template: SDKResourceTemplate) -> ResourceTemplate
@@ -133,7 +138,7 @@ from_mcp_template(cls, mcp_template: SDKResourceTemplate) -> ResourceTemplate
Creates a FastMCP ResourceTemplate from a raw MCP ResourceTemplate object.
-#### `key`
+#### `key`
```python
key(self) -> str
@@ -142,7 +147,7 @@ key(self) -> str
The globally unique lookup key for this template.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -151,7 +156,7 @@ register_with_docket(self, docket: Docket) -> None
Register this template with docket for background execution.
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution
@@ -167,7 +172,7 @@ Schedule this template for background execution via docket.
- `**kwargs`: Additional kwargs passed to docket.add()
-### `FunctionResourceTemplate`
+### `FunctionResourceTemplate`
A template for dynamically creating resources.
@@ -175,7 +180,7 @@ A template for dynamically creating resources.
**Methods:**
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any]) -> Resource
@@ -184,16 +189,16 @@ 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
+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
@@ -205,7 +210,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
@@ -223,7 +228,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, 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) -> FunctionResourceTemplate
diff --git a/docs/python-sdk/fastmcp-resources-types.mdx b/docs/python-sdk/fastmcp-resources-types.mdx
index 28cf6ff61d..c6aabe7a6f 100644
--- a/docs/python-sdk/fastmcp-resources-types.mdx
+++ b/docs/python-sdk/fastmcp-resources-types.mdx
@@ -21,13 +21,13 @@ A resource that reads from a string.
#### `read`
```python
-read(self) -> ResourceContent
+read(self) -> ResourceResult
```
Read the text content.
-### `BinaryResource`
+### `BinaryResource`
A resource that reads from bytes.
@@ -35,16 +35,16 @@ A resource that reads from bytes.
**Methods:**
-#### `read`
+#### `read`
```python
-read(self) -> ResourceContent
+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,16 +72,16 @@ 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) -> ResourceContent
+read(self) -> ResourceResult
```
Read the file content.
-### `HttpResource`
+### `HttpResource`
A resource that reads from an HTTP endpoint.
@@ -89,16 +89,16 @@ A resource that reads from an HTTP endpoint.
**Methods:**
-#### `read`
+#### `read`
```python
-read(self) -> ResourceContent
+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,10 +124,10 @@ list_files(self) -> list[Path]
List files in the directory.
-#### `read`
+#### `read`
```python
-read(self) -> ResourceContent
+read(self) -> ResourceResult
```
Read the directory listing.
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx b/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx
index 356504ada2..f8bad3ede1 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 e4b3637e4f..4260e9aa87 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) -> TokenVerifier
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx
index dc86cb301d..411a17550d 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.
## Classes
-### `AzureProvider`
+### `AzureProvider`
Azure (Microsoft Entra) OAuth provider for FastMCP.
@@ -49,7 +49,7 @@ Setup:
**Methods:**
-#### `authorize`
+#### `authorize`
```python
authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-descope.mdx b/docs/python-sdk/fastmcp-server-auth-providers-descope.mdx
index cf122ae85f..ece4c16fda 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-descope.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-descope.mdx
@@ -15,7 +15,7 @@ for seamless MCP client authentication.
## Classes
-### `DescopeProvider`
+### `DescopeProvider`
Descope metadata provider for DCR (Dynamic Client Registration).
@@ -43,7 +43,7 @@ https://docs.descope.com/identity-federation/inbound-apps/creating-inbound-apps#
**Methods:**
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self, mcp_path: str | None = None) -> list[Route]
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-discord.mdx b/docs/python-sdk/fastmcp-server-auth-providers-discord.mdx
index bb4839cfec..cc9e47523e 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 b0ae5806d5..e67657b7c5 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 89383de69c..551bcde4ff 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-introspection.mdx b/docs/python-sdk/fastmcp-server-auth-providers-introspection.mdx
index 603e537f69..2a0d2e22d9 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-introspection.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-introspection.mdx
@@ -31,7 +31,7 @@ Example:
## Classes
-### `IntrospectionTokenVerifier`
+### `IntrospectionTokenVerifier`
OAuth 2.0 Token Introspection verifier (RFC 7662).
@@ -52,7 +52,7 @@ Use this when:
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx b/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx
index 610c658a47..9ea8f27018 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx
@@ -10,19 +10,19 @@ TokenVerifier implementations for FastMCP.
## Classes
-### `JWKData`
+### `JWKData`
JSON Web Key data structure.
-### `JWKSData`
+### `JWKSData`
JSON Web Key Set data structure.
-### `RSAKeyPair`
+### `RSAKeyPair`
RSA key pair for JWT testing.
@@ -30,7 +30,7 @@ RSA key pair for JWT testing.
**Methods:**
-#### `generate`
+#### `generate`
```python
generate(cls) -> RSAKeyPair
@@ -42,7 +42,7 @@ Generate an RSA key pair for testing.
- Generated key pair
-#### `create_token`
+#### `create_token`
```python
create_token(self, subject: str = 'fastmcp-user', issuer: str = 'https://fastmcp.example.com', audience: str | list[str] | None = None, scopes: list[str] | None = None, expires_in_seconds: int = 3600, additional_claims: dict[str, Any] | None = None, kid: str | None = None) -> str
@@ -60,7 +60,7 @@ Generate a test JWT token for testing purposes.
- `kid`: Key ID to include in header
-### `JWTVerifier`
+### `JWTVerifier`
JWT token verifier supporting both asymmetric (RSA/ECDSA) and symmetric (HMAC) algorithms.
@@ -82,7 +82,7 @@ Use this when:
**Methods:**
-#### `load_access_token`
+#### `load_access_token`
```python
load_access_token(self, token: str) -> AccessToken | None
@@ -97,7 +97,7 @@ Validate a JWT bearer token and return an AccessToken when the token is valid.
- AccessToken | None: An AccessToken populated from token claims if the token is valid; `None` if the token is expired, has an invalid signature or format, fails issuer/audience/scope validation, or any other validation error occurs.
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
@@ -115,7 +115,7 @@ to our existing load_access_token method.
- AccessToken object if valid, None if invalid or expired
-### `StaticTokenVerifier`
+### `StaticTokenVerifier`
Simple static token verifier for testing and development.
@@ -136,7 +136,7 @@ WARNING: Never use this in production - tokens are stored in plain text!
**Methods:**
-#### `verify_token`
+#### `verify_token`
```python
verify_token(self, token: str) -> AccessToken | None
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx b/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx
index 9d767dae3a..6d6ef728e4 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx
@@ -33,16 +33,16 @@ Example:
logger = get_logger(__name__)
# Load configuration from environment
- OCI_CONFIG_URL = os.environ.get("OCI_CONFIG_URL")
- OCI_CLIENT_ID = os.environ.get("OCI_CLIENT_ID")
- OCI_CLIENT_SECRET = os.environ.get("OCI_CLIENT_SECRET")
- OCI_IAM_GUID = os.environ.get("OCI_IAM_GUID")
+ config_url = os.environ.get("OCI_CONFIG_URL") # OCI IAM Domain OIDC discovery URL
+ client_id = os.environ.get("OCI_CLIENT_ID") # Client ID configured for the OCI IAM Domain Integrated Application
+ client_secret = os.environ.get("OCI_CLIENT_SECRET") # Client secret configured for the OCI IAM Domain Integrated Application
+ iam_guid = os.environ.get("OCI_IAM_GUID") # IAM GUID configured for the OCI IAM Domain
# Simple OCI OIDC protection
auth = OCIProvider(
- config_url=OCI_CONFIG_URL, # config URL is the OCI IAM Domain OIDC discovery URL
- client_id=OCI_CLIENT_ID, # This is same as the client ID configured for the OCI IAM Domain Integrated Application
- client_secret=OCI_CLIENT_SECRET, # This is same as the client secret configured for the OCI IAM Domain Integrated Application
+ config_url=config_url, # config URL is the OCI IAM Domain OIDC discovery URL
+ client_id=client_id, # This is same as the client ID configured for the OCI IAM Domain Integrated Application
+ client_secret=client_secret, # This is same as the client secret configured for the OCI IAM Domain Integrated Application
required_scopes=["openid", "profile", "email"],
redirect_path="/auth/callback",
base_url="http://localhost:8000",
@@ -69,9 +69,9 @@ Example:
logger.debug(f"Creating new signer for token ID: {tokenID}")
signer = TokenExchangeSigner(
jwt_or_func=token,
- oci_domain_id=OCI_IAM_GUID.split(".")[0] if OCI_IAM_GUID else "", # This is same as IAM GUID configured for the OCI IAM Domain
- client_id=OCI_CLIENT_ID, # This is same as the client ID configured for the OCI IAM Domain Integrated Application
- client_secret=OCI_CLIENT_SECRET # This is same as the client secret configured for the OCI IAM Domain Integrated Application
+ oci_domain_id=iam_guid.split(".")[0] if iam_guid else None, # This is same as IAM GUID configured for the OCI IAM Domain
+ client_id=client_id, # This is same as the client ID configured for the OCI IAM Domain Integrated Application
+ client_secret=client_secret, # This is same as the client secret configured for the OCI IAM Domain Integrated Application
)
logger.debug(f"Signer {signer} created for token ID: {tokenID}")
@@ -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-scalekit.mdx b/docs/python-sdk/fastmcp-server-auth-providers-scalekit.mdx
index 50f9f3c4d9..a36e35e427 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-scalekit.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-scalekit.mdx
@@ -15,7 +15,7 @@ authentication for seamless MCP client authentication.
## Classes
-### `ScalekitProvider`
+### `ScalekitProvider`
Scalekit resource server provider for OAuth 2.1 authentication.
@@ -44,7 +44,7 @@ https://docs.scalekit.com/mcp/overview/
**Methods:**
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self, mcp_path: str | None = None) -> list[Route]
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-supabase.mdx b/docs/python-sdk/fastmcp-server-auth-providers-supabase.mdx
index f803af1d58..630f8e0a05 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-supabase.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-supabase.mdx
@@ -15,7 +15,7 @@ for seamless MCP client authentication.
## Classes
-### `SupabaseProvider`
+### `SupabaseProvider`
Supabase metadata provider for DCR (Dynamic Client Registration).
@@ -49,7 +49,7 @@ https://supabase.com/docs/guides/auth/jwts
**Methods:**
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self, mcp_path: str | None = None) -> list[Route]
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx
index dce09b8b57..afd05187f3 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-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx
index 112c89c70e..fe55722632 100644
--- a/docs/python-sdk/fastmcp-server-context.mdx
+++ b/docs/python-sdk/fastmcp-server-context.mdx
@@ -163,10 +163,10 @@ Get a prompt by name with optional arguments.
- The prompt result
-#### `read_resource`
+#### `read_resource`
```python
-read_resource(self, uri: str | AnyUrl) -> list[ResourceContent]
+read_resource(self, uri: str | AnyUrl) -> ResourceResult
```
Read a resource by URI.
@@ -175,10 +175,10 @@ Read a resource by URI.
- `uri`: Resource URI to read
**Returns:**
-- List of ResourceContent objects
+- 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
@@ -196,7 +196,7 @@ Messages sent to Clients are also logged to the `fastmcp.server.context.to_clien
- `extra`: Optional mapping for additional arguments
-#### `client_id`
+#### `client_id`
```python
client_id(self) -> str | None
@@ -205,7 +205,7 @@ client_id(self) -> str | None
Get the client ID if available.
-#### `request_id`
+#### `request_id`
```python
request_id(self) -> str
@@ -216,7 +216,7 @@ Get the unique ID for this request.
Raises RuntimeError if MCP request context is not available.
-#### `session_id`
+#### `session_id`
```python
session_id(self) -> str
@@ -233,7 +233,7 @@ the same client session.
- for other transports.
-#### `session`
+#### `session`
```python
session(self) -> ServerSession
@@ -244,7 +244,7 @@ Access to the underlying session for advanced usage.
Raises RuntimeError if MCP request context is not available.
-#### `debug`
+#### `debug`
```python
debug(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -255,7 +255,7 @@ Send a `DEBUG`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `info`
+#### `info`
```python
info(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -266,7 +266,7 @@ Send a `INFO`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `warning`
+#### `warning`
```python
warning(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -277,7 +277,7 @@ Send a `WARNING`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `error`
+#### `error`
```python
error(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -288,7 +288,7 @@ Send a `ERROR`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `list_roots`
+#### `list_roots`
```python
list_roots(self) -> list[Root]
@@ -297,7 +297,7 @@ list_roots(self) -> list[Root]
List the roots available to the server, as indicated by the client.
-#### `send_notification`
+#### `send_notification`
```python
send_notification(self, notification: mcp.types.ServerNotificationType) -> None
@@ -313,7 +313,7 @@ for the background flusher.
- `notification`: An MCP notification instance (e.g., ToolListChangedNotification())
-#### `send_notification_sync`
+#### `send_notification_sync`
```python
send_notification_sync(self, notification: mcp.types.ServerNotificationType) -> None
@@ -328,7 +328,7 @@ sent within ~1 second by the background flusher.
- `notification`: An MCP notification instance (e.g., ToolListChangedNotification())
-#### `close_sse_stream`
+#### `close_sse_stream`
```python
close_sse_stream(self) -> None
@@ -346,7 +346,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
@@ -383,7 +383,7 @@ Tools can raise ToolError to bypass masking.
- - .text: The text content (if any)
-#### `sample`
+#### `sample`
```python
sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ResultT]
@@ -392,7 +392,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]
@@ -401,7 +401,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]
@@ -443,43 +443,43 @@ Tools can raise ToolError to bypass masking.
- - .history: All messages exchanged during sampling
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: None) -> AcceptedElicitation[dict[str, Any]] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: type[T]) -> AcceptedElicitation[T] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: list[str]) -> AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: dict[str, dict[str, str]]) -> AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: list[list[str]]) -> AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: list[dict[str, dict[str, str]]]) -> AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation
```
-#### `elicit`
+#### `elicit`
```python
elicit(self, message: str, response_type: type[T] | list[str] | dict[str, dict[str, str]] | list[list[str]] | list[dict[str, dict[str, str]]] | None = None) -> AcceptedElicitation[T] | AcceptedElicitation[dict[str, Any]] | AcceptedElicitation[str] | AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation
@@ -508,7 +508,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
@@ -517,7 +517,7 @@ set_state(self, key: str, value: Any) -> None
Set a value in the context state.
-#### `get_state`
+#### `get_state`
```python
get_state(self, key: str) -> Any
diff --git a/docs/python-sdk/fastmcp-server-dependencies.mdx b/docs/python-sdk/fastmcp-server-dependencies.mdx
index 6c7478ccde..125ba2ecb3 100644
--- a/docs/python-sdk/fastmcp-server-dependencies.mdx
+++ b/docs/python-sdk/fastmcp-server-dependencies.mdx
@@ -7,7 +7,7 @@ sidebarTitle: dependencies
## Functions
-### `without_injected_parameters`
+### `without_injected_parameters`
```python
without_injected_parameters(fn: Callable[..., Any]) -> Callable[..., Any]
@@ -28,7 +28,7 @@ Context injection when called.
- 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]
@@ -52,27 +52,13 @@ providing values for dependency parameter names. This is a security feature.
which will be filtered out)
-### `get_context`
+### `get_context`
```python
get_context() -> Context
```
-### `get_task_metadata`
-
-```python
-get_task_metadata() -> dict[str, Any] | None
-```
-
-
-Get the current task metadata from the context.
-
-**Returns:**
-- The task metadata dict if this is a background task request,
-- or None if this is a normal execution.
-
-
-### `CurrentContext`
+### `CurrentContext`
```python
CurrentContext() -> Context
@@ -91,7 +77,7 @@ current MCP operation (tool/resource/prompt call).
- `RuntimeError`: If no active context found (during resolution)
-### `CurrentDocket`
+### `CurrentDocket`
```python
CurrentDocket() -> Docket
@@ -110,7 +96,7 @@ automatically creates for background task scheduling.
- `RuntimeError`: If not within a FastMCP server context
-### `CurrentWorker`
+### `CurrentWorker`
```python
CurrentWorker() -> Worker
@@ -129,7 +115,7 @@ automatically creates for background task processing.
- `RuntimeError`: If not within a FastMCP server context
-### `CurrentFastMCP`
+### `CurrentFastMCP`
```python
CurrentFastMCP()
@@ -147,7 +133,7 @@ This dependency provides access to the active FastMCP server.
- `RuntimeError`: If no server in context (during resolution)
-### `get_server`
+### `get_server`
```python
get_server()
@@ -163,13 +149,13 @@ Get the current FastMCP server instance directly.
- `RuntimeError`: If no server in context
-### `get_http_request`
+### `get_http_request`
```python
get_http_request() -> Request
```
-### `get_http_headers`
+### `get_http_headers`
```python
get_http_headers(include_all: bool = False) -> dict[str, str]
@@ -185,7 +171,7 @@ By default, strips problematic headers like `content-length` that cause issues i
If `include_all` is True, all headers are returned.
-### `get_access_token`
+### `get_access_token`
```python
get_access_token() -> AccessToken | None
@@ -205,7 +191,7 @@ request is available.
## Classes
-### `InMemoryProgress`
+### `InMemoryProgress`
In-memory progress tracker for immediate tool execution.
@@ -217,25 +203,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
@@ -244,7 +230,7 @@ set_total(self, total: int) -> None
Set the total/target value for progress tracking.
-#### `increment`
+#### `increment`
```python
increment(self, amount: int = 1) -> None
@@ -253,7 +239,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
@@ -262,7 +248,7 @@ set_message(self, message: str | None) -> None
Update the progress status message.
-### `Progress`
+### `Progress`
FastMCP Progress dependency that works in both server and worker contexts.
diff --git a/docs/python-sdk/fastmcp-server-low_level.mdx b/docs/python-sdk/fastmcp-server-low_level.mdx
index a85c403d3a..40ef65ff11 100644
--- a/docs/python-sdk/fastmcp-server-low_level.mdx
+++ b/docs/python-sdk/fastmcp-server-low_level.mdx
@@ -7,7 +7,7 @@ sidebarTitle: low_level
## Classes
-### `MiddlewareServerSession`
+### `MiddlewareServerSession`
ServerSession that routes initialization requests through FastMCP middleware.
@@ -15,7 +15,7 @@ ServerSession that routes initialization requests through FastMCP middleware.
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -24,11 +24,11 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-### `LowLevelServer`
+### `LowLevelServer`
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -37,13 +37,13 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-#### `create_initialization_options`
+#### `create_initialization_options`
```python
create_initialization_options(self, notification_options: NotificationOptions | None = None, experimental_capabilities: dict[str, dict[str, Any]] | None = None, **kwargs: Any) -> InitializationOptions
```
-#### `run`
+#### `run`
```python
run(self, read_stream: MemoryObjectReceiveStream[SessionMessage | Exception], write_stream: MemoryObjectSendStream[SessionMessage], initialization_options: InitializationOptions, raise_exceptions: bool = False, stateless: bool = False)
@@ -51,3 +51,33 @@ run(self, read_stream: MemoryObjectReceiveStream[SessionMessage | Exception], wr
Overrides the run method to use the MiddlewareServerSession.
+
+#### `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]]]
+```
+
+Decorator for registering a read_resource handler with CreateTaskResult support.
+
+The MCP SDK's read_resource decorator does not support returning CreateTaskResult
+for background task execution. This decorator wraps the result in ServerResult.
+
+This decorator can be removed once the MCP SDK adds native CreateTaskResult support
+for resources.
+
+
+#### `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]]]
+```
+
+Decorator for registering a get_prompt handler with CreateTaskResult support.
+
+The MCP SDK's get_prompt decorator does not support returning CreateTaskResult
+for background task execution. This decorator wraps the result in ServerResult.
+
+This decorator can be removed once the MCP SDK adds native CreateTaskResult support
+for prompts.
+
diff --git a/docs/python-sdk/fastmcp-server-middleware-caching.mdx b/docs/python-sdk/fastmcp-server-middleware-caching.mdx
index 58b15ce607..8a997b6dfe 100644
--- a/docs/python-sdk/fastmcp-server-middleware-caching.mdx
+++ b/docs/python-sdk/fastmcp-server-middleware-caching.mdx
@@ -10,99 +10,131 @@ A middleware for response caching.
## Classes
-### `CachableReadResourceContents`
+### `CachableResourceContent`
A wrapper for ResourceContent that can be cached.
+### `CachableResourceResult`
+
+
+A wrapper for ResourceResult that can be cached.
+
+
**Methods:**
-#### `get_size`
+#### `get_size`
```python
get_size(self) -> int
```
-#### `get_sizes`
+#### `wrap`
+
+```python
+wrap(cls, value: ResourceResult) -> Self
+```
+
+#### `unwrap`
```python
-get_sizes(cls, values: Sequence[Self]) -> int
+unwrap(self) -> ResourceResult
```
-#### `wrap`
+### `CachableToolResult`
+
+**Methods:**
+
+#### `wrap`
```python
-wrap(cls, values: Sequence[ResourceContent]) -> list[Self]
+wrap(cls, value: ToolResult) -> Self
```
-#### `unwrap`
+#### `unwrap`
```python
-unwrap(cls, values: Sequence[Self]) -> list[ResourceContent]
+unwrap(self) -> ToolResult
```
-### `CachableToolResult`
+### `CachableMessage`
+
+
+A wrapper for Message that can be cached.
+
+
+### `CachablePromptResult`
+
+
+A wrapper for PromptResult that can be cached.
+
**Methods:**
-#### `wrap`
+#### `get_size`
```python
-wrap(cls, value: ToolResult) -> Self
+get_size(self) -> int
```
-#### `unwrap`
+#### `wrap`
```python
-unwrap(self) -> ToolResult
+wrap(cls, value: PromptResult) -> Self
+```
+
+#### `unwrap`
+
+```python
+unwrap(self) -> PromptResult
```
-### `SharedMethodSettings`
+### `SharedMethodSettings`
Shared config for a cache method.
-### `ListToolsSettings`
+### `ListToolsSettings`
Configuration options for Tool-related caching.
-### `ListResourcesSettings`
+### `ListResourcesSettings`
Configuration options for Resource-related caching.
-### `ListPromptsSettings`
+### `ListPromptsSettings`
Configuration options for Prompt-related caching.
-### `CallToolSettings`
+### `CallToolSettings`
Configuration options for Tool-related caching.
-### `ReadResourceSettings`
+### `ReadResourceSettings`
Configuration options for Resource-related caching.
-### `GetPromptSettings`
+### `GetPromptSettings`
Configuration options for Prompt-related caching.
-### `ResponseCachingStatistics`
+### `ResponseCachingStatistics`
-### `ResponseCachingMiddleware`
+### `ResponseCachingMiddleware`
The response caching middleware offers a simple way to cache responses to mcp methods. The Middleware
@@ -119,7 +151,7 @@ Notes:
**Methods:**
-#### `on_list_tools`
+#### `on_list_tools`
```python
on_list_tools(self, context: MiddlewareContext[mcp.types.ListToolsRequest], call_next: CallNext[mcp.types.ListToolsRequest, Sequence[Tool]]) -> Sequence[Tool]
@@ -129,7 +161,7 @@ List tools from the cache, if caching is enabled, and the result is in the cache
otherwise call the next middleware and store the result in the cache if caching is enabled.
-#### `on_list_resources`
+#### `on_list_resources`
```python
on_list_resources(self, context: MiddlewareContext[mcp.types.ListResourcesRequest], call_next: CallNext[mcp.types.ListResourcesRequest, Sequence[Resource]]) -> Sequence[Resource]
@@ -139,7 +171,7 @@ List resources from the cache, if caching is enabled, and the result is in the c
otherwise call the next middleware and store the result in the cache if caching is enabled.
-#### `on_list_prompts`
+#### `on_list_prompts`
```python
on_list_prompts(self, context: MiddlewareContext[mcp.types.ListPromptsRequest], call_next: CallNext[mcp.types.ListPromptsRequest, Sequence[Prompt]]) -> Sequence[Prompt]
@@ -149,7 +181,7 @@ List prompts from the cache, if caching is enabled, and the result is in the cac
otherwise call the next middleware and store the result in the cache if caching is enabled.
-#### `on_call_tool`
+#### `on_call_tool`
```python
on_call_tool(self, context: MiddlewareContext[mcp.types.CallToolRequestParams], call_next: CallNext[mcp.types.CallToolRequestParams, ToolResult]) -> ToolResult
@@ -159,17 +191,17 @@ Call a tool from the cache, if caching is enabled, and the result is in the cach
otherwise call the next middleware and store the result in the cache if caching is enabled.
-#### `on_read_resource`
+#### `on_read_resource`
```python
-on_read_resource(self, context: MiddlewareContext[mcp.types.ReadResourceRequestParams], call_next: CallNext[mcp.types.ReadResourceRequestParams, Sequence[ResourceContent]]) -> Sequence[ResourceContent]
+on_read_resource(self, context: MiddlewareContext[mcp.types.ReadResourceRequestParams], call_next: CallNext[mcp.types.ReadResourceRequestParams, ResourceResult]) -> ResourceResult
```
Read a resource from the cache, if caching is enabled, and the result is in the cache. Otherwise,
otherwise call the next middleware and store the result in the cache if caching is enabled.
-#### `on_get_prompt`
+#### `on_get_prompt`
```python
on_get_prompt(self, context: MiddlewareContext[mcp.types.GetPromptRequestParams], call_next: CallNext[mcp.types.GetPromptRequestParams, PromptResult]) -> PromptResult
@@ -179,7 +211,7 @@ Get a prompt from the cache, if caching is enabled, and the result is in the cac
otherwise call the next middleware and store the result in the cache if caching is enabled.
-#### `statistics`
+#### `statistics`
```python
statistics(self) -> ResponseCachingStatistics
diff --git a/docs/python-sdk/fastmcp-server-middleware-middleware.mdx b/docs/python-sdk/fastmcp-server-middleware-middleware.mdx
index 9f5f8fd0fe..5022617ada 100644
--- a/docs/python-sdk/fastmcp-server-middleware-middleware.mdx
+++ b/docs/python-sdk/fastmcp-server-middleware-middleware.mdx
@@ -78,7 +78,7 @@ on_call_tool(self, context: MiddlewareContext[mt.CallToolRequestParams], call_ne
#### `on_read_resource`
```python
-on_read_resource(self, context: MiddlewareContext[mt.ReadResourceRequestParams], call_next: CallNext[mt.ReadResourceRequestParams, Sequence[ResourceContent]]) -> Sequence[ResourceContent]
+on_read_resource(self, context: MiddlewareContext[mt.ReadResourceRequestParams], call_next: CallNext[mt.ReadResourceRequestParams, ResourceResult]) -> ResourceResult
```
#### `on_get_prompt`
diff --git a/docs/python-sdk/fastmcp-server-middleware-tool_injection.mdx b/docs/python-sdk/fastmcp-server-middleware-tool_injection.mdx
index 9e2c663c1b..a39a62c193 100644
--- a/docs/python-sdk/fastmcp-server-middleware-tool_injection.mdx
+++ b/docs/python-sdk/fastmcp-server-middleware-tool_injection.mdx
@@ -43,7 +43,7 @@ List resources available on the server.
### `read_resource`
```python
-read_resource(context: Context, uri: Annotated[AnyUrl | str, 'The URI of the resource to read.']) -> list[ResourceContent]
+read_resource(context: Context, uri: Annotated[AnyUrl | str, 'The URI of the resource to read.']) -> ResourceResult
```
diff --git a/docs/python-sdk/fastmcp-server-providers-base.mdx b/docs/python-sdk/fastmcp-server-providers-base.mdx
index d7af88d69a..12c036a084 100644
--- a/docs/python-sdk/fastmcp-server-providers-base.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-base.mdx
@@ -36,7 +36,7 @@ Example:
## Classes
-### `Provider`
+### `Provider`
Base class for dynamic component providers.
@@ -48,7 +48,7 @@ supports.
**Methods:**
-#### `with_transforms`
+#### `with_transforms`
```python
with_transforms(self) -> Provider
@@ -70,7 +70,7 @@ use the specified name instead of namespace prefixing.
- A TransformingProvider wrapping this provider.
-#### `with_namespace`
+#### `with_namespace`
```python
with_namespace(self, namespace: str) -> Provider
@@ -85,7 +85,7 @@ Shorthand for with_transforms(namespace=...).
- A TransformingProvider wrapping this provider.
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> Sequence[Tool]
@@ -96,7 +96,7 @@ Return all available tools.
Override to provide tools dynamically.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str) -> Tool | None
@@ -111,7 +111,7 @@ Override for more efficient single-tool lookup.
- The Tool if found, or None to continue searching other providers.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> Sequence[Resource]
@@ -122,7 +122,7 @@ Return all available resources.
Override to provide resources dynamically.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str) -> Resource | None
@@ -137,7 +137,7 @@ Override for more efficient single-resource lookup.
- The Resource if found, or None to continue searching other providers.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> Sequence[ResourceTemplate]
@@ -148,7 +148,7 @@ Return all available resource templates.
Override to provide resource templates dynamically.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str) -> ResourceTemplate | None
@@ -164,7 +164,7 @@ Override for more efficient lookup.
- The ResourceTemplate if a matching one is found, or None to continue searching.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> Sequence[Prompt]
@@ -175,7 +175,7 @@ Return all available prompts.
Override to provide prompts dynamically.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str) -> Prompt | None
@@ -190,7 +190,7 @@ Override for more efficient single-prompt lookup.
- The Prompt if found, or None to continue searching other providers.
-#### `get_component`
+#### `get_component`
```python
get_component(self, key: str) -> Tool | Resource | ResourceTemplate | Prompt | None
@@ -205,7 +205,7 @@ Get a component by its prefixed key.
- The component if found, or None to continue searching other providers.
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -214,13 +214,13 @@ get_tasks(self) -> Sequence[FastMCPComponent]
Return components that should be registered as background tasks.
Override to customize which components are task-eligible.
-Default calls list_* methods and filters for function-based components
+Default calls list_* methods and filters for components
with task_config.mode != 'forbidden'.
Used by the server during startup to register functions with Docket.
-#### `lifespan`
+#### `lifespan`
```python
lifespan(self) -> AsyncIterator[None]
@@ -236,7 +236,7 @@ The lifespan scope matches the server's lifespan - code before yield
runs at startup, code after yield runs at shutdown.
-#### `enable`
+#### `enable`
```python
enable(self) -> None
@@ -250,7 +250,7 @@ Enable components by removing from blocklist, or set allowlist with only=True.
- `only`: If True, switches to allowlist mode - ONLY show these keys/tags.
-#### `disable`
+#### `disable`
```python
disable(self) -> None
diff --git a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
index a93457ff56..32f940c040 100644
--- a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
@@ -18,7 +18,7 @@ executed.
## Classes
-### `FastMCPProviderTool`
+### `FastMCPProviderTool`
Tool that delegates execution to a wrapped server's middleware.
@@ -30,7 +30,7 @@ chain is executed.
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, tool: Tool) -> FastMCPProviderTool
@@ -39,31 +39,30 @@ wrap(cls, server: Any, tool: Tool) -> FastMCPProviderTool
Wrap a Tool to delegate execution to the server's middleware.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult | mcp.types.CreateTaskResult
```
-Delegate to child server's middleware chain.
+Not implemented - use _run() which delegates to child server.
-This runs BEFORE any backgrounding decision - the actual underlying
-tool will check contextvars and submit to Docket if appropriate.
+FastMCPProviderTool._run() handles all execution by delegating
+to the child server's call_tool() with task_meta.
-### `FastMCPProviderResource`
+### `FastMCPProviderResource`
-Resource that delegates reading to a wrapped server's middleware.
+Resource that delegates reading to a wrapped server's read_resource().
When `read()` is called, this resource invokes the wrapped server's
-`_read_resource_middleware()` method, ensuring the server's middleware
-chain is executed.
+`read_resource()` method, ensuring the server's middleware chain is executed.
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource
@@ -72,37 +71,18 @@ wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource
Wrap a Resource to delegate reading to the server's middleware.
-#### `read`
-
-```python
-read(self) -> ResourceContent | mcp.types.CreateTaskResult
-```
-
-Delegate to child server's middleware.
-
-When called from a Docket worker (background task), there's no FastMCP
-context set up, so we create one for the child server.
+### `FastMCPProviderPrompt`
-Note: The _docket_fn_key contextvar is intentionally NOT updated here.
-The parent set it to the full namespaced key (e.g., data://c/gc/value)
-which is what the function is registered under in Docket. All provider
-layers pass this through unchanged so the eventual resource._read()
-uses the correct Docket lookup key.
-
-### `FastMCPProviderPrompt`
-
-
-Prompt that delegates rendering to a wrapped server's middleware.
+Prompt that delegates rendering to a wrapped server's render_prompt().
When `render()` is called, this prompt invokes the wrapped server's
-`_get_prompt_content_middleware()` method, ensuring the server's middleware
-chain is executed.
+`render_prompt()` method, ensuring the server's middleware chain is executed.
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt
@@ -111,25 +91,19 @@ wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt
Wrap a Prompt to delegate rendering to the server's middleware.
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any] | None = None) -> PromptResult | mcp.types.CreateTaskResult
```
-Delegate to child server's middleware.
-
-When called from a Docket worker (background task), there's no FastMCP
-context set up, so we create one for the child server.
+Not implemented - use _render() which delegates to child server.
-Note: The _docket_fn_key contextvar is intentionally NOT updated here.
-The parent set it to the full namespaced name (e.g., c_gc_greet) which
-is what the function is registered under in Docket. All provider layers
-pass this through unchanged so the eventual prompt._render() uses the
-correct Docket lookup key.
+FastMCPProviderPrompt._render() handles all execution by delegating
+to the child server's render_prompt() with task_meta.
-### `FastMCPProviderResourceTemplate`
+### `FastMCPProviderResourceTemplate`
Resource template that creates FastMCPProviderResources.
@@ -141,7 +115,7 @@ when read.
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTemplate
@@ -150,7 +124,7 @@ wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTem
Wrap a ResourceTemplate to create FastMCPProviderResources.
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any]) -> Resource
@@ -163,19 +137,19 @@ We use `_original_uri_template` with `params` to construct the internal
URI that the nested server understands.
-#### `read`
+#### `read`
```python
-read(self, arguments: dict[str, Any]) -> str | bytes
+read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult
```
Read the resource content for background task execution.
-Creates a resource from this template and reads its content.
+Reads the resource via the wrapped server and returns the ResourceResult.
This method is called by Docket during background task execution.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -184,7 +158,7 @@ register_with_docket(self, docket: Docket) -> None
No-op: the child's actual template is registered via get_tasks().
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution
@@ -196,7 +170,7 @@ The child's FunctionResourceTemplate.fn is registered (via get_tasks),
and it expects splatted **kwargs, so we splat params here.
-### `FastMCPProvider`
+### `FastMCPProvider`
Provider that wraps a FastMCP server.
@@ -212,7 +186,7 @@ This ensures middleware runs when components are executed.
**Methods:**
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> Sequence[Tool]
@@ -225,7 +199,7 @@ each tool as a FastMCPProviderTool that delegates execution to the
nested server's middleware.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str) -> Tool | None
@@ -234,7 +208,7 @@ get_tool(self, name: str) -> Tool | None
Get a tool by name as a FastMCPProviderTool.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> Sequence[Resource]
@@ -247,7 +221,7 @@ each resource as a FastMCPProviderResource that delegates reading to the
nested server's middleware.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str) -> Resource | None
@@ -256,7 +230,7 @@ get_resource(self, uri: str) -> Resource | None
Get a concrete resource by URI as a FastMCPProviderResource.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> Sequence[ResourceTemplate]
@@ -268,7 +242,7 @@ Returns FastMCPProviderResourceTemplate instances that create
FastMCPProviderResources when materialized.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str) -> ResourceTemplate | None
@@ -277,7 +251,7 @@ get_resource_template(self, uri: str) -> ResourceTemplate | None
Get a resource template that matches the given URI.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> Sequence[Prompt]
@@ -289,7 +263,7 @@ Returns FastMCPProviderPrompt instances that delegate rendering to the
wrapped server's middleware.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str) -> Prompt | None
@@ -298,7 +272,7 @@ get_prompt(self, name: str) -> Prompt | None
Get a prompt by name as a FastMCPProviderPrompt.
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -314,7 +288,7 @@ Iterates through all providers in the wrapped server (including its
LocalProvider) to collect task-eligible components.
-#### `lifespan`
+#### `lifespan`
```python
lifespan(self) -> AsyncIterator[None]
diff --git a/docs/python-sdk/fastmcp-server-providers-local_provider.mdx b/docs/python-sdk/fastmcp-server-providers-local_provider.mdx
index 40c4141e1f..f002b48b1d 100644
--- a/docs/python-sdk/fastmcp-server-providers-local_provider.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-local_provider.mdx
@@ -32,7 +32,7 @@ server2 = FastMCP("Server2", providers=[provider])
## Classes
-### `LocalProvider`
+### `LocalProvider`
Provider for locally-defined components.
@@ -47,7 +47,7 @@ like `_tool_serializer` and `_support_tasks_by_default` are injected.
**Methods:**
-#### `add_tool`
+#### `add_tool`
```python
add_tool(self, tool: Tool) -> Tool
@@ -56,7 +56,7 @@ add_tool(self, tool: Tool) -> Tool
Add a tool to this provider's storage.
-#### `remove_tool`
+#### `remove_tool`
```python
remove_tool(self, name: str) -> None
@@ -65,7 +65,7 @@ remove_tool(self, name: str) -> None
Remove a tool from this provider's storage.
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource) -> Resource
@@ -74,7 +74,7 @@ add_resource(self, resource: Resource) -> Resource
Add a resource to this provider's storage.
-#### `remove_resource`
+#### `remove_resource`
```python
remove_resource(self, uri: str) -> None
@@ -83,7 +83,7 @@ remove_resource(self, uri: str) -> None
Remove a resource from this provider's storage.
-#### `add_template`
+#### `add_template`
```python
add_template(self, template: ResourceTemplate) -> ResourceTemplate
@@ -92,7 +92,7 @@ add_template(self, template: ResourceTemplate) -> ResourceTemplate
Add a resource template to this provider's storage.
-#### `remove_template`
+#### `remove_template`
```python
remove_template(self, uri_template: str) -> None
@@ -101,7 +101,7 @@ remove_template(self, uri_template: str) -> None
Remove a resource template from this provider's storage.
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt) -> Prompt
@@ -110,7 +110,7 @@ add_prompt(self, prompt: Prompt) -> Prompt
Add a prompt to this provider's storage.
-#### `remove_prompt`
+#### `remove_prompt`
```python
remove_prompt(self, name: str) -> None
@@ -119,7 +119,7 @@ remove_prompt(self, name: str) -> None
Remove a prompt from this provider's storage.
-#### `add_tool_transformation`
+#### `add_tool_transformation`
```python
add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None
@@ -132,7 +132,7 @@ Add a tool transformation.
- `transformation`: The transformation configuration.
-#### `get_tool_transformation`
+#### `get_tool_transformation`
```python
get_tool_transformation(self, tool_name: str) -> ToolTransformConfig | None
@@ -147,7 +147,7 @@ Get a tool transformation.
- The transformation config, or None if not found.
-#### `remove_tool_transformation`
+#### `remove_tool_transformation`
```python
remove_tool_transformation(self, tool_name: str) -> None
@@ -159,7 +159,7 @@ Remove a tool transformation.
- `tool_name`: The name of the tool.
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> Sequence[Tool]
@@ -168,7 +168,7 @@ list_tools(self) -> Sequence[Tool]
Return all visible tools with transformations applied.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str) -> Tool | None
@@ -177,7 +177,7 @@ get_tool(self, name: str) -> Tool | None
Get a tool by name, with transformations applied.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> Sequence[Resource]
@@ -186,7 +186,7 @@ list_resources(self) -> Sequence[Resource]
Return all visible resources.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str) -> Resource | None
@@ -195,7 +195,7 @@ get_resource(self, uri: str) -> Resource | None
Get a resource by URI if visible.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> Sequence[ResourceTemplate]
@@ -204,7 +204,7 @@ list_resource_templates(self) -> Sequence[ResourceTemplate]
Return all visible resource templates.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str) -> ResourceTemplate | None
@@ -213,7 +213,7 @@ get_resource_template(self, uri: str) -> ResourceTemplate | None
Get a resource template that matches the given URI if visible.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> Sequence[Prompt]
@@ -222,7 +222,7 @@ list_prompts(self) -> Sequence[Prompt]
Return all visible prompts.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str) -> Prompt | None
@@ -231,7 +231,7 @@ get_prompt(self, name: str) -> Prompt | None
Get a prompt by name if visible.
-#### `get_component`
+#### `get_component`
```python
get_component(self, key: str) -> Tool | Resource | ResourceTemplate | Prompt | None
@@ -242,7 +242,7 @@ Get a component by its prefixed key.
Efficient O(1) lookup in the unified components dict.
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -255,19 +255,19 @@ This includes both FunctionTool/Resource/Prompt instances created via
decorators and custom Tool/Resource/Prompt subclasses.
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: AnyFunction) -> FunctionTool
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool]
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool]
@@ -295,13 +295,13 @@ This decorator supports multiple calling patterns:
- `meta`: Optional meta information about the tool
- `enabled`: Whether the tool is enabled (default True). If False, adds to blocklist.
- `task`: Optional task configuration for background execution
-- `serializer`: Optional serializer for the tool result
+- `serializer`: Deprecated. Return ToolResult from your tools for full control over serialization.
**Returns:**
- The registered FunctionTool or a decorator function.
-#### `resource`
+#### `resource`
```python
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate]
@@ -329,19 +329,19 @@ has parameters, it will be registered as a template resource.
- A decorator function.
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt]
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt]
diff --git a/docs/python-sdk/fastmcp-server-providers-openapi-components.mdx b/docs/python-sdk/fastmcp-server-providers-openapi-components.mdx
index fa5728a3bb..a6a9f5a378 100644
--- a/docs/python-sdk/fastmcp-server-providers-openapi-components.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-openapi-components.mdx
@@ -10,7 +10,7 @@ OpenAPI component classes: Tool, Resource, and ResourceTemplate.
## Classes
-### `OpenAPITool`
+### `OpenAPITool`
Tool implementation for OpenAPI endpoints.
@@ -18,7 +18,7 @@ Tool implementation for OpenAPI endpoints.
**Methods:**
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -27,7 +27,7 @@ run(self, arguments: dict[str, Any]) -> ToolResult
Execute the HTTP request using RequestDirector.
-### `OpenAPIResource`
+### `OpenAPIResource`
Resource implementation for OpenAPI endpoints.
@@ -35,16 +35,16 @@ Resource implementation for OpenAPI endpoints.
**Methods:**
-#### `read`
+#### `read`
```python
-read(self) -> ResourceContent
+read(self) -> ResourceResult
```
Fetch the resource data by making an HTTP request.
-### `OpenAPIResourceTemplate`
+### `OpenAPIResourceTemplate`
Resource template implementation for OpenAPI endpoints.
@@ -52,7 +52,7 @@ Resource template implementation for OpenAPI endpoints.
**Methods:**
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any], context: Context | None = None) -> Resource
diff --git a/docs/python-sdk/fastmcp-server-providers-proxy.mdx b/docs/python-sdk/fastmcp-server-providers-proxy.mdx
index 866109ca9b..5076de3071 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
@@ -131,13 +131,13 @@ Factory method to create a ProxyResource from a raw MCP resource schema.
#### `read`
```python
-read(self) -> ResourceContent
+read(self) -> ResourceResult
```
Read the resource content from the remote server.
-### `ProxyTemplate`
+### `ProxyTemplate`
A ResourceTemplate that represents and creates resources from a remote server template.
@@ -145,7 +145,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
@@ -154,7 +154,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
@@ -163,7 +163,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
@@ -172,7 +172,7 @@ create_resource(self, uri: str, params: dict[str, Any], context: Context | None
Create a resource from the template by calling the remote server.
-### `ProxyPrompt`
+### `ProxyPrompt`
A Prompt that represents and renders a prompt from a remote server.
@@ -180,7 +180,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
@@ -189,7 +189,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
@@ -198,7 +198,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
@@ -207,7 +207,7 @@ render(self, arguments: dict[str, Any]) -> PromptResult
Render the prompt by making a call through the client.
-### `ProxyProvider`
+### `ProxyProvider`
Provider that proxies to a remote MCP server via a client factory.
@@ -221,7 +221,7 @@ because tasks cannot be executed through a proxy.
**Methods:**
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> Sequence[Tool]
@@ -230,7 +230,7 @@ list_tools(self) -> Sequence[Tool]
List all tools from the remote server.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> Sequence[Resource]
@@ -239,7 +239,7 @@ list_resources(self) -> Sequence[Resource]
List all resources from the remote server.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> Sequence[ResourceTemplate]
@@ -248,7 +248,7 @@ list_resource_templates(self) -> Sequence[ResourceTemplate]
List all resource templates from the remote server.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> Sequence[Prompt]
@@ -257,7 +257,7 @@ list_prompts(self) -> Sequence[Prompt]
List all prompts from the remote server.
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -270,7 +270,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.
@@ -279,7 +279,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.
@@ -287,7 +287,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.
@@ -301,7 +301,7 @@ Note that it is essential to ensure that the proxy server itself is also statefu
**Methods:**
-#### `clear`
+#### `clear`
```python
clear(self)
@@ -310,7 +310,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 cdcead1a40..1231624f5f 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
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index 535d593e38..356abcda27 100644
--- a/docs/python-sdk/fastmcp-server-server.mdx
+++ b/docs/python-sdk/fastmcp-server-server.mdx
@@ -10,7 +10,7 @@ FastMCP - A more ergonomic interface for MCP servers.
## Functions
-### `default_lifespan`
+### `default_lifespan`
```python
default_lifespan(server: FastMCP[LifespanResultT]) -> AsyncIterator[Any]
@@ -28,7 +28,7 @@ Default lifespan context manager that does nothing.
## Classes
-### `FastMCP`
+### `FastMCP`
**Methods:**
@@ -85,7 +85,7 @@ Get the Docket instance if Docket support is enabled.
Returns None if Docket is not enabled or server hasn't been started yet.
-#### `run_async`
+#### `run_async`
```python
run_async(self, transport: Transport | None = None, show_banner: bool = True, **transport_kwargs: Any) -> None
@@ -97,7 +97,7 @@ Run the FastMCP server asynchronously.
- `transport`: Transport protocol to use ("stdio", "sse", or "streamable-http")
-#### `run`
+#### `run`
```python
run(self, transport: Transport | None = None, show_banner: bool = True, **transport_kwargs: Any) -> None
@@ -109,13 +109,13 @@ Run the FastMCP server. Note this is a synchronous function.
- `transport`: Transport protocol to use ("http", "stdio", "sse", or "streamable-http")
-#### `add_middleware`
+#### `add_middleware`
```python
add_middleware(self, middleware: Middleware) -> None
```
-#### `add_provider`
+#### `add_provider`
```python
add_provider(self, provider: Provider) -> None
@@ -131,7 +131,7 @@ always take precedence over providers.
- `provider`: A Provider instance that will provide components dynamically.
-#### `enable`
+#### `enable`
```python
enable(self) -> None
@@ -146,7 +146,7 @@ Enable components by removing from blocklist, or set allowlist with only=True.
This clears existing allowlists and sets default visibility to False.
-#### `disable`
+#### `disable`
```python
disable(self) -> None
@@ -159,19 +159,23 @@ Disable components by adding to the blocklist.
- `tags`: Tags to disable - components with these tags will be disabled.
-#### `get_tools`
+#### `get_tools`
```python
-get_tools(self) -> dict[str, Tool]
+get_tools(self) -> list[Tool]
```
-Get all enabled tools from providers, indexed by name.
+Get all enabled tools from providers.
-Iterates through all providers (LocalProvider first) and collects tools.
-First provider wins for duplicate names. Filters by server blocklist.
+Queries all providers in parallel and collects tools.
+First provider wins for duplicate keys. Filters by server blocklist.
+
+**Args:**
+- `run_middleware`: If True, apply the middleware chain before
+returning results. Used by MCP handlers and mounted servers.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str) -> Tool
@@ -179,23 +183,27 @@ get_tool(self, name: str) -> Tool
Get an enabled tool by name.
-Iterates through all providers (LocalProvider first) to find the tool.
+Queries all providers in parallel to find the tool.
First provider wins. Returns only if enabled.
-#### `get_resources`
+#### `get_resources`
```python
-get_resources(self) -> dict[str, Resource]
+get_resources(self) -> list[Resource]
```
-Get all enabled resources from providers, indexed by URI.
+Get all enabled resources from providers.
-Iterates through all providers (LocalProvider first) and collects resources.
-First provider wins for duplicate URIs. Filters by server blocklist.
+Queries all providers in parallel and collects resources.
+First provider wins for duplicate keys. Filters by server blocklist.
+**Args:**
+- `run_middleware`: If True, apply the middleware chain before
+returning results. Used by MCP handlers and mounted servers.
-#### `get_resource`
+
+#### `get_resource`
```python
get_resource(self, uri: str) -> Resource
@@ -203,23 +211,27 @@ get_resource(self, uri: str) -> Resource
Get an enabled resource by URI.
-Iterates through all providers (LocalProvider first) to find the resource.
+Queries all providers in parallel to find the resource.
First provider wins. Returns only if enabled.
-#### `get_resource_templates`
+#### `get_resource_templates`
```python
-get_resource_templates(self) -> dict[str, ResourceTemplate]
+get_resource_templates(self) -> list[ResourceTemplate]
```
-Get all enabled resource templates from providers, indexed by uri_template.
+Get all enabled resource templates from providers.
-Iterates through all providers (LocalProvider first) and collects templates.
-First provider wins for duplicate uri_templates. Filters by server blocklist.
+Queries all providers in parallel and collects templates.
+First provider wins for duplicate keys. Filters by server blocklist.
+**Args:**
+- `run_middleware`: If True, apply the middleware chain before
+returning results. Used by MCP handlers and mounted servers.
-#### `get_resource_template`
+
+#### `get_resource_template`
```python
get_resource_template(self, uri: str) -> ResourceTemplate
@@ -227,23 +239,27 @@ get_resource_template(self, uri: str) -> ResourceTemplate
Get an enabled resource template that matches the given URI.
-Iterates through all providers (LocalProvider first) to find the template.
+Queries all providers in parallel to find the template.
First provider wins. Returns only if enabled.
-#### `get_prompts`
+#### `get_prompts`
```python
-get_prompts(self) -> dict[str, Prompt]
+get_prompts(self) -> list[Prompt]
```
-Get all enabled prompts from providers, indexed by name.
+Get all enabled prompts from providers.
+
+Queries all providers in parallel and collects prompts.
+First provider wins for duplicate keys. Filters by server blocklist.
-Iterates through all providers (LocalProvider first) and collects prompts.
-First provider wins for duplicate names. Filters by server blocklist.
+**Args:**
+- `run_middleware`: If True, apply the middleware chain before
+returning results. Used by MCP handlers and mounted servers.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str) -> Prompt
@@ -251,11 +267,11 @@ get_prompt(self, name: str) -> Prompt
Get an enabled prompt by name.
-Iterates through all providers (LocalProvider first) to find the prompt.
+Queries all providers in parallel to find the prompt.
First provider wins. Returns only if enabled.
-#### `get_component`
+#### `get_component`
```python
get_component(self, key: str) -> Tool | Resource | ResourceTemplate | Prompt
@@ -263,7 +279,7 @@ get_component(self, key: str) -> Tool | Resource | ResourceTemplate | Prompt
Get a component by its prefixed key.
-Iterates through all providers (LocalProvider first) to find the component.
+Queries all providers in parallel to find the component.
First provider wins.
**Args:**
@@ -276,7 +292,129 @@ First provider wins.
- `NotFoundError`: If no component is found with the given key.
-#### `custom_route`
+#### `call_tool`
+
+```python
+call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult
+```
+
+#### `call_tool`
+
+```python
+call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult
+```
+
+#### `call_tool`
+
+```python
+call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult | mcp.types.CreateTaskResult
+```
+
+Call a tool by name.
+
+This is the public API for executing tools. By default, middleware is applied.
+
+**Args:**
+- `name`: The tool name
+- `arguments`: Tool arguments (optional)
+- `run_middleware`: If True (default), apply the middleware chain.
+Set to False when called from middleware to avoid re-applying.
+- `task_meta`: If provided, execute as a background task and return
+CreateTaskResult. If None (default), execute synchronously and
+return ToolResult.
+
+**Returns:**
+- ToolResult when task_meta is None.
+- CreateTaskResult when task_meta is provided.
+
+**Raises:**
+- `NotFoundError`: If tool not found or disabled
+- `ToolError`: If tool execution fails
+- `ValidationError`: If arguments fail validation
+
+
+#### `read_resource`
+
+```python
+read_resource(self, uri: str) -> ResourceResult
+```
+
+#### `read_resource`
+
+```python
+read_resource(self, uri: str) -> mcp.types.CreateTaskResult
+```
+
+#### `read_resource`
+
+```python
+read_resource(self, uri: str) -> ResourceResult | mcp.types.CreateTaskResult
+```
+
+Read a resource by URI.
+
+This is the public API for reading resources. By default, middleware is applied.
+Checks concrete resources first, then templates.
+
+**Args:**
+- `uri`: The resource URI
+- `run_middleware`: If True (default), apply the middleware chain.
+Set to False when called from middleware to avoid re-applying.
+- `task_meta`: If provided, execute as a background task and return
+CreateTaskResult. If None (default), execute synchronously and
+return ResourceResult.
+
+**Returns:**
+- ResourceResult when task_meta is None.
+- CreateTaskResult when task_meta is provided.
+
+**Raises:**
+- `NotFoundError`: If resource not found or disabled
+- `ResourceError`: If resource read fails
+
+
+#### `render_prompt`
+
+```python
+render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult
+```
+
+#### `render_prompt`
+
+```python
+render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult
+```
+
+#### `render_prompt`
+
+```python
+render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult | mcp.types.CreateTaskResult
+```
+
+Render a prompt by name.
+
+This is the public API for rendering prompts. By default, middleware is applied.
+Use get_prompt() to retrieve the prompt definition without rendering.
+
+**Args:**
+- `name`: The prompt name
+- `arguments`: Prompt arguments (optional)
+- `run_middleware`: If True (default), apply the middleware chain.
+Set to False when called from middleware to avoid re-applying.
+- `task_meta`: If provided, execute as a background task and return
+CreateTaskResult. If None (default), execute synchronously and
+return PromptResult.
+
+**Returns:**
+- PromptResult when task_meta is None.
+- CreateTaskResult when task_meta is provided.
+
+**Raises:**
+- `NotFoundError`: If prompt not found or disabled
+- `PromptError`: If prompt rendering fails
+
+
+#### `custom_route`
```python
custom_route(self, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True) -> Callable[[Callable[[Request], Awaitable[Response]]], Callable[[Request], Awaitable[Response]]]
@@ -297,7 +435,7 @@ Starlette's reverse URL lookup feature)
- `include_in_schema`: Whether to include in OpenAPI schema, defaults to True
-#### `add_tool`
+#### `add_tool`
```python
add_tool(self, tool: Tool) -> Tool
@@ -315,7 +453,7 @@ with the Context type annotation. See the @tool decorator for examples.
- The tool instance that was added to the server.
-#### `remove_tool`
+#### `remove_tool`
```python
remove_tool(self, name: str) -> None
@@ -330,7 +468,7 @@ Remove a tool from the server.
- `NotFoundError`: If the tool is not found
-#### `add_tool_transformation`
+#### `add_tool_transformation`
```python
add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None
@@ -339,7 +477,7 @@ add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfi
Add a tool transformation.
-#### `remove_tool_transformation`
+#### `remove_tool_transformation`
```python
remove_tool_transformation(self, tool_name: str) -> None
@@ -348,19 +486,19 @@ remove_tool_transformation(self, tool_name: str) -> None
Remove a tool transformation.
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: AnyFunction) -> FunctionTool
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool]
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool]
@@ -416,7 +554,7 @@ server.tool(my_function, name="custom_name")
```
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource) -> Resource
@@ -431,7 +569,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
@@ -446,7 +584,7 @@ Add a resource template to the server.
- The template instance that was added to the server.
-#### `resource`
+#### `resource`
```python
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate]
@@ -505,7 +643,7 @@ async def get_weather(city: str) -> str:
```
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt) -> Prompt
@@ -520,19 +658,19 @@ Add a prompt to the server.
- The prompt instance that was added to the server.
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt]
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt]
@@ -609,7 +747,7 @@ Decorator to register a prompt.
```
-#### `run_stdio_async`
+#### `run_stdio_async`
```python
run_stdio_async(self, show_banner: bool = True, log_level: str | None = None) -> None
@@ -622,7 +760,7 @@ Run the server using stdio transport.
- `log_level`: Log level for the server
-#### `run_http_async`
+#### `run_http_async`
```python
run_http_async(self, show_banner: bool = True, transport: Literal['http', 'streamable-http', 'sse'] = 'http', host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None) -> None
@@ -642,7 +780,7 @@ Run the server using HTTP transport.
- `stateless_http`: Whether to use stateless HTTP (defaults to settings.stateless_http)
-#### `http_app`
+#### `http_app`
```python
http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http', event_store: EventStore | None = None, retry_interval: int | None = None) -> StarletteWithLifespan
@@ -668,7 +806,7 @@ streamable-http transport.
- A Starlette application configured with the specified transport
-#### `mount`
+#### `mount`
```python
mount(self, server: FastMCP[LifespanResultT], namespace: str | None = None, as_proxy: bool | None = None, tool_names: dict[str, str] | None = None, prefix: str | None = None) -> None
@@ -715,7 +853,7 @@ mounted server.
- `prefix`: Deprecated. Use namespace instead.
-#### `import_server`
+#### `import_server`
```python
import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None
@@ -756,7 +894,7 @@ templates, and prompts are imported with their original names.
objects are imported with their original names.
-#### `from_openapi`
+#### `from_openapi`
```python
from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, name: str = 'OpenAPI Server', route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self
@@ -780,7 +918,7 @@ Create a FastMCP server from an OpenAPI specification.
- A FastMCP server with an OpenAPIProvider attached.
-#### `from_fastapi`
+#### `from_fastapi`
```python
from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self
@@ -804,7 +942,7 @@ Create a FastMCP server from a FastAPI application.
- A FastMCP server with an OpenAPIProvider attached.
-#### `as_proxy`
+#### `as_proxy`
```python
as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
@@ -818,7 +956,7 @@ instance or any value accepted as the `transport` argument of
`fastmcp.client.Client` constructor.
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
diff --git a/docs/python-sdk/fastmcp-server-tasks-config.mdx b/docs/python-sdk/fastmcp-server-tasks-config.mdx
index 01ceba2758..129fe896c2 100644
--- a/docs/python-sdk/fastmcp-server-tasks-config.mdx
+++ b/docs/python-sdk/fastmcp-server-tasks-config.mdx
@@ -14,7 +14,20 @@ handle task-augmented execution as specified in SEP-1686.
## Classes
-### `TaskConfig`
+### `TaskMeta`
+
+
+Metadata for task-augmented execution requests.
+
+When passed to call_tool/read_resource/get_prompt, signals that
+the operation should be submitted as a background task.
+
+**Attributes:**
+- `ttl`: Client-requested TTL in milliseconds. If None, uses server default.
+- `fn_key`: Docket routing key. Auto-derived from component name if None.
+
+
+### `TaskConfig`
Configuration for MCP background task execution (SEP-1686).
@@ -31,7 +44,7 @@ Controls how a component handles task-augmented requests:
**Methods:**
-#### `from_bool`
+#### `from_bool`
```python
from_bool(cls, value: bool) -> TaskConfig
@@ -46,7 +59,7 @@ Convert boolean task flag to TaskConfig.
- TaskConfig with appropriate mode.
-#### `supports_tasks`
+#### `supports_tasks`
```python
supports_tasks(self) -> bool
@@ -58,7 +71,7 @@ Check if this component supports task execution.
- True if mode is "optional" or "required", False if "forbidden".
-#### `validate_function`
+#### `validate_function`
```python
validate_function(self, fn: Callable[..., Any], name: str) -> None
diff --git a/docs/python-sdk/fastmcp-server-tasks-handlers.mdx b/docs/python-sdk/fastmcp-server-tasks-handlers.mdx
index e633a193cb..bee4b0b931 100644
--- a/docs/python-sdk/fastmcp-server-tasks-handlers.mdx
+++ b/docs/python-sdk/fastmcp-server-tasks-handlers.mdx
@@ -13,10 +13,10 @@ Handles queuing tool/prompt/resource executions to Docket as background tasks.
## Functions
-### `submit_to_docket`
+### `submit_to_docket`
```python
-submit_to_docket(task_type: Literal['tool', 'resource', 'template', 'prompt'], key: str, component: Tool | Resource | ResourceTemplate | Prompt, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult
+submit_to_docket(task_type: Literal['tool', 'resource', 'template', 'prompt'], key: str, component: Tool | Resource | ResourceTemplate | Prompt, arguments: dict[str, Any] | None = None, task_meta: TaskMeta | None = None) -> mcp.types.CreateTaskResult
```
@@ -28,15 +28,13 @@ methods (_run, _read, _render) when task metadata is present and mode allows.
Queues the component's method to Docket, stores raw return values,
and converts to MCP types on retrieval.
-Note: Client-requested TTL in task_meta is intentionally ignored.
-Server-side TTL policy (docket.execution_ttl) takes precedence for
-consistent task lifecycle management.
-
**Args:**
- `task_type`: Component type for task key construction
- `key`: The component key as seen by MCP layer (with namespace prefix)
- `component`: The component instance (Tool, Resource, ResourceTemplate, Prompt)
- `arguments`: Arguments/params (None for Resource which has no args)
+- `task_meta`: Task execution metadata. If task_meta.ttl is provided, it
+overrides the server default (docket.execution_ttl).
**Returns:**
- Task stub with proper Task object
diff --git a/docs/python-sdk/fastmcp-server-tasks-requests.mdx b/docs/python-sdk/fastmcp-server-tasks-requests.mdx
index 912fc9cc51..25f051d14d 100644
--- a/docs/python-sdk/fastmcp-server-tasks-requests.mdx
+++ b/docs/python-sdk/fastmcp-server-tasks-requests.mdx
@@ -50,7 +50,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
@@ -69,7 +69,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-tasks-routing.mdx b/docs/python-sdk/fastmcp-server-tasks-routing.mdx
index 7402e77ff3..64d45c2225 100644
--- a/docs/python-sdk/fastmcp-server-tasks-routing.mdx
+++ b/docs/python-sdk/fastmcp-server-tasks-routing.mdx
@@ -16,7 +16,7 @@ Provides unified task mode enforcement and docket routing logic.
### `check_background_task`
```python
-check_background_task(component: Tool | Resource | ResourceTemplate | Prompt, task_type: TaskType, key: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult | None
+check_background_task(component: Tool | Resource | ResourceTemplate | Prompt, task_type: TaskType, arguments: dict[str, Any] | None = None, task_meta: TaskMeta | None = None) -> mcp.types.CreateTaskResult | None
```
@@ -25,8 +25,8 @@ Check task mode and submit to background if requested.
**Args:**
- `component`: The MCP component
- `task_type`: Type of task ("tool", "resource", "template", "prompt")
-- `key`: Docket registration key (caller resolves from contextvar + fallback)
- `arguments`: Arguments for tool/prompt/template execution
+- `task_meta`: Task execution metadata. If provided, execute as background task.
**Returns:**
- CreateTaskResult if submitted to docket, None for sync execution
diff --git a/docs/python-sdk/fastmcp-settings.mdx b/docs/python-sdk/fastmcp-settings.mdx
index 21260703cd..8c6470a39d 100644
--- a/docs/python-sdk/fastmcp-settings.mdx
+++ b/docs/python-sdk/fastmcp-settings.mdx
@@ -7,15 +7,15 @@ sidebarTitle: settings
## Classes
-### `DocketSettings`
+### `DocketSettings`
Docket worker configuration.
-### `ExperimentalSettings`
+### `ExperimentalSettings`
-### `Settings`
+### `Settings`
FastMCP settings.
@@ -23,7 +23,7 @@ FastMCP settings.
**Methods:**
-#### `get_setting`
+#### `get_setting`
```python
get_setting(self, attr: str) -> Any
@@ -33,7 +33,7 @@ Get a setting. If the setting contains one or more `__`, it will be
treated as a nested setting.
-#### `set_setting`
+#### `set_setting`
```python
set_setting(self, attr: str, value: Any) -> None
@@ -43,7 +43,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 141e4c9428..c5e5e1c3a3 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(fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionTool
@@ -51,7 +51,7 @@ from_function(fn: Callable[..., Any], name: str | None = None, title: str | None
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,17 +103,17 @@ Schedule this tool for background execution via docket.
- `**kwargs`: Additional kwargs passed to docket.add()
-#### `from_tool`
+#### `from_tool`
```python
from_tool(cls, tool: Tool) -> TransformedTool
```
-### `FunctionTool`
+### `FunctionTool`
**Methods:**
-#### `to_mcp_tool`
+#### `to_mcp_tool`
```python
to_mcp_tool(self, **overrides: Any) -> MCPTool
@@ -124,7 +124,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], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionTool
@@ -133,7 +133,7 @@ from_function(cls, fn: Callable[..., Any], name: str | None = None, title: str |
Create a Tool from a function.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -142,7 +142,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
@@ -154,7 +154,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
@@ -172,11 +172,11 @@ FunctionTool splats the arguments dict since .fn expects **kwargs.
- `**kwargs`: Additional kwargs passed to docket.add()
-### `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-tool_transform.mdx b/docs/python-sdk/fastmcp-tools-tool_transform.mdx
index ba171fcb7d..0288596ac2 100644
--- a/docs/python-sdk/fastmcp-tools-tool_transform.mdx
+++ b/docs/python-sdk/fastmcp-tools-tool_transform.mdx
@@ -7,7 +7,7 @@ sidebarTitle: tool_transform
## Functions
-### `forward`
+### `forward`
```python
forward(**kwargs: Any) -> ToolResult
@@ -36,7 +36,7 @@ tool has args `a` and `b`, and an `transform_args` was provided that maps `x` to
- `TypeError`: If provided arguments don't match the transformed schema.
-### `forward_raw`
+### `forward_raw`
```python
forward_raw(**kwargs: Any) -> ToolResult
@@ -62,7 +62,7 @@ y=2)` will call the parent tool with `x=1` and `y=2`.
- `RuntimeError`: If called outside a transformed tool context.
-### `apply_transformations_to_tools`
+### `apply_transformations_to_tools`
```python
apply_transformations_to_tools(tools: dict[str, Tool], transformations: dict[str, ToolTransformConfig]) -> dict[str, Tool]
@@ -78,7 +78,7 @@ but transformations are keyed by tool name (e.g., "my_tool").
## Classes
-### `ArgTransform`
+### `ArgTransform`
Configuration for transforming a parent tool's argument.
@@ -150,7 +150,7 @@ ArgTransform(name="new_name", description="New desc", default=None, type=int)
```
-### `ArgTransformConfig`
+### `ArgTransformConfig`
A model for requesting a single argument transform.
@@ -158,7 +158,7 @@ A model for requesting a single argument transform.
**Methods:**
-#### `to_arg_transform`
+#### `to_arg_transform`
```python
to_arg_transform(self) -> ArgTransform
@@ -167,7 +167,7 @@ to_arg_transform(self) -> ArgTransform
Convert the argument transform to a FastMCP argument transform.
-### `TransformedTool`
+### `TransformedTool`
A tool that is transformed from another tool.
@@ -191,7 +191,7 @@ validation when forward() is called from custom functions.
**Methods:**
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -210,7 +210,7 @@ functions.
- ToolResult object containing content and optional structured output.
-#### `from_tool`
+#### `from_tool`
```python
from_tool(cls, tool: Tool, name: str | None = None, title: str | NotSetT | None = NotSet, description: str | NotSetT | None = NotSet, tags: set[str] | None = None, transform_fn: Callable[..., Any] | None = None, transform_args: dict[str, ArgTransform] | None = None, annotations: ToolAnnotations | NotSetT | None = NotSet, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: Callable[[Any], str] | NotSetT | None = NotSet, meta: dict[str, Any] | NotSetT | None = NotSet) -> TransformedTool
@@ -237,7 +237,7 @@ Only specified arguments are transformed, others pass through unchanged\:
- None (default)\: Inherit from transform_fn if available, then parent tool
- dict\: Use custom output schema
- False\: Disable output schema and structured outputs
-- `serializer`: New serializer. Defaults to parent's serializer.
+- `serializer`: Deprecated. Return ToolResult from your tools for full control over serialization.
- `meta`: Control meta information\:
- NotSet (default)\: Inherit from parent tool
- dict\: Use custom meta information
@@ -292,7 +292,7 @@ async def custom_output(**kwargs) -> ToolResult:
```
-### `ToolTransformConfig`
+### `ToolTransformConfig`
Provides a way to transform a tool.
@@ -300,7 +300,7 @@ Provides a way to transform a tool.
**Methods:**
-#### `apply`
+#### `apply`
```python
apply(self, tool: Tool) -> TransformedTool
diff --git a/docs/python-sdk/fastmcp-utilities-async_utils.mdx b/docs/python-sdk/fastmcp-utilities-async_utils.mdx
new file mode 100644
index 0000000000..7a44351b66
--- /dev/null
+++ b/docs/python-sdk/fastmcp-utilities-async_utils.mdx
@@ -0,0 +1,31 @@
+---
+title: async_utils
+sidebarTitle: async_utils
+---
+
+# `fastmcp.utilities.async_utils`
+
+
+Async utilities for FastMCP.
+
+## Functions
+
+### `gather`
+
+```python
+gather(*awaitables: Awaitable[T]) -> list[T] | list[T | BaseException]
+```
+
+
+Run awaitables concurrently and return results in order.
+
+Uses anyio TaskGroup for structured concurrency.
+
+**Args:**
+- `*awaitables`: Awaitables to run concurrently
+- `return_exceptions`: If True, exceptions are returned in results.
+ If False, first exception cancels all and raises.
+
+**Returns:**
+- List of results in the same order as input awaitables.
+
diff --git a/docs/python-sdk/fastmcp-utilities-json_schema.mdx b/docs/python-sdk/fastmcp-utilities-json_schema.mdx
index a436dda8ea..3be29930d1 100644
--- a/docs/python-sdk/fastmcp-utilities-json_schema.mdx
+++ b/docs/python-sdk/fastmcp-utilities-json_schema.mdx
@@ -7,7 +7,29 @@ sidebarTitle: json_schema
## Functions
-### `compress_schema`
+### `resolve_root_ref`
+
+```python
+resolve_root_ref(schema: dict[str, Any]) -> dict[str, Any]
+```
+
+
+Resolve $ref at root level to meet MCP spec requirements.
+
+MCP specification requires outputSchema to have "type": "object" at the root level.
+When Pydantic generates schemas for self-referential models, it uses $ref at the
+root level pointing to $defs. This function resolves such references by inlining
+the referenced definition while preserving $defs for nested references.
+
+**Args:**
+- `schema`: JSON schema dict that may have $ref at root level
+
+**Returns:**
+- A new schema dict with root-level $ref resolved, or the original schema
+- if no resolution is needed
+
+
+### `compress_schema`
```python
compress_schema(schema: dict, prune_params: list[str] | None = None, prune_defs: bool = True, prune_additional_properties: bool = True, prune_titles: bool = False) -> dict