diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx
index 60838c769f..83677c6715 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
-### `with_argv`
+### `with_argv`
```python
with_argv(args: list[str] | None)
@@ -27,7 +27,7 @@ Args are provided without the script name, so we preserve sys.argv[0]
and replace the rest.
-### `version`
+### `version`
```python
version()
@@ -37,7 +37,7 @@ version()
Display version information and platform details.
-### `dev`
+### `dev`
```python
dev(server_spec: str | None = None) -> None
@@ -50,7 +50,7 @@ Run an MCP server with the MCP Inspector for development.
- `server_spec`: Python file to run, optionally with \:object suffix, or None to auto-detect fastmcp.json
-### `run`
+### `run`
```python
run(server_spec: str | None = None, *server_args: str) -> None
@@ -74,7 +74,7 @@ fastmcp run server.py -- --config config.json --debug
- `server_spec`: Python file, object specification (file\:obj), config file, URL, or None to auto-detect
-### `inspect`
+### `inspect`
```python
inspect(server_spec: str | None = None) -> None
@@ -105,7 +105,7 @@ fastmcp inspect # auto-detect fastmcp.json
- `server_spec`: Python file to inspect, optionally with \:object suffix, or fastmcp.json
-### `prepare`
+### `prepare`
```python
prepare(config_path: Annotated[str | None, cyclopts.Parameter(help='Path to fastmcp.json configuration file')] = None, output_dir: Annotated[str | None, cyclopts.Parameter(help='Directory to create the persistent environment in')] = None, skip_source: Annotated[bool, cyclopts.Parameter(help='Skip source preparation (e.g., git clone)')] = False) -> None
diff --git a/docs/python-sdk/fastmcp-cli-install-claude_code.mdx b/docs/python-sdk/fastmcp-cli-install-claude_code.mdx
index fd1d888ff3..3889da224e 100644
--- a/docs/python-sdk/fastmcp-cli-install-claude_code.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-claude_code.mdx
@@ -57,7 +57,7 @@ Install FastMCP server in Claude Code.
- True if installation was successful, False otherwise
-### `claude_code_command`
+### `claude_code_command`
```python
claude_code_command(server_spec: str) -> None
diff --git a/docs/python-sdk/fastmcp-cli-install-claude_desktop.mdx b/docs/python-sdk/fastmcp-cli-install-claude_desktop.mdx
index e31704d321..145de8ea8b 100644
--- a/docs/python-sdk/fastmcp-cli-install-claude_desktop.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-claude_desktop.mdx
@@ -44,7 +44,7 @@ Install FastMCP server in Claude Desktop.
- 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 218575f867..6c9ada03c6 100644
--- a/docs/python-sdk/fastmcp-cli-install-cursor.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-cursor.mdx
@@ -68,7 +68,7 @@ Install FastMCP server to workspace-specific Cursor configuration.
- True if installation was successful, False otherwise
-### `install_cursor`
+### `install_cursor`
```python
install_cursor(file: Path, server_object: str | None, name: str) -> bool
@@ -93,7 +93,7 @@ Install FastMCP server in Cursor.
- 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_json.mdx b/docs/python-sdk/fastmcp-cli-install-mcp_json.mdx
index 0d218623e5..e13343bd7b 100644
--- a/docs/python-sdk/fastmcp-cli-install-mcp_json.mdx
+++ b/docs/python-sdk/fastmcp-cli-install-mcp_json.mdx
@@ -35,7 +35,7 @@ Generate MCP configuration JSON for manual installation.
- True if generation was successful, False otherwise
-### `mcp_json_command`
+### `mcp_json_command`
```python
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 9f352a1e19..6822553335 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.
-### `run_with_uv`
+### `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, editable: str | list[str] | None = None) -> None
@@ -29,6 +29,10 @@ run_with_uv(server_spec: str, python_version: str | None = None, with_packages:
Run a MCP server using uv run subprocess.
+This function is called when we need to set up a Python environment with specific
+dependencies before running the server. The config parsing and merging should already
+be done by the caller.
+
**Args:**
- `server_spec`: Python file, object specification (file\:obj), config file, or URL
- `python_version`: Python version to use (e.g. "3.10")
@@ -41,9 +45,10 @@ Run a MCP server using uv run subprocess.
- `path`: Path to bind to when using http transport
- `log_level`: Log level
- `show_banner`: Whether to show the server banner
+- `editable`: Editable package paths
-### `create_client_server`
+### `create_client_server`
```python
create_client_server(url: str) -> Any
@@ -59,7 +64,7 @@ Create a FastMCP server from a client URL.
- A FastMCP server instance
-### `create_mcp_config_server`
+### `create_mcp_config_server`
```python
create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None]
@@ -69,7 +74,7 @@ create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None]
Create a FastMCP server from a MCPConfig.
-### `load_fastmcp_config`
+### `load_fastmcp_config`
```python
load_fastmcp_config(config_path: Path) -> FastMCPConfig
@@ -85,7 +90,7 @@ Load a FastMCP configuration from a fastmcp.json file.
- FastMCPConfig object
-### `run_command`
+### `run_command`
```python
run_command(server_spec: str, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, server_args: list[str] | None = None, show_banner: bool = True, use_direct_import: bool = False, skip_source: bool = False) -> None
@@ -107,7 +112,7 @@ Run a MCP server or connect to a remote one.
- `skip_source`: Whether to skip source preparation step
-### `run_v1_server`
+### `run_v1_server`
```python
run_v1_server(server: FastMCP1x, host: str | None = None, port: int | None = None, transport: TransportType | None = None) -> None
diff --git a/docs/python-sdk/fastmcp-client-auth-oauth.mdx b/docs/python-sdk/fastmcp-client-auth-oauth.mdx
index 0b261f9b01..1bc7c1704c 100644
--- a/docs/python-sdk/fastmcp-client-auth-oauth.mdx
+++ b/docs/python-sdk/fastmcp-client-auth-oauth.mdx
@@ -7,13 +7,13 @@ sidebarTitle: oauth
## Functions
-### `default_cache_dir`
+### `default_cache_dir`
```python
default_cache_dir() -> Path
```
-### `check_if_auth_required`
+### `check_if_auth_required`
```python
check_if_auth_required(mcp_url: str, httpx_kwargs: dict[str, Any] | None = None) -> bool
@@ -28,7 +28,13 @@ Check if the MCP endpoint requires authentication by making a test request.
## Classes
-### `FileTokenStorage`
+### `StoredToken`
+
+
+Token storage format with absolute expiry time.
+
+
+### `FileTokenStorage`
File-based token storage implementation for OAuth credentials and tokens.
@@ -39,7 +45,7 @@ Each instance is tied to a specific server URL for proper token isolation.
**Methods:**
-#### `get_base_url`
+#### `get_base_url`
```python
get_base_url(url: str) -> str
@@ -48,7 +54,7 @@ get_base_url(url: str) -> str
Extract the base URL (scheme + host) from a URL.
-#### `get_cache_key`
+#### `get_cache_key`
```python
get_cache_key(self) -> str
@@ -57,7 +63,7 @@ get_cache_key(self) -> str
Generate a safe filesystem key from the server's base URL.
-#### `get_tokens`
+#### `get_tokens`
```python
get_tokens(self) -> OAuthToken | None
@@ -66,7 +72,7 @@ get_tokens(self) -> OAuthToken | None
Load tokens from file storage.
-#### `set_tokens`
+#### `set_tokens`
```python
set_tokens(self, tokens: OAuthToken) -> None
@@ -75,7 +81,7 @@ set_tokens(self, tokens: OAuthToken) -> None
Save tokens to file storage.
-#### `get_client_info`
+#### `get_client_info`
```python
get_client_info(self) -> OAuthClientInformationFull | None
@@ -84,7 +90,7 @@ get_client_info(self) -> OAuthClientInformationFull | None
Load client information from file storage.
-#### `set_client_info`
+#### `set_client_info`
```python
set_client_info(self, client_info: OAuthClientInformationFull) -> None
@@ -93,7 +99,7 @@ set_client_info(self, client_info: OAuthClientInformationFull) -> None
Save client information to file storage.
-#### `clear`
+#### `clear`
```python
clear(self) -> None
@@ -102,7 +108,7 @@ clear(self) -> None
Clear all cached data for this server.
-#### `clear_all`
+#### `clear_all`
```python
clear_all(cls, cache_dir: Path | None = None) -> None
@@ -111,7 +117,7 @@ clear_all(cls, cache_dir: Path | None = None) -> None
Clear all cached data for all servers.
-### `OAuth`
+### `OAuth`
OAuth client provider for MCP servers with browser-based authentication.
@@ -122,7 +128,7 @@ a browser for user authorization and running a local callback server.
**Methods:**
-#### `redirect_handler`
+#### `redirect_handler`
```python
redirect_handler(self, authorization_url: str) -> None
@@ -131,7 +137,7 @@ redirect_handler(self, authorization_url: str) -> None
Open browser for authorization.
-#### `callback_handler`
+#### `callback_handler`
```python
callback_handler(self) -> tuple[str, str | None]
diff --git a/docs/python-sdk/fastmcp-client-client.mdx b/docs/python-sdk/fastmcp-client-client.mdx
index 406d0c329a..cc92038eb3 100644
--- a/docs/python-sdk/fastmcp-client-client.mdx
+++ b/docs/python-sdk/fastmcp-client-client.mdx
@@ -7,7 +7,7 @@ sidebarTitle: client
## Classes
-### `ClientSessionState`
+### `ClientSessionState`
Holds all session-related state for a Client instance.
@@ -16,7 +16,7 @@ This allows clean separation of configuration (which is copied) from
session state (which should be fresh for each new client instance).
-### `Client`
+### `Client`
MCP client that delegates connection management to a Transport instance.
@@ -79,7 +79,7 @@ async with client:
**Methods:**
-#### `session`
+#### `session`
```python
session(self) -> ClientSession
@@ -88,7 +88,7 @@ session(self) -> ClientSession
Get the current active session. Raises RuntimeError if not connected.
-#### `initialize_result`
+#### `initialize_result`
```python
initialize_result(self) -> mcp.types.InitializeResult
@@ -97,7 +97,7 @@ initialize_result(self) -> mcp.types.InitializeResult
Get the result of the initialization request.
-#### `set_roots`
+#### `set_roots`
```python
set_roots(self, roots: RootsList | RootsHandler) -> None
@@ -106,7 +106,7 @@ set_roots(self, roots: RootsList | RootsHandler) -> None
Set the roots for the client. This does not automatically call `send_roots_list_changed`.
-#### `set_sampling_callback`
+#### `set_sampling_callback`
```python
set_sampling_callback(self, sampling_callback: ClientSamplingHandler) -> None
@@ -115,7 +115,7 @@ set_sampling_callback(self, sampling_callback: ClientSamplingHandler) -> None
Set the sampling callback for the client.
-#### `set_elicitation_callback`
+#### `set_elicitation_callback`
```python
set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
@@ -124,7 +124,7 @@ set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
Set the elicitation callback for the client.
-#### `is_connected`
+#### `is_connected`
```python
is_connected(self) -> bool
@@ -133,7 +133,7 @@ is_connected(self) -> bool
Check if the client is currently connected.
-#### `new`
+#### `new`
```python
new(self) -> Client[ClientTransportT]
@@ -149,13 +149,13 @@ share state with the original client.
- A new Client instance with the same configuration but disconnected state.
-#### `close`
+#### `close`
```python
close(self)
```
-#### `ping`
+#### `ping`
```python
ping(self) -> bool
@@ -164,7 +164,7 @@ ping(self) -> bool
Send a ping request.
-#### `cancel`
+#### `cancel`
```python
cancel(self, request_id: str | int, reason: str | None = None) -> None
@@ -173,7 +173,7 @@ cancel(self, request_id: str | int, reason: str | None = None) -> None
Send a cancellation notification for an in-progress request.
-#### `progress`
+#### `progress`
```python
progress(self, progress_token: str | int, progress: float, total: float | None = None, message: str | None = None) -> None
@@ -182,7 +182,7 @@ progress(self, progress_token: str | int, progress: float, total: float | None =
Send a progress notification.
-#### `set_logging_level`
+#### `set_logging_level`
```python
set_logging_level(self, level: mcp.types.LoggingLevel) -> None
@@ -191,7 +191,7 @@ set_logging_level(self, level: mcp.types.LoggingLevel) -> None
Send a logging/setLevel request.
-#### `send_roots_list_changed`
+#### `send_roots_list_changed`
```python
send_roots_list_changed(self) -> None
@@ -200,7 +200,7 @@ send_roots_list_changed(self) -> None
Send a roots/list_changed notification.
-#### `list_resources_mcp`
+#### `list_resources_mcp`
```python
list_resources_mcp(self) -> mcp.types.ListResourcesResult
@@ -216,7 +216,7 @@ containing the list of resources and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `list_resources`
+#### `list_resources`
```python
list_resources(self) -> list[mcp.types.Resource]
@@ -231,7 +231,7 @@ Retrieve a list of resources available on the server.
- `RuntimeError`: If called while the client is not connected.
-#### `list_resource_templates_mcp`
+#### `list_resource_templates_mcp`
```python
list_resource_templates_mcp(self) -> mcp.types.ListResourceTemplatesResult
@@ -247,7 +247,7 @@ containing the list of resource templates and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `list_resource_templates`
+#### `list_resource_templates`
```python
list_resource_templates(self) -> list[mcp.types.ResourceTemplate]
@@ -262,7 +262,7 @@ Retrieve a list of resource templates available on the server.
- `RuntimeError`: If called while the client is not connected.
-#### `read_resource_mcp`
+#### `read_resource_mcp`
```python
read_resource_mcp(self, uri: AnyUrl | str) -> mcp.types.ReadResourceResult
@@ -281,7 +281,7 @@ containing the resource contents and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `read_resource`
+#### `read_resource`
```python
read_resource(self, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents]
@@ -300,7 +300,7 @@ objects, typically containing either text or binary data.
- `RuntimeError`: If called while the client is not connected.
-#### `list_prompts_mcp`
+#### `list_prompts_mcp`
```python
list_prompts_mcp(self) -> mcp.types.ListPromptsResult
@@ -316,7 +316,7 @@ containing the list of prompts and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `list_prompts`
+#### `list_prompts`
```python
list_prompts(self) -> list[mcp.types.Prompt]
@@ -331,7 +331,7 @@ Retrieve a list of prompts available on the server.
- `RuntimeError`: If called while the client is not connected.
-#### `get_prompt_mcp`
+#### `get_prompt_mcp`
```python
get_prompt_mcp(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
@@ -351,7 +351,7 @@ containing the prompt messages and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `get_prompt`
+#### `get_prompt`
```python
get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
@@ -371,7 +371,7 @@ containing the prompt messages and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `complete_mcp`
+#### `complete_mcp`
```python
complete_mcp(self, ref: mcp.types.ResourceReference | mcp.types.PromptReference, argument: dict[str, str]) -> mcp.types.CompleteResult
@@ -391,7 +391,7 @@ containing the completion and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `complete`
+#### `complete`
```python
complete(self, ref: mcp.types.ResourceReference | mcp.types.PromptReference, argument: dict[str, str]) -> mcp.types.Completion
@@ -410,7 +410,7 @@ Send a completion request to the server.
- `RuntimeError`: If called while the client is not connected.
-#### `list_tools_mcp`
+#### `list_tools_mcp`
```python
list_tools_mcp(self) -> mcp.types.ListToolsResult
@@ -426,7 +426,7 @@ containing the list of tools and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `list_tools`
+#### `list_tools`
```python
list_tools(self) -> list[mcp.types.Tool]
@@ -441,7 +441,7 @@ Retrieve a list of tools available on the server.
- `RuntimeError`: If called while the client is not connected.
-#### `call_tool_mcp`
+#### `call_tool_mcp`
```python
call_tool_mcp(self, name: str, arguments: dict[str, Any], progress_handler: ProgressHandler | None = None, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.CallToolResult
@@ -466,7 +466,7 @@ containing the tool result and any additional metadata.
- `RuntimeError`: If called while the client is not connected.
-#### `call_tool`
+#### `call_tool`
```python
call_tool(self, name: str, arguments: dict[str, Any] | None = None, timeout: datetime.timedelta | float | int | None = None, progress_handler: ProgressHandler | None = None, raise_on_error: bool = True) -> CallToolResult
@@ -496,10 +496,10 @@ raw result object.
- `RuntimeError`: If called while the client is not connected.
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
```
-### `CallToolResult`
+### `CallToolResult`
diff --git a/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx b/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx
index b592bdc8c8..163843467f 100644
--- a/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx
@@ -182,7 +182,7 @@ Handles provider-specific requirements:
**Methods:**
-#### `get_client`
+#### `get_client`
```python
get_client(self, client_id: str) -> OAuthClientInformationFull | None
@@ -199,7 +199,7 @@ handles the case where a client with cached tokens reconnects
on a different port.
-#### `register_client`
+#### `register_client`
```python
register_client(self, client_info: OAuthClientInformationFull) -> None
@@ -226,7 +226,7 @@ The flow:
4. When client reconnects with a different port, ProxyDCRClient accepts it
-#### `authorize`
+#### `authorize`
```python
authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str
@@ -240,7 +240,7 @@ This implements the DCR-compliant proxy pattern:
3. Redirect to IdP with our fixed callback URL
-#### `load_authorization_code`
+#### `load_authorization_code`
```python
load_authorization_code(self, client: OAuthClientInformationFull, authorization_code: str) -> AuthorizationCode | None
@@ -252,7 +252,7 @@ Look up our client code and return authorization code object
with PKCE challenge for validation.
-#### `exchange_authorization_code`
+#### `exchange_authorization_code`
```python
exchange_authorization_code(self, client: OAuthClientInformationFull, authorization_code: AuthorizationCode) -> OAuthToken
@@ -264,7 +264,7 @@ For the DCR-compliant proxy flow, we return the IdP tokens that were obtained
during the IdP callback exchange. PKCE validation is handled by the MCP framework.
-#### `load_refresh_token`
+#### `load_refresh_token`
```python
load_refresh_token(self, client: OAuthClientInformationFull, refresh_token: str) -> RefreshToken | None
@@ -273,7 +273,7 @@ load_refresh_token(self, client: OAuthClientInformationFull, refresh_token: str)
Load refresh token from local storage.
-#### `exchange_refresh_token`
+#### `exchange_refresh_token`
```python
exchange_refresh_token(self, client: OAuthClientInformationFull, refresh_token: RefreshToken, scopes: list[str]) -> OAuthToken
@@ -282,7 +282,7 @@ exchange_refresh_token(self, client: OAuthClientInformationFull, refresh_token:
Exchange refresh token for new access token using authlib.
-#### `load_access_token`
+#### `load_access_token`
```python
load_access_token(self, token: str) -> AccessToken | None
@@ -294,7 +294,7 @@ Delegates to the JWT verifier which handles signature validation,
expiration checking, and claims validation using the upstream JWKS.
-#### `revoke_token`
+#### `revoke_token`
```python
revoke_token(self, token: AccessToken | RefreshToken) -> None
@@ -306,7 +306,7 @@ Removes tokens from local storage and attempts to revoke them with
the upstream server if a revocation endpoint is configured.
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self) -> list[Route]
diff --git a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx
index 60781bf248..31d0145d26 100644
--- a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx
@@ -65,9 +65,9 @@ Setup Requirements:
4. Note your Client ID and Client Secret
-### `AuthKitProviderSettings`
+### `AuthKitProviderSettings`
-### `AuthKitProvider`
+### `AuthKitProvider`
AuthKit metadata provider for DCR (Dynamic Client Registration).
@@ -93,7 +93,7 @@ https://workos.com/docs/authkit/mcp/integrating/token-verification
**Methods:**
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self) -> list[Route]
diff --git a/docs/python-sdk/fastmcp-server-auth-redirect_validation.mdx b/docs/python-sdk/fastmcp-server-auth-redirect_validation.mdx
index ba44efebe3..c7aa26786d 100644
--- a/docs/python-sdk/fastmcp-server-auth-redirect_validation.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-redirect_validation.mdx
@@ -44,8 +44,9 @@ Validate a redirect URI against allowed patterns.
**Args:**
- `redirect_uri`: The redirect URI to validate
-- `allowed_patterns`: List of allowed patterns. If None, defaults to localhost.
- If empty list, all URIs are allowed.
+- `allowed_patterns`: List of allowed patterns. If None, all URIs are allowed (for DCR compatibility).
+ If empty list, no URIs are allowed.
+ To restrict to localhost only, explicitly pass DEFAULT_LOCALHOST_PATTERNS.
**Returns:**
- True if the redirect URI is allowed
diff --git a/docs/python-sdk/fastmcp-server-middleware-logging.mdx b/docs/python-sdk/fastmcp-server-middleware-logging.mdx
index 9beb8300ab..853725a015 100644
--- a/docs/python-sdk/fastmcp-server-middleware-logging.mdx
+++ b/docs/python-sdk/fastmcp-server-middleware-logging.mdx
@@ -8,9 +8,21 @@ sidebarTitle: logging
Comprehensive logging middleware for FastMCP servers.
+## Functions
+
+### `default_serializer`
+
+```python
+default_serializer(data: Any) -> str
+```
+
+
+The default serializer for Payloads in the logging middleware.
+
+
## Classes
-### `LoggingMiddleware`
+### `LoggingMiddleware`
Middleware that provides comprehensive request and response logging.
@@ -21,16 +33,16 @@ monitoring, and understanding server usage patterns.
**Methods:**
-#### `on_message`
+#### `on_message`
```python
-on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any
+on_message(self, context: MiddlewareContext[Any], call_next: CallNext[Any, Any]) -> Any
```
Log all messages.
-### `StructuredLoggingMiddleware`
+### `StructuredLoggingMiddleware`
Middleware that provides structured JSON logging for better log analysis.
@@ -41,10 +53,10 @@ aggregation tools like ELK stack, Splunk, or cloud logging services.
**Methods:**
-#### `on_message`
+#### `on_message`
```python
-on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any
+on_message(self, context: MiddlewareContext[Any], call_next: CallNext[Any, Any]) -> Any
```
Log structured message information.
diff --git a/docs/python-sdk/fastmcp-utilities-cli.mdx b/docs/python-sdk/fastmcp-utilities-cli.mdx
index 6d49ca6e07..1d85eb95a5 100644
--- a/docs/python-sdk/fastmcp-utilities-cli.mdx
+++ b/docs/python-sdk/fastmcp-utilities-cli.mdx
@@ -7,7 +7,37 @@ sidebarTitle: cli
## Functions
-### `log_server_banner`
+### `is_already_in_uv_subprocess`
+
+```python
+is_already_in_uv_subprocess() -> bool
+```
+
+
+Check if we're already running in a FastMCP uv subprocess.
+
+
+### `load_and_merge_config`
+
+```python
+load_and_merge_config(server_spec: str | None, **cli_overrides) -> tuple[FastMCPConfig, str]
+```
+
+
+Load config from server_spec and apply CLI overrides.
+
+This consolidates the config parsing logic that was duplicated across
+run, inspect, and dev commands.
+
+**Args:**
+- `server_spec`: Python file, config file, URL, or None to auto-detect
+- `cli_overrides`: CLI arguments that override config values
+
+**Returns:**
+- Tuple of (FastMCPConfig, resolved_server_spec)
+
+
+### `log_server_banner`
```python
log_server_banner(server: FastMCP[Any], transport: Literal['stdio', 'http', 'sse', 'streamable-http']) -> None
diff --git a/docs/python-sdk/fastmcp-utilities-fastmcp_config-v1-fastmcp_config.mdx b/docs/python-sdk/fastmcp-utilities-fastmcp_config-v1-fastmcp_config.mdx
index d66382bc16..833eaa8e52 100644
--- a/docs/python-sdk/fastmcp-utilities-fastmcp_config-v1-fastmcp_config.mdx
+++ b/docs/python-sdk/fastmcp-utilities-fastmcp_config-v1-fastmcp_config.mdx
@@ -15,7 +15,7 @@ command-line arguments.
## Functions
-### `generate_schema`
+### `generate_schema`
```python
generate_schema(output_path: Path | str | None = None) -> dict[str, Any] | None
@@ -46,22 +46,22 @@ Configuration for Python environment setup.
**Methods:**
-#### `build_uv_args`
+#### `build_uv_run_command`
```python
-build_uv_args(self, command: str | list[str] | None = None) -> list[str]
+build_uv_run_command(self, command: list[str]) -> list[str]
```
-Build uv run arguments from this environment configuration.
+Build complete uv run command with environment args and command to execute.
**Args:**
-- `command`: Optional command to append (string or list of args)
+- `command`: Command to execute (e.g., ["fastmcp", "run", "server.py"])
**Returns:**
-- List of arguments for uv run command
+- Complete command ready for subprocess.run, including "uv" prefix
-#### `run_with_uv`
+#### `run_with_uv`
```python
run_with_uv(self, command: list[str]) -> None
@@ -73,7 +73,7 @@ Execute a command using uv run with this environment configuration.
- `command`: Command and arguments to execute (e.g., ["fastmcp", "run", "server.py"])
-#### `needs_uv`
+#### `needs_uv`
```python
needs_uv(self) -> bool
@@ -85,7 +85,7 @@ Check if this environment config requires uv to set up.
- True if any environment settings require uv run
-#### `prepare`
+#### `prepare`
```python
prepare(self, output_dir: Path | None = None) -> None
@@ -98,7 +98,7 @@ Prepare the Python environment using uv.
If None, creates a temporary directory for ephemeral use.
-### `Deployment`
+### `Deployment`
Configuration for server deployment and runtime settings.
@@ -106,7 +106,7 @@ Configuration for server deployment and runtime settings.
**Methods:**
-#### `apply_runtime_settings`
+#### `apply_runtime_settings`
```python
apply_runtime_settings(self, config_path: Path | None = None) -> None
@@ -122,7 +122,7 @@ For example: "API_URL": "https://api.${ENVIRONMENT}.example.com"
will substitute the value of the ENVIRONMENT variable at runtime.
-### `FastMCPConfig`
+### `FastMCPConfig`
Configuration for a FastMCP server.
@@ -133,7 +133,7 @@ a FastMCP server in a declarative format.
**Methods:**
-#### `validate_source`
+#### `validate_source`
```python
validate_source(cls, v: dict | FileSystemSource) -> FileSystemSource
@@ -149,7 +149,7 @@ No string parsing happens here - that's only at CLI boundaries.
FastMCPConfig works only with properly typed objects.
-#### `validate_environment`
+#### `validate_environment`
```python
validate_environment(cls, v: dict | Environment) -> Environment
@@ -162,7 +162,7 @@ Accepts:
- dict that can be converted to Environment
-#### `validate_deployment`
+#### `validate_deployment`
```python
validate_deployment(cls, v: dict | Deployment) -> Deployment
@@ -175,7 +175,7 @@ Accepts:
- dict that can be converted to Deployment
-#### `from_file`
+#### `from_file`
```python
from_file(cls, file_path: Path) -> FastMCPConfig
@@ -195,7 +195,7 @@ Load configuration from a JSON file.
- `pydantic.ValidationError`: If the configuration is invalid
-#### `from_cli_args`
+#### `from_cli_args`
```python
from_cli_args(cls, source: FileSystemSource, transport: Literal['stdio', 'http', 'sse', 'streamable-http'] | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: Literal['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'] | None = None, python: str | None = None, dependencies: list[str] | None = None, requirements: str | None = None, project: str | None = None, editable: str | None = None, env: dict[str, str] | None = None, cwd: str | None = None, args: list[str] | None = None) -> FastMCPConfig
@@ -226,7 +226,7 @@ goes through a config object.
- FastMCPConfig instance
-#### `find_config`
+#### `find_config`
```python
find_config(cls, start_path: Path | None = None) -> Path | None
@@ -241,7 +241,7 @@ Find a fastmcp.json file in the specified directory.
- Path to the configuration file, or None if not found
-#### `prepare`
+#### `prepare`
```python
prepare(self, skip_source: bool = False, output_dir: Path | None = None) -> None
@@ -257,7 +257,7 @@ When output_dir is None, does ephemeral caching (for backwards compatibility).
- `output_dir`: Directory to create the persistent uv project in (optional)
-#### `prepare_environment`
+#### `prepare_environment`
```python
prepare_environment(self, output_dir: Path | None = None) -> None
@@ -272,7 +272,7 @@ Prepare the Python environment.
Delegates to the environment's prepare() method
-#### `prepare_source`
+#### `prepare_source`
```python
prepare_source(self) -> None
@@ -283,7 +283,7 @@ Prepare the source for loading.
Delegates to the source's prepare() method.
-#### `run_server`
+#### `run_server`
```python
run_server(self, **kwargs: Any) -> None