From d9f2e67f70a235ee554dccd1070128ffea8f91c3 Mon Sep 17 00:00:00 2001
From: "marvin-context-protocol[bot]"
<225465937+marvin-context-protocol[bot]@users.noreply.github.com>
Date: Sun, 18 Jan 2026 21:32:20 -0500
Subject: [PATCH] chore: Update SDK documentation (#2916)
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
---
docs/docs.json | 3 +-
docs/python-sdk/fastmcp-server-context.mdx | 99 ++++------
.../fastmcp-server-providers-aggregate.mdx | 36 +++-
.../fastmcp-server-providers-base.mdx | 47 +++--
...tmcp-server-providers-fastmcp_provider.mdx | 38 ++--
...astmcp-server-providers-local_provider.mdx | 32 ++--
...tmcp-server-providers-wrapped_provider.mdx | 13 ++
docs/python-sdk/fastmcp-server-server.mdx | 178 +++++++++---------
8 files changed, 239 insertions(+), 207 deletions(-)
create mode 100644 docs/python-sdk/fastmcp-server-providers-wrapped_provider.mdx
diff --git a/docs/docs.json b/docs/docs.json
index 4a499ef2c..4fcc03c3b 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -463,7 +463,8 @@
"python-sdk/fastmcp-server-providers-openapi-routing"
]
},
- "python-sdk/fastmcp-server-providers-proxy"
+ "python-sdk/fastmcp-server-providers-proxy",
+ "python-sdk/fastmcp-server-providers-wrapped_provider"
]
},
"python-sdk/fastmcp-server-proxy",
diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx
index 2fa8088d5..cf601ed8d 100644
--- a/docs/python-sdk/fastmcp-server-context.mdx
+++ b/docs/python-sdk/fastmcp-server-context.mdx
@@ -7,7 +7,7 @@ sidebarTitle: context
## Functions
-### `set_transport`
+### `set_transport`
```python
set_transport(transport: TransportType) -> Token[TransportType | None]
@@ -17,7 +17,7 @@ set_transport(transport: TransportType) -> Token[TransportType | None]
Set the current transport type. Returns token for reset.
-### `reset_transport`
+### `reset_transport`
```python
reset_transport(token: Token[TransportType | None]) -> None
@@ -27,7 +27,7 @@ reset_transport(token: Token[TransportType | None]) -> None
Reset transport to previous value.
-### `set_context`
+### `set_context`
```python
set_context(context: Context) -> Generator[Context, None, None]
@@ -35,7 +35,7 @@ set_context(context: Context) -> Generator[Context, None, None]
## Classes
-### `LogData`
+### `LogData`
Data object for passing log arguments to client-side handlers.
@@ -44,7 +44,7 @@ This provides an interface to match the Python standard library logging,
for compatibility with structured logging.
-### `Context`
+### `Context`
Context object providing access to MCP capabilities.
@@ -96,7 +96,7 @@ The context is optional - tools that don't need it can omit the parameter.
**Methods:**
-#### `fastmcp`
+#### `fastmcp`
```python
fastmcp(self) -> FastMCP
@@ -105,7 +105,7 @@ fastmcp(self) -> FastMCP
Get the FastMCP instance.
-#### `request_context`
+#### `request_context`
```python
request_context(self) -> RequestContext[ServerSession, Any, Request] | None
@@ -134,7 +134,7 @@ async def on_request(self, context, call_next):
```
-#### `lifespan_context`
+#### `lifespan_context`
```python
lifespan_context(self) -> dict[str, Any]
@@ -157,7 +157,7 @@ def my_tool(ctx: Context) -> str:
```
-#### `report_progress`
+#### `report_progress`
```python
report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None
@@ -170,7 +170,7 @@ Report progress for the current operation.
- `total`: Optional total value e.g. 100
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> list[SDKResource]
@@ -182,7 +182,7 @@ List all available resources from the server.
- List of Resource objects available on the server
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> list[SDKPrompt]
@@ -194,7 +194,7 @@ List all available prompts from the server.
- List of Prompt objects available on the server
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult
@@ -210,7 +210,7 @@ Get a prompt by name with optional arguments.
- The prompt result
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str | AnyUrl) -> ResourceResult
@@ -225,7 +225,7 @@ Read a resource by URI.
- ResourceResult with contents
-#### `log`
+#### `log`
```python
log(self, message: str, level: LoggingLevel | None = None, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -243,7 +243,7 @@ Messages sent to Clients are also logged to the `fastmcp.server.context.to_clien
- `extra`: Optional mapping for additional arguments
-#### `transport`
+#### `transport`
```python
transport(self) -> TransportType | None
@@ -255,7 +255,7 @@ Returns the transport type used to run this server: "stdio", "sse",
or "streamable-http". Returns None if called outside of a server context.
-#### `client_id`
+#### `client_id`
```python
client_id(self) -> str | None
@@ -264,7 +264,7 @@ client_id(self) -> str | None
Get the client ID if available.
-#### `request_id`
+#### `request_id`
```python
request_id(self) -> str
@@ -275,7 +275,7 @@ Get the unique ID for this request.
Raises RuntimeError if MCP request context is not available.
-#### `session_id`
+#### `session_id`
```python
session_id(self) -> str
@@ -292,7 +292,7 @@ the same client session.
- for other transports.
-#### `session`
+#### `session`
```python
session(self) -> ServerSession
@@ -303,7 +303,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
@@ -314,7 +314,7 @@ Send a `DEBUG`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `info`
+#### `info`
```python
info(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -325,7 +325,7 @@ Send a `INFO`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `warning`
+#### `warning`
```python
warning(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -336,7 +336,7 @@ Send a `WARNING`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `error`
+#### `error`
```python
error(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None
@@ -347,7 +347,7 @@ Send a `ERROR`-level message to the connected MCP Client.
Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`.
-#### `list_roots`
+#### `list_roots`
```python
list_roots(self) -> list[Root]
@@ -356,7 +356,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
@@ -364,30 +364,11 @@ send_notification(self, notification: mcp.types.ServerNotificationType) -> None
Send a notification to the client immediately.
-Use this in async code when you want the notification sent right away.
-For sync code, use send_notification_sync() which queues the notification
-for the background flusher.
-
**Args:**
- `notification`: An MCP notification instance (e.g., ToolListChangedNotification())
-#### `send_notification_sync`
-
-```python
-send_notification_sync(self, notification: mcp.types.ServerNotificationType) -> None
-```
-
-Queue a notification to be sent by the background flusher.
-
-Use this in sync code when you can't await. The notification will be
-sent within ~1 second by the background flusher.
-
-**Args:**
-- `notification`: An MCP notification instance (e.g., ToolListChangedNotification())
-
-
-#### `close_sse_stream`
+#### `close_sse_stream`
```python
close_sse_stream(self) -> None
@@ -405,7 +386,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
@@ -442,7 +423,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]
@@ -451,7 +432,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]
@@ -460,7 +441,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]
@@ -502,43 +483,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
@@ -567,7 +548,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
@@ -580,7 +561,7 @@ The key is automatically prefixed with the session identifier.
State expires after 1 day to prevent unbounded memory growth.
-#### `get_state`
+#### `get_state`
```python
get_state(self, key: str) -> Any
@@ -591,7 +572,7 @@ Get a value from the session-scoped state store.
Returns None if the key is not found.
-#### `delete_state`
+#### `delete_state`
```python
delete_state(self, key: str) -> None
diff --git a/docs/python-sdk/fastmcp-server-providers-aggregate.mdx b/docs/python-sdk/fastmcp-server-providers-aggregate.mdx
index d128d1a5d..f5a5fecaa 100644
--- a/docs/python-sdk/fastmcp-server-providers-aggregate.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-aggregate.mdx
@@ -17,7 +17,9 @@ Example:
from fastmcp.server.providers import AggregateProvider
# Combine multiple providers into one
- combined = AggregateProvider([provider1, provider2, provider3])
+ combined = AggregateProvider()
+ combined.add_provider(provider1)
+ combined.add_provider(provider2, namespace="api") # Tools become "api_foo"
# Use like any other provider
tools = await combined.list_tools()
@@ -26,7 +28,7 @@ Example:
## Classes
-### `AggregateProvider`
+### `AggregateProvider`
Utility provider that combines multiple providers into one.
@@ -34,15 +36,35 @@ Utility provider that combines multiple providers into one.
Components are aggregated from all providers. For get_* operations,
providers are queried in parallel and the highest version is returned.
-Errors from individual providers are logged and skipped (graceful degradation).
+When adding providers with a namespace, wrap_transform() is used to apply
+the Namespace transform. This means namespace transformation is handled
+by the wrapped provider, not by AggregateProvider.
-This is useful when you want to combine custom providers without creating
-a full FastMCP server.
+Errors from individual providers are logged and skipped (graceful degradation).
**Methods:**
-#### `get_tasks`
+#### `add_provider`
+
+```python
+add_provider(self, provider: Provider) -> None
+```
+
+Add a provider with optional namespace.
+
+If the provider is a FastMCP server, it's automatically wrapped in
+FastMCPProvider to ensure middleware is invoked correctly.
+
+**Args:**
+- `provider`: The provider to add.
+- `namespace`: Optional namespace prefix. When set\:
+- Tools become "namespace_toolname"
+- Resources become "protocol\://namespace/path"
+- Prompts become "namespace_promptname"
+
+
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -51,7 +73,7 @@ get_tasks(self) -> Sequence[FastMCPComponent]
Get all task-eligible components from all providers.
-#### `lifespan`
+#### `lifespan`
```python
lifespan(self) -> AsyncIterator[None]
diff --git a/docs/python-sdk/fastmcp-server-providers-base.mdx b/docs/python-sdk/fastmcp-server-providers-base.mdx
index 36ed3cc06..e7ecb6c05 100644
--- a/docs/python-sdk/fastmcp-server-providers-base.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-base.mdx
@@ -72,7 +72,30 @@ through the provider. They're applied in order - first added is innermost.
- `transform`: The transform to add.
-#### `list_tools`
+#### `wrap_transform`
+
+```python
+wrap_transform(self, transform: Transform) -> Provider
+```
+
+Return a new provider with this transform applied (immutable).
+
+Unlike add_transform() which mutates this provider, wrap_transform()
+returns a new provider that wraps this one. The original provider
+is unchanged.
+
+This is useful when you want to apply transforms without side effects,
+such as adding the same provider to multiple aggregators with different
+namespaces.
+
+**Args:**
+- `transform`: The transform to apply.
+
+**Returns:**
+- A new provider that wraps this one with the transform applied.
+
+
+#### `list_tools`
```python
list_tools(self) -> Sequence[Tool]
@@ -89,7 +112,7 @@ filtering happens at the server level to allow session transforms to override.
- Transformed sequence of tools (including disabled ones).
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None
@@ -109,7 +132,7 @@ allowing session-level transforms to override provider-level disables.
- The tool if found (may be marked disabled), None if not found.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> Sequence[Resource]
@@ -120,7 +143,7 @@ List resources with all transforms applied.
Components may be marked as disabled but are NOT filtered here.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None
@@ -139,7 +162,7 @@ Note: This method does NOT filter disabled components. The Server
- The resource if found (may be marked disabled), None if not found.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> Sequence[ResourceTemplate]
@@ -150,7 +173,7 @@ List resource templates with all transforms applied.
Components may be marked as disabled but are NOT filtered here.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None
@@ -169,7 +192,7 @@ Note: This method does NOT filter disabled components. The Server
- The template if found (may be marked disabled), None if not found.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> Sequence[Prompt]
@@ -180,7 +203,7 @@ List prompts with all transforms applied.
Components may be marked as disabled but are NOT filtered here.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None
@@ -199,7 +222,7 @@ Note: This method does NOT filter disabled components. The Server
- The prompt if found (may be marked disabled), None if not found.
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -214,7 +237,7 @@ 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]
@@ -230,7 +253,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) -> Self
@@ -258,7 +281,7 @@ VersionSpec(gte="v2")). Unversioned components will not match.
- Self for method chaining.
-#### `disable`
+#### `disable`
```python
disable(self) -> Self
diff --git a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
index fda42ad19..821cbd794 100644
--- a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx
@@ -39,7 +39,7 @@ wrap(cls, server: Any, tool: Tool) -> FastMCPProviderTool
Wrap a Tool to delegate execution to the server's middleware.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -51,13 +51,13 @@ This is called when the tool is used within a TransformedTool
forwarding function or other contexts where task_meta is not available.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProviderResource`
+### `FastMCPProviderResource`
Resource that delegates reading to a wrapped server's read_resource().
@@ -68,7 +68,7 @@ When `read()` is called, this resource invokes the wrapped server's
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource
@@ -77,13 +77,13 @@ wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource
Wrap a Resource to delegate reading to the server's middleware.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProviderPrompt`
+### `FastMCPProviderPrompt`
Prompt that delegates rendering to a wrapped server's render_prompt().
@@ -94,7 +94,7 @@ When `render()` is called, this prompt invokes the wrapped server's
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt
@@ -103,7 +103,7 @@ wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt
Wrap a Prompt to delegate rendering to the server's middleware.
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any] | None = None) -> PromptResult
@@ -115,13 +115,13 @@ This is called when the prompt is used within a transformed context
or other contexts where task_meta is not available.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProviderResourceTemplate`
+### `FastMCPProviderResourceTemplate`
Resource template that creates FastMCPProviderResources.
@@ -133,7 +133,7 @@ when read.
**Methods:**
-#### `wrap`
+#### `wrap`
```python
wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTemplate
@@ -142,7 +142,7 @@ wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTem
Wrap a ResourceTemplate to create FastMCPProviderResources.
-#### `create_resource`
+#### `create_resource`
```python
create_resource(self, uri: str, params: dict[str, Any]) -> Resource
@@ -155,7 +155,7 @@ We use `_original_uri_template` with `params` to construct the internal
URI that the nested server understands.
-#### `read`
+#### `read`
```python
read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult
@@ -167,7 +167,7 @@ Reads the resource via the wrapped server and returns the ResourceResult.
This method is called by Docket during background task execution.
-#### `register_with_docket`
+#### `register_with_docket`
```python
register_with_docket(self, docket: Docket) -> None
@@ -176,7 +176,7 @@ register_with_docket(self, docket: Docket) -> None
No-op: the child's actual template is registered via get_tasks().
-#### `add_to_docket`
+#### `add_to_docket`
```python
add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution
@@ -188,13 +188,13 @@ The child's FunctionResourceTemplate.fn is registered (via get_tasks),
and it expects splatted **kwargs, so we splat params here.
-#### `get_span_attributes`
+#### `get_span_attributes`
```python
get_span_attributes(self) -> dict[str, Any]
```
-### `FastMCPProvider`
+### `FastMCPProvider`
Provider that wraps a FastMCP server.
@@ -210,7 +210,7 @@ This ensures middleware runs when components are executed.
**Methods:**
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -224,7 +224,7 @@ server's transforms applied, then applies this provider's transforms
for correct registration keys.
-#### `lifespan`
+#### `lifespan`
```python
lifespan(self) -> AsyncIterator[None]
diff --git a/docs/python-sdk/fastmcp-server-providers-local_provider.mdx b/docs/python-sdk/fastmcp-server-providers-local_provider.mdx
index 0cd3fbbb9..5fa847d37 100644
--- a/docs/python-sdk/fastmcp-server-providers-local_provider.mdx
+++ b/docs/python-sdk/fastmcp-server-providers-local_provider.mdx
@@ -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 | Callable[..., Any]) -> Tool
@@ -58,7 +58,7 @@ Add a tool to this provider's storage.
Accepts either a Tool object or a decorated function with __fastmcp__ metadata.
-#### `remove_tool`
+#### `remove_tool`
```python
remove_tool(self, name: str, version: str | None = None) -> None
@@ -74,7 +74,7 @@ Remove tool(s) from this provider's storage.
- `KeyError`: If no matching tool is found.
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource | ResourceTemplate | Callable[..., Any]) -> Resource | ResourceTemplate
@@ -85,7 +85,7 @@ Add a resource to this provider's storage.
Accepts either a Resource/ResourceTemplate object or a decorated function with __fastmcp__ metadata.
-#### `remove_resource`
+#### `remove_resource`
```python
remove_resource(self, uri: str, version: str | None = None) -> None
@@ -101,7 +101,7 @@ Remove resource(s) from this provider's storage.
- `KeyError`: If no matching resource is found.
-#### `add_template`
+#### `add_template`
```python
add_template(self, template: ResourceTemplate) -> ResourceTemplate
@@ -110,7 +110,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, version: str | None = None) -> None
@@ -126,7 +126,7 @@ Remove resource template(s) from this provider's storage.
- `KeyError`: If no matching template is found.
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt
@@ -137,7 +137,7 @@ Add a prompt to this provider's storage.
Accepts either a Prompt object or a decorated function with __fastmcp__ metadata.
-#### `remove_prompt`
+#### `remove_prompt`
```python
remove_prompt(self, name: str, version: str | None = None) -> None
@@ -153,7 +153,7 @@ Remove prompt(s) from this provider's storage.
- `KeyError`: If no matching prompt is found.
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -166,19 +166,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]
@@ -212,7 +212,7 @@ This decorator supports multiple calling patterns:
- The registered FunctionTool or a decorator function.
-#### `resource`
+#### `resource`
```python
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate | AnyFunction]
@@ -241,19 +241,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-wrapped_provider.mdx b/docs/python-sdk/fastmcp-server-providers-wrapped_provider.mdx
new file mode 100644
index 000000000..22fc90b40
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-providers-wrapped_provider.mdx
@@ -0,0 +1,13 @@
+---
+title: wrapped_provider
+sidebarTitle: wrapped_provider
+---
+
+# `fastmcp.server.providers.wrapped_provider`
+
+
+WrappedProvider for immutable transform composition.
+
+This module provides `_WrappedProvider`, an internal class that wraps a provider
+with an additional transform. Created by `Provider.wrap_transform()`.
+
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index ae6831070..c058bb7a6 100644
--- a/docs/python-sdk/fastmcp-server-server.mdx
+++ b/docs/python-sdk/fastmcp-server-server.mdx
@@ -10,7 +10,7 @@ FastMCP - A more ergonomic interface for MCP servers.
## Functions
-### `default_lifespan`
+### `default_lifespan`
```python
default_lifespan(server: FastMCP[LifespanResultT]) -> AsyncIterator[Any]
@@ -26,7 +26,7 @@ Default lifespan context manager that does nothing.
- An empty dictionary as the lifespan result.
-### `create_proxy`
+### `create_proxy`
```python
create_proxy(target: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
@@ -54,59 +54,59 @@ use `FastMCPProxy` or `ProxyProvider` directly from `fastmcp.server.providers.pr
## Classes
-### `StateValue`
+### `StateValue`
Wrapper for stored context state values.
-### `FastMCP`
+### `FastMCP`
**Methods:**
-#### `settings`
+#### `settings`
```python
settings(self) -> Settings
```
-#### `name`
+#### `name`
```python
name(self) -> str
```
-#### `instructions`
+#### `instructions`
```python
instructions(self) -> str | None
```
-#### `instructions`
+#### `instructions`
```python
instructions(self, value: str | None) -> None
```
-#### `version`
+#### `version`
```python
version(self) -> str | None
```
-#### `website_url`
+#### `website_url`
```python
website_url(self) -> str | None
```
-#### `icons`
+#### `icons`
```python
icons(self) -> list[mcp.types.Icon]
```
-#### `docket`
+#### `docket`
```python
docket(self) -> Docket | None
@@ -117,7 +117,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 | None = None, **transport_kwargs: Any) -> None
@@ -131,7 +131,7 @@ Run the FastMCP server asynchronously.
FASTMCP_SHOW_SERVER_BANNER setting (default\: True).
-#### `run`
+#### `run`
```python
run(self, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None
@@ -145,13 +145,13 @@ Run the FastMCP server. Note this is a synchronous function.
FASTMCP_SHOW_SERVER_BANNER setting (default\: True).
-#### `add_middleware`
+#### `add_middleware`
```python
add_middleware(self, middleware: Middleware) -> None
```
-#### `add_provider`
+#### `add_provider`
```python
add_provider(self, provider: Provider) -> None
@@ -165,9 +165,13 @@ always take precedence over providers.
**Args:**
- `provider`: A Provider instance that will provide components dynamically.
+- `namespace`: Optional namespace prefix. When set\:
+- Tools become "namespace_toolname"
+- Resources become "protocol\://namespace/path"
+- Prompts become "namespace_promptname"
-#### `get_tasks`
+#### `get_tasks`
```python
get_tasks(self) -> Sequence[FastMCPComponent]
@@ -175,11 +179,11 @@ get_tasks(self) -> Sequence[FastMCPComponent]
Get task-eligible components with all transforms applied.
-Overrides Provider.get_tasks() to collect task-eligible components
-from all sub-providers and apply server-level transforms.
+Overrides AggregateProvider.get_tasks() to apply server-level transforms
+after aggregation. AggregateProvider handles provider-level namespacing.
-#### `add_transform`
+#### `add_transform`
```python
add_transform(self, transform: Transform) -> None
@@ -194,7 +198,7 @@ They transform tools, resources, and prompts from ALL providers.
- `transform`: The transform to add.
-#### `add_tool_transformation`
+#### `add_tool_transformation`
```python
add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None
@@ -206,7 +210,7 @@ Add a tool transformation.
Use ``add_transform(ToolTransform({...}))`` instead.
-#### `remove_tool_transformation`
+#### `remove_tool_transformation`
```python
remove_tool_transformation(self, _tool_name: str) -> None
@@ -218,23 +222,20 @@ Remove a tool transformation.
Tool transformations are now immutable. Use enable/disable controls instead.
-#### `get_tools`
+#### `list_tools`
```python
-get_tools(self) -> list[Tool]
+list_tools(self) -> Sequence[Tool]
```
-Get all enabled tools from providers.
+List all enabled tools from providers.
-Queries all providers via the root provider (which applies provider transforms,
-server transforms, and enabled filtering). First provider wins for duplicate keys.
-
-**Args:**
-- `run_middleware`: If True, apply the middleware chain before returning.
-Used by MCP handlers and FastMCPProvider for nested servers.
+Overrides Provider.list_tools() to add enabled filtering, auth filtering,
+and middleware execution. Returns all versions (no deduplication).
+Protocol handlers deduplicate for MCP wire format.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None
@@ -254,23 +255,20 @@ session transforms can override provider-level disables.
- The tool if found and enabled, None otherwise.
-#### `get_resources`
+#### `list_resources`
```python
-get_resources(self) -> list[Resource]
+list_resources(self) -> Sequence[Resource]
```
-Get all enabled resources from providers.
+List all enabled resources from providers.
-Queries all providers via the root provider (which applies provider transforms,
-server transforms, and enabled filtering). First provider wins for duplicate keys.
-
-**Args:**
-- `run_middleware`: If True, apply the middleware chain before returning.
-Used by MCP handlers and FastMCPProvider for nested servers.
+Overrides Provider.list_resources() to add enabled filtering, auth filtering,
+and middleware execution. Returns all versions (no deduplication).
+Protocol handlers deduplicate for MCP wire format.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None
@@ -289,23 +287,20 @@ transforms (including session-level) have been applied.
- The resource if found and enabled, None otherwise.
-#### `get_resource_templates`
+#### `list_resource_templates`
```python
-get_resource_templates(self) -> list[ResourceTemplate]
+list_resource_templates(self) -> Sequence[ResourceTemplate]
```
-Get all enabled resource templates from providers.
+List all enabled resource templates from providers.
-Queries all providers via the root provider (which applies provider transforms,
-server transforms, and enabled filtering). First provider wins for duplicate keys.
-
-**Args:**
-- `run_middleware`: If True, apply the middleware chain before returning.
-Used by MCP handlers and FastMCPProvider for nested servers.
+Overrides Provider.list_resource_templates() to add enabled filtering,
+auth filtering, and middleware execution. Returns all versions (no deduplication).
+Protocol handlers deduplicate for MCP wire format.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None
@@ -324,23 +319,20 @@ all transforms (including session-level) have been applied.
- The template if found and enabled, None otherwise.
-#### `get_prompts`
+#### `list_prompts`
```python
-get_prompts(self) -> list[Prompt]
+list_prompts(self) -> Sequence[Prompt]
```
-Get all enabled prompts from providers.
+List all enabled prompts from providers.
-Queries all providers via the root provider (which applies provider transforms,
-server transforms, and enabled filtering). First provider wins for duplicate keys.
-
-**Args:**
-- `run_middleware`: If True, apply the middleware chain before returning.
-Used by MCP handlers and FastMCPProvider for nested servers.
+Overrides Provider.list_prompts() to add enabled filtering, auth filtering,
+and middleware execution. Returns all versions (no deduplication).
+Protocol handlers deduplicate for MCP wire format.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None
@@ -359,19 +351,19 @@ transforms (including session-level) have been applied.
- The prompt if found and enabled, None otherwise.
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult
```
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult
```
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult | mcp.types.CreateTaskResult
@@ -401,19 +393,19 @@ return ToolResult.
- `ValidationError`: If arguments fail validation
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str) -> ResourceResult
```
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str) -> mcp.types.CreateTaskResult
```
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str) -> ResourceResult | mcp.types.CreateTaskResult
@@ -442,19 +434,19 @@ return ResourceResult.
- `ResourceError`: If resource read fails
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult
```
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult
```
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult | mcp.types.CreateTaskResult
@@ -484,7 +476,7 @@ return PromptResult.
- `PromptError`: If prompt rendering fails
-#### `custom_route`
+#### `custom_route`
```python
custom_route(self, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True) -> Callable[[Callable[[Request], Awaitable[Response]]], Callable[[Request], Awaitable[Response]]]
@@ -505,7 +497,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 | Callable[..., Any]) -> Tool
@@ -523,7 +515,7 @@ with the Context type annotation. See the @tool decorator for examples.
- The tool instance that was added to the server.
-#### `remove_tool`
+#### `remove_tool`
```python
remove_tool(self, name: str, version: str | None = None) -> None
@@ -539,19 +531,19 @@ Remove tool(s) from the server.
- `NotFoundError`: If no matching tool is found.
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: AnyFunction) -> FunctionTool
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool]
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool]
@@ -607,7 +599,7 @@ server.tool(my_function, name="custom_name")
```
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource | Callable[..., Any]) -> Resource | ResourceTemplate
@@ -622,7 +614,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
@@ -637,7 +629,7 @@ Add a resource template to the server.
- The template instance that was added to the server.
-#### `resource`
+#### `resource`
```python
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate | AnyFunction]
@@ -696,7 +688,7 @@ async def get_weather(city: str) -> str:
```
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt
@@ -711,19 +703,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]
@@ -800,7 +792,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, stateless: bool = False) -> None
@@ -814,7 +806,7 @@ Run the server using stdio transport.
- `stateless`: Whether to run in stateless mode (no session initialization)
-#### `run_http_async`
+#### `run_http_async`
```python
run_http_async(self, show_banner: bool = True, transport: Literal['http', 'streamable-http', 'sse'] = 'http', host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, stateless: bool | None = None) -> None
@@ -835,7 +827,7 @@ Run the server using HTTP transport.
- `stateless`: Alias for stateless_http for CLI consistency
-#### `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
@@ -861,7 +853,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
@@ -908,7 +900,7 @@ mounted server.
- `prefix`: Deprecated. Use namespace instead.
-#### `import_server`
+#### `import_server`
```python
import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None
@@ -949,7 +941,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
@@ -973,7 +965,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
@@ -997,7 +989,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
@@ -1015,7 +1007,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