diff --git a/docs/docs.json b/docs/docs.json
index c81d310a9..bff00e977 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -65,7 +65,10 @@
{
"group": "Essentials",
"icon": "cube",
- "pages": ["servers/server", "deployment/running-server"]
+ "pages": [
+ "servers/server",
+ "deployment/running-server"
+ ]
},
{
"group": "Core Components",
@@ -93,7 +96,9 @@
{
"group": "Authentication",
"icon": "shield-check",
- "pages": ["servers/auth/bearer"]
+ "pages": [
+ "servers/auth/bearer"
+ ]
}
]
},
@@ -103,7 +108,10 @@
{
"group": "Essentials",
"icon": "cube",
- "pages": ["clients/client", "clients/transports"]
+ "pages": [
+ "clients/client",
+ "clients/transports"
+ ]
},
{
"group": "Core Operations",
@@ -129,7 +137,10 @@
{
"group": "Authentication",
"icon": "user-shield",
- "pages": ["clients/auth/oauth", "clients/auth/bearer"]
+ "pages": [
+ "clients/auth/oauth",
+ "clients/auth/bearer"
+ ]
}
]
},
@@ -175,12 +186,17 @@
},
{
"anchor": "What's New",
- "pages": ["updates", "changelog"]
+ "pages": [
+ "updates",
+ "changelog"
+ ]
},
{
"anchor": "Community",
"icon": "users",
- "pages": ["community/showcase"]
+ "pages": [
+ "community/showcase"
+ ]
}
]
},
@@ -207,7 +223,7 @@
"python-sdk/fastmcp-cli-install-claude_code",
"python-sdk/fastmcp-cli-install-claude_desktop",
"python-sdk/fastmcp-cli-install-cursor",
- "python-sdk/fastmcp-cli-install-mcp_config",
+ "python-sdk/fastmcp-cli-install-mcp_json",
"python-sdk/fastmcp-cli-install-shared"
]
},
@@ -318,6 +334,7 @@
"python-sdk/fastmcp-utilities-json_schema",
"python-sdk/fastmcp-utilities-json_schema_type",
"python-sdk/fastmcp-utilities-logging",
+ "python-sdk/fastmcp-utilities-mcp_config",
"python-sdk/fastmcp-utilities-openapi",
"python-sdk/fastmcp-utilities-tests",
"python-sdk/fastmcp-utilities-types"
diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx
index 51e8bd4e1..3c1bd0c60 100644
--- a/docs/python-sdk/fastmcp-cli-cli.mdx
+++ b/docs/python-sdk/fastmcp-cli-cli.mdx
@@ -10,7 +10,7 @@ FastMCP CLI tools using Cyclopts.
## Functions
-### `version`
+### `version`
```python
version()
@@ -20,7 +20,7 @@ version()
Display version information and platform details.
-### `dev`
+### `dev`
```python
dev(server_spec: str) -> None
@@ -33,7 +33,7 @@ Run an MCP server with the MCP Inspector for development.
- `server_spec`: Python file to run, optionally with \:object suffix
-### `run`
+### `run`
```python
run(server_spec: str) -> None
@@ -42,19 +42,20 @@ run(server_spec: str) -> None
Run an MCP server or connect to a remote one.
-The server can be specified in three ways:
-1. Module approach: server.py - runs the module directly, looking for an object named 'mcp', 'server', or 'app'
-2. Import approach: server.py:app - imports and runs the specified server object
-3. URL approach: http://server-url - connects to a remote server and creates a proxy
+The server can be specified in four ways:
+1. Module approach: "server.py" - runs the module directly, looking for an object named 'mcp', 'server', or 'app'
+2. Import approach: "server.py:app" - imports and runs the specified server object
+3. URL approach: "http://server-url" - connects to a remote server and creates a proxy
+4. MCPConfig file: "mcp.json" - runs as a proxy server for the MCP Servers in the MCPConfig file
Server arguments can be passed after -- :
fastmcp run server.py -- --config config.json --debug
**Args:**
-- `server_spec`: Python file, object specification (file\:obj), or URL
+- `server_spec`: Python file, object specification (file\:obj), MCPConfig file, or URL
-### `inspect`
+### `inspect`
```python
inspect(server_spec: str) -> None
diff --git a/docs/python-sdk/fastmcp-cli-install-claude_code.mdx b/docs/python-sdk/fastmcp-cli-install-claude_code.mdx
index 207756e69..cd2c07592 100644
--- a/docs/python-sdk/fastmcp-cli-install-claude_code.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-claude_code.mdx
@@ -49,12 +49,15 @@ Install FastMCP server in Claude Code.
- `with_editable`: Optional directory to install in editable mode
- `with_packages`: Optional list of additional packages to install
- `env_vars`: Optional dictionary of environment variables
+- `python_version`: Optional Python version to use
+- `with_requirements`: Optional requirements file to install from
+- `project`: Optional project directory to run within
**Returns:**
- True if installation was successful, False otherwise
-### `claude_code_command`
+### `claude_code_command`
```python
claude_code_command(server_spec: str) -> None
diff --git a/docs/python-sdk/fastmcp-cli-install-claude_desktop.mdx b/docs/python-sdk/fastmcp-cli-install-claude_desktop.mdx
index ceb3ee328..4bd05ac95 100644
--- a/docs/python-sdk/fastmcp-cli-install-claude_desktop.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-claude_desktop.mdx
@@ -36,12 +36,15 @@ Install FastMCP server in Claude Desktop.
- `with_editable`: Optional directory to install in editable mode
- `with_packages`: Optional list of additional packages to install
- `env_vars`: Optional dictionary of environment variables
+- `python_version`: Optional Python version to use
+- `with_requirements`: Optional requirements file to install from
+- `project`: Optional project directory to run within
**Returns:**
- True if installation was successful, False otherwise
-### `claude_desktop_command`
+### `claude_desktop_command`
```python
claude_desktop_command(server_spec: str) -> None
diff --git a/docs/python-sdk/fastmcp-cli-install-cursor.mdx b/docs/python-sdk/fastmcp-cli-install-cursor.mdx
index 29c20d827..2f2c9499a 100644
--- a/docs/python-sdk/fastmcp-cli-install-cursor.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-cursor.mdx
@@ -59,12 +59,15 @@ Install FastMCP server in Cursor.
- `with_editable`: Optional directory to install in editable mode
- `with_packages`: Optional list of additional packages to install
- `env_vars`: Optional dictionary of environment variables
+- `python_version`: Optional Python version to use
+- `with_requirements`: Optional requirements file to install from
+- `project`: Optional project directory to run within
**Returns:**
- True if installation was successful, False otherwise
-### `cursor_command`
+### `cursor_command`
```python
cursor_command(server_spec: str) -> None
diff --git a/docs/python-sdk/fastmcp-cli-install-mcp_config.mdx b/docs/python-sdk/fastmcp-cli-install-mcp_json.mdx
similarity index 51%
rename from docs/python-sdk/fastmcp-cli-install-mcp_config.mdx
rename to docs/python-sdk/fastmcp-cli-install-mcp_json.mdx
index f22480400..aecf21fa7 100644
--- a/docs/python-sdk/fastmcp-cli-install-mcp_config.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-mcp_json.mdx
@@ -1,19 +1,19 @@
---
-title: mcp_config
-sidebarTitle: mcp_config
+title: mcp_json
+sidebarTitle: mcp_json
---
-# `fastmcp.cli.install.mcp_config`
+# `fastmcp.cli.install.mcp_json`
MCP configuration JSON generation for FastMCP install using Cyclopts.
## Functions
-### `install_mcp_config`
+### `install_mcp_json`
```python
-install_mcp_config(file: Path, server_object: str | None, name: str) -> bool
+install_mcp_json(file: Path, server_object: str | None, name: str) -> bool
```
@@ -27,15 +27,18 @@ Generate MCP configuration JSON for manual installation.
- `with_packages`: Optional list of additional packages to install
- `env_vars`: Optional dictionary of environment variables
- `copy`: If True, copy to clipboard instead of printing to stdout
+- `python_version`: Optional Python version to use
+- `with_requirements`: Optional requirements file to install from
+- `project`: Optional project directory to run within
**Returns:**
- True if generation was successful, False otherwise
-### `mcp_config_command`
+### `mcp_json_command`
```python
-mcp_config_command(server_spec: str) -> None
+mcp_json_command(server_spec: str) -> None
```
diff --git a/docs/python-sdk/fastmcp-cli-run.mdx b/docs/python-sdk/fastmcp-cli-run.mdx
index 16cb54405..b1a477db1 100644
--- a/docs/python-sdk/fastmcp-cli-run.mdx
+++ b/docs/python-sdk/fastmcp-cli-run.mdx
@@ -10,7 +10,7 @@ FastMCP run command implementation with enhanced type hints.
## Functions
-### `is_url`
+### `is_url`
```python
is_url(path: str) -> bool
@@ -20,7 +20,7 @@ is_url(path: str) -> bool
Check if a string is a URL.
-### `parse_file_path`
+### `parse_file_path`
```python
parse_file_path(server_spec: str) -> tuple[Path, str | None]
@@ -36,7 +36,7 @@ Parse a file path that may include a server object specification.
- Tuple of (file_path, server_object)
-### `import_server`
+### `import_server`
```python
import_server(file: Path, server_object: str | None = None) -> Any
@@ -53,7 +53,30 @@ Import a MCP server from a file.
- The server object
-### `create_client_server`
+### `run_with_uv`
+
+```python
+run_with_uv(server_spec: str, python_version: str | None = None, with_packages: list[str] | None = None, with_requirements: Path | None = None, project: Path | None = None, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, show_banner: bool = True) -> None
+```
+
+
+Run a MCP server using uv run subprocess.
+
+**Args:**
+- `server_spec`: Python file, object specification (file\:obj), or URL
+- `python_version`: Python version to use (e.g. "3.10")
+- `with_packages`: Additional packages to install
+- `with_requirements`: Requirements file to use
+- `project`: Run the command within the given project directory
+- `transport`: Transport protocol to use
+- `host`: Host to bind to when using http transport
+- `port`: Port to bind to when using http transport
+- `path`: Path to bind to when using http transport
+- `log_level`: Log level
+- `show_banner`: Whether to show the server banner
+
+
+### `create_client_server`
```python
create_client_server(url: str) -> Any
@@ -69,7 +92,17 @@ Create a FastMCP server from a client URL.
- A FastMCP server instance
-### `import_server_with_args`
+### `create_mcp_config_server`
+
+```python
+create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None]
+```
+
+
+Create a FastMCP server from a MCPConfig.
+
+
+### `import_server_with_args`
```python
import_server_with_args(file: Path, server_object: str | None = None, server_args: list[str] | None = None) -> Any
@@ -87,17 +120,17 @@ Import a server with optional command line arguments.
- The imported server object
-### `run_command`
+### `run_command`
```python
-run_command(server_spec: str, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, server_args: list[str] | None = None, show_banner: bool = True) -> None
+run_command(server_spec: str, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, server_args: list[str] | None = None, show_banner: bool = True, use_direct_import: bool = False) -> None
```
Run a MCP server or connect to a remote one.
**Args:**
-- `server_spec`: Python file, object specification (file\:obj), or URL
+- `server_spec`: Python file, object specification (file\:obj), MCPConfig file, or URL
- `transport`: Transport protocol to use
- `host`: Host to bind to when using http transport
- `port`: Port to bind to when using http transport
@@ -105,4 +138,5 @@ Run a MCP server or connect to a remote one.
- `log_level`: Log level
- `server_args`: Additional arguments to pass to the server
- `show_banner`: Whether to show the server banner
+- `use_direct_import`: Whether to use direct import instead of subprocess
diff --git a/docs/python-sdk/fastmcp-client-transports.mdx b/docs/python-sdk/fastmcp-client-transports.mdx
index 8e29e754f..0a1c7190d 100644
--- a/docs/python-sdk/fastmcp-client-transports.mdx
+++ b/docs/python-sdk/fastmcp-client-transports.mdx
@@ -7,7 +7,7 @@ sidebarTitle: transports
## Functions
-### `infer_transport`
+### `infer_transport`
```python
infer_transport(transport: ClientTransport | FastMCP | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str) -> ClientTransport
@@ -238,7 +238,7 @@ object or dictionary matching the MCPConfig schema. It supports two key scenario
1. If the MCPConfig contains exactly one server, it creates a direct transport to that server.
2. If the MCPConfig contains multiple servers, it creates a composite client by mounting
- all servers on a single FastMCP instance, with each server's name used as its mounting prefix.
+ all servers on a single FastMCP instance, with each server's name, by default, used as its mounting prefix.
In the multi-server case, tools are accessible with the prefix pattern `{server_name}_{tool_name}`
and resources with the pattern `protocol://{server_name}/path/to/resource`.
@@ -281,7 +281,7 @@ async with client:
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
diff --git a/docs/python-sdk/fastmcp-mcp_config.mdx b/docs/python-sdk/fastmcp-mcp_config.mdx
index 3c6839dad..bd3bd8e06 100644
--- a/docs/python-sdk/fastmcp-mcp_config.mdx
+++ b/docs/python-sdk/fastmcp-mcp_config.mdx
@@ -15,22 +15,24 @@ The configuration format supports both stdio and remote (HTTP/SSE) transports, w
field definitions for server metadata, authentication, and execution parameters.
Example configuration:
- {
- "mcpServers": {
- "my-server": {
- "command": "npx",
- "args": ["-y", "@my/mcp-server"],
- "env": {"API_KEY": "secret"},
- "timeout": 30000,
- "description": "My MCP server"
- }
+```json
+{
+ "mcpServers": {
+ "my-server": {
+ "command": "npx",
+ "args": ["-y", "@my/mcp-server"],
+ "env": {"API_KEY": "secret"},
+ "timeout": 30000,
+ "description": "My MCP server"
}
}
+}
+```
## Functions
-### `infer_transport_type_from_url`
+### `infer_transport_type_from_url`
```python
infer_transport_type_from_url(url: str | AnyUrl) -> Literal['http', 'sse']
@@ -40,19 +42,22 @@ infer_transport_type_from_url(url: str | AnyUrl) -> Literal['http', 'sse']
Infer the appropriate transport type from the given URL.
-### `update_config_file`
+### `update_config_file`
```python
-update_config_file(file_path: Path, server_name: str, server_config: StdioMCPServer | RemoteMCPServer) -> None
+update_config_file(file_path: Path, server_name: str, server_config: CanonicalMCPServerTypes) -> None
```
-Update MCP configuration file with new server, preserving existing fields.
+Update an MCP configuration file from a server object, preserving existing fields.
+
+This is used for updating the mcpServer configurations of third-party tools so we do not
+worry about transforming server objects here.
## Classes
-### `StdioMCPServer`
+### `StdioMCPServer`
MCP server configuration for stdio transport.
@@ -62,13 +67,19 @@ This is the canonical configuration format for MCP servers using stdio transport
**Methods:**
-#### `to_transport`
+#### `to_transport`
```python
to_transport(self) -> StdioTransport
```
-### `RemoteMCPServer`
+### `TransformingStdioMCPServer`
+
+
+A Stdio server with tool transforms.
+
+
+### `RemoteMCPServer`
MCP server configuration for HTTP/SSE transport.
@@ -78,13 +89,85 @@ This is the canonical configuration format for MCP servers using remote transpor
**Methods:**
-#### `to_transport`
+#### `to_transport`
```python
to_transport(self) -> StreamableHttpTransport | SSETransport
```
-### `MCPConfig`
+### `TransformingRemoteMCPServer`
+
+
+A Remote server with tool transforms.
+
+
+### `MCPConfig`
+
+
+A configuration object for MCP Servers that conforms to the canonical MCP configuration format
+while adding additional fields for enabling FastMCP-specific features like tool transformations
+and filtering by tags.
+
+For an MCPConfig that is strictly canonical, see the `CanonicalMCPConfig` class.
+
+
+**Methods:**
+
+#### `validate_mcp_servers`
+
+```python
+validate_mcp_servers(self, info: ValidationInfo) -> dict[str, Any]
+```
+
+Validate the MCP servers.
+
+
+#### `add_server`
+
+```python
+add_server(self, name: str, server: MCPServerTypes) -> None
+```
+
+Add or update a server in the configuration.
+
+
+#### `from_dict`
+
+```python
+from_dict(cls, config: dict[str, Any]) -> Self
+```
+
+Parse MCP configuration from dictionary format.
+
+
+#### `to_dict`
+
+```python
+to_dict(self) -> dict[str, Any]
+```
+
+Convert MCPConfig to dictionary format, preserving all fields.
+
+
+#### `write_to_file`
+
+```python
+write_to_file(self, file_path: Path) -> None
+```
+
+Write configuration to JSON file.
+
+
+#### `from_file`
+
+```python
+from_file(cls, file_path: Path) -> Self
+```
+
+Load configuration from JSON file.
+
+
+### `CanonicalMCPConfig`
Canonical MCP configuration format.
@@ -95,56 +178,11 @@ The format is designed to be client-agnostic and extensible for future use cases
**Methods:**
-#### `from_dict`
+#### `add_server`
```python
-from_dict(cls, config: dict[str, Any]) -> MCPConfig
-```
-
-Parse MCP configuration from dictionary format.
-
-
-#### `to_dict`
-
-```python
-to_dict(self) -> dict[str, Any]
-```
-
-Convert MCPConfig to dictionary format, preserving all fields.
-
-
-#### `write_to_file`
-
-```python
-write_to_file(self, file_path: Path) -> None
-```
-
-Write configuration to JSON file.
-
-
-#### `from_file`
-
-```python
-from_file(cls, file_path: Path) -> MCPConfig
-```
-
-Load configuration from JSON file.
-
-
-#### `add_server`
-
-```python
-add_server(self, name: str, server: StdioMCPServer | RemoteMCPServer) -> None
+add_server(self, name: str, server: CanonicalMCPServerTypes) -> None
```
Add or update a server in the configuration.
-
-#### `remove_server`
-
-```python
-remove_server(self, name: str) -> None
-```
-
-Remove a server from the configuration.
-
diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx
index b41e84aa0..edca73dda 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_context`
+### `set_context`
```python
set_context(context: Context) -> Generator[Context, None, None]
@@ -15,7 +15,7 @@ set_context(context: Context) -> Generator[Context, None, None]
## Classes
-### `Context`
+### `Context`
Context object providing access to MCP capabilities.
@@ -44,16 +44,26 @@ def my_tool(x: int, ctx: Context) -> str:
request_id = ctx.request_id
client_id = ctx.client_id
+ # Manage state across the request
+ ctx.set_state_value("key", "value")
+ value = ctx.get_state_value("key")
+
return str(x)
```
+State Management:
+Context objects maintain a state dictionary that can be used to store and share
+data across middleware and tool calls within a request. When a new context
+is created (nested contexts), it inherits a copy of its parent's state, ensuring
+that modifications in child contexts don't affect parent contexts.
+
The context parameter name can be anything as long as it's annotated with Context.
The context is optional - tools that don't need it can omit the parameter.
**Methods:**
-#### `request_context`
+#### `request_context`
```python
request_context(self) -> RequestContext
@@ -64,7 +74,7 @@ Access to the underlying request context.
If called outside of a request context, this will raise a ValueError.
-#### `report_progress`
+#### `report_progress`
```python
report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None
@@ -77,7 +87,7 @@ Report progress for the current operation.
- `total`: Optional total value e.g. 100
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: str | AnyUrl) -> list[ReadResourceContents]
@@ -92,7 +102,7 @@ Read a resource by URI.
- The resource content as either text or bytes
-#### `log`
+#### `log`
```python
log(self, message: str, level: LoggingLevel | None = None, logger_name: str | None = None) -> None
@@ -107,7 +117,7 @@ Send a log message to the client.
- `logger_name`: Optional logger name
-#### `client_id`
+#### `client_id`
```python
client_id(self) -> str | None
@@ -116,7 +126,7 @@ client_id(self) -> str | None
Get the client ID if available.
-#### `request_id`
+#### `request_id`
```python
request_id(self) -> str
@@ -125,7 +135,7 @@ request_id(self) -> str
Get the unique ID for this request.
-#### `session_id`
+#### `session_id`
```python
session_id(self) -> str | None
@@ -142,7 +152,7 @@ the same client session.
- for stdio and in-memory transports which don't use session IDs.
-#### `session`
+#### `session`
```python
session(self) -> ServerSession
@@ -151,7 +161,7 @@ session(self) -> ServerSession
Access to the underlying session for advanced usage.
-#### `debug`
+#### `debug`
```python
debug(self, message: str, logger_name: str | None = None) -> None
@@ -160,7 +170,7 @@ debug(self, message: str, logger_name: str | None = None) -> None
Send a debug log message.
-#### `info`
+#### `info`
```python
info(self, message: str, logger_name: str | None = None) -> None
@@ -169,7 +179,7 @@ info(self, message: str, logger_name: str | None = None) -> None
Send an info log message.
-#### `warning`
+#### `warning`
```python
warning(self, message: str, logger_name: str | None = None) -> None
@@ -178,7 +188,7 @@ warning(self, message: str, logger_name: str | None = None) -> None
Send a warning log message.
-#### `error`
+#### `error`
```python
error(self, message: str, logger_name: str | None = None) -> None
@@ -187,7 +197,7 @@ error(self, message: str, logger_name: str | None = None) -> None
Send an error log message.
-#### `list_roots`
+#### `list_roots`
```python
list_roots(self) -> list[Root]
@@ -196,7 +206,7 @@ list_roots(self) -> list[Root]
List the roots available to the server, as indicated by the client.
-#### `send_tool_list_changed`
+#### `send_tool_list_changed`
```python
send_tool_list_changed(self) -> None
@@ -205,7 +215,7 @@ send_tool_list_changed(self) -> None
Send a tool list changed notification to the client.
-#### `send_resource_list_changed`
+#### `send_resource_list_changed`
```python
send_resource_list_changed(self) -> None
@@ -214,7 +224,7 @@ send_resource_list_changed(self) -> None
Send a resource list changed notification to the client.
-#### `send_prompt_list_changed`
+#### `send_prompt_list_changed`
```python
send_prompt_list_changed(self) -> None
@@ -223,7 +233,7 @@ send_prompt_list_changed(self) -> None
Send a prompt list changed notification to the client.
-#### `sample`
+#### `sample`
```python
sample(self, messages: str | list[str | SamplingMessage], system_prompt: str | None = None, include_context: IncludeContext | None = None, temperature: float | None = None, max_tokens: int | None = None, model_preferences: ModelPreferences | str | list[str] | None = None) -> ContentBlock
@@ -236,25 +246,25 @@ completion from the client. The client must be appropriately configured,
or the request will error.
-#### `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: type[T] | list[str] | None = None) -> AcceptedElicitation[T] | AcceptedElicitation[dict[str, Any]] | AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation
@@ -283,7 +293,7 @@ type or dataclass or BaseModel. If it is a primitive type, an
object schema with a single "value" field will be generated.
-#### `get_http_request`
+#### `get_http_request`
```python
get_http_request(self) -> Request
@@ -291,3 +301,21 @@ get_http_request(self) -> Request
Get the active starlette request.
+
+#### `set_state`
+
+```python
+set_state(self, key: str, value: Any) -> None
+```
+
+Set a value in the context state.
+
+
+#### `get_state`
+
+```python
+get_state(self, key: str) -> Any
+```
+
+Get a value from the context state. Returns None if the key is not found.
+
diff --git a/docs/python-sdk/fastmcp-server-middleware.mdx b/docs/python-sdk/fastmcp-server-middleware.mdx
deleted file mode 100644
index ec8eab242..000000000
--- a/docs/python-sdk/fastmcp-server-middleware.mdx
+++ /dev/null
@@ -1,56 +0,0 @@
----
-title: middleware
-sidebarTitle: middleware
----
-
-# `fastmcp.server.middleware`
-
-## Functions
-
-### `make_middleware_wrapper`
-
-```python
-make_middleware_wrapper(middleware: Middleware, call_next: CallNext[T, R]) -> CallNext[T, R]
-```
-
-
-Create a wrapper that applies a single middleware to a context. The
-closure bakes in the middleware and call_next function, so it can be
-passed to other functions that expect a call_next function.
-
-
-## Classes
-
-### `CallNext`
-
-### `CallToolResult`
-
-### `ListToolsResult`
-
-### `ListResourcesResult`
-
-### `ListResourceTemplatesResult`
-
-### `ListPromptsResult`
-
-### `ServerResultProtocol`
-
-### `MiddlewareContext`
-
-
-Unified context for all middleware operations.
-
-
-**Methods:**
-
-#### `copy`
-
-```python
-copy(self, **kwargs: Any) -> MiddlewareContext[T]
-```
-
-### `Middleware`
-
-
-Base class for FastMCP middleware with dispatching hooks.
-
diff --git a/docs/python-sdk/fastmcp-server-proxy.mdx b/docs/python-sdk/fastmcp-server-proxy.mdx
index db83a5611..ca07a9cda 100644
--- a/docs/python-sdk/fastmcp-server-proxy.mdx
+++ b/docs/python-sdk/fastmcp-server-proxy.mdx
@@ -7,7 +7,7 @@ sidebarTitle: proxy
## Functions
-### `default_proxy_roots_handler`
+### `default_proxy_roots_handler`
```python
default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanContextT]) -> RootsList
@@ -19,7 +19,7 @@ A handler that forwards the list roots request from the remote server to the pro
## Classes
-### `ProxyToolManager`
+### `ProxyToolManager`
A ToolManager that sources its tools from a remote client in addition to local and mounted tools.
@@ -27,7 +27,7 @@ A ToolManager that sources its tools from a remote client in addition to local a
**Methods:**
-#### `get_tools`
+#### `get_tools`
```python
get_tools(self) -> dict[str, Tool]
@@ -36,7 +36,7 @@ get_tools(self) -> dict[str, Tool]
Gets the unfiltered tool inventory including local, mounted, and proxy tools.
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> list[Tool]
@@ -45,7 +45,7 @@ list_tools(self) -> list[Tool]
Gets the filtered list of tools including local, mounted, and proxy tools.
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult
@@ -54,7 +54,7 @@ call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult
Calls a tool, trying local/mounted first, then proxy if not found.
-### `ProxyResourceManager`
+### `ProxyResourceManager`
A ResourceManager that sources its resources from a remote client in addition to local and mounted resources.
@@ -62,7 +62,7 @@ A ResourceManager that sources its resources from a remote client in addition to
**Methods:**
-#### `get_resources`
+#### `get_resources`
```python
get_resources(self) -> dict[str, Resource]
@@ -71,7 +71,7 @@ get_resources(self) -> dict[str, Resource]
Gets the unfiltered resource inventory including local, mounted, and proxy resources.
-#### `get_resource_templates`
+#### `get_resource_templates`
```python
get_resource_templates(self) -> dict[str, ResourceTemplate]
@@ -80,7 +80,7 @@ get_resource_templates(self) -> dict[str, ResourceTemplate]
Gets the unfiltered template inventory including local, mounted, and proxy templates.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> list[Resource]
@@ -89,7 +89,7 @@ list_resources(self) -> list[Resource]
Gets the filtered list of resources including local, mounted, and proxy resources.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> list[ResourceTemplate]
@@ -98,7 +98,7 @@ list_resource_templates(self) -> list[ResourceTemplate]
Gets the filtered list of templates including local, mounted, and proxy templates.
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: AnyUrl | str) -> str | bytes
@@ -107,7 +107,7 @@ read_resource(self, uri: AnyUrl | str) -> str | bytes
Reads a resource, trying local/mounted first, then proxy if not found.
-### `ProxyPromptManager`
+### `ProxyPromptManager`
A PromptManager that sources its prompts from a remote client in addition to local and mounted prompts.
@@ -115,7 +115,7 @@ A PromptManager that sources its prompts from a remote client in addition to loc
**Methods:**
-#### `get_prompts`
+#### `get_prompts`
```python
get_prompts(self) -> dict[str, Prompt]
@@ -124,7 +124,7 @@ get_prompts(self) -> dict[str, Prompt]
Gets the unfiltered prompt inventory including local, mounted, and proxy prompts.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> list[Prompt]
@@ -133,7 +133,7 @@ list_prompts(self) -> list[Prompt]
Gets the filtered list of prompts including local, mounted, and proxy prompts.
-#### `render_prompt`
+#### `render_prompt`
```python
render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult
@@ -142,7 +142,7 @@ render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPr
Renders a prompt, trying local/mounted first, then proxy if not found.
-### `ProxyTool`
+### `ProxyTool`
A Tool that represents and executes a tool on a remote server.
@@ -150,7 +150,7 @@ A Tool that represents and executes a tool on a remote server.
**Methods:**
-#### `from_mcp_tool`
+#### `from_mcp_tool`
```python
from_mcp_tool(cls, client: Client, mcp_tool: mcp.types.Tool) -> ProxyTool
@@ -159,7 +159,7 @@ from_mcp_tool(cls, client: Client, mcp_tool: mcp.types.Tool) -> ProxyTool
Factory method to create a ProxyTool from a raw MCP tool schema.
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResult
@@ -168,7 +168,7 @@ run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResu
Executes the tool by making a call through the client.
-### `ProxyResource`
+### `ProxyResource`
A Resource that represents and reads a resource from a remote server.
@@ -176,7 +176,7 @@ A Resource that represents and reads a resource from a remote server.
**Methods:**
-#### `from_mcp_resource`
+#### `from_mcp_resource`
```python
from_mcp_resource(cls, client: Client, mcp_resource: mcp.types.Resource) -> ProxyResource
@@ -185,7 +185,7 @@ from_mcp_resource(cls, client: Client, mcp_resource: mcp.types.Resource) -> Prox
Factory method to create a ProxyResource from a raw MCP resource schema.
-#### `read`
+#### `read`
```python
read(self) -> str | bytes
@@ -194,7 +194,7 @@ read(self) -> str | bytes
Read the resource content from the remote server.
-### `ProxyTemplate`
+### `ProxyTemplate`
A ResourceTemplate that represents and creates resources from a remote server template.
@@ -202,7 +202,7 @@ A ResourceTemplate that represents and creates resources from a remote server te
**Methods:**
-#### `from_mcp_template`
+#### `from_mcp_template`
```python
from_mcp_template(cls, client: Client, mcp_template: mcp.types.ResourceTemplate) -> ProxyTemplate
@@ -211,7 +211,7 @@ from_mcp_template(cls, client: Client, mcp_template: mcp.types.ResourceTemplate)
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
@@ -220,7 +220,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.
@@ -228,7 +228,7 @@ A Prompt that represents and renders a prompt from a remote server.
**Methods:**
-#### `from_mcp_prompt`
+#### `from_mcp_prompt`
```python
from_mcp_prompt(cls, client: Client, mcp_prompt: mcp.types.Prompt) -> ProxyPrompt
@@ -237,7 +237,7 @@ from_mcp_prompt(cls, client: Client, mcp_prompt: mcp.types.Prompt) -> ProxyPromp
Factory method to create a ProxyPrompt from a raw MCP prompt schema.
-#### `render`
+#### `render`
```python
render(self, arguments: dict[str, Any]) -> list[PromptMessage]
@@ -246,14 +246,14 @@ render(self, arguments: dict[str, Any]) -> list[PromptMessage]
Render the prompt by making a call through the client.
-### `FastMCPProxy`
+### `FastMCPProxy`
A FastMCP server that acts as a proxy to a remote MCP-compliant server.
It uses specialized managers that fulfill requests via a client factory.
-### `ProxyClient`
+### `ProxyClient`
A proxy client that forwards advanced interactions between a remote MCP server and the proxy's connected clients.
@@ -262,7 +262,7 @@ Supports forwarding roots, sampling, elicitation, logging, and progress.
**Methods:**
-#### `default_sampling_handler`
+#### `default_sampling_handler`
```python
default_sampling_handler(cls, messages: list[mcp.types.SamplingMessage], params: mcp.types.CreateMessageRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> mcp.types.CreateMessageResult
@@ -271,7 +271,7 @@ default_sampling_handler(cls, messages: list[mcp.types.SamplingMessage], params:
A handler that forwards the sampling request from the remote server to the proxy's connected clients and relays the response back to the remote server.
-#### `default_elicitation_handler`
+#### `default_elicitation_handler`
```python
default_elicitation_handler(cls, message: str, response_type: type, params: mcp.types.ElicitRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> ElicitResult
@@ -280,7 +280,7 @@ default_elicitation_handler(cls, message: str, response_type: type, params: mcp.
A handler that forwards the elicitation request from the remote server to the proxy's connected clients and relays the response back to the remote server.
-#### `default_log_handler`
+#### `default_log_handler`
```python
default_log_handler(cls, message: LogMessage) -> None
@@ -289,7 +289,7 @@ default_log_handler(cls, message: LogMessage) -> None
A handler that forwards the log notification from the remote server to the proxy's connected clients.
-#### `default_progress_handler`
+#### `default_progress_handler`
```python
default_progress_handler(cls, progress: float, total: float | None, message: str | None) -> None
@@ -297,3 +297,28 @@ default_progress_handler(cls, progress: float, total: float | None, message: str
A handler that forwards the progress notification from the remote server to the proxy's connected clients.
+
+### `StatefulProxyClient`
+
+
+A proxy client that provides a stateful client factory for the proxy server.
+
+The stateful proxy client bound its copy to the server session.
+And it will be disconnected when the session is exited.
+
+This is useful to proxy a stateful mcp server such as the Playwright MCP server.
+Note that it is essential to ensure that the proxy server itself is also stateful.
+
+
+**Methods:**
+
+#### `new_stateful`
+
+```python
+new_stateful(self) -> Client[ClientTransportT]
+```
+
+Create a new stateful proxy client instance with the same configuration.
+
+Use this method as the client factory for stateful proxy server.
+
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index 986e382bd..611980c70 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 context object
-### `add_resource_prefix`
+### `add_resource_prefix`
```python
add_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> str
@@ -64,7 +64,7 @@ add_resource_prefix("resource:///absolute/path", "prefix")
- `ValueError`: If the URI doesn't match the expected protocol\://path format
-### `remove_resource_prefix`
+### `remove_resource_prefix`
```python
remove_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> str
@@ -103,7 +103,7 @@ remove_resource_prefix("resource://prefix//absolute/path", "prefix")
- `ValueError`: If the URI doesn't match the expected protocol\://path format
-### `has_resource_prefix`
+### `has_resource_prefix`
```python
has_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> bool
@@ -143,29 +143,29 @@ False
## Classes
-### `FastMCP`
+### `FastMCP`
**Methods:**
-#### `settings`
+#### `settings`
```python
settings(self) -> Settings
```
-#### `name`
+#### `name`
```python
name(self) -> str
```
-#### `instructions`
+#### `instructions`
```python
instructions(self) -> str | None
```
-#### `run_async`
+#### `run_async`
```python
run_async(self, transport: Transport | None = None, show_banner: bool = True, **transport_kwargs: Any) -> None
@@ -177,7 +177,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
@@ -189,13 +189,13 @@ Run the FastMCP server. Note this is a synchronous function.
- `transport`: Transport protocol to use ("stdio", "sse", or "streamable-http")
-#### `add_middleware`
+#### `add_middleware`
```python
add_middleware(self, middleware: Middleware) -> None
```
-#### `get_tools`
+#### `get_tools`
```python
get_tools(self) -> dict[str, Tool]
@@ -204,13 +204,13 @@ get_tools(self) -> dict[str, Tool]
Get all registered tools, indexed by registered key.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, key: str) -> Tool
```
-#### `get_resources`
+#### `get_resources`
```python
get_resources(self) -> dict[str, Resource]
@@ -219,13 +219,13 @@ get_resources(self) -> dict[str, Resource]
Get all registered resources, indexed by registered key.
-#### `get_resource`
+#### `get_resource`
```python
get_resource(self, key: str) -> Resource
```
-#### `get_resource_templates`
+#### `get_resource_templates`
```python
get_resource_templates(self) -> dict[str, ResourceTemplate]
@@ -234,7 +234,7 @@ get_resource_templates(self) -> dict[str, ResourceTemplate]
Get all registered resource templates, indexed by registered key.
-#### `get_resource_template`
+#### `get_resource_template`
```python
get_resource_template(self, key: str) -> ResourceTemplate
@@ -243,7 +243,7 @@ get_resource_template(self, key: str) -> ResourceTemplate
Get a registered resource template by key.
-#### `get_prompts`
+#### `get_prompts`
```python
get_prompts(self) -> dict[str, Prompt]
@@ -252,16 +252,16 @@ get_prompts(self) -> dict[str, Prompt]
List all available prompts.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, key: str) -> Prompt
```
-#### `custom_route`
+#### `custom_route`
```python
-custom_route(self, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True)
+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]]]
```
Decorator to register a custom HTTP route on the FastMCP server.
@@ -279,7 +279,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
@@ -297,7 +297,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
@@ -312,19 +312,37 @@ Remove a tool from the server.
- `NotFoundError`: If the tool is not found
-#### `tool`
+#### `add_tool_transformation`
+
+```python
+add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None
+```
+
+Add a tool transformation.
+
+
+#### `remove_tool_transformation`
+
+```python
+remove_tool_transformation(self, tool_name: str) -> None
+```
+
+Remove a tool transformation.
+
+
+#### `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
@@ -379,7 +397,7 @@ server.tool(my_function, name="custom_name")
```
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource) -> Resource
@@ -394,7 +412,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
@@ -409,7 +427,7 @@ Add a resource template to the server.
- The template instance that was added to the server.
-#### `add_resource_fn`
+#### `add_resource_fn`
```python
add_resource_fn(self, fn: AnyFunction, uri: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> None
@@ -429,7 +447,7 @@ has parameters, it will be registered as a template resource.
- `tags`: Optional set of tags for categorizing the resource
-#### `resource`
+#### `resource`
```python
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate]
@@ -487,7 +505,7 @@ async def get_weather(city: str) -> str:
```
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt) -> Prompt
@@ -502,19 +520,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
@@ -591,7 +609,7 @@ Decorator to register a prompt.
```
-#### `run_stdio_async`
+#### `run_stdio_async`
```python
run_stdio_async(self, show_banner: bool = True) -> None
@@ -600,7 +618,7 @@ run_stdio_async(self, show_banner: bool = True) -> None
Run the server using stdio transport.
-#### `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, stateless_http: bool | None = None) -> None
@@ -619,7 +637,7 @@ Run the server using HTTP transport.
- `stateless_http`: Whether to use stateless HTTP (defaults to settings.stateless_http)
-#### `run_sse_async`
+#### `run_sse_async`
```python
run_sse_async(self, host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None) -> None
@@ -628,7 +646,7 @@ run_sse_async(self, host: str | None = None, port: int | None = None, log_level:
Run the server using SSE transport.
-#### `sse_app`
+#### `sse_app`
```python
sse_app(self, path: str | None = None, message_path: str | None = None, middleware: list[ASGIMiddleware] | None = None) -> StarletteWithLifespan
@@ -642,7 +660,7 @@ Create a Starlette app for the SSE server.
- `middleware`: A list of middleware to apply to the app
-#### `streamable_http_app`
+#### `streamable_http_app`
```python
streamable_http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None) -> StarletteWithLifespan
@@ -655,7 +673,7 @@ Create a Starlette app for the StreamableHTTP server.
- `middleware`: A list of middleware to apply to the app
-#### `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') -> StarletteWithLifespan
@@ -672,13 +690,13 @@ Create a Starlette app using the specified HTTP transport.
- A Starlette application configured with the specified transport
-#### `run_streamable_http_async`
+#### `run_streamable_http_async`
```python
run_streamable_http_async(self, host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None) -> None
```
-#### `mount`
+#### `mount`
```python
mount(self, server: FastMCP[LifespanResultT], prefix: str | None = None, as_proxy: bool | None = None) -> None
@@ -732,7 +750,7 @@ automatically determined based on whether the server has a custom lifespan
- `prompt_separator`: Deprecated. Separator character for prompt names.
-#### `import_server`
+#### `import_server`
```python
import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None, tool_separator: str | None = None, resource_separator: str | None = None, prompt_separator: str | None = None) -> None
@@ -773,25 +791,25 @@ applied using the protocol\://prefix/path format
- `prompt_separator`: Deprecated. Separator for prompt names.
-#### `from_openapi`
+#### `from_openapi`
```python
-from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, 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, **settings: Any) -> FastMCPOpenAPI
+from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, route_maps: list[RouteMap] | list[RouteMapNew] | None = None, route_map_fn: OpenAPIRouteMapFn | OpenAPIRouteMapFnNew | None = None, mcp_component_fn: OpenAPIComponentFn | OpenAPIComponentFnNew | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI | FastMCPOpenAPINew
```
Create a FastMCP server from an OpenAPI specification.
-#### `from_fastapi`
+#### `from_fastapi`
```python
-from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI
+from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | list[RouteMapNew] | None = None, route_map_fn: OpenAPIRouteMapFn | OpenAPIRouteMapFnNew | None = None, mcp_component_fn: OpenAPIComponentFn | OpenAPIComponentFnNew | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI | FastMCPOpenAPINew
```
Create a FastMCP server from a FastAPI application.
-#### `as_proxy`
+#### `as_proxy`
```python
as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
@@ -805,7 +823,7 @@ instance or any value accepted as the `transport` argument of
`fastmcp.client.Client` constructor.
-#### `from_client`
+#### `from_client`
```python
from_client(cls, client: Client[ClientTransportT], **settings: Any) -> FastMCPProxy
@@ -814,4 +832,4 @@ from_client(cls, client: Client[ClientTransportT], **settings: Any) -> FastMCPPr
Create a FastMCP proxy server from a FastMCP client.
-### `MountedServer`
+### `MountedServer`
diff --git a/docs/python-sdk/fastmcp-settings.mdx b/docs/python-sdk/fastmcp-settings.mdx
index 7f546c31b..6c460937b 100644
--- a/docs/python-sdk/fastmcp-settings.mdx
+++ b/docs/python-sdk/fastmcp-settings.mdx
@@ -25,7 +25,9 @@ get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str, bool
### `ExtendedSettingsConfigDict`
-### `Settings`
+### `ExperimentalSettings`
+
+### `Settings`
FastMCP settings.
@@ -33,13 +35,33 @@ FastMCP settings.
**Methods:**
-#### `settings_customise_sources`
+#### `get_setting`
+
+```python
+get_setting(self, attr: str) -> Any
+```
+
+Get a setting. If the setting contains one or more `__`, it will be
+treated as a nested setting.
+
+
+#### `set_setting`
+
+```python
+set_setting(self, attr: str, value: Any) -> None
+```
+
+Set a setting. If the setting contains one or more `__`, it will be
+treated as a nested setting.
+
+
+#### `settings_customise_sources`
```python
settings_customise_sources(cls, settings_cls: type[BaseSettings], init_settings: PydanticBaseSettingsSource, env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource) -> tuple[PydanticBaseSettingsSource, ...]
```
-#### `settings`
+#### `settings`
```python
settings(self) -> Self
@@ -49,17 +71,8 @@ This property is for backwards compatibility with FastMCP < 2.8.0,
which accessed fastmcp.settings.settings
-#### `normalize_log_level`
+#### `normalize_log_level`
```python
normalize_log_level(cls, v)
```
-
-#### `setup_logging`
-
-```python
-setup_logging(self) -> Self
-```
-
-Finalize the settings.
-
diff --git a/docs/python-sdk/fastmcp-tools-tool.mdx b/docs/python-sdk/fastmcp-tools-tool.mdx
index 60c8fff9a..ce27bb86f 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]]
```
-### `Tool`
+### `Tool`
Internal tool registration info.
@@ -33,25 +33,25 @@ Internal tool registration info.
**Methods:**
-#### `enable`
+#### `enable`
```python
enable(self) -> None
```
-#### `disable`
+#### `disable`
```python
disable(self) -> None
```
-#### `to_mcp_tool`
+#### `to_mcp_tool`
```python
to_mcp_tool(self, **overrides: Any) -> MCPTool
```
-#### `from_function`
+#### `from_function`
```python
from_function(fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | None | NotSetT | Literal[False] = NotSet, serializer: Callable[[Any], str] | None = None, enabled: bool | None = None) -> FunctionTool
@@ -60,7 +60,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
@@ -75,17 +75,17 @@ implemented by subclasses.
(list of ContentBlocks, dict of structured output).
-#### `from_tool`
+#### `from_tool`
```python
from_tool(cls, tool: Tool, transform_fn: Callable[..., Any] | None = None, name: str | None = None, title: str | None | NotSetT = NotSet, transform_args: dict[str, ArgTransform] | None = None, description: str | None | NotSetT = NotSet, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, output_schema: dict[str, Any] | None | Literal[False] = None, serializer: Callable[[Any], str] | None = None, enabled: bool | None = None) -> TransformedTool
```
-### `FunctionTool`
+### `FunctionTool`
**Methods:**
-#### `from_function`
+#### `from_function`
```python
from_function(cls, fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | None | NotSetT | Literal[False] = NotSet, serializer: Callable[[Any], str] | None = None, enabled: bool | None = None) -> FunctionTool
@@ -94,7 +94,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
@@ -103,11 +103,11 @@ run(self, arguments: dict[str, Any]) -> ToolResult
Run the tool with arguments.
-### `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_manager.mdx b/docs/python-sdk/fastmcp-tools-tool_manager.mdx
index f9b6b61f7..3b94ee85e 100644
--- a/docs/python-sdk/fastmcp-tools-tool_manager.mdx
+++ b/docs/python-sdk/fastmcp-tools-tool_manager.mdx
@@ -7,7 +7,7 @@ sidebarTitle: tool_manager
## Classes
-### `ToolManager`
+### `ToolManager`
Manages FastMCP tools.
@@ -15,7 +15,7 @@ Manages FastMCP tools.
**Methods:**
-#### `mount`
+#### `mount`
```python
mount(self, server: MountedServer) -> None
@@ -24,7 +24,7 @@ mount(self, server: MountedServer) -> None
Adds a mounted server as a source for tools.
-#### `has_tool`
+#### `has_tool`
```python
has_tool(self, key: str) -> bool
@@ -33,7 +33,7 @@ has_tool(self, key: str) -> bool
Check if a tool exists.
-#### `get_tool`
+#### `get_tool`
```python
get_tool(self, key: str) -> Tool
@@ -42,7 +42,7 @@ get_tool(self, key: str) -> Tool
Get tool by key.
-#### `get_tools`
+#### `get_tools`
```python
get_tools(self) -> dict[str, Tool]
@@ -51,7 +51,7 @@ get_tools(self) -> dict[str, Tool]
Gets the complete, unfiltered inventory of all tools.
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> list[Tool]
@@ -60,7 +60,7 @@ list_tools(self) -> list[Tool]
Lists all tools, applying protocol filtering.
-#### `add_tool_from_fn`
+#### `add_tool_from_fn`
```python
add_tool_from_fn(self, fn: Callable[..., Any], name: str | None = None, description: str | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, serializer: Callable[[Any], str] | None = None, exclude_args: list[str] | None = None) -> Tool
@@ -69,7 +69,7 @@ add_tool_from_fn(self, fn: Callable[..., Any], name: str | None = None, descript
Add a tool to the server.
-#### `add_tool`
+#### `add_tool`
```python
add_tool(self, tool: Tool) -> Tool
@@ -78,7 +78,34 @@ add_tool(self, tool: Tool) -> Tool
Register a tool with the server.
-#### `remove_tool`
+#### `add_tool_transformation`
+
+```python
+add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None
+```
+
+Add a tool transformation.
+
+
+#### `get_tool_transformation`
+
+```python
+get_tool_transformation(self, tool_name: str) -> ToolTransformConfig | None
+```
+
+Get a tool transformation.
+
+
+#### `remove_tool_transformation`
+
+```python
+remove_tool_transformation(self, tool_name: str) -> None
+```
+
+Remove a tool transformation.
+
+
+#### `remove_tool`
```python
remove_tool(self, key: str) -> None
@@ -93,7 +120,7 @@ Remove a tool from the server.
- `NotFoundError`: If the tool is not found
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult
diff --git a/docs/python-sdk/fastmcp-tools-tool_transform.mdx b/docs/python-sdk/fastmcp-tools-tool_transform.mdx
index f39ece8f4..b2ad153fb 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) -> 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) -> ToolResult
@@ -62,9 +62,20 @@ 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`
+
+```python
+apply_transformations_to_tools(tools: dict[str, Tool], transformations: dict[str, ToolTransformConfig]) -> dict[str, Tool]
+```
+
+
+Apply a list of transformations to a list of tools. Tools that do not have any transforamtions
+are left unchanged.
+
+
## Classes
-### `ArgTransform`
+### `ArgTransform`
Configuration for transforming a parent tool's argument.
@@ -126,7 +137,24 @@ ArgTransform(name="new_name", description="New desc", default=None, type=int)
```
-### `TransformedTool`
+### `ArgTransformConfig`
+
+
+A model for requesting a single argument transform.
+
+
+**Methods:**
+
+#### `to_arg_transform`
+
+```python
+to_arg_transform(self) -> ArgTransform
+```
+
+Convert the argument transform to a FastMCP argument transform.
+
+
+### `TransformedTool`
A tool that is transformed from another tool.
@@ -143,7 +171,7 @@ inherited from the parent tool but can be overridden or disabled.
**Methods:**
-#### `run`
+#### `run`
```python
run(self, arguments: dict[str, Any]) -> ToolResult
@@ -162,7 +190,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 | None | NotSetT = NotSet, description: str | None | NotSetT = NotSet, tags: set[str] | None = None, transform_fn: Callable[..., Any] | None = None, transform_args: dict[str, ArgTransform] | None = None, annotations: ToolAnnotations | None = None, output_schema: dict[str, Any] | None | Literal[False] = None, serializer: Callable[[Any], str] | None = None, enabled: bool | None = None) -> TransformedTool
@@ -239,3 +267,20 @@ async def custom_output(**kwargs) -> ToolResult:
)
```
+
+### `ToolTransformConfig`
+
+
+Provides a way to transform a tool.
+
+
+**Methods:**
+
+#### `apply`
+
+```python
+apply(self, tool: Tool) -> TransformedTool
+```
+
+Create a TransformedTool from a provided tool and this transformation configuration.
+
diff --git a/docs/python-sdk/fastmcp-utilities-json_schema.mdx b/docs/python-sdk/fastmcp-utilities-json_schema.mdx
index 451b3dbff..b782a2668 100644
--- a/docs/python-sdk/fastmcp-utilities-json_schema.mdx
+++ b/docs/python-sdk/fastmcp-utilities-json_schema.mdx
@@ -7,7 +7,7 @@ sidebarTitle: json_schema
## Functions
-### `compress_schema`
+### `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
diff --git a/docs/python-sdk/fastmcp-utilities-mcp_config.mdx b/docs/python-sdk/fastmcp-utilities-mcp_config.mdx
index fe1d6f156..eac19c909 100644
--- a/docs/python-sdk/fastmcp-utilities-mcp_config.mdx
+++ b/docs/python-sdk/fastmcp-utilities-mcp_config.mdx
@@ -7,44 +7,22 @@ sidebarTitle: mcp_config
## Functions
-### `infer_transport_type_from_url`
+### `composite_server_from_mcp_config`
```python
-infer_transport_type_from_url(url: str | AnyUrl) -> Literal['http', 'sse']
+composite_server_from_mcp_config(config: MCPConfig, name_as_prefix: bool = True) -> FastMCP
```
-Infer the appropriate transport type from the given URL.
+A utility function to create a composite server from an MCPConfig.
-## Classes
-
-### `StdioMCPServer`
-
-**Methods:**
-
-#### `to_transport`
+### `mount_mcp_config_into_server`
```python
-to_transport(self) -> StdioTransport
+mount_mcp_config_into_server(config: MCPConfig, server: FastMCP, name_as_prefix: bool = True) -> None
```
-### `RemoteMCPServer`
-**Methods:**
+A utility function to mount the servers from an MCPConfig into a FastMCP server.
-#### `to_transport`
-
-```python
-to_transport(self) -> StreamableHttpTransport | SSETransport
-```
-
-### `MCPConfig`
-
-**Methods:**
-
-#### `from_dict`
-
-```python
-from_dict(cls, config: dict[str, Any]) -> MCPConfig
-```
diff --git a/docs/python-sdk/fastmcp-utilities-openapi.mdx b/docs/python-sdk/fastmcp-utilities-openapi.mdx
index 4cb84f5f4..970ebaaf1 100644
--- a/docs/python-sdk/fastmcp-utilities-openapi.mdx
+++ b/docs/python-sdk/fastmcp-utilities-openapi.mdx
@@ -7,7 +7,7 @@ sidebarTitle: openapi
## Functions
-### `format_array_parameter`
+### `format_array_parameter`
```python
format_array_parameter(values: list, parameter_name: str, is_query_parameter: bool = False) -> str | list
@@ -25,7 +25,7 @@ Format an array parameter according to OpenAPI specifications.
- String (comma-separated) or list (for query params with explode=True)
-### `format_deep_object_parameter`
+### `format_deep_object_parameter`
```python
format_deep_object_parameter(param_value: dict, parameter_name: str) -> dict[str, str]
@@ -37,8 +37,7 @@ Format a dictionary parameter for deepObject style serialization.
According to OpenAPI 3.0 spec, deepObject style with explode=true serializes
object properties as separate query parameters with bracket notation.
-For example: {"id": "123", "type": "user"} becomes:
-param[id]=123¶m[type]=user
+For example: `{"id": "123", "type": "user"}` becomes `param[id]=123¶m[type]=user`.
**Args:**
- `param_value`: Dictionary value to format
@@ -48,7 +47,7 @@ param[id]=123¶m[type]=user
- Dictionary with bracketed parameter names as keys
-### `parse_openapi_to_http_routes`
+### `parse_openapi_to_http_routes`
```python
parse_openapi_to_http_routes(openapi_dict: dict[str, Any]) -> list[HTTPRoute]
@@ -61,7 +60,7 @@ using the openapi-pydantic library.
Supports both OpenAPI 3.0.x and 3.1.x versions.
-### `clean_schema_for_display`
+### `clean_schema_for_display`
```python
clean_schema_for_display(schema: JsonSchema | None) -> JsonSchema | None
@@ -71,7 +70,7 @@ clean_schema_for_display(schema: JsonSchema | None) -> JsonSchema | None
Clean up a schema dictionary for display by removing internal/complex fields.
-### `generate_example_from_schema`
+### `generate_example_from_schema`
```python
generate_example_from_schema(schema: JsonSchema | None) -> Any
@@ -82,7 +81,7 @@ Generate a simple example value from a JSON schema dictionary.
Very basic implementation focusing on types.
-### `format_json_for_description`
+### `format_json_for_description`
```python
format_json_for_description(data: Any, indent: int = 2) -> str
@@ -92,7 +91,7 @@ format_json_for_description(data: Any, indent: int = 2) -> str
Formats Python data as a JSON string block for markdown.
-### `format_description_with_responses`
+### `format_description_with_responses`
```python
format_description_with_responses(base_description: str, responses: dict[str, Any], parameters: list[ParameterInfo] | None = None, request_body: RequestBodyInfo | None = None) -> str
@@ -115,7 +114,7 @@ including its description, whether it is required, and its content schema.
- and the request body.
-### `extract_output_schema_from_responses`
+### `extract_output_schema_from_responses`
```python
extract_output_schema_from_responses(responses: dict[str, ResponseInfo], schema_definitions: dict[str, Any] | None = None) -> dict[str, Any] | None
@@ -138,31 +137,31 @@ object type, it wraps it to comply with MCP requirements.
## Classes
-### `ParameterInfo`
+### `ParameterInfo`
Represents a single parameter for an HTTP operation in our IR.
-### `RequestBodyInfo`
+### `RequestBodyInfo`
Represents the request body for an HTTP operation in our IR.
-### `ResponseInfo`
+### `ResponseInfo`
Represents response information in our IR.
-### `HTTPRoute`
+### `HTTPRoute`
Intermediate Representation for a single OpenAPI operation.
-### `OpenAPIParser`
+### `OpenAPIParser`
Unified parser for OpenAPI schemas with generic type parameters to handle both 3.0 and 3.1.
@@ -170,7 +169,7 @@ Unified parser for OpenAPI schemas with generic type parameters to handle both 3
**Methods:**
-#### `parse`
+#### `parse`
```python
parse(self) -> list[HTTPRoute]
diff --git a/docs/python-sdk/fastmcp-utilities-tests.mdx b/docs/python-sdk/fastmcp-utilities-tests.mdx
index f8f1d8fb8..5766b4d02 100644
--- a/docs/python-sdk/fastmcp-utilities-tests.mdx
+++ b/docs/python-sdk/fastmcp-utilities-tests.mdx
@@ -20,7 +20,7 @@ Temporarily override FastMCP setting values.
- `**kwargs`: The settings to override, including nested settings.
-### `run_server_in_process`
+### `run_server_in_process`
```python
run_server_in_process(server_fn: Callable[..., None], *args, **kwargs) -> Generator[str, None, None]
@@ -41,7 +41,7 @@ not pickleable, so we need a function that creates and runs one.
- The server URL.
-### `caplog_for_fastmcp`
+### `caplog_for_fastmcp`
```python
caplog_for_fastmcp(caplog)
diff --git a/docs/python-sdk/fastmcp-utilities-types.mdx b/docs/python-sdk/fastmcp-utilities-types.mdx
index 378e0e076..4d08be539 100644
--- a/docs/python-sdk/fastmcp-utilities-types.mdx
+++ b/docs/python-sdk/fastmcp-utilities-types.mdx
@@ -10,7 +10,7 @@ Common types used across FastMCP.
## Functions
-### `get_cached_typeadapter`
+### `get_cached_typeadapter`
```python
get_cached_typeadapter(cls: T) -> TypeAdapter[T]
@@ -23,7 +23,7 @@ However, this isn't feasible for user-generated functions. Instead, we use a
cache to minimize the cost of creating them as much as possible.
-### `issubclass_safe`
+### `issubclass_safe`
```python
issubclass_safe(cls: type, base: type) -> bool
@@ -33,7 +33,7 @@ issubclass_safe(cls: type, base: type) -> bool
Check if cls is a subclass of base, even if cls is a type variable.
-### `is_class_member_of_type`
+### `is_class_member_of_type`
```python
is_class_member_of_type(cls: type, base: type) -> bool
@@ -46,7 +46,7 @@ Base can be a type, a UnionType, or an Annotated type. Generic types are not
considered members (e.g. T is not a member of list\[T]).
-### `find_kwarg_by_type`
+### `find_kwarg_by_type`
```python
find_kwarg_by_type(fn: Callable, kwarg_type: type) -> str | None
@@ -58,7 +58,7 @@ Find the name of the kwarg that is of type kwarg_type.
Includes union types that contain the kwarg_type, as well as Annotated types.
-### `replace_type`
+### `replace_type`
```python
replace_type(type_, type_map: dict[type, type])
@@ -75,23 +75,25 @@ This is useful for transforming types when creating tools.
- `old_type`: The type to replace.
- `new_type`: The type to replace old_type with.
-**Examples:**
+Examples:
+```python
+>>> replace_type(list[int | bool], {int: str})
+list[str | bool]
->>> replace_type(list\[int | bool], {int: str})
-list\[str | bool]
->>> replace_type(list\[list\[int]], {int: str})
-list\[list\[str]]
+>>> replace_type(list[list[int]], {int: str})
+list[list[str]]
+```
## Classes
-### `FastMCPBaseModel`
+### `FastMCPBaseModel`
Base model for FastMCP models.
-### `Image`
+### `Image`
Helper class for returning images from tools.
@@ -99,7 +101,7 @@ Helper class for returning images from tools.
**Methods:**
-#### `to_image_content`
+#### `to_image_content`
```python
to_image_content(self, mime_type: str | None = None, annotations: Annotations | None = None) -> mcp.types.ImageContent
@@ -108,7 +110,7 @@ to_image_content(self, mime_type: str | None = None, annotations: Annotations |
Convert to MCP ImageContent.
-### `Audio`
+### `Audio`
Helper class for returning audio from tools.
@@ -116,13 +118,13 @@ Helper class for returning audio from tools.
**Methods:**
-#### `to_audio_content`
+#### `to_audio_content`
```python
to_audio_content(self, mime_type: str | None = None, annotations: Annotations | None = None) -> mcp.types.AudioContent
```
-### `File`
+### `File`
Helper class for returning audio from tools.
@@ -130,7 +132,7 @@ Helper class for returning audio from tools.
**Methods:**
-#### `to_resource_content`
+#### `to_resource_content`
```python
to_resource_content(self, mime_type: str | None = None, annotations: Annotations | None = None) -> mcp.types.EmbeddedResource
diff --git a/src/fastmcp/mcp_config.py b/src/fastmcp/mcp_config.py
index e6758e0c7..a534fac38 100644
--- a/src/fastmcp/mcp_config.py
+++ b/src/fastmcp/mcp_config.py
@@ -7,17 +7,19 @@ The configuration format supports both stdio and remote (HTTP/SSE) transports, w
field definitions for server metadata, authentication, and execution parameters.
Example configuration:
- {
- "mcpServers": {
- "my-server": {
- "command": "npx",
- "args": ["-y", "@my/mcp-server"],
- "env": {"API_KEY": "secret"},
- "timeout": 30000,
- "description": "My MCP server"
- }
+```json
+{
+ "mcpServers": {
+ "my-server": {
+ "command": "npx",
+ "args": ["-y", "@my/mcp-server"],
+ "env": {"API_KEY": "secret"},
+ "timeout": 30000,
+ "description": "My MCP server"
}
}
+}
+```
"""
from __future__ import annotations
diff --git a/src/fastmcp/utilities/openapi.py b/src/fastmcp/utilities/openapi.py
index a636e815c..ef7ae874f 100644
--- a/src/fastmcp/utilities/openapi.py
+++ b/src/fastmcp/utilities/openapi.py
@@ -101,8 +101,7 @@ def format_deep_object_parameter(
According to OpenAPI 3.0 spec, deepObject style with explode=true serializes
object properties as separate query parameters with bracket notation.
- For example: {"id": "123", "type": "user"} becomes:
- param[id]=123¶m[type]=user
+ For example: `{"id": "123", "type": "user"}` becomes `param[id]=123¶m[type]=user`.
Args:
param_value: Dictionary value to format
diff --git a/src/fastmcp/utilities/types.py b/src/fastmcp/utilities/types.py
index d309f2af9..815e1faba 100644
--- a/src/fastmcp/utilities/types.py
+++ b/src/fastmcp/utilities/types.py
@@ -368,12 +368,13 @@ def replace_type(type_, type_map: dict[type, type]):
new_type: The type to replace old_type with.
Examples:
- >>> replace_type(list[int | bool], {int: str})
- list[str | bool]
-
- >>> replace_type(list[list[int]], {int: str})
- list[list[str]]
+ ```python
+ >>> replace_type(list[int | bool], {int: str})
+ list[str | bool]
+ >>> replace_type(list[list[int]], {int: str})
+ list[list[str]]
+ ```
"""
if type_ in type_map:
return type_map[type_]