From e98e04fb83bbf52a49cd4fa01442779cdfbd2d28 Mon Sep 17 00:00:00 2001
From: "marvin-context-protocol[bot]"
<225465937+marvin-context-protocol[bot]@users.noreply.github.com>
Date: Mon, 19 Jan 2026 10:16:14 -0500
Subject: [PATCH] chore: Update SDK documentation (#2932)
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
---
docs/docs.json | 17 +-
docs/python-sdk/fastmcp-client-client.mdx | 492 +-----------------
docs/python-sdk/fastmcp-client-prompts.mdx | 119 +++++
docs/python-sdk/fastmcp-client-resources.mdx | 158 ++++++
.../fastmcp-client-task_management.mdx | 110 ++++
.../fastmcp-client-tools_client.mdx | 141 +++++
.../fastmcp-client-transports-http.mdx | 25 +-
.../fastmcp-client-transports-inference.mdx | 2 +-
.../fastmcp-client-transports-sse.mdx | 25 +
...stmcp-server-auth-oauth_proxy-__init__.mdx | 16 +
...astmcp-server-auth-oauth_proxy-consent.mdx | 28 +
...fastmcp-server-auth-oauth_proxy-models.mdx | 104 ++++
...fastmcp-server-auth-oauth_proxy-proxy.mdx} | 160 +-----
.../fastmcp-server-auth-oauth_proxy-ui.mdx | 50 ++
docs/python-sdk/fastmcp-server-server.mdx | 44 +-
docs/python-sdk/fastmcp-utilities-timeout.mdx | 44 ++
16 files changed, 877 insertions(+), 658 deletions(-)
create mode 100644 docs/python-sdk/fastmcp-client-prompts.mdx
create mode 100644 docs/python-sdk/fastmcp-client-resources.mdx
create mode 100644 docs/python-sdk/fastmcp-client-task_management.mdx
create mode 100644 docs/python-sdk/fastmcp-client-tools_client.mdx
create mode 100644 docs/python-sdk/fastmcp-client-transports-sse.mdx
create mode 100644 docs/python-sdk/fastmcp-server-auth-oauth_proxy-__init__.mdx
create mode 100644 docs/python-sdk/fastmcp-server-auth-oauth_proxy-consent.mdx
create mode 100644 docs/python-sdk/fastmcp-server-auth-oauth_proxy-models.mdx
rename docs/python-sdk/{fastmcp-server-auth-oauth_proxy.mdx => fastmcp-server-auth-oauth_proxy-proxy.mdx} (61%)
create mode 100644 docs/python-sdk/fastmcp-server-auth-oauth_proxy-ui.mdx
create mode 100644 docs/python-sdk/fastmcp-utilities-timeout.mdx
diff --git a/docs/docs.json b/docs/docs.json
index c27f55a00..b1db8d756 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -337,6 +337,8 @@
"python-sdk/fastmcp-client-messages",
"python-sdk/fastmcp-client-oauth_callback",
"python-sdk/fastmcp-client-progress",
+ "python-sdk/fastmcp-client-prompts",
+ "python-sdk/fastmcp-client-resources",
"python-sdk/fastmcp-client-roots",
{
"group": "sampling",
@@ -352,8 +354,10 @@
}
]
},
+ "python-sdk/fastmcp-client-task_management",
"python-sdk/fastmcp-client-tasks",
"python-sdk/fastmcp-client-telemetry",
+ "python-sdk/fastmcp-client-tools_client",
{
"group": "transports",
"pages": [
@@ -363,6 +367,7 @@
"python-sdk/fastmcp-client-transports-http",
"python-sdk/fastmcp-client-transports-inference",
"python-sdk/fastmcp-client-transports-memory",
+ "python-sdk/fastmcp-client-transports-sse",
"python-sdk/fastmcp-client-transports-stdio"
]
}
@@ -398,7 +403,16 @@
"python-sdk/fastmcp-server-auth-authorization",
"python-sdk/fastmcp-server-auth-jwt_issuer",
"python-sdk/fastmcp-server-auth-middleware",
- "python-sdk/fastmcp-server-auth-oauth_proxy",
+ {
+ "group": "oauth_proxy",
+ "pages": [
+ "python-sdk/fastmcp-server-auth-oauth_proxy-__init__",
+ "python-sdk/fastmcp-server-auth-oauth_proxy-consent",
+ "python-sdk/fastmcp-server-auth-oauth_proxy-models",
+ "python-sdk/fastmcp-server-auth-oauth_proxy-proxy",
+ "python-sdk/fastmcp-server-auth-oauth_proxy-ui"
+ ]
+ },
"python-sdk/fastmcp-server-auth-oidc_proxy",
{
"group": "providers",
@@ -582,6 +596,7 @@
},
"python-sdk/fastmcp-utilities-pagination",
"python-sdk/fastmcp-utilities-tests",
+ "python-sdk/fastmcp-utilities-timeout",
"python-sdk/fastmcp-utilities-types",
"python-sdk/fastmcp-utilities-ui",
"python-sdk/fastmcp-utilities-version_check",
diff --git a/docs/python-sdk/fastmcp-client-client.mdx b/docs/python-sdk/fastmcp-client-client.mdx
index 3c9315106..7a913c6e8 100644
--- a/docs/python-sdk/fastmcp-client-client.mdx
+++ b/docs/python-sdk/fastmcp-client-client.mdx
@@ -7,7 +7,7 @@ sidebarTitle: client
## Classes
-### `ClientSessionState`
+### `ClientSessionState`
Holds all session-related state for a Client instance.
@@ -16,13 +16,13 @@ This allows clean separation of configuration (which is copied) from
session state (which should be fresh for each new client instance).
-### `CallToolResult`
+### `CallToolResult`
Parsed result from a tool call.
-### `Client`
+### `Client`
MCP client that delegates connection management to a Transport instance.
@@ -85,7 +85,7 @@ async with client:
**Methods:**
-#### `session`
+#### `session`
```python
session(self) -> ClientSession
@@ -94,7 +94,7 @@ session(self) -> ClientSession
Get the current active session. Raises RuntimeError if not connected.
-#### `initialize_result`
+#### `initialize_result`
```python
initialize_result(self) -> mcp.types.InitializeResult | None
@@ -103,7 +103,7 @@ initialize_result(self) -> mcp.types.InitializeResult | None
Get the result of the initialization request.
-#### `set_roots`
+#### `set_roots`
```python
set_roots(self, roots: RootsList | RootsHandler) -> None
@@ -112,7 +112,7 @@ set_roots(self, roots: RootsList | RootsHandler) -> None
Set the roots for the client. This does not automatically call `send_roots_list_changed`.
-#### `set_sampling_callback`
+#### `set_sampling_callback`
```python
set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabilities: mcp.types.SamplingCapability | None = None) -> None
@@ -121,7 +121,7 @@ set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabil
Set the sampling callback for the client.
-#### `set_elicitation_callback`
+#### `set_elicitation_callback`
```python
set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
@@ -130,7 +130,7 @@ set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None
Set the elicitation callback for the client.
-#### `is_connected`
+#### `is_connected`
```python
is_connected(self) -> bool
@@ -139,7 +139,7 @@ is_connected(self) -> bool
Check if the client is currently connected.
-#### `new`
+#### `new`
```python
new(self) -> Client[ClientTransportT]
@@ -155,7 +155,7 @@ share state with the original client.
- A new Client instance with the same configuration but disconnected state.
-#### `initialize`
+#### `initialize`
```python
initialize(self, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.InitializeResult
@@ -183,13 +183,13 @@ capabilities, protocol version, and optional instructions.
- `RuntimeError`: If the client is not connected or initialization times out.
-#### `close`
+#### `close`
```python
close(self)
```
-#### `ping`
+#### `ping`
```python
ping(self) -> bool
@@ -198,7 +198,7 @@ ping(self) -> bool
Send a ping request.
-#### `cancel`
+#### `cancel`
```python
cancel(self, request_id: str | int, reason: str | None = None) -> None
@@ -207,7 +207,7 @@ cancel(self, request_id: str | int, reason: str | None = None) -> None
Send a cancellation notification for an in-progress request.
-#### `progress`
+#### `progress`
```python
progress(self, progress_token: str | int, progress: float, total: float | None = None, message: str | None = None) -> None
@@ -216,7 +216,7 @@ progress(self, progress_token: str | int, progress: float, total: float | None =
Send a progress notification.
-#### `set_logging_level`
+#### `set_logging_level`
```python
set_logging_level(self, level: mcp.types.LoggingLevel) -> None
@@ -225,7 +225,7 @@ set_logging_level(self, level: mcp.types.LoggingLevel) -> None
Send a logging/setLevel request.
-#### `send_roots_list_changed`
+#### `send_roots_list_changed`
```python
send_roots_list_changed(self) -> None
@@ -234,246 +234,7 @@ send_roots_list_changed(self) -> None
Send a roots/list_changed notification.
-#### `list_resources_mcp`
-
-```python
-list_resources_mcp(self) -> mcp.types.ListResourcesResult
-```
-
-Send a resources/list request and return the complete MCP protocol result.
-
-**Args:**
-- `cursor`: Optional pagination cursor from a previous request's nextCursor.
-
-**Returns:**
-- mcp.types.ListResourcesResult: The complete response object from the protocol,
-containing the list of resources and any additional metadata.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `list_resources`
-
-```python
-list_resources(self) -> list[mcp.types.Resource]
-```
-
-Retrieve all resources available on the server.
-
-This method automatically fetches all pages if the server paginates results,
-returning the complete list. For manual pagination control (e.g., to handle
-large result sets incrementally), use list_resources_mcp() with the cursor parameter.
-
-**Returns:**
-- list\[mcp.types.Resource]: A list of all Resource objects.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `list_resource_templates_mcp`
-
-```python
-list_resource_templates_mcp(self) -> mcp.types.ListResourceTemplatesResult
-```
-
-Send a resources/listResourceTemplates request and return the complete MCP protocol result.
-
-**Args:**
-- `cursor`: Optional pagination cursor from a previous request's nextCursor.
-
-**Returns:**
-- mcp.types.ListResourceTemplatesResult: The complete response object from the protocol,
-containing the list of resource templates and any additional metadata.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `list_resource_templates`
-
-```python
-list_resource_templates(self) -> list[mcp.types.ResourceTemplate]
-```
-
-Retrieve all resource templates available on the server.
-
-This method automatically fetches all pages if the server paginates results,
-returning the complete list. For manual pagination control (e.g., to handle
-large result sets incrementally), use list_resource_templates_mcp() with the
-cursor parameter.
-
-**Returns:**
-- list\[mcp.types.ResourceTemplate]: A list of all ResourceTemplate objects.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `read_resource_mcp`
-
-```python
-read_resource_mcp(self, uri: AnyUrl | str, meta: dict[str, Any] | None = None) -> mcp.types.ReadResourceResult
-```
-
-Send a resources/read request and return the complete MCP protocol result.
-
-**Args:**
-- `uri`: The URI of the resource to read. Can be a string or an AnyUrl object.
-- `meta`: Request metadata (e.g., for SEP-1686 tasks). Defaults to None.
-
-**Returns:**
-- mcp.types.ReadResourceResult: The complete response object from the protocol,
-containing the resource contents and any additional metadata.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `read_resource`
-
-```python
-read_resource(self, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents]
-```
-
-#### `read_resource`
-
-```python
-read_resource(self, uri: AnyUrl | str) -> ResourceTask
-```
-
-#### `read_resource`
-
-```python
-read_resource(self, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] | ResourceTask
-```
-
-Read the contents of a resource or resolved template.
-
-**Args:**
-- `uri`: The URI of the resource to read. Can be a string or an AnyUrl object.
-- `version`: Specific version to read. If None, reads highest version.
-- `meta`: Optional request-level metadata.
-- `task`: If True, execute as background task (SEP-1686). Defaults to False.
-- `task_id`: Optional client-provided task ID (auto-generated if not provided).
-- `ttl`: Time to keep results available in milliseconds (default 60s).
-
-**Returns:**
-- list\[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] | ResourceTask:
-A list of content objects if task=False, or a ResourceTask object if task=True.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `list_prompts_mcp`
-
-```python
-list_prompts_mcp(self) -> mcp.types.ListPromptsResult
-```
-
-Send a prompts/list request and return the complete MCP protocol result.
-
-**Args:**
-- `cursor`: Optional pagination cursor from a previous request's nextCursor.
-
-**Returns:**
-- mcp.types.ListPromptsResult: The complete response object from the protocol,
-containing the list of prompts and any additional metadata.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `list_prompts`
-
-```python
-list_prompts(self) -> list[mcp.types.Prompt]
-```
-
-Retrieve all prompts available on the server.
-
-This method automatically fetches all pages if the server paginates results,
-returning the complete list. For manual pagination control (e.g., to handle
-large result sets incrementally), use list_prompts_mcp() with the cursor parameter.
-
-**Returns:**
-- list\[mcp.types.Prompt]: A list of all Prompt objects.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `get_prompt_mcp`
-
-```python
-get_prompt_mcp(self, name: str, arguments: dict[str, Any] | None = None, meta: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
-```
-
-Send a prompts/get request and return the complete MCP protocol result.
-
-**Args:**
-- `name`: The name of the prompt to retrieve.
-- `arguments`: Arguments to pass to the prompt. Defaults to None.
-- `meta`: Request metadata (e.g., for SEP-1686 tasks). Defaults to None.
-
-**Returns:**
-- mcp.types.GetPromptResult: The complete response object from the protocol,
-containing the prompt messages and any additional metadata.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `get_prompt`
-
-```python
-get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
-```
-
-#### `get_prompt`
-
-```python
-get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptTask
-```
-
-#### `get_prompt`
-
-```python
-get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult | PromptTask
-```
-
-Retrieve a rendered prompt message list from the server.
-
-**Args:**
-- `name`: The name of the prompt to retrieve.
-- `arguments`: Arguments to pass to the prompt. Defaults to None.
-- `version`: Specific prompt version to get. If None, gets highest version.
-- `meta`: Optional request-level metadata.
-- `task`: If True, execute as background task (SEP-1686). Defaults to False.
-- `task_id`: Optional client-provided task ID (auto-generated if not provided).
-- `ttl`: Time to keep results available in milliseconds (default 60s).
-
-**Returns:**
-- mcp.types.GetPromptResult | PromptTask: The complete response object if task=False,
-or a PromptTask object if task=True.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `complete_mcp`
+#### `complete_mcp`
```python
complete_mcp(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.CompleteResult
@@ -496,7 +257,7 @@ containing the completion and any additional metadata.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `complete`
+#### `complete`
```python
complete(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.Completion
@@ -518,220 +279,7 @@ include with the completion request. Defaults to None.
- `McpError`: If the request results in a TimeoutError | JSONRPCError
-#### `list_tools_mcp`
-
-```python
-list_tools_mcp(self) -> mcp.types.ListToolsResult
-```
-
-Send a tools/list request and return the complete MCP protocol result.
-
-**Args:**
-- `cursor`: Optional pagination cursor from a previous request's nextCursor.
-
-**Returns:**
-- mcp.types.ListToolsResult: The complete response object from the protocol,
-containing the list of tools and any additional metadata.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `list_tools`
-
-```python
-list_tools(self) -> list[mcp.types.Tool]
-```
-
-Retrieve all tools available on the server.
-
-This method automatically fetches all pages if the server paginates results,
-returning the complete list. For manual pagination control (e.g., to handle
-large result sets incrementally), use list_tools_mcp() with the cursor parameter.
-
-**Returns:**
-- list\[mcp.types.Tool]: A list of all Tool objects.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `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, meta: dict[str, Any] | None = None) -> mcp.types.CallToolResult
-```
-
-Send a tools/call request and return the complete MCP protocol result.
-
-This method returns the raw CallToolResult object, which includes an isError flag
-and other metadata. It does not raise an exception if the tool call results in an error.
-
-**Args:**
-- `name`: The name of the tool to call.
-- `arguments`: Arguments to pass to the tool.
-- `timeout`: The timeout for the tool call. Defaults to None.
-- `progress_handler`: The progress handler to use for the tool call. Defaults to None.
-- `meta`: Additional metadata to include with the request.
-This is useful for passing contextual information (like user IDs, trace IDs, or preferences)
-that shouldn't be tool arguments but may influence server-side processing. The server
-can access this via `context.request_context.meta`. Defaults to None.
-
-**Returns:**
-- mcp.types.CallToolResult: The complete response object from the protocol,
-containing the tool result and any additional metadata.
-
-**Raises:**
-- `RuntimeError`: If called while the client is not connected.
-- `McpError`: If the tool call requests results in a TimeoutError | JSONRPCError
-
-
-#### `call_tool`
-
-```python
-call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult
-```
-
-#### `call_tool`
-
-```python
-call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolTask
-```
-
-#### `call_tool`
-
-```python
-call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult | ToolTask
-```
-
-Call a tool on the server.
-
-Unlike call_tool_mcp, this method raises a ToolError if the tool call results in an error.
-
-**Args:**
-- `name`: The name of the tool to call.
-- `arguments`: Arguments to pass to the tool. Defaults to None.
-- `version`: Specific tool version to call. If None, calls highest version.
-- `timeout`: The timeout for the tool call. Defaults to None.
-- `progress_handler`: The progress handler to use for the tool call. Defaults to None.
-- `raise_on_error`: Whether to raise an exception if the tool call results in an error. Defaults to True.
-- `meta`: Additional metadata to include with the request.
-This is useful for passing contextual information (like user IDs, trace IDs, or preferences)
-that shouldn't be tool arguments but may influence server-side processing. The server
-can access this via `context.request_context.meta`. Defaults to None.
-- `task`: If True, execute as background task (SEP-1686). Defaults to False.
-- `task_id`: Optional client-provided task ID (auto-generated if not provided).
-- `ttl`: Time to keep results available in milliseconds (default 60s).
-
-**Returns:**
-- CallToolResult | ToolTask: The content returned by the tool if task=False,
-or a ToolTask object if task=True. If the tool returns structured
-outputs, they are returned as a dataclass (if an output schema
-is available) or a dictionary; otherwise, a list of content
-blocks is returned. Note: to receive both structured and
-unstructured outputs, use call_tool_mcp instead and access the
-raw result object.
-
-**Raises:**
-- `ToolError`: If the tool call results in an error.
-- `McpError`: If the tool call request results in a TimeoutError | JSONRPCError
-- `RuntimeError`: If called while the client is not connected.
-
-
-#### `get_task_status`
-
-```python
-get_task_status(self, task_id: str) -> GetTaskResult
-```
-
-Query the status of a background task.
-
-Sends a 'tasks/get' MCP protocol request over the existing transport.
-
-**Args:**
-- `task_id`: The task ID returned from call_tool_as_task
-
-**Returns:**
-- Status information including taskId, status, pollInterval, etc.
-
-**Raises:**
-- `RuntimeError`: If client not connected
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `get_task_result`
-
-```python
-get_task_result(self, task_id: str) -> Any
-```
-
-Retrieve the raw result of a completed background task.
-
-Sends a 'tasks/result' MCP protocol request over the existing transport.
-Returns the raw result - callers should parse it appropriately.
-
-**Args:**
-- `task_id`: The task ID returned from call_tool_as_task
-
-**Returns:**
-- The raw result (could be tool, prompt, or resource result)
-
-**Raises:**
-- `RuntimeError`: If client not connected, task not found, or task failed
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `list_tasks`
-
-```python
-list_tasks(self, cursor: str | None = None, limit: int = 50) -> dict[str, Any]
-```
-
-List background tasks.
-
-Sends a 'tasks/list' MCP protocol request to the server. If the server
-returns an empty list (indicating client-side tracking), falls back to
-querying status for locally tracked task IDs.
-
-**Args:**
-- `cursor`: Optional pagination cursor
-- `limit`: Maximum number of tasks to return (default 50)
-
-**Returns:**
-- Response with structure:
-- tasks: List of task status dicts with taskId, status, etc.
-- nextCursor: Optional cursor for next page
-
-**Raises:**
-- `RuntimeError`: If client not connected
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `cancel_task`
-
-```python
-cancel_task(self, task_id: str) -> mcp.types.CancelTaskResult
-```
-
-Cancel a task, transitioning it to cancelled state.
-
-Sends a 'tasks/cancel' MCP protocol request. Task will halt execution
-and transition to cancelled state.
-
-**Args:**
-- `task_id`: The task ID to cancel
-
-**Returns:**
-- The task status showing cancelled state
-
-**Raises:**
-- `RuntimeError`: If task doesn't exist
-- `McpError`: If the request results in a TimeoutError | JSONRPCError
-
-
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
diff --git a/docs/python-sdk/fastmcp-client-prompts.mdx b/docs/python-sdk/fastmcp-client-prompts.mdx
new file mode 100644
index 000000000..73b58b4df
--- /dev/null
+++ b/docs/python-sdk/fastmcp-client-prompts.mdx
@@ -0,0 +1,119 @@
+---
+title: prompts
+sidebarTitle: prompts
+---
+
+# `fastmcp.client.prompts`
+
+
+Prompt-related methods for FastMCP Client.
+
+## Classes
+
+### `ClientPromptsMixin`
+
+
+Mixin providing prompt-related methods for Client.
+
+
+**Methods:**
+
+#### `list_prompts_mcp`
+
+```python
+list_prompts_mcp(self: Client) -> mcp.types.ListPromptsResult
+```
+
+Send a prompts/list request and return the complete MCP protocol result.
+
+**Args:**
+- `cursor`: Optional pagination cursor from a previous request's nextCursor.
+
+**Returns:**
+- mcp.types.ListPromptsResult: The complete response object from the protocol,
+containing the list of prompts and any additional metadata.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `list_prompts`
+
+```python
+list_prompts(self: Client) -> list[mcp.types.Prompt]
+```
+
+Retrieve all prompts available on the server.
+
+This method automatically fetches all pages if the server paginates results,
+returning the complete list. For manual pagination control (e.g., to handle
+large result sets incrementally), use list_prompts_mcp() with the cursor parameter.
+
+**Returns:**
+- list\[mcp.types.Prompt]: A list of all Prompt objects.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `get_prompt_mcp`
+
+```python
+get_prompt_mcp(self: Client, name: str, arguments: dict[str, Any] | None = None, meta: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
+```
+
+Send a prompts/get request and return the complete MCP protocol result.
+
+**Args:**
+- `name`: The name of the prompt to retrieve.
+- `arguments`: Arguments to pass to the prompt. Defaults to None.
+- `meta`: Request metadata (e.g., for SEP-1686 tasks). Defaults to None.
+
+**Returns:**
+- mcp.types.GetPromptResult: The complete response object from the protocol,
+containing the prompt messages and any additional metadata.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `get_prompt`
+
+```python
+get_prompt(self: Client, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult
+```
+
+#### `get_prompt`
+
+```python
+get_prompt(self: Client, name: str, arguments: dict[str, Any] | None = None) -> PromptTask
+```
+
+#### `get_prompt`
+
+```python
+get_prompt(self: Client, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult | PromptTask
+```
+
+Retrieve a rendered prompt message list from the server.
+
+**Args:**
+- `name`: The name of the prompt to retrieve.
+- `arguments`: Arguments to pass to the prompt. Defaults to None.
+- `version`: Specific prompt version to get. If None, gets highest version.
+- `meta`: Optional request-level metadata.
+- `task`: If True, execute as background task (SEP-1686). Defaults to False.
+- `task_id`: Optional client-provided task ID (auto-generated if not provided).
+- `ttl`: Time to keep results available in milliseconds (default 60s).
+
+**Returns:**
+- mcp.types.GetPromptResult | PromptTask: The complete response object if task=False,
+or a PromptTask object if task=True.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
diff --git a/docs/python-sdk/fastmcp-client-resources.mdx b/docs/python-sdk/fastmcp-client-resources.mdx
new file mode 100644
index 000000000..8dfb84cfa
--- /dev/null
+++ b/docs/python-sdk/fastmcp-client-resources.mdx
@@ -0,0 +1,158 @@
+---
+title: resources
+sidebarTitle: resources
+---
+
+# `fastmcp.client.resources`
+
+
+Resource-related methods for FastMCP Client.
+
+## Classes
+
+### `ClientResourcesMixin`
+
+
+Mixin providing resource-related methods for Client.
+
+
+**Methods:**
+
+#### `list_resources_mcp`
+
+```python
+list_resources_mcp(self: Client) -> mcp.types.ListResourcesResult
+```
+
+Send a resources/list request and return the complete MCP protocol result.
+
+**Args:**
+- `cursor`: Optional pagination cursor from a previous request's nextCursor.
+
+**Returns:**
+- mcp.types.ListResourcesResult: The complete response object from the protocol,
+containing the list of resources and any additional metadata.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `list_resources`
+
+```python
+list_resources(self: Client) -> list[mcp.types.Resource]
+```
+
+Retrieve all resources available on the server.
+
+This method automatically fetches all pages if the server paginates results,
+returning the complete list. For manual pagination control (e.g., to handle
+large result sets incrementally), use list_resources_mcp() with the cursor parameter.
+
+**Returns:**
+- list\[mcp.types.Resource]: A list of all Resource objects.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `list_resource_templates_mcp`
+
+```python
+list_resource_templates_mcp(self: Client) -> mcp.types.ListResourceTemplatesResult
+```
+
+Send a resources/listResourceTemplates request and return the complete MCP protocol result.
+
+**Args:**
+- `cursor`: Optional pagination cursor from a previous request's nextCursor.
+
+**Returns:**
+- mcp.types.ListResourceTemplatesResult: The complete response object from the protocol,
+containing the list of resource templates and any additional metadata.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `list_resource_templates`
+
+```python
+list_resource_templates(self: Client) -> list[mcp.types.ResourceTemplate]
+```
+
+Retrieve all resource templates available on the server.
+
+This method automatically fetches all pages if the server paginates results,
+returning the complete list. For manual pagination control (e.g., to handle
+large result sets incrementally), use list_resource_templates_mcp() with the
+cursor parameter.
+
+**Returns:**
+- list\[mcp.types.ResourceTemplate]: A list of all ResourceTemplate objects.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `read_resource_mcp`
+
+```python
+read_resource_mcp(self: Client, uri: AnyUrl | str, meta: dict[str, Any] | None = None) -> mcp.types.ReadResourceResult
+```
+
+Send a resources/read request and return the complete MCP protocol result.
+
+**Args:**
+- `uri`: The URI of the resource to read. Can be a string or an AnyUrl object.
+- `meta`: Request metadata (e.g., for SEP-1686 tasks). Defaults to None.
+
+**Returns:**
+- mcp.types.ReadResourceResult: The complete response object from the protocol,
+containing the resource contents and any additional metadata.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `read_resource`
+
+```python
+read_resource(self: Client, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents]
+```
+
+#### `read_resource`
+
+```python
+read_resource(self: Client, uri: AnyUrl | str) -> ResourceTask
+```
+
+#### `read_resource`
+
+```python
+read_resource(self: Client, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] | ResourceTask
+```
+
+Read the contents of a resource or resolved template.
+
+**Args:**
+- `uri`: The URI of the resource to read. Can be a string or an AnyUrl object.
+- `version`: Specific version to read. If None, reads highest version.
+- `meta`: Optional request-level metadata.
+- `task`: If True, execute as background task (SEP-1686). Defaults to False.
+- `task_id`: Optional client-provided task ID (auto-generated if not provided).
+- `ttl`: Time to keep results available in milliseconds (default 60s).
+
+**Returns:**
+- list\[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] | ResourceTask:
+A list of content objects if task=False, or a ResourceTask object if task=True.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
diff --git a/docs/python-sdk/fastmcp-client-task_management.mdx b/docs/python-sdk/fastmcp-client-task_management.mdx
new file mode 100644
index 000000000..f9d4ef18d
--- /dev/null
+++ b/docs/python-sdk/fastmcp-client-task_management.mdx
@@ -0,0 +1,110 @@
+---
+title: task_management
+sidebarTitle: task_management
+---
+
+# `fastmcp.client.task_management`
+
+
+Task management methods for FastMCP Client.
+
+## Classes
+
+### `ClientTaskManagementMixin`
+
+
+Mixin providing task management methods for Client.
+
+
+**Methods:**
+
+#### `get_task_status`
+
+```python
+get_task_status(self: Client, task_id: str) -> GetTaskResult
+```
+
+Query the status of a background task.
+
+Sends a 'tasks/get' MCP protocol request over the existing transport.
+
+**Args:**
+- `task_id`: The task ID returned from call_tool_as_task
+
+**Returns:**
+- Status information including taskId, status, pollInterval, etc.
+
+**Raises:**
+- `RuntimeError`: If client not connected
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `get_task_result`
+
+```python
+get_task_result(self: Client, task_id: str) -> Any
+```
+
+Retrieve the raw result of a completed background task.
+
+Sends a 'tasks/result' MCP protocol request over the existing transport.
+Returns the raw result - callers should parse it appropriately.
+
+**Args:**
+- `task_id`: The task ID returned from call_tool_as_task
+
+**Returns:**
+- The raw result (could be tool, prompt, or resource result)
+
+**Raises:**
+- `RuntimeError`: If client not connected, task not found, or task failed
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `list_tasks`
+
+```python
+list_tasks(self: Client, cursor: str | None = None, limit: int = 50) -> dict[str, Any]
+```
+
+List background tasks.
+
+Sends a 'tasks/list' MCP protocol request to the server. If the server
+returns an empty list (indicating client-side tracking), falls back to
+querying status for locally tracked task IDs.
+
+**Args:**
+- `cursor`: Optional pagination cursor
+- `limit`: Maximum number of tasks to return (default 50)
+
+**Returns:**
+- Response with structure:
+- tasks: List of task status dicts with taskId, status, etc.
+- nextCursor: Optional cursor for next page
+
+**Raises:**
+- `RuntimeError`: If client not connected
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `cancel_task`
+
+```python
+cancel_task(self: Client, task_id: str) -> mcp.types.CancelTaskResult
+```
+
+Cancel a task, transitioning it to cancelled state.
+
+Sends a 'tasks/cancel' MCP protocol request. Task will halt execution
+and transition to cancelled state.
+
+**Args:**
+- `task_id`: The task ID to cancel
+
+**Returns:**
+- The task status showing cancelled state
+
+**Raises:**
+- `RuntimeError`: If task doesn't exist
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
diff --git a/docs/python-sdk/fastmcp-client-tools_client.mdx b/docs/python-sdk/fastmcp-client-tools_client.mdx
new file mode 100644
index 000000000..681abc997
--- /dev/null
+++ b/docs/python-sdk/fastmcp-client-tools_client.mdx
@@ -0,0 +1,141 @@
+---
+title: tools_client
+sidebarTitle: tools_client
+---
+
+# `fastmcp.client.tools_client`
+
+
+Tool-related methods for FastMCP Client.
+
+## Classes
+
+### `ClientToolsMixin`
+
+
+Mixin providing tool-related methods for Client.
+
+
+**Methods:**
+
+#### `list_tools_mcp`
+
+```python
+list_tools_mcp(self: Client) -> mcp.types.ListToolsResult
+```
+
+Send a tools/list request and return the complete MCP protocol result.
+
+**Args:**
+- `cursor`: Optional pagination cursor from a previous request's nextCursor.
+
+**Returns:**
+- mcp.types.ListToolsResult: The complete response object from the protocol,
+containing the list of tools and any additional metadata.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `list_tools`
+
+```python
+list_tools(self: Client) -> list[mcp.types.Tool]
+```
+
+Retrieve all tools available on the server.
+
+This method automatically fetches all pages if the server paginates results,
+returning the complete list. For manual pagination control (e.g., to handle
+large result sets incrementally), use list_tools_mcp() with the cursor parameter.
+
+**Returns:**
+- list\[mcp.types.Tool]: A list of all Tool objects.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the request results in a TimeoutError | JSONRPCError
+
+
+#### `call_tool_mcp`
+
+```python
+call_tool_mcp(self: Client, name: str, arguments: dict[str, Any], progress_handler: ProgressHandler | None = None, timeout: datetime.timedelta | float | int | None = None, meta: dict[str, Any] | None = None) -> mcp.types.CallToolResult
+```
+
+Send a tools/call request and return the complete MCP protocol result.
+
+This method returns the raw CallToolResult object, which includes an isError flag
+and other metadata. It does not raise an exception if the tool call results in an error.
+
+**Args:**
+- `name`: The name of the tool to call.
+- `arguments`: Arguments to pass to the tool.
+- `timeout`: The timeout for the tool call. Defaults to None.
+- `progress_handler`: The progress handler to use for the tool call. Defaults to None.
+- `meta`: Additional metadata to include with the request.
+This is useful for passing contextual information (like user IDs, trace IDs, or preferences)
+that shouldn't be tool arguments but may influence server-side processing. The server
+can access this via `context.request_context.meta`. Defaults to None.
+
+**Returns:**
+- mcp.types.CallToolResult: The complete response object from the protocol,
+containing the tool result and any additional metadata.
+
+**Raises:**
+- `RuntimeError`: If called while the client is not connected.
+- `McpError`: If the tool call requests results in a TimeoutError | JSONRPCError
+
+
+#### `call_tool`
+
+```python
+call_tool(self: Client, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult
+```
+
+#### `call_tool`
+
+```python
+call_tool(self: Client, name: str, arguments: dict[str, Any] | None = None) -> ToolTask
+```
+
+#### `call_tool`
+
+```python
+call_tool(self: Client, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult | ToolTask
+```
+
+Call a tool on the server.
+
+Unlike call_tool_mcp, this method raises a ToolError if the tool call results in an error.
+
+**Args:**
+- `name`: The name of the tool to call.
+- `arguments`: Arguments to pass to the tool. Defaults to None.
+- `version`: Specific tool version to call. If None, calls highest version.
+- `timeout`: The timeout for the tool call. Defaults to None.
+- `progress_handler`: The progress handler to use for the tool call. Defaults to None.
+- `raise_on_error`: Whether to raise an exception if the tool call results in an error. Defaults to True.
+- `meta`: Additional metadata to include with the request.
+This is useful for passing contextual information (like user IDs, trace IDs, or preferences)
+that shouldn't be tool arguments but may influence server-side processing. The server
+can access this via `context.request_context.meta`. Defaults to None.
+- `task`: If True, execute as background task (SEP-1686). Defaults to False.
+- `task_id`: Optional client-provided task ID (auto-generated if not provided).
+- `ttl`: Time to keep results available in milliseconds (default 60s).
+
+**Returns:**
+- CallToolResult | ToolTask: The content returned by the tool if task=False,
+or a ToolTask object if task=True. If the tool returns structured
+outputs, they are returned as a dataclass (if an output schema
+is available) or a dictionary; otherwise, a list of content
+blocks is returned. Note: to receive both structured and
+unstructured outputs, use call_tool_mcp instead and access the
+raw result object.
+
+**Raises:**
+- `ToolError`: If the tool call results in an error.
+- `McpError`: If the tool call request results in a TimeoutError | JSONRPCError
+- `RuntimeError`: If called while the client is not connected.
+
diff --git a/docs/python-sdk/fastmcp-client-transports-http.mdx b/docs/python-sdk/fastmcp-client-transports-http.mdx
index 584632184..e5ba1599a 100644
--- a/docs/python-sdk/fastmcp-client-transports-http.mdx
+++ b/docs/python-sdk/fastmcp-client-transports-http.mdx
@@ -5,23 +5,12 @@ sidebarTitle: http
# `fastmcp.client.transports.http`
+
+Streamable HTTP transport for FastMCP Client.
+
## Classes
-### `SSETransport`
-
-
-Transport implementation that connects to an MCP server via Server-Sent Events.
-
-
-**Methods:**
-
-#### `connect_session`
-
-```python
-connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
-```
-
-### `StreamableHttpTransport`
+### `StreamableHttpTransport`
Transport implementation that connects to an MCP server via Streamable HTTP Requests.
@@ -29,19 +18,19 @@ Transport implementation that connects to an MCP server via Streamable HTTP Requ
**Methods:**
-#### `connect_session`
+#### `connect_session`
```python
connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
```
-#### `get_session_id`
+#### `get_session_id`
```python
get_session_id(self) -> str | None
```
-#### `close`
+#### `close`
```python
close(self)
diff --git a/docs/python-sdk/fastmcp-client-transports-inference.mdx b/docs/python-sdk/fastmcp-client-transports-inference.mdx
index fd6c53d30..7281e8f37 100644
--- a/docs/python-sdk/fastmcp-client-transports-inference.mdx
+++ b/docs/python-sdk/fastmcp-client-transports-inference.mdx
@@ -7,7 +7,7 @@ sidebarTitle: inference
## Functions
-### `infer_transport`
+### `infer_transport`
```python
infer_transport(transport: ClientTransport | FastMCP | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str) -> ClientTransport
diff --git a/docs/python-sdk/fastmcp-client-transports-sse.mdx b/docs/python-sdk/fastmcp-client-transports-sse.mdx
new file mode 100644
index 000000000..2f3449e2d
--- /dev/null
+++ b/docs/python-sdk/fastmcp-client-transports-sse.mdx
@@ -0,0 +1,25 @@
+---
+title: sse
+sidebarTitle: sse
+---
+
+# `fastmcp.client.transports.sse`
+
+
+Server-Sent Events (SSE) transport for FastMCP Client.
+
+## Classes
+
+### `SSETransport`
+
+
+Transport implementation that connects to an MCP server via Server-Sent Events.
+
+
+**Methods:**
+
+#### `connect_session`
+
+```python
+connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession]
+```
diff --git a/docs/python-sdk/fastmcp-server-auth-oauth_proxy-__init__.mdx b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-__init__.mdx
new file mode 100644
index 000000000..7c4665aa8
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-__init__.mdx
@@ -0,0 +1,16 @@
+---
+title: __init__
+sidebarTitle: __init__
+---
+
+# `fastmcp.server.auth.oauth_proxy`
+
+
+OAuth Proxy Provider for FastMCP.
+
+This package provides OAuth proxy functionality split across multiple modules:
+- models: Pydantic models and constants
+- ui: HTML generation functions
+- consent: Consent management mixin
+- proxy: Main OAuthProxy class
+
diff --git a/docs/python-sdk/fastmcp-server-auth-oauth_proxy-consent.mdx b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-consent.mdx
new file mode 100644
index 000000000..0b9f709f1
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-consent.mdx
@@ -0,0 +1,28 @@
+---
+title: consent
+sidebarTitle: consent
+---
+
+# `fastmcp.server.auth.oauth_proxy.consent`
+
+
+OAuth Proxy Consent Management.
+
+This module contains consent management functionality for the OAuth proxy.
+The ConsentMixin class provides methods for handling user consent flows,
+cookie management, and consent page rendering.
+
+
+## Classes
+
+### `ConsentMixin`
+
+
+Mixin class providing consent management functionality for OAuthProxy.
+
+This mixin contains all methods related to:
+- Cookie signing and verification
+- Consent page rendering
+- Consent approval/denial handling
+- URI normalization for consent tracking
+
diff --git a/docs/python-sdk/fastmcp-server-auth-oauth_proxy-models.mdx b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-models.mdx
new file mode 100644
index 000000000..9de2cf8d2
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-models.mdx
@@ -0,0 +1,104 @@
+---
+title: models
+sidebarTitle: models
+---
+
+# `fastmcp.server.auth.oauth_proxy.models`
+
+
+OAuth Proxy Models and Constants.
+
+This module contains all Pydantic models and constants used by the OAuth proxy.
+
+
+## Classes
+
+### `OAuthTransaction`
+
+
+OAuth transaction state for consent flow.
+
+Stored server-side to track active authorization flows with client context.
+Includes CSRF tokens for consent protection per MCP security best practices.
+
+
+### `ClientCode`
+
+
+Client authorization code with PKCE and upstream tokens.
+
+Stored server-side after upstream IdP callback. Contains the upstream
+tokens bound to the client's PKCE challenge for secure token exchange.
+
+
+### `UpstreamTokenSet`
+
+
+Stored upstream OAuth tokens from identity provider.
+
+These tokens are obtained from the upstream provider (Google, GitHub, etc.)
+and stored in plaintext within this model. Encryption is handled transparently
+at the storage layer via FernetEncryptionWrapper. Tokens are never exposed to MCP clients.
+
+
+### `JTIMapping`
+
+
+Maps FastMCP token JTI to upstream token ID.
+
+This allows stateless JWT validation while still being able to look up
+the corresponding upstream token when tools need to access upstream APIs.
+
+
+### `RefreshTokenMetadata`
+
+
+Metadata for a refresh token, stored keyed by token hash.
+
+We store only metadata (not the token itself) for security - if storage
+is compromised, attackers get hashes they can't reverse into usable tokens.
+
+
+### `ProxyDCRClient`
+
+
+Client for DCR proxy with configurable redirect URI validation.
+
+This special client class is critical for the OAuth proxy to work correctly
+with Dynamic Client Registration (DCR). Here's why it exists:
+
+Problem:
+--------
+When MCP clients use OAuth, they dynamically register with random localhost
+ports (e.g., http://localhost:55454/callback). The OAuth proxy needs to:
+1. Accept these dynamic redirect URIs from clients based on configured patterns
+2. Use its own fixed redirect URI with the upstream provider (Google, GitHub, etc.)
+3. Forward the authorization code back to the client's dynamic URI
+
+Solution:
+---------
+This class validates redirect URIs against configurable patterns,
+while the proxy internally uses its own fixed redirect URI with the upstream
+provider. This allows the flow to work even when clients reconnect with
+different ports or when tokens are cached.
+
+Without proper validation, clients could get "Redirect URI not registered" errors
+when trying to authenticate with cached tokens, or security vulnerabilities could
+arise from accepting arbitrary redirect URIs.
+
+
+**Methods:**
+
+#### `validate_redirect_uri`
+
+```python
+validate_redirect_uri(self, redirect_uri: AnyUrl | None) -> AnyUrl
+```
+
+Validate redirect URI against allowed patterns.
+
+Since we're acting as a proxy and clients register dynamically,
+we validate their redirect URIs against configurable patterns.
+This is essential for cached token scenarios where the client may
+reconnect with a different port.
+
diff --git a/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx
similarity index 61%
rename from docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx
rename to docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx
index 46f190430..20f839f46 100644
--- a/docs/python-sdk/fastmcp-server-auth-oauth_proxy.mdx
+++ b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx
@@ -1,9 +1,9 @@
---
-title: oauth_proxy
-sidebarTitle: oauth_proxy
+title: proxy
+sidebarTitle: proxy
---
-# `fastmcp.server.auth.oauth_proxy`
+# `fastmcp.server.auth.oauth_proxy.proxy`
OAuth Proxy Provider for FastMCP.
@@ -24,137 +24,9 @@ This implementation is based on the OAuth 2.1 specification and is designed for
production use with enterprise identity providers.
-## Functions
-
-### `create_consent_html`
-
-```python
-create_consent_html(client_id: str, redirect_uri: str, scopes: list[str], txn_id: str, csrf_token: str, client_name: str | None = None, title: str = 'Application Access Request', server_name: str | None = None, server_icon_url: str | None = None, server_website_url: str | None = None, client_website_url: str | None = None, csp_policy: str | None = None) -> str
-```
-
-
-Create a styled HTML consent page for OAuth authorization requests.
-
-**Args:**
-- `csp_policy`: Content Security Policy override.
-If None, uses the built-in CSP policy with appropriate directives.
-If empty string "", disables CSP entirely (no meta tag is rendered).
-If a non-empty string, uses that as the CSP policy value.
-
-
-### `create_error_html`
-
-```python
-create_error_html(error_title: str, error_message: str, error_details: dict[str, str] | None = None, server_name: str | None = None, server_icon_url: str | None = None) -> str
-```
-
-
-Create a styled HTML error page for OAuth errors.
-
-**Args:**
-- `error_title`: The error title (e.g., "OAuth Error", "Authorization Failed")
-- `error_message`: The main error message to display
-- `error_details`: Optional dictionary of error details to show (e.g., `{"Error Code"\: "invalid_client"}`)
-- `server_name`: Optional server name to display
-- `server_icon_url`: Optional URL to server icon/logo
-
-**Returns:**
-- Complete HTML page as a string
-
-
## Classes
-### `OAuthTransaction`
-
-
-OAuth transaction state for consent flow.
-
-Stored server-side to track active authorization flows with client context.
-Includes CSRF tokens for consent protection per MCP security best practices.
-
-
-### `ClientCode`
-
-
-Client authorization code with PKCE and upstream tokens.
-
-Stored server-side after upstream IdP callback. Contains the upstream
-tokens bound to the client's PKCE challenge for secure token exchange.
-
-
-### `UpstreamTokenSet`
-
-
-Stored upstream OAuth tokens from identity provider.
-
-These tokens are obtained from the upstream provider (Google, GitHub, etc.)
-and stored in plaintext within this model. Encryption is handled transparently
-at the storage layer via FernetEncryptionWrapper. Tokens are never exposed to MCP clients.
-
-
-### `JTIMapping`
-
-
-Maps FastMCP token JTI to upstream token ID.
-
-This allows stateless JWT validation while still being able to look up
-the corresponding upstream token when tools need to access upstream APIs.
-
-
-### `RefreshTokenMetadata`
-
-
-Metadata for a refresh token, stored keyed by token hash.
-
-We store only metadata (not the token itself) for security - if storage
-is compromised, attackers get hashes they can't reverse into usable tokens.
-
-
-### `ProxyDCRClient`
-
-
-Client for DCR proxy with configurable redirect URI validation.
-
-This special client class is critical for the OAuth proxy to work correctly
-with Dynamic Client Registration (DCR). Here's why it exists:
-
-Problem:
---------
-When MCP clients use OAuth, they dynamically register with random localhost
-ports (e.g., http://localhost:55454/callback). The OAuth proxy needs to:
-1. Accept these dynamic redirect URIs from clients based on configured patterns
-2. Use its own fixed redirect URI with the upstream provider (Google, GitHub, etc.)
-3. Forward the authorization code back to the client's dynamic URI
-
-Solution:
----------
-This class validates redirect URIs against configurable patterns,
-while the proxy internally uses its own fixed redirect URI with the upstream
-provider. This allows the flow to work even when clients reconnect with
-different ports or when tokens are cached.
-
-Without proper validation, clients could get "Redirect URI not registered" errors
-when trying to authenticate with cached tokens, or security vulnerabilities could
-arise from accepting arbitrary redirect URIs.
-
-
-**Methods:**
-
-#### `validate_redirect_uri`
-
-```python
-validate_redirect_uri(self, redirect_uri: AnyUrl | None) -> AnyUrl
-```
-
-Validate redirect URI against allowed patterns.
-
-Since we're acting as a proxy and clients register dynamically,
-we validate their redirect URIs against configurable patterns.
-This is essential for cached token scenarios where the client may
-reconnect with a different port.
-
-
-### `OAuthProxy`
+### `OAuthProxy`
OAuth provider that presents a DCR-compliant interface while proxying to non-DCR IDPs.
@@ -268,7 +140,7 @@ Handles provider-specific requirements:
**Methods:**
-#### `set_mcp_path`
+#### `set_mcp_path`
```python
set_mcp_path(self, mcp_path: str | None) -> None
@@ -285,7 +157,7 @@ this specific MCP endpoint.
- `mcp_path`: The path where the MCP endpoint is mounted (e.g., "/mcp")
-#### `jwt_issuer`
+#### `jwt_issuer`
```python
jwt_issuer(self) -> JWTIssuer
@@ -297,7 +169,7 @@ The JWT issuer is created when set_mcp_path() is called (via get_routes()).
This property ensures a clear error if used before initialization.
-#### `get_client`
+#### `get_client`
```python
get_client(self, client_id: str) -> OAuthClientInformationFull | None
@@ -309,7 +181,7 @@ provided to the DCR client during registration, not the upstream client ID.
For unregistered clients, returns None (which will raise an error in the SDK).
-#### `register_client`
+#### `register_client`
```python
register_client(self, client_info: OAuthClientInformationFull) -> None
@@ -323,7 +195,7 @@ redirect URI will likely be localhost or unknown to the proxied IDP. The
proxied IDP only knows about this server's fixed redirect URI.
-#### `authorize`
+#### `authorize`
```python
authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str
@@ -341,7 +213,7 @@ If consent is disabled (require_authorization_consent=False), skip the consent s
and redirect directly to the upstream IdP.
-#### `load_authorization_code`
+#### `load_authorization_code`
```python
load_authorization_code(self, client: OAuthClientInformationFull, authorization_code: str) -> AuthorizationCode | None
@@ -353,7 +225,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
@@ -371,7 +243,7 @@ Implements the token factory pattern:
PKCE validation is handled by the MCP framework before this method is called.
-#### `load_refresh_token`
+#### `load_refresh_token`
```python
load_refresh_token(self, client: OAuthClientInformationFull, refresh_token: str) -> RefreshToken | None
@@ -383,7 +255,7 @@ Looks up by token hash and reconstructs the RefreshToken object.
Validates that the token belongs to the requesting client.
-#### `exchange_refresh_token`
+#### `exchange_refresh_token`
```python
exchange_refresh_token(self, client: OAuthClientInformationFull, refresh_token: RefreshToken, scopes: list[str]) -> OAuthToken
@@ -400,7 +272,7 @@ Implements two-tier refresh:
6. Keep same FastMCP refresh token (unless upstream rotates)
-#### `load_access_token`
+#### `load_access_token`
```python
load_access_token(self, token: str) -> AccessToken | None
@@ -419,7 +291,7 @@ The FastMCP JWT is a reference token - all authorization data comes
from validating the upstream token via the TokenVerifier.
-#### `revoke_token`
+#### `revoke_token`
```python
revoke_token(self, token: AccessToken | RefreshToken) -> None
@@ -432,7 +304,7 @@ For all tokens, attempts upstream revocation if endpoint is configured.
Access token JTI mappings expire via TTL.
-#### `get_routes`
+#### `get_routes`
```python
get_routes(self, mcp_path: str | None = None) -> list[Route]
diff --git a/docs/python-sdk/fastmcp-server-auth-oauth_proxy-ui.mdx b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-ui.mdx
new file mode 100644
index 000000000..efd2338d6
--- /dev/null
+++ b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-ui.mdx
@@ -0,0 +1,50 @@
+---
+title: ui
+sidebarTitle: ui
+---
+
+# `fastmcp.server.auth.oauth_proxy.ui`
+
+
+OAuth Proxy UI Generation Functions.
+
+This module contains HTML generation functions for consent and error pages.
+
+
+## Functions
+
+### `create_consent_html`
+
+```python
+create_consent_html(client_id: str, redirect_uri: str, scopes: list[str], txn_id: str, csrf_token: str, client_name: str | None = None, title: str = 'Application Access Request', server_name: str | None = None, server_icon_url: str | None = None, server_website_url: str | None = None, client_website_url: str | None = None, csp_policy: str | None = None) -> str
+```
+
+
+Create a styled HTML consent page for OAuth authorization requests.
+
+**Args:**
+- `csp_policy`: Content Security Policy override.
+If None, uses the built-in CSP policy with appropriate directives.
+If empty string "", disables CSP entirely (no meta tag is rendered).
+If a non-empty string, uses that as the CSP policy value.
+
+
+### `create_error_html`
+
+```python
+create_error_html(error_title: str, error_message: str, error_details: dict[str, str] | None = None, server_name: str | None = None, server_icon_url: str | None = None) -> str
+```
+
+
+Create a styled HTML error page for OAuth errors.
+
+**Args:**
+- `error_title`: The error title (e.g., "OAuth Error", "Authorization Failed")
+- `error_message`: The main error message to display
+- `error_details`: Optional dictionary of error details to show (e.g., `{"Error Code"\: "invalid_client"}`)
+- `server_name`: Optional server name to display
+- `server_icon_url`: Optional URL to server icon/logo
+
+**Returns:**
+- Complete HTML page as a string
+
diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx
index 6f101ab75..4fdca2448 100644
--- a/docs/python-sdk/fastmcp-server-server.mdx
+++ b/docs/python-sdk/fastmcp-server-server.mdx
@@ -26,7 +26,7 @@ Default lifespan context manager that does nothing.
- An empty dictionary as the lifespan result.
-### `create_proxy`
+### `create_proxy`
```python
create_proxy(target: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
@@ -497,7 +497,7 @@ Starlette's reverse URL lookup feature)
- `include_in_schema`: Whether to include in OpenAPI schema, defaults to True
-#### `add_tool`
+#### `add_tool`
```python
add_tool(self, tool: Tool | Callable[..., Any]) -> Tool
@@ -515,7 +515,7 @@ with the Context type annotation. See the @tool decorator for examples.
- The tool instance that was added to the server.
-#### `remove_tool`
+#### `remove_tool`
```python
remove_tool(self, name: str, version: str | None = None) -> None
@@ -531,19 +531,19 @@ Remove tool(s) from the server.
- `NotFoundError`: If no matching tool is found.
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: AnyFunction) -> FunctionTool
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool]
```
-#### `tool`
+#### `tool`
```python
tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool]
@@ -599,7 +599,7 @@ server.tool(my_function, name="custom_name")
```
-#### `add_resource`
+#### `add_resource`
```python
add_resource(self, resource: Resource | Callable[..., Any]) -> Resource | ResourceTemplate
@@ -614,7 +614,7 @@ Add a resource to the server.
- The resource instance that was added to the server.
-#### `add_template`
+#### `add_template`
```python
add_template(self, template: ResourceTemplate) -> ResourceTemplate
@@ -629,7 +629,7 @@ Add a resource template to the server.
- The template instance that was added to the server.
-#### `resource`
+#### `resource`
```python
resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate | AnyFunction]
@@ -688,7 +688,7 @@ async def get_weather(city: str) -> str:
```
-#### `add_prompt`
+#### `add_prompt`
```python
add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt
@@ -703,19 +703,19 @@ Add a prompt to the server.
- The prompt instance that was added to the server.
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt]
```
-#### `prompt`
+#### `prompt`
```python
prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt]
@@ -792,7 +792,7 @@ Decorator to register a prompt.
```
-#### `run_stdio_async`
+#### `run_stdio_async`
```python
run_stdio_async(self, show_banner: bool = True, log_level: str | None = None, stateless: bool = False) -> None
@@ -806,7 +806,7 @@ Run the server using stdio transport.
- `stateless`: Whether to run in stateless mode (no session initialization)
-#### `run_http_async`
+#### `run_http_async`
```python
run_http_async(self, show_banner: bool = True, transport: Literal['http', 'streamable-http', 'sse'] = 'http', host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, stateless: bool | None = None) -> None
@@ -827,7 +827,7 @@ Run the server using HTTP transport.
- `stateless`: Alias for stateless_http for CLI consistency
-#### `http_app`
+#### `http_app`
```python
http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http', event_store: EventStore | None = None, retry_interval: int | None = None) -> StarletteWithLifespan
@@ -853,7 +853,7 @@ streamable-http transport.
- A Starlette application configured with the specified transport
-#### `mount`
+#### `mount`
```python
mount(self, server: FastMCP[LifespanResultT], namespace: str | None = None, as_proxy: bool | None = None, tool_names: dict[str, str] | None = None, prefix: str | None = None) -> None
@@ -900,7 +900,7 @@ mounted server.
- `prefix`: Deprecated. Use namespace instead.
-#### `import_server`
+#### `import_server`
```python
import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None
@@ -941,7 +941,7 @@ templates, and prompts are imported with their original names.
objects are imported with their original names.
-#### `from_openapi`
+#### `from_openapi`
```python
from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, name: str = 'OpenAPI Server', route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self
@@ -965,7 +965,7 @@ Create a FastMCP server from an OpenAPI specification.
- A FastMCP server with an OpenAPIProvider attached.
-#### `from_fastapi`
+#### `from_fastapi`
```python
from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self
@@ -989,7 +989,7 @@ Create a FastMCP server from a FastAPI application.
- A FastMCP server with an OpenAPIProvider attached.
-#### `as_proxy`
+#### `as_proxy`
```python
as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy
@@ -1007,7 +1007,7 @@ instance or any value accepted as the `transport` argument of
`fastmcp.client.Client` constructor.
-#### `generate_name`
+#### `generate_name`
```python
generate_name(cls, name: str | None = None) -> str
diff --git a/docs/python-sdk/fastmcp-utilities-timeout.mdx b/docs/python-sdk/fastmcp-utilities-timeout.mdx
new file mode 100644
index 000000000..8c23d5350
--- /dev/null
+++ b/docs/python-sdk/fastmcp-utilities-timeout.mdx
@@ -0,0 +1,44 @@
+---
+title: timeout
+sidebarTitle: timeout
+---
+
+# `fastmcp.utilities.timeout`
+
+
+Timeout normalization utilities.
+
+## Functions
+
+### `normalize_timeout_to_timedelta`
+
+```python
+normalize_timeout_to_timedelta(value: int | float | datetime.timedelta | None) -> datetime.timedelta | None
+```
+
+
+Normalize a timeout value to a timedelta.
+
+**Args:**
+- `value`: Timeout value as int/float (seconds), timedelta, or None
+
+**Returns:**
+- timedelta if value provided, None otherwise
+
+
+### `normalize_timeout_to_seconds`
+
+```python
+normalize_timeout_to_seconds(value: int | float | datetime.timedelta | None) -> float | None
+```
+
+
+Normalize a timeout value to seconds (float).
+
+**Args:**
+- `value`: Timeout value as int/float (seconds), timedelta, or None.
+Zero values are treated as "disabled" and return None.
+
+**Returns:**
+- float seconds if value provided and non-zero, None otherwise
+