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 +