diff --git a/docs/docs.json b/docs/docs.json index 4a6b4bd59..60a072fcb 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -320,7 +320,20 @@ "python-sdk/fastmcp-client-oauth_callback", "python-sdk/fastmcp-client-progress", "python-sdk/fastmcp-client-roots", - "python-sdk/fastmcp-client-sampling", + { + "group": "sampling", + "pages": [ + "python-sdk/fastmcp-client-sampling-__init__", + { + "group": "handlers", + "pages": [ + "python-sdk/fastmcp-client-sampling-handlers-__init__", + "python-sdk/fastmcp-client-sampling-handlers-anthropic", + "python-sdk/fastmcp-client-sampling-handlers-openai" + ] + } + ] + }, "python-sdk/fastmcp-client-tasks", "python-sdk/fastmcp-client-transports" ] @@ -329,8 +342,7 @@ "group": "fastmcp.prompts", "pages": [ "python-sdk/fastmcp-prompts-__init__", - "python-sdk/fastmcp-prompts-prompt", - "python-sdk/fastmcp-prompts-prompt_manager" + "python-sdk/fastmcp-prompts-prompt" ] }, { @@ -338,7 +350,6 @@ "pages": [ "python-sdk/fastmcp-resources-__init__", "python-sdk/fastmcp-resources-resource", - "python-sdk/fastmcp-resources-resource_manager", "python-sdk/fastmcp-resources-template", "python-sdk/fastmcp-resources-types" ] @@ -408,7 +419,35 @@ "python-sdk/fastmcp-server-openapi-server" ] }, + { + "group": "providers", + "pages": [ + "python-sdk/fastmcp-server-providers-__init__", + "python-sdk/fastmcp-server-providers-base", + "python-sdk/fastmcp-server-providers-fastmcp_provider", + "python-sdk/fastmcp-server-providers-local_provider", + { + "group": "openapi", + "pages": [ + "python-sdk/fastmcp-server-providers-openapi-__init__", + "python-sdk/fastmcp-server-providers-openapi-components", + "python-sdk/fastmcp-server-providers-openapi-provider", + "python-sdk/fastmcp-server-providers-openapi-routing" + ] + }, + "python-sdk/fastmcp-server-providers-proxy", + "python-sdk/fastmcp-server-providers-transforming" + ] + }, "python-sdk/fastmcp-server-proxy", + { + "group": "sampling", + "pages": [ + "python-sdk/fastmcp-server-sampling-__init__", + "python-sdk/fastmcp-server-sampling-run", + "python-sdk/fastmcp-server-sampling-sampling_tool" + ] + }, "python-sdk/fastmcp-server-server", { "group": "tasks", @@ -416,10 +455,10 @@ "python-sdk/fastmcp-server-tasks-__init__", "python-sdk/fastmcp-server-tasks-capabilities", "python-sdk/fastmcp-server-tasks-config", - "python-sdk/fastmcp-server-tasks-converters", "python-sdk/fastmcp-server-tasks-handlers", "python-sdk/fastmcp-server-tasks-keys", - "python-sdk/fastmcp-server-tasks-protocol", + "python-sdk/fastmcp-server-tasks-requests", + "python-sdk/fastmcp-server-tasks-routing", "python-sdk/fastmcp-server-tasks-subscriptions" ] } @@ -430,7 +469,6 @@ "pages": [ "python-sdk/fastmcp-tools-__init__", "python-sdk/fastmcp-tools-tool", - "python-sdk/fastmcp-tools-tool_manager", "python-sdk/fastmcp-tools-tool_transform" ] }, @@ -491,7 +529,8 @@ }, "python-sdk/fastmcp-utilities-tests", "python-sdk/fastmcp-utilities-types", - "python-sdk/fastmcp-utilities-ui" + "python-sdk/fastmcp-utilities-ui", + "python-sdk/fastmcp-utilities-visibility" ] } ] diff --git a/docs/python-sdk/fastmcp-client-client.mdx b/docs/python-sdk/fastmcp-client-client.mdx index 95907eb4f..eb9f152e7 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,16 +112,16 @@ set_roots(self, roots: RootsList | RootsHandler) -> None Set the roots for the client. This does not automatically call `send_roots_list_changed`. -#### `set_sampling_callback` +#### `set_sampling_callback` ```python -set_sampling_callback(self, sampling_callback: ClientSamplingHandler) -> None +set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabilities: mcp.types.SamplingCapability | None = None) -> None ``` 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,7 +234,7 @@ send_roots_list_changed(self) -> None Send a roots/list_changed notification. -#### `list_resources_mcp` +#### `list_resources_mcp` ```python list_resources_mcp(self) -> mcp.types.ListResourcesResult @@ -248,9 +248,10 @@ 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` +#### `list_resources` ```python list_resources(self) -> list[mcp.types.Resource] @@ -263,9 +264,10 @@ Retrieve a list of resources available on the server. **Raises:** - `RuntimeError`: If called while the client is not connected. +- `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `list_resource_templates_mcp` +#### `list_resource_templates_mcp` ```python list_resource_templates_mcp(self) -> mcp.types.ListResourceTemplatesResult @@ -279,9 +281,10 @@ 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` +#### `list_resource_templates` ```python list_resource_templates(self) -> list[mcp.types.ResourceTemplate] @@ -294,9 +297,10 @@ Retrieve a list of resource templates available on the server. **Raises:** - `RuntimeError`: If called while the client is not connected. +- `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `read_resource_mcp` +#### `read_resource_mcp` ```python read_resource_mcp(self, uri: AnyUrl | str, meta: dict[str, Any] | None = None) -> mcp.types.ReadResourceResult @@ -314,21 +318,22 @@ 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` +#### `read_resource` ```python read_resource(self, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] ``` -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: AnyUrl | str) -> ResourceTask ``` -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: AnyUrl | str) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] | ResourceTask @@ -348,9 +353,10 @@ 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` +#### `list_prompts_mcp` ```python list_prompts_mcp(self) -> mcp.types.ListPromptsResult @@ -364,9 +370,10 @@ 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` +#### `list_prompts` ```python list_prompts(self) -> list[mcp.types.Prompt] @@ -379,9 +386,10 @@ Retrieve a list of prompts available on the server. **Raises:** - `RuntimeError`: If called while the client is not connected. +- `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `get_prompt_mcp` +#### `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 @@ -400,21 +408,22 @@ 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` +#### `get_prompt` ```python get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult ``` -#### `get_prompt` +#### `get_prompt` ```python get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptTask ``` -#### `get_prompt` +#### `get_prompt` ```python get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.GetPromptResult | PromptTask @@ -435,9 +444,10 @@ 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 @@ -457,9 +467,10 @@ containing the completion and any additional metadata. **Raises:** - `RuntimeError`: If called while the client is not connected. +- `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 @@ -478,9 +489,10 @@ include with the completion request. Defaults to None. **Raises:** - `RuntimeError`: If called while the client is not connected. +- `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `list_tools_mcp` +#### `list_tools_mcp` ```python list_tools_mcp(self) -> mcp.types.ListToolsResult @@ -494,9 +506,10 @@ 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` +#### `list_tools` ```python list_tools(self) -> list[mcp.types.Tool] @@ -509,9 +522,10 @@ Retrieve a list of tools available on the server. **Raises:** - `RuntimeError`: If called while the client is not connected. +- `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `call_tool_mcp` +#### `call_tool_mcp` ```python call_tool_mcp(self, name: str, arguments: dict[str, Any], progress_handler: ProgressHandler | None = None, timeout: datetime.timedelta | float | int | None = None, meta: dict[str, Any] | None = None) -> mcp.types.CallToolResult @@ -538,21 +552,22 @@ 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` +#### `call_tool` ```python call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult ``` -#### `call_tool` +#### `call_tool` ```python call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolTask ``` -#### `call_tool` +#### `call_tool` ```python call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> CallToolResult | ToolTask @@ -587,10 +602,11 @@ 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` +#### `get_task_status` ```python get_task_status(self, task_id: str) -> GetTaskResult @@ -608,9 +624,10 @@ Sends a 'tasks/get' MCP protocol request over the existing transport. **Raises:** - `RuntimeError`: If client not connected +- `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `get_task_result` +#### `get_task_result` ```python get_task_result(self, task_id: str) -> Any @@ -629,9 +646,10 @@ Returns the raw result - callers should parse it appropriately. **Raises:** - `RuntimeError`: If client not connected, task not found, or task failed +- `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `list_tasks` +#### `list_tasks` ```python list_tasks(self, cursor: str | None = None, limit: int = 50) -> dict[str, Any] @@ -654,9 +672,10 @@ querying status for locally tracked task IDs. **Raises:** - `RuntimeError`: If client not connected +- `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `cancel_task` +#### `cancel_task` ```python cancel_task(self, task_id: str) -> mcp.types.CancelTaskResult @@ -675,9 +694,10 @@ and transition to 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-sampling-__init__.mdx b/docs/python-sdk/fastmcp-client-sampling-__init__.mdx new file mode 100644 index 000000000..ec69f61c7 --- /dev/null +++ b/docs/python-sdk/fastmcp-client-sampling-__init__.mdx @@ -0,0 +1,14 @@ +--- +title: __init__ +sidebarTitle: __init__ +--- + +# `fastmcp.client.sampling` + +## Functions + +### `create_sampling_callback` + +```python +create_sampling_callback(sampling_handler: SamplingHandler) -> SamplingFnT +``` diff --git a/docs/python-sdk/fastmcp-client-sampling-handlers-__init__.mdx b/docs/python-sdk/fastmcp-client-sampling-handlers-__init__.mdx new file mode 100644 index 000000000..43329b5e6 --- /dev/null +++ b/docs/python-sdk/fastmcp-client-sampling-handlers-__init__.mdx @@ -0,0 +1,8 @@ +--- +title: __init__ +sidebarTitle: __init__ +--- + +# `fastmcp.client.sampling.handlers` + +*This module is empty or contains only private/internal implementations.* diff --git a/docs/python-sdk/fastmcp-client-sampling-handlers-anthropic.mdx b/docs/python-sdk/fastmcp-client-sampling-handlers-anthropic.mdx new file mode 100644 index 000000000..b1c9af0a9 --- /dev/null +++ b/docs/python-sdk/fastmcp-client-sampling-handlers-anthropic.mdx @@ -0,0 +1,17 @@ +--- +title: anthropic +sidebarTitle: anthropic +--- + +# `fastmcp.client.sampling.handlers.anthropic` + + +Anthropic sampling handler for FastMCP. + +## Classes + +### `AnthropicSamplingHandler` + + +Sampling handler that uses the Anthropic API. + diff --git a/docs/python-sdk/fastmcp-client-sampling-handlers-openai.mdx b/docs/python-sdk/fastmcp-client-sampling-handlers-openai.mdx new file mode 100644 index 000000000..08ac49f40 --- /dev/null +++ b/docs/python-sdk/fastmcp-client-sampling-handlers-openai.mdx @@ -0,0 +1,17 @@ +--- +title: openai +sidebarTitle: openai +--- + +# `fastmcp.client.sampling.handlers.openai` + + +OpenAI sampling handler for FastMCP. + +## Classes + +### `OpenAISamplingHandler` + + +Sampling handler that uses the OpenAI API. + diff --git a/docs/python-sdk/fastmcp-client-sampling.mdx b/docs/python-sdk/fastmcp-client-sampling.mdx deleted file mode 100644 index 5fa3e70e1..000000000 --- a/docs/python-sdk/fastmcp-client-sampling.mdx +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: sampling -sidebarTitle: sampling ---- - -# `fastmcp.client.sampling` - -## Functions - -### `create_sampling_callback` - -```python -create_sampling_callback(sampling_handler: ClientSamplingHandler[LifespanContextT]) -> SamplingFnT -``` diff --git a/docs/python-sdk/fastmcp-client-tasks.mdx b/docs/python-sdk/fastmcp-client-tasks.mdx index 8e8e60578..c080943d4 100644 --- a/docs/python-sdk/fastmcp-client-tasks.mdx +++ b/docs/python-sdk/fastmcp-client-tasks.mdx @@ -10,7 +10,7 @@ SEP-1686 client Task classes. ## Classes -### `TaskNotificationHandler` +### `TaskNotificationHandler` MessageHandler that routes task status notifications to Task objects. @@ -18,7 +18,7 @@ MessageHandler that routes task status notifications to Task objects. **Methods:** -#### `dispatch` +#### `dispatch` ```python dispatch(self, message: Message) -> None @@ -27,7 +27,7 @@ dispatch(self, message: Message) -> None Dispatch messages, including task status notifications. -### `Task` +### `Task` Abstract base class for MCP background tasks (SEP-1686). @@ -38,7 +38,7 @@ or executes synchronously (graceful degradation per SEP-1686). **Methods:** -#### `task_id` +#### `task_id` ```python task_id(self) -> str @@ -47,7 +47,7 @@ task_id(self) -> str Get the task ID. -#### `returned_immediately` +#### `returned_immediately` ```python returned_immediately(self) -> bool @@ -60,7 +60,7 @@ Check if server executed the task immediately. - False if server accepted background execution -#### `on_status_change` +#### `on_status_change` ```python on_status_change(self, callback: Callable[[GetTaskResult], None | Awaitable[None]]) -> None @@ -78,7 +78,7 @@ Supports both sync and async callbacks (auto-detected). Can return None (sync) or Awaitable[None] (async). -#### `status` +#### `status` ```python status(self) -> GetTaskResult @@ -90,7 +90,7 @@ If server executed immediately, returns synthetic completed status. Otherwise queries the server for current status. -#### `result` +#### `result` ```python result(self) -> TaskResultT @@ -101,7 +101,7 @@ Wait for and return the task result. Must be implemented by subclasses to return the appropriate result type. -#### `wait` +#### `wait` ```python wait(self) -> GetTaskResult @@ -125,7 +125,7 @@ on status changes when server sends notifications/tasks/status. - `TimeoutError`: If desired state not reached within timeout -#### `cancel` +#### `cancel` ```python cancel(self) -> None @@ -140,7 +140,7 @@ Note: If server executed immediately (graceful degradation), this is a no-op as there's no server-side task to cancel. -### `ToolTask` +### `ToolTask` Represents a tool call that may execute in background or immediately. @@ -151,7 +151,7 @@ or executes synchronously (graceful degradation per SEP-1686). **Methods:** -#### `result` +#### `result` ```python result(self) -> CallToolResult @@ -166,7 +166,7 @@ Otherwise waits for background task to complete and retrieves result. - The parsed tool result (same as call_tool returns) -### `PromptTask` +### `PromptTask` Represents a prompt call that may execute in background or immediately. @@ -177,7 +177,7 @@ or executes synchronously (graceful degradation per SEP-1686). **Methods:** -#### `result` +#### `result` ```python result(self) -> mcp.types.GetPromptResult @@ -192,7 +192,7 @@ Otherwise waits for background task to complete and retrieves result. - The prompt result with messages and description -### `ResourceTask` +### `ResourceTask` Represents a resource read that may execute in background or immediately. @@ -203,7 +203,7 @@ or executes synchronously (graceful degradation per SEP-1686). **Methods:** -#### `result` +#### `result` ```python result(self) -> list[mcp.types.TextResourceContents | mcp.types.BlobResourceContents] diff --git a/docs/python-sdk/fastmcp-client-transports.mdx b/docs/python-sdk/fastmcp-client-transports.mdx index e34088801..410021c22 100644 --- a/docs/python-sdk/fastmcp-client-transports.mdx +++ b/docs/python-sdk/fastmcp-client-transports.mdx @@ -7,7 +7,7 @@ sidebarTitle: transports ## Functions -### `infer_transport` +### `infer_transport` ```python infer_transport(transport: ClientTransport | FastMCP | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str) -> ClientTransport @@ -63,7 +63,7 @@ transport = infer_transport(config) Keyword arguments for the MCP ClientSession constructor. -### `ClientTransport` +### `ClientTransport` Abstract base class for different MCP client transport mechanisms. @@ -74,7 +74,7 @@ to an MCP server, and providing a ClientSession within an async context. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] @@ -93,7 +93,7 @@ within this context. constructor (e.g., callbacks, timeouts). -#### `close` +#### `close` ```python close(self) @@ -102,7 +102,7 @@ close(self) Close the transport. -### `WSTransport` +### `WSTransport` Transport implementation that connects to an MCP server via WebSockets. @@ -110,13 +110,13 @@ Transport implementation that connects to an MCP server via WebSockets. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] ``` -### `SSETransport` +### `SSETransport` Transport implementation that connects to an MCP server via Server-Sent Events. @@ -124,13 +124,13 @@ Transport implementation that connects to an MCP server via Server-Sent Events. **Methods:** -#### `connect_session` +#### `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. @@ -138,25 +138,25 @@ 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) ``` -### `StdioTransport` +### `StdioTransport` Base transport for connecting to an MCP server via subprocess with stdio. @@ -167,67 +167,67 @@ transports like Python, Node, Uvx, etc. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] ``` -#### `connect` +#### `connect` ```python connect(self, **session_kwargs: Unpack[SessionKwargs]) -> ClientSession | None ``` -#### `disconnect` +#### `disconnect` ```python disconnect(self) ``` -#### `close` +#### `close` ```python close(self) ``` -### `PythonStdioTransport` +### `PythonStdioTransport` Transport for running Python scripts. -### `FastMCPStdioTransport` +### `FastMCPStdioTransport` Transport for running FastMCP servers using the FastMCP CLI. -### `NodeStdioTransport` +### `NodeStdioTransport` Transport for running Node.js scripts. -### `UvStdioTransport` +### `UvStdioTransport` Transport for running commands via the uv tool. -### `UvxStdioTransport` +### `UvxStdioTransport` Transport for running commands via the uvx tool. -### `NpxStdioTransport` +### `NpxStdioTransport` Transport for running commands via the npx tool. -### `FastMCPTransport` +### `FastMCPTransport` In-memory transport for FastMCP servers. @@ -240,13 +240,13 @@ tests or scenarios where client and server run in the same runtime. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] ``` -### `MCPConfigTransport` +### `MCPConfigTransport` Transport for connecting to one or more MCP servers defined in an MCPConfig. @@ -299,13 +299,13 @@ async with client: **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] ``` -#### `close` +#### `close` ```python close(self) diff --git a/docs/python-sdk/fastmcp-prompts-prompt.mdx b/docs/python-sdk/fastmcp-prompts-prompt.mdx index fbcd6ff5a..8a24524ee 100644 --- a/docs/python-sdk/fastmcp-prompts-prompt.mdx +++ b/docs/python-sdk/fastmcp-prompts-prompt.mdx @@ -10,7 +10,7 @@ Base classes for FastMCP prompts. ## Functions -### `Message` +### `Message` ```python Message(content: str | ContentBlock, role: Role | None = None, **kwargs: Any) -> PromptMessage @@ -22,13 +22,42 @@ A user-friendly constructor for PromptMessage. ## Classes -### `PromptArgument` +### `PromptArgument` An argument that can be passed to a prompt. -### `Prompt` +### `PromptResult` + + +Canonical result type for prompt rendering. + +This is the internal type that all prompt renders return. It wraps the +messages with optional description and metadata. + + +**Methods:** + +#### `from_value` + +```python +from_value(cls, value: list[PromptMessage] | PromptResult, description: str | None = None, meta: dict[str, Any] | None = None) -> PromptResult +``` + +Convert various types to PromptResult. + + +#### `to_mcp_prompt_result` + +```python +to_mcp_prompt_result(self) -> GetPromptResult +``` + +Convert to MCP GetPromptResult. + + +### `Prompt` A prompt template that can be rendered with parameters. @@ -36,31 +65,19 @@ A prompt template that can be rendered with parameters. **Methods:** -#### `enable` +#### `to_mcp_prompt` ```python -enable(self) -> None -``` - -#### `disable` - -```python -disable(self) -> None -``` - -#### `to_mcp_prompt` - -```python -to_mcp_prompt(self, **overrides: Any) -> MCPPrompt +to_mcp_prompt(self, **overrides: Any) -> SDKPrompt ``` Convert the prompt to an MCP prompt. -#### `from_function` +#### `from_function` ```python -from_function(fn: Callable[..., PromptResult | Awaitable[PromptResult]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, enabled: bool | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt +from_function(fn: Callable[..., _PromptFnReturn | Awaitable[_PromptFnReturn]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt ``` Create a Prompt from a function. @@ -72,19 +89,56 @@ The function can return: - A sequence of any of the above -#### `render` +#### `render` ```python -render(self, arguments: dict[str, Any] | None = None) -> list[PromptMessage] +render(self, arguments: dict[str, Any] | None = None) -> list[PromptMessage] | PromptResult ``` Render the prompt with arguments. This method is not implemented in the base Prompt class and must be -implemented by subclasses. +implemented by subclasses. The preferred return type is PromptResult, +but list\[PromptMessage] is still supported for backwards compatibility. -### `FunctionPrompt` +#### `convert_result` + +```python +convert_result(self, raw_value: Any) -> PromptResult +``` + +Convert a raw return value to PromptResult. + +Handles PromptResult passthrough and converts raw values to messages. + + +#### `register_with_docket` + +```python +register_with_docket(self, docket: Docket) -> None +``` + +Register this prompt with docket for background execution. + + +#### `add_to_docket` + +```python +add_to_docket(self, docket: Docket, arguments: dict[str, Any] | None, **kwargs: Any) -> Execution +``` + +Schedule this prompt for background execution via docket. + +**Args:** +- `docket`: The Docket instance +- `arguments`: Prompt arguments +- `fn_key`: Function lookup key in Docket registry (defaults to self.key) +- `task_key`: Redis storage key for the result +- `**kwargs`: Additional kwargs passed to docket.add() + + +### `FunctionPrompt` A prompt that is a function. @@ -92,10 +146,10 @@ A prompt that is a function. **Methods:** -#### `from_function` +#### `from_function` ```python -from_function(cls, fn: Callable[..., PromptResult | Awaitable[PromptResult]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, enabled: bool | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt +from_function(cls, fn: Callable[..., _PromptFnReturn | Awaitable[_PromptFnReturn]], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt ``` Create a Prompt from a function. @@ -107,11 +161,41 @@ The function can return: - A sequence of any of the above -#### `render` +#### `render` ```python -render(self, arguments: dict[str, Any] | None = None) -> list[PromptMessage] +render(self, arguments: dict[str, Any] | None = None) -> PromptResult ``` Render the prompt with arguments. + +#### `register_with_docket` + +```python +register_with_docket(self, docket: Docket) -> None +``` + +Register this prompt with docket for background execution. + +FunctionPrompt registers the underlying function, which has the user's +Depends parameters for docket to resolve. + + +#### `add_to_docket` + +```python +add_to_docket(self, docket: Docket, arguments: dict[str, Any] | None, **kwargs: Any) -> Execution +``` + +Schedule this prompt for background execution via docket. + +FunctionPrompt splats the arguments dict since .fn expects **kwargs. + +**Args:** +- `docket`: The Docket instance +- `arguments`: Prompt arguments +- `fn_key`: Function lookup key in Docket registry (defaults to self.key) +- `task_key`: Redis storage key for the result +- `**kwargs`: Additional kwargs passed to docket.add() + diff --git a/docs/python-sdk/fastmcp-prompts-prompt_manager.mdx b/docs/python-sdk/fastmcp-prompts-prompt_manager.mdx deleted file mode 100644 index 30f85c18d..000000000 --- a/docs/python-sdk/fastmcp-prompts-prompt_manager.mdx +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: prompt_manager -sidebarTitle: prompt_manager ---- - -# `fastmcp.prompts.prompt_manager` - -## Classes - -### `PromptManager` - - -Manages FastMCP prompts. - - -**Methods:** - -#### `has_prompt` - -```python -has_prompt(self, key: str) -> bool -``` - -Check if a prompt exists. - - -#### `get_prompt` - -```python -get_prompt(self, key: str) -> Prompt -``` - -Get prompt by key. - - -#### `get_prompts` - -```python -get_prompts(self) -> dict[str, Prompt] -``` - -Gets the complete, unfiltered inventory of local prompts. - - -#### `add_prompt_from_fn` - -```python -add_prompt_from_fn(self, fn: Callable[..., PromptResult | Awaitable[PromptResult]], name: str | None = None, description: str | None = None, tags: set[str] | None = None) -> FunctionPrompt -``` - -Create a prompt from a function. - - -#### `add_prompt` - -```python -add_prompt(self, prompt: Prompt) -> Prompt -``` - -Add a prompt to the manager. - - -#### `render_prompt` - -```python -render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult -``` - -Internal API for servers: Finds and renders a prompt, respecting the -filtered protocol path. - diff --git a/docs/python-sdk/fastmcp-resources-resource.mdx b/docs/python-sdk/fastmcp-resources-resource.mdx index 7ed4f805d..8a21b4f6b 100644 --- a/docs/python-sdk/fastmcp-resources-resource.mdx +++ b/docs/python-sdk/fastmcp-resources-resource.mdx @@ -10,7 +10,58 @@ Base classes and interfaces for FastMCP resources. ## Classes -### `Resource` +### `ResourceContent` + + +Canonical wrapper for resource content. + +This is the internal representation for all resource reads. Users can +return ResourceContent directly for full control, or return simpler types +(str, bytes, dict) which will be automatically converted. + + +**Methods:** + +#### `from_value` + +```python +from_value(cls, value: Any, mime_type: str | None = None, meta: dict[str, Any] | None = None) -> ResourceContent +``` + +Convert any value to ResourceContent, handling serialization. + +**Args:** +- `value`: The value to convert. Can be\: +- ResourceContent\: returned as-is (meta param ignored) +- str\: text content +- bytes\: binary content +- other\: serialized to JSON string +- `mime_type`: Optional MIME type override. If not provided\: +- str → "text/plain" +- bytes → "application/octet-stream" +- other → "application/json" +- `meta`: Optional metadata (ignored if value is already ResourceContent) + +**Returns:** +- ResourceContent instance + + +#### `to_mcp_resource_contents` + +```python +to_mcp_resource_contents(self, uri: AnyUrl | str) -> mcp.types.TextResourceContents | mcp.types.BlobResourceContents +``` + +Convert to MCP resource contents type. + +**Args:** +- `uri`: The URI of the resource (required by MCP types) + +**Returns:** +- TextResourceContents for str content, BlobResourceContents for bytes + + +### `Resource` Base class for all resources. @@ -18,25 +69,13 @@ Base class for all resources. **Methods:** -#### `enable` +#### `from_function` ```python -enable(self) -> None +from_function(fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResource ``` -#### `disable` - -```python -disable(self) -> None -``` - -#### `from_function` - -```python -from_function(fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResource -``` - -#### `set_default_mime_type` +#### `set_default_mime_type` ```python set_default_mime_type(cls, mime_type: str | None) -> str @@ -45,7 +84,7 @@ set_default_mime_type(cls, mime_type: str | None) -> str Set default MIME type if not provided. -#### `set_default_name` +#### `set_default_name` ```python set_default_name(self) -> Self @@ -54,40 +93,78 @@ set_default_name(self) -> Self Set default name from URI if not provided. -#### `read` +#### `read` ```python -read(self) -> str | bytes +read(self) -> str | bytes | ResourceContent ``` Read the resource content. -This method is not implemented in the base Resource class and must be -implemented by subclasses. +This method must be implemented by subclasses. For backwards compatibility, +subclasses can return str, bytes, or ResourceContent. However, returning +str or bytes is deprecated - new code should return ResourceContent. + +**Returns:** +- str | bytes | ResourceContent: The resource content. Returning str +- or bytes is deprecated; prefer ResourceContent for full control +- over MIME type and metadata. -#### `to_mcp_resource` +#### `convert_result` ```python -to_mcp_resource(self, **overrides: Any) -> MCPResource +convert_result(self, raw_value: Any) -> ResourceContent ``` -Convert the resource to an MCPResource. +Convert a raw return value to ResourceContent. + +Handles ResourceContent passthrough and converts raw values using mime_type. -#### `key` +#### `to_mcp_resource` + +```python +to_mcp_resource(self, **overrides: Any) -> SDKResource +``` + +Convert the resource to an SDKResource. + + +#### `key` ```python key(self) -> str ``` -The key of the component. This is used for internal bookkeeping -and may reflect e.g. prefixes or other identifiers. You should not depend on -keys having a certain value, as the same tool loaded from different -hierarchies of servers may have different keys. +The globally unique lookup key for this resource. -### `FunctionResource` +#### `register_with_docket` + +```python +register_with_docket(self, docket: Docket) -> None +``` + +Register this resource with docket for background execution. + + +#### `add_to_docket` + +```python +add_to_docket(self, docket: Docket, **kwargs: Any) -> Execution +``` + +Schedule this resource for background execution via docket. + +**Args:** +- `docket`: The Docket instance +- `fn_key`: Function lookup key in Docket registry (defaults to self.key) +- `task_key`: Redis storage key for the result +- `**kwargs`: Additional kwargs passed to docket.add() + + +### `FunctionResource` A resource that defers data loading by wrapping a function. @@ -104,20 +181,37 @@ The function can return: **Methods:** -#### `from_function` +#### `from_function` ```python -from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResource +from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResource ``` Create a FunctionResource from a function. -#### `read` +#### `read` ```python -read(self) -> str | bytes +read(self) -> str | bytes | ResourceContent ``` Read the resource by calling the wrapped function. +**Returns:** +- str | bytes | ResourceContent: The resource content. If the user's +- function returns str, bytes, dict, etc., it will be wrapped +- in ResourceContent. Nested Resource reads may return raw types. + + +#### `register_with_docket` + +```python +register_with_docket(self, docket: Docket) -> None +``` + +Register this resource with docket for background execution. + +FunctionResource registers the underlying function, which has the user's +Depends parameters for docket to resolve. + diff --git a/docs/python-sdk/fastmcp-resources-resource_manager.mdx b/docs/python-sdk/fastmcp-resources-resource_manager.mdx deleted file mode 100644 index c977132ba..000000000 --- a/docs/python-sdk/fastmcp-resources-resource_manager.mdx +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: resource_manager -sidebarTitle: resource_manager ---- - -# `fastmcp.resources.resource_manager` - - -Resource manager functionality. - -## Classes - -### `ResourceManager` - - -Manages FastMCP resources. - - -**Methods:** - -#### `get_resources` - -```python -get_resources(self) -> dict[str, Resource] -``` - -Get all registered resources, keyed by URI. - - -#### `get_resource_templates` - -```python -get_resource_templates(self) -> dict[str, ResourceTemplate] -``` - -Get all registered templates, keyed by URI template. - - -#### `add_resource_or_template_from_fn` - -```python -add_resource_or_template_from_fn(self, fn: Callable[..., Any], uri: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> Resource | ResourceTemplate -``` - -Add a resource or template to the manager from a function. - -**Args:** -- `fn`: The function to register as a resource or template -- `uri`: The URI for the resource or template -- `name`: Optional name for the resource or template -- `description`: Optional description of the resource or template -- `mime_type`: Optional MIME type for the resource or template -- `tags`: Optional set of tags for categorizing the resource or template - -**Returns:** -- The added resource or template. If a resource or template with the same URI already exists, -- returns the existing resource or template. - - -#### `add_resource_from_fn` - -```python -add_resource_from_fn(self, fn: Callable[..., Any], uri: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> Resource -``` - -Add a resource to the manager from a function. - -**Args:** -- `fn`: The function to register as a resource -- `uri`: The URI for the resource -- `name`: Optional name for the resource -- `description`: Optional description of the resource -- `mime_type`: Optional MIME type for the resource -- `tags`: Optional set of tags for categorizing the resource - -**Returns:** -- The added resource. If a resource with the same URI already exists, -- returns the existing resource. - - -#### `add_resource` - -```python -add_resource(self, resource: Resource) -> Resource -``` - -Add a resource to the manager. - -**Args:** -- `resource`: A Resource instance to add. The resource's .key attribute -will be used as the storage key. To overwrite it, call -Resource.model_copy(key=new_key) before calling this method. - - -#### `add_template_from_fn` - -```python -add_template_from_fn(self, fn: Callable[..., Any], uri_template: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> ResourceTemplate -``` - -Create a template from a function. - - -#### `add_template` - -```python -add_template(self, template: ResourceTemplate) -> ResourceTemplate -``` - -Add a template to the manager. - -**Args:** -- `template`: A ResourceTemplate instance to add. The template's .key attribute -will be used as the storage key. To overwrite it, call -ResourceTemplate.model_copy(key=new_key) before calling this method. - -**Returns:** -- The added template. If a template with the same URI already exists, -- returns the existing template. - - -#### `has_resource` - -```python -has_resource(self, uri: AnyUrl | str) -> bool -``` - -Check if a resource exists. - - -#### `get_resource` - -```python -get_resource(self, uri: AnyUrl | str) -> Resource -``` - -Get resource by URI, checking concrete resources first, then templates. - -**Args:** -- `uri`: The URI of the resource to get - -**Raises:** -- `NotFoundError`: If no resource or template matching the URI is found. - - -#### `read_resource` - -```python -read_resource(self, uri: AnyUrl | str) -> str | bytes -``` - -Internal API for servers: Finds and reads a resource, respecting the -filtered protocol path. - diff --git a/docs/python-sdk/fastmcp-resources-template.mdx b/docs/python-sdk/fastmcp-resources-template.mdx index 1effd3bc6..e01ab0abb 100644 --- a/docs/python-sdk/fastmcp-resources-template.mdx +++ b/docs/python-sdk/fastmcp-resources-template.mdx @@ -10,7 +10,7 @@ Resource template functionality. ## Functions -### `extract_query_params` +### `extract_query_params` ```python extract_query_params(uri_template: str) -> set[str] @@ -20,7 +20,7 @@ extract_query_params(uri_template: str) -> set[str] Extract query parameter names from RFC 6570 `{?param1,param2}` syntax. -### `build_regex` +### `build_regex` ```python build_regex(template: str) -> re.Pattern @@ -35,7 +35,7 @@ Supports: - `{?var1,var2}` - query parameters (ignored in path matching) -### `match_uri_template` +### `match_uri_template` ```python match_uri_template(uri: str, uri_template: str) -> dict[str, str] | None @@ -51,7 +51,7 @@ Supports RFC 6570 URI templates: ## Classes -### `ResourceTemplate` +### `ResourceTemplate` A template for dynamically creating resources. @@ -59,25 +59,13 @@ A template for dynamically creating resources. **Methods:** -#### `enable` +#### `from_function` ```python -enable(self) -> None +from_function(fn: Callable[..., Any], uri_template: str, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResourceTemplate ``` -#### `disable` - -```python -disable(self) -> None -``` - -#### `from_function` - -```python -from_function(fn: Callable[..., Any], uri_template: str, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResourceTemplate -``` - -#### `set_default_mime_type` +#### `set_default_mime_type` ```python set_default_mime_type(cls, mime_type: str | None) -> str @@ -86,7 +74,7 @@ set_default_mime_type(cls, mime_type: str | None) -> str Set default MIME type if not provided. -#### `matches` +#### `matches` ```python matches(self, uri: str) -> dict[str, Any] | None @@ -95,7 +83,7 @@ matches(self, uri: str) -> dict[str, Any] | None Check if URI matches template and extract parameters. -#### `read` +#### `read` ```python read(self, arguments: dict[str, Any]) -> str | bytes @@ -104,7 +92,18 @@ read(self, arguments: dict[str, Any]) -> str | bytes Read the resource content. -#### `create_resource` +#### `convert_result` + +```python +convert_result(self, raw_value: Any) -> ResourceContent +``` + +Convert a raw return value to ResourceContent. + +Handles ResourceContent passthrough and converts raw values using mime_type. + + +#### `create_resource` ```python create_resource(self, uri: str, params: dict[str, Any]) -> Resource @@ -116,37 +115,59 @@ The base implementation does not support background tasks. Use FunctionResourceTemplate for task support. -#### `to_mcp_template` +#### `to_mcp_template` ```python -to_mcp_template(self, **overrides: Any) -> MCPResourceTemplate +to_mcp_template(self, **overrides: Any) -> SDKResourceTemplate ``` -Convert the resource template to an MCPResourceTemplate. +Convert the resource template to an SDKResourceTemplate. -#### `from_mcp_template` +#### `from_mcp_template` ```python -from_mcp_template(cls, mcp_template: MCPResourceTemplate) -> ResourceTemplate +from_mcp_template(cls, mcp_template: SDKResourceTemplate) -> ResourceTemplate ``` Creates a FastMCP ResourceTemplate from a raw MCP ResourceTemplate object. -#### `key` +#### `key` ```python key(self) -> str ``` -The key of the component. This is used for internal bookkeeping -and may reflect e.g. prefixes or other identifiers. You should not depend on -keys having a certain value, as the same tool loaded from different -hierarchies of servers may have different keys. +The globally unique lookup key for this template. -### `FunctionResourceTemplate` +#### `register_with_docket` + +```python +register_with_docket(self, docket: Docket) -> None +``` + +Register this template with docket for background execution. + + +#### `add_to_docket` + +```python +add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution +``` + +Schedule this template for background execution via docket. + +**Args:** +- `docket`: The Docket instance +- `params`: Template parameters +- `fn_key`: Function lookup key in Docket registry (defaults to self.key) +- `task_key`: Redis storage key for the result +- `**kwargs`: Additional kwargs passed to docket.add() + + +### `FunctionResourceTemplate` A template for dynamically creating resources. @@ -154,7 +175,7 @@ A template for dynamically creating resources. **Methods:** -#### `create_resource` +#### `create_resource` ```python create_resource(self, uri: str, params: dict[str, Any]) -> Resource @@ -163,7 +184,7 @@ create_resource(self, uri: str, params: dict[str, Any]) -> Resource Create a resource from the template with the given parameters. -#### `read` +#### `read` ```python read(self, arguments: dict[str, Any]) -> str | bytes @@ -172,10 +193,40 @@ read(self, arguments: dict[str, Any]) -> str | bytes Read the resource content. -#### `from_function` +#### `register_with_docket` ```python -from_function(cls, fn: Callable[..., Any], uri_template: str, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, enabled: bool | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResourceTemplate +register_with_docket(self, docket: Docket) -> None +``` + +Register this template with docket for background execution. + +FunctionResourceTemplate registers the underlying function, which has the +user's Depends parameters for docket to resolve. + + +#### `add_to_docket` + +```python +add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution +``` + +Schedule this template for background execution via docket. + +FunctionResourceTemplate splats the params dict since .fn expects **kwargs. + +**Args:** +- `docket`: The Docket instance +- `params`: Template parameters +- `fn_key`: Function lookup key in Docket registry (defaults to self.key) +- `task_key`: Redis storage key for the result +- `**kwargs`: Additional kwargs passed to docket.add() + + +#### `from_function` + +```python +from_function(cls, fn: Callable[..., Any], uri_template: str, name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, mime_type: str | None = None, tags: set[str] | None = None, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResourceTemplate ``` Create a template from a function. diff --git a/docs/python-sdk/fastmcp-resources-types.mdx b/docs/python-sdk/fastmcp-resources-types.mdx index cebe83516..28cf6ff61 100644 --- a/docs/python-sdk/fastmcp-resources-types.mdx +++ b/docs/python-sdk/fastmcp-resources-types.mdx @@ -21,7 +21,7 @@ A resource that reads from a string. #### `read` ```python -read(self) -> str +read(self) -> ResourceContent ``` Read the text content. @@ -38,7 +38,7 @@ A resource that reads from bytes. #### `read` ```python -read(self) -> bytes +read(self) -> ResourceContent ``` Read the binary content. @@ -75,13 +75,13 @@ Set is_binary based on mime_type if not explicitly set. #### `read` ```python -read(self) -> str | bytes +read(self) -> ResourceContent ``` Read the file content. -### `HttpResource` +### `HttpResource` A resource that reads from an HTTP endpoint. @@ -89,16 +89,16 @@ A resource that reads from an HTTP endpoint. **Methods:** -#### `read` +#### `read` ```python -read(self) -> str | bytes +read(self) -> ResourceContent ``` Read the HTTP content. -### `DirectoryResource` +### `DirectoryResource` A resource that lists files in a directory. @@ -106,7 +106,7 @@ A resource that lists files in a directory. **Methods:** -#### `validate_absolute_path` +#### `validate_absolute_path` ```python validate_absolute_path(cls, path: Path) -> Path @@ -115,7 +115,7 @@ validate_absolute_path(cls, path: Path) -> Path Ensure path is absolute. -#### `list_files` +#### `list_files` ```python list_files(self) -> list[Path] @@ -124,10 +124,10 @@ list_files(self) -> list[Path] List files in the directory. -#### `read` +#### `read` ```python -read(self) -> str +read(self) -> ResourceContent ``` Read the directory listing. diff --git a/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx b/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx index 69d85f724..56d2527ef 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx @@ -72,7 +72,7 @@ Features: **Methods:** -#### `get_token_verifier` +#### `get_token_verifier` ```python get_token_verifier(self) -> TokenVerifier diff --git a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx index 5fb265b32..686052344 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx @@ -55,7 +55,7 @@ Setup: **Methods:** -#### `authorize` +#### `authorize` ```python authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str diff --git a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx index a2ec529ad..b91f02263 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx @@ -65,9 +65,9 @@ Setup Requirements: 4. Note your Client ID and Client Secret -### `AuthKitProviderSettings` +### `AuthKitProviderSettings` -### `AuthKitProvider` +### `AuthKitProvider` AuthKit metadata provider for DCR (Dynamic Client Registration). @@ -93,7 +93,7 @@ https://workos.com/docs/authkit/mcp/integrating/token-verification **Methods:** -#### `get_routes` +#### `get_routes` ```python get_routes(self, mcp_path: str | None = None) -> list[Route] diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx index fa3a35f2f..112c89c70 100644 --- a/docs/python-sdk/fastmcp-server-context.mdx +++ b/docs/python-sdk/fastmcp-server-context.mdx @@ -7,7 +7,7 @@ sidebarTitle: context ## Functions -### `set_context` +### `set_context` ```python set_context(context: Context) -> Generator[Context, None, None] @@ -15,7 +15,7 @@ set_context(context: Context) -> Generator[Context, None, None] ## Classes -### `LogData` +### `LogData` Data object for passing log arguments to client-side handlers. @@ -24,7 +24,7 @@ This provides an interface to match the Python standard library logging, for compatibility with structured logging. -### `Context` +### `Context` Context object providing access to MCP capabilities. @@ -72,7 +72,7 @@ The context is optional - tools that don't need it can omit the parameter. **Methods:** -#### `fastmcp` +#### `fastmcp` ```python fastmcp(self) -> FastMCP @@ -81,7 +81,7 @@ fastmcp(self) -> FastMCP Get the FastMCP instance. -#### `request_context` +#### `request_context` ```python request_context(self) -> RequestContext[ServerSession, Any, Request] | None @@ -110,7 +110,7 @@ async def on_request(self, context, call_next): ``` -#### `report_progress` +#### `report_progress` ```python report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None @@ -123,10 +123,10 @@ Report progress for the current operation. - `total`: Optional total value e.g. 100 -#### `list_resources` +#### `list_resources` ```python -list_resources(self) -> list[MCPResource] +list_resources(self) -> list[SDKResource] ``` List all available resources from the server. @@ -135,10 +135,10 @@ List all available resources from the server. - List of Resource objects available on the server -#### `list_prompts` +#### `list_prompts` ```python -list_prompts(self) -> list[MCPPrompt] +list_prompts(self) -> list[SDKPrompt] ``` List all available prompts from the server. @@ -147,7 +147,7 @@ List all available prompts from the server. - List of Prompt objects available on the server -#### `get_prompt` +#### `get_prompt` ```python get_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult @@ -163,10 +163,10 @@ Get a prompt by name with optional arguments. - The prompt result -#### `read_resource` +#### `read_resource` ```python -read_resource(self, uri: str | AnyUrl) -> list[ReadResourceContents] +read_resource(self, uri: str | AnyUrl) -> list[ResourceContent] ``` Read a resource by URI. @@ -175,10 +175,10 @@ Read a resource by URI. - `uri`: Resource URI to read **Returns:** -- The resource content as either text or bytes +- List of ResourceContent objects -#### `log` +#### `log` ```python log(self, message: str, level: LoggingLevel | None = None, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -196,7 +196,7 @@ Messages sent to Clients are also logged to the `fastmcp.server.context.to_clien - `extra`: Optional mapping for additional arguments -#### `client_id` +#### `client_id` ```python client_id(self) -> str | None @@ -205,7 +205,7 @@ client_id(self) -> str | None Get the client ID if available. -#### `request_id` +#### `request_id` ```python request_id(self) -> str @@ -216,7 +216,7 @@ Get the unique ID for this request. Raises RuntimeError if MCP request context is not available. -#### `session_id` +#### `session_id` ```python session_id(self) -> str @@ -233,7 +233,7 @@ the same client session. - for other transports. -#### `session` +#### `session` ```python session(self) -> ServerSession @@ -244,7 +244,7 @@ Access to the underlying session for advanced usage. Raises RuntimeError if MCP request context is not available. -#### `debug` +#### `debug` ```python debug(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -255,7 +255,7 @@ Send a `DEBUG`-level message to the connected MCP Client. Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`. -#### `info` +#### `info` ```python info(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -266,7 +266,7 @@ Send a `INFO`-level message to the connected MCP Client. Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`. -#### `warning` +#### `warning` ```python warning(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -277,7 +277,7 @@ Send a `WARNING`-level message to the connected MCP Client. Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`. -#### `error` +#### `error` ```python error(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -288,7 +288,7 @@ Send a `ERROR`-level message to the connected MCP Client. Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`. -#### `list_roots` +#### `list_roots` ```python list_roots(self) -> list[Root] @@ -297,34 +297,38 @@ list_roots(self) -> list[Root] List the roots available to the server, as indicated by the client. -#### `send_tool_list_changed` +#### `send_notification` ```python -send_tool_list_changed(self) -> None +send_notification(self, notification: mcp.types.ServerNotificationType) -> None ``` -Send a tool list changed notification to the client. +Send a notification to the client immediately. + +Use this in async code when you want the notification sent right away. +For sync code, use send_notification_sync() which queues the notification +for the background flusher. + +**Args:** +- `notification`: An MCP notification instance (e.g., ToolListChangedNotification()) -#### `send_resource_list_changed` +#### `send_notification_sync` ```python -send_resource_list_changed(self) -> None +send_notification_sync(self, notification: mcp.types.ServerNotificationType) -> None ``` -Send a resource list changed notification to the client. +Queue a notification to be sent by the background flusher. + +Use this in sync code when you can't await. The notification will be +sent within ~1 second by the background flusher. + +**Args:** +- `notification`: An MCP notification instance (e.g., ToolListChangedNotification()) -#### `send_prompt_list_changed` - -```python -send_prompt_list_changed(self) -> None -``` - -Send a prompt list changed notification to the client. - - -#### `close_sse_stream` +#### `close_sse_stream` ```python close_sse_stream(self) -> None @@ -342,41 +346,143 @@ Instead of holding a connection open for minutes, you can periodically close and let the client reconnect. -#### `sample` +#### `sample_step` ```python -sample(self, messages: str | Sequence[str | SamplingMessage], system_prompt: str | None = None, include_context: IncludeContext | None = None, temperature: float | None = None, max_tokens: int | None = None, model_preferences: ModelPreferences | str | list[str] | None = None) -> SamplingMessageContentBlock | list[SamplingMessageContentBlock] +sample_step(self, messages: str | Sequence[str | SamplingMessage]) -> SampleStep +``` + +Make a single LLM sampling call. + +This is a stateless function that makes exactly one LLM call and optionally +executes any requested tools. Use this for fine-grained control over the +sampling loop. + +**Args:** +- `messages`: The message(s) to send. Can be a string, list of strings, +or list of SamplingMessage objects. +- `system_prompt`: Optional system prompt for the LLM. +- `temperature`: Optional sampling temperature. +- `max_tokens`: Maximum tokens to generate. Defaults to 512. +- `model_preferences`: Optional model preferences. +- `tools`: Optional list of tools the LLM can use. +- `tool_choice`: Tool choice mode ("auto", "required", or "none"). +- `execute_tools`: If True (default), execute tool calls and append results +to history. If False, return immediately with tool_calls available +in the step for manual execution. +- `mask_error_details`: If True, mask detailed error messages from tool +execution. When None (default), uses the global settings value. +Tools can raise ToolError to bypass masking. + +**Returns:** +- SampleStep containing: +- - .response: The raw LLM response +- - .history: Messages including input, assistant response, and tool results +- - .is_tool_use: True if the LLM requested tool execution +- - .tool_calls: List of tool calls (if any) +- - .text: The text content (if any) + + +#### `sample` + +```python +sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ResultT] +``` + +Overload: With result_type, returns SamplingResult[ResultT]. + + +#### `sample` + +```python +sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[str] +``` + +Overload: Without result_type, returns SamplingResult[str]. + + +#### `sample` + +```python +sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ResultT] | SamplingResult[str] ``` Send a sampling request to the client and await the response. -Call this method at any time to have the server request an LLM -completion from the client. The client must be appropriately configured, -or the request will error. +This method runs to completion automatically. When tools are provided, +it executes a tool loop: if the LLM returns a tool use request, the tools +are executed and the results are sent back to the LLM. This continues +until the LLM provides a final text response. + +When result_type is specified, a synthetic `final_response` tool is +created. The LLM calls this tool to provide the structured response, +which is validated against the result_type and returned as `.result`. + +For fine-grained control over the sampling loop, use sample_step() instead. + +**Args:** +- `messages`: The message(s) to send. Can be a string, list of strings, +or list of SamplingMessage objects. +- `system_prompt`: Optional system prompt for the LLM. +- `temperature`: Optional sampling temperature. +- `max_tokens`: Maximum tokens to generate. Defaults to 512. +- `model_preferences`: Optional model preferences. +- `tools`: Optional list of tools the LLM can use. Accepts plain +functions or SamplingTools. +- `result_type`: Optional type for structured output. When specified, +a synthetic `final_response` tool is created and the LLM's +response is validated against this type. +- `mask_error_details`: If True, mask detailed error messages from tool +execution. When None (default), uses the global settings value. +Tools can raise ToolError to bypass masking. + +**Returns:** +- SamplingResult[T] containing: +- - .text: The text representation (raw text or JSON for structured) +- - .result: The typed result (str for text, parsed object for structured) +- - .history: All messages exchanged during sampling -#### `elicit` +#### `elicit` ```python elicit(self, message: str, response_type: None) -> AcceptedElicitation[dict[str, Any]] | DeclinedElicitation | CancelledElicitation ``` -#### `elicit` +#### `elicit` ```python elicit(self, message: str, response_type: type[T]) -> AcceptedElicitation[T] | DeclinedElicitation | CancelledElicitation ``` -#### `elicit` +#### `elicit` ```python elicit(self, message: str, response_type: list[str]) -> AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation ``` -#### `elicit` +#### `elicit` ```python -elicit(self, message: str, response_type: type[T] | list[str] | None = None) -> AcceptedElicitation[T] | AcceptedElicitation[dict[str, Any]] | AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation +elicit(self, message: str, response_type: dict[str, dict[str, str]]) -> AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation +``` + +#### `elicit` + +```python +elicit(self, message: str, response_type: list[list[str]]) -> AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation +``` + +#### `elicit` + +```python +elicit(self, message: str, response_type: list[dict[str, dict[str, str]]]) -> AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation +``` + +#### `elicit` + +```python +elicit(self, message: str, response_type: type[T] | list[str] | dict[str, dict[str, str]] | list[list[str]] | list[dict[str, dict[str, str]]] | None = None) -> AcceptedElicitation[T] | AcceptedElicitation[dict[str, Any]] | AcceptedElicitation[str] | AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation ``` Send an elicitation request to the client and await the response. @@ -402,7 +508,7 @@ type or dataclass or BaseModel. If it is a primitive type, an object schema with a single "value" field will be generated. -#### `set_state` +#### `set_state` ```python set_state(self, key: str, value: Any) -> None @@ -411,7 +517,7 @@ set_state(self, key: str, value: Any) -> None Set a value in the context state. -#### `get_state` +#### `get_state` ```python get_state(self, key: str) -> Any diff --git a/docs/python-sdk/fastmcp-server-dependencies.mdx b/docs/python-sdk/fastmcp-server-dependencies.mdx index 19636c2ce..6c7478ccd 100644 --- a/docs/python-sdk/fastmcp-server-dependencies.mdx +++ b/docs/python-sdk/fastmcp-server-dependencies.mdx @@ -7,7 +7,7 @@ sidebarTitle: dependencies ## Functions -### `without_injected_parameters` +### `without_injected_parameters` ```python without_injected_parameters(fn: Callable[..., Any]) -> Callable[..., Any] @@ -28,7 +28,7 @@ Context injection when called. - Async wrapper function without injected parameters -### `resolve_dependencies` +### `resolve_dependencies` ```python resolve_dependencies(fn: Callable[..., Any], arguments: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None] @@ -52,13 +52,27 @@ providing values for dependency parameter names. This is a security feature. which will be filtered out) -### `get_context` +### `get_context` ```python get_context() -> Context ``` -### `CurrentContext` +### `get_task_metadata` + +```python +get_task_metadata() -> dict[str, Any] | None +``` + + +Get the current task metadata from the context. + +**Returns:** +- The task metadata dict if this is a background task request, +- or None if this is a normal execution. + + +### `CurrentContext` ```python CurrentContext() -> Context @@ -77,7 +91,7 @@ current MCP operation (tool/resource/prompt call). - `RuntimeError`: If no active context found (during resolution) -### `CurrentDocket` +### `CurrentDocket` ```python CurrentDocket() -> Docket @@ -96,7 +110,7 @@ automatically creates for background task scheduling. - `RuntimeError`: If not within a FastMCP server context -### `CurrentWorker` +### `CurrentWorker` ```python CurrentWorker() -> Worker @@ -115,7 +129,7 @@ automatically creates for background task processing. - `RuntimeError`: If not within a FastMCP server context -### `CurrentFastMCP` +### `CurrentFastMCP` ```python CurrentFastMCP() @@ -133,7 +147,7 @@ This dependency provides access to the active FastMCP server. - `RuntimeError`: If no server in context (during resolution) -### `get_server` +### `get_server` ```python get_server() @@ -149,13 +163,13 @@ Get the current FastMCP server instance directly. - `RuntimeError`: If no server in context -### `get_http_request` +### `get_http_request` ```python get_http_request() -> Request ``` -### `get_http_headers` +### `get_http_headers` ```python get_http_headers(include_all: bool = False) -> dict[str, str] @@ -171,7 +185,7 @@ By default, strips problematic headers like `content-length` that cause issues i If `include_all` is True, all headers are returned. -### `get_access_token` +### `get_access_token` ```python get_access_token() -> AccessToken | None @@ -191,7 +205,7 @@ request is available. ## Classes -### `InMemoryProgress` +### `InMemoryProgress` In-memory progress tracker for immediate tool execution. @@ -203,25 +217,25 @@ progress doesn't need to be observable across processes. **Methods:** -#### `current` +#### `current` ```python current(self) -> int | None ``` -#### `total` +#### `total` ```python total(self) -> int ``` -#### `message` +#### `message` ```python message(self) -> str | None ``` -#### `set_total` +#### `set_total` ```python set_total(self, total: int) -> None @@ -230,7 +244,7 @@ set_total(self, total: int) -> None Set the total/target value for progress tracking. -#### `increment` +#### `increment` ```python increment(self, amount: int = 1) -> None @@ -239,7 +253,7 @@ increment(self, amount: int = 1) -> None Atomically increment the current progress value. -#### `set_message` +#### `set_message` ```python set_message(self, message: str | None) -> None @@ -248,7 +262,7 @@ set_message(self, message: str | None) -> None Update the progress status message. -### `Progress` +### `Progress` FastMCP Progress dependency that works in both server and worker contexts. diff --git a/docs/python-sdk/fastmcp-server-elicitation.mdx b/docs/python-sdk/fastmcp-server-elicitation.mdx index 04a9be73a..109181232 100644 --- a/docs/python-sdk/fastmcp-server-elicitation.mdx +++ b/docs/python-sdk/fastmcp-server-elicitation.mdx @@ -138,3 +138,8 @@ Result when user accepts the elicitation. Configuration for an elicitation request. +**Attributes:** +- `schema`: The JSON schema to send to the client +- `response_type`: The type to validate responses with (None for raw schemas) +- `is_raw`: True if schema was built directly (extract "value" from response) + diff --git a/docs/python-sdk/fastmcp-server-middleware-caching.mdx b/docs/python-sdk/fastmcp-server-middleware-caching.mdx index 929203e2f..58b15ce60 100644 --- a/docs/python-sdk/fastmcp-server-middleware-caching.mdx +++ b/docs/python-sdk/fastmcp-server-middleware-caching.mdx @@ -10,10 +10,10 @@ A middleware for response caching. ## Classes -### `CachableReadResourceContents` +### `CachableReadResourceContents` -A wrapper for ReadResourceContents that can be cached. +A wrapper for ResourceContent that can be cached. **Methods:** @@ -33,76 +33,76 @@ get_sizes(cls, values: Sequence[Self]) -> int #### `wrap` ```python -wrap(cls, values: Sequence[ReadResourceContents]) -> list[Self] +wrap(cls, values: Sequence[ResourceContent]) -> list[Self] ``` -#### `unwrap` +#### `unwrap` ```python -unwrap(cls, values: Sequence[Self]) -> list[ReadResourceContents] +unwrap(cls, values: Sequence[Self]) -> list[ResourceContent] ``` -### `CachableToolResult` +### `CachableToolResult` **Methods:** -#### `wrap` +#### `wrap` ```python wrap(cls, value: ToolResult) -> Self ``` -#### `unwrap` +#### `unwrap` ```python unwrap(self) -> ToolResult ``` -### `SharedMethodSettings` +### `SharedMethodSettings` Shared config for a cache method. -### `ListToolsSettings` +### `ListToolsSettings` Configuration options for Tool-related caching. -### `ListResourcesSettings` +### `ListResourcesSettings` Configuration options for Resource-related caching. -### `ListPromptsSettings` +### `ListPromptsSettings` Configuration options for Prompt-related caching. -### `CallToolSettings` +### `CallToolSettings` Configuration options for Tool-related caching. -### `ReadResourceSettings` +### `ReadResourceSettings` Configuration options for Resource-related caching. -### `GetPromptSettings` +### `GetPromptSettings` Configuration options for Prompt-related caching. -### `ResponseCachingStatistics` +### `ResponseCachingStatistics` -### `ResponseCachingMiddleware` +### `ResponseCachingMiddleware` The response caching middleware offers a simple way to cache responses to mcp methods. The Middleware @@ -119,7 +119,7 @@ Notes: **Methods:** -#### `on_list_tools` +#### `on_list_tools` ```python on_list_tools(self, context: MiddlewareContext[mcp.types.ListToolsRequest], call_next: CallNext[mcp.types.ListToolsRequest, Sequence[Tool]]) -> Sequence[Tool] @@ -129,7 +129,7 @@ List tools from the cache, if caching is enabled, and the result is in the cache otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_list_resources` +#### `on_list_resources` ```python on_list_resources(self, context: MiddlewareContext[mcp.types.ListResourcesRequest], call_next: CallNext[mcp.types.ListResourcesRequest, Sequence[Resource]]) -> Sequence[Resource] @@ -139,7 +139,7 @@ List resources from the cache, if caching is enabled, and the result is in the c otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_list_prompts` +#### `on_list_prompts` ```python on_list_prompts(self, context: MiddlewareContext[mcp.types.ListPromptsRequest], call_next: CallNext[mcp.types.ListPromptsRequest, Sequence[Prompt]]) -> Sequence[Prompt] @@ -149,7 +149,7 @@ List prompts from the cache, if caching is enabled, and the result is in the cac otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_call_tool` +#### `on_call_tool` ```python on_call_tool(self, context: MiddlewareContext[mcp.types.CallToolRequestParams], call_next: CallNext[mcp.types.CallToolRequestParams, ToolResult]) -> ToolResult @@ -159,20 +159,20 @@ Call a tool from the cache, if caching is enabled, and the result is in the cach otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_read_resource` +#### `on_read_resource` ```python -on_read_resource(self, context: MiddlewareContext[mcp.types.ReadResourceRequestParams], call_next: CallNext[mcp.types.ReadResourceRequestParams, Sequence[ReadResourceContents]]) -> Sequence[ReadResourceContents] +on_read_resource(self, context: MiddlewareContext[mcp.types.ReadResourceRequestParams], call_next: CallNext[mcp.types.ReadResourceRequestParams, Sequence[ResourceContent]]) -> Sequence[ResourceContent] ``` Read a resource from the cache, if caching is enabled, and the result is in the cache. Otherwise, otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_get_prompt` +#### `on_get_prompt` ```python -on_get_prompt(self, context: MiddlewareContext[mcp.types.GetPromptRequestParams], call_next: CallNext[mcp.types.GetPromptRequestParams, mcp.types.GetPromptResult]) -> mcp.types.GetPromptResult +on_get_prompt(self, context: MiddlewareContext[mcp.types.GetPromptRequestParams], call_next: CallNext[mcp.types.GetPromptRequestParams, PromptResult]) -> PromptResult ``` Get a prompt from the cache, if caching is enabled, and the result is in the cache. Otherwise, diff --git a/docs/python-sdk/fastmcp-server-middleware-middleware.mdx b/docs/python-sdk/fastmcp-server-middleware-middleware.mdx index baeffa691..9f5f8fd0f 100644 --- a/docs/python-sdk/fastmcp-server-middleware-middleware.mdx +++ b/docs/python-sdk/fastmcp-server-middleware-middleware.mdx @@ -7,7 +7,7 @@ sidebarTitle: middleware ## Functions -### `make_middleware_wrapper` +### `make_middleware_wrapper` ```python make_middleware_wrapper(middleware: Middleware, call_next: CallNext[T, R]) -> CallNext[T, R] @@ -21,9 +21,9 @@ passed to other functions that expect a call_next function. ## Classes -### `CallNext` +### `CallNext` -### `MiddlewareContext` +### `MiddlewareContext` Unified context for all middleware operations. @@ -31,13 +31,13 @@ Unified context for all middleware operations. **Methods:** -#### `copy` +#### `copy` ```python copy(self, **kwargs: Any) -> MiddlewareContext[T] ``` -### `Middleware` +### `Middleware` Base class for FastMCP middleware with dispatching hooks. @@ -45,67 +45,67 @@ Base class for FastMCP middleware with dispatching hooks. **Methods:** -#### `on_message` +#### `on_message` ```python on_message(self, context: MiddlewareContext[Any], call_next: CallNext[Any, Any]) -> Any ``` -#### `on_request` +#### `on_request` ```python on_request(self, context: MiddlewareContext[mt.Request[Any, Any]], call_next: CallNext[mt.Request[Any, Any], Any]) -> Any ``` -#### `on_notification` +#### `on_notification` ```python on_notification(self, context: MiddlewareContext[mt.Notification[Any, Any]], call_next: CallNext[mt.Notification[Any, Any], Any]) -> Any ``` -#### `on_initialize` +#### `on_initialize` ```python on_initialize(self, context: MiddlewareContext[mt.InitializeRequest], call_next: CallNext[mt.InitializeRequest, mt.InitializeResult | None]) -> mt.InitializeResult | None ``` -#### `on_call_tool` +#### `on_call_tool` ```python on_call_tool(self, context: MiddlewareContext[mt.CallToolRequestParams], call_next: CallNext[mt.CallToolRequestParams, ToolResult]) -> ToolResult ``` -#### `on_read_resource` +#### `on_read_resource` ```python -on_read_resource(self, context: MiddlewareContext[mt.ReadResourceRequestParams], call_next: CallNext[mt.ReadResourceRequestParams, Sequence[ReadResourceContents]]) -> Sequence[ReadResourceContents] +on_read_resource(self, context: MiddlewareContext[mt.ReadResourceRequestParams], call_next: CallNext[mt.ReadResourceRequestParams, Sequence[ResourceContent]]) -> Sequence[ResourceContent] ``` -#### `on_get_prompt` +#### `on_get_prompt` ```python -on_get_prompt(self, context: MiddlewareContext[mt.GetPromptRequestParams], call_next: CallNext[mt.GetPromptRequestParams, mt.GetPromptResult]) -> mt.GetPromptResult +on_get_prompt(self, context: MiddlewareContext[mt.GetPromptRequestParams], call_next: CallNext[mt.GetPromptRequestParams, PromptResult]) -> PromptResult ``` -#### `on_list_tools` +#### `on_list_tools` ```python on_list_tools(self, context: MiddlewareContext[mt.ListToolsRequest], call_next: CallNext[mt.ListToolsRequest, Sequence[Tool]]) -> Sequence[Tool] ``` -#### `on_list_resources` +#### `on_list_resources` ```python on_list_resources(self, context: MiddlewareContext[mt.ListResourcesRequest], call_next: CallNext[mt.ListResourcesRequest, Sequence[Resource]]) -> Sequence[Resource] ``` -#### `on_list_resource_templates` +#### `on_list_resource_templates` ```python on_list_resource_templates(self, context: MiddlewareContext[mt.ListResourceTemplatesRequest], call_next: CallNext[mt.ListResourceTemplatesRequest, Sequence[ResourceTemplate]]) -> Sequence[ResourceTemplate] ``` -#### `on_list_prompts` +#### `on_list_prompts` ```python on_list_prompts(self, context: MiddlewareContext[mt.ListPromptsRequest], call_next: CallNext[mt.ListPromptsRequest, Sequence[Prompt]]) -> Sequence[Prompt] diff --git a/docs/python-sdk/fastmcp-server-middleware-tool_injection.mdx b/docs/python-sdk/fastmcp-server-middleware-tool_injection.mdx index 946a5f33a..9e2c663c1 100644 --- a/docs/python-sdk/fastmcp-server-middleware-tool_injection.mdx +++ b/docs/python-sdk/fastmcp-server-middleware-tool_injection.mdx @@ -43,7 +43,7 @@ List resources available on the server. ### `read_resource` ```python -read_resource(context: Context, uri: Annotated[AnyUrl | str, 'The URI of the resource to read.']) -> list[ReadResourceContents] +read_resource(context: Context, uri: Annotated[AnyUrl | str, 'The URI of the resource to read.']) -> list[ResourceContent] ``` diff --git a/docs/python-sdk/fastmcp-server-openapi-__init__.mdx b/docs/python-sdk/fastmcp-server-openapi-__init__.mdx index 2e2cfe6e2..af9cd5517 100644 --- a/docs/python-sdk/fastmcp-server-openapi-__init__.mdx +++ b/docs/python-sdk/fastmcp-server-openapi-__init__.mdx @@ -6,4 +6,22 @@ sidebarTitle: __init__ # `fastmcp.server.openapi` -OpenAPI server implementation for FastMCP - refactored for better maintainability. +OpenAPI server implementation for FastMCP. + +.. deprecated:: + This module is deprecated. Import from fastmcp.server.providers.openapi instead. + +The recommended approach is to use OpenAPIProvider with FastMCP: + + from fastmcp import FastMCP + from fastmcp.server.providers.openapi import OpenAPIProvider + import httpx + + client = httpx.AsyncClient(base_url="https://api.example.com") + provider = OpenAPIProvider(openapi_spec=spec, client=client) + + mcp = FastMCP("My API Server") + mcp.add_provider(provider) + +FastMCPOpenAPI is still available but deprecated. + diff --git a/docs/python-sdk/fastmcp-server-openapi-components.mdx b/docs/python-sdk/fastmcp-server-openapi-components.mdx index 4a12d363f..320cc7092 100644 --- a/docs/python-sdk/fastmcp-server-openapi-components.mdx +++ b/docs/python-sdk/fastmcp-server-openapi-components.mdx @@ -6,57 +6,7 @@ sidebarTitle: components # `fastmcp.server.openapi.components` -OpenAPI component implementations: Tool, Resource, and ResourceTemplate classes. +OpenAPI component implementations - backwards compatibility stub. -## Classes - -### `OpenAPITool` - - -Tool implementation for OpenAPI endpoints. - - -**Methods:** - -#### `run` - -```python -run(self, arguments: dict[str, Any]) -> ToolResult -``` - -Execute the HTTP request using RequestDirector for simplified parameter handling. - - -### `OpenAPIResource` - - -Resource implementation for OpenAPI endpoints. - - -**Methods:** - -#### `read` - -```python -read(self) -> str | bytes -``` - -Fetch the resource data by making an HTTP request. - - -### `OpenAPIResourceTemplate` - - -Resource template implementation for OpenAPI endpoints. - - -**Methods:** - -#### `create_resource` - -```python -create_resource(self, uri: str, params: dict[str, Any], context: 'Context | None' = None) -> Resource -``` - -Create a resource with the given parameters. +This module is deprecated. Import from fastmcp.server.providers.openapi instead. diff --git a/docs/python-sdk/fastmcp-server-openapi-routing.mdx b/docs/python-sdk/fastmcp-server-openapi-routing.mdx index cbe4b7ce1..650a4a497 100644 --- a/docs/python-sdk/fastmcp-server-openapi-routing.mdx +++ b/docs/python-sdk/fastmcp-server-openapi-routing.mdx @@ -8,16 +8,6 @@ sidebarTitle: routing Route mapping logic for OpenAPI operations. -## Classes - -### `MCPType` - - -Type of FastMCP component to create from a route. - - -### `RouteMap` - - -Mapping configuration for HTTP routes to FastMCP component types. +.. deprecated:: + This module is deprecated. Import from fastmcp.server.providers.openapi instead. diff --git a/docs/python-sdk/fastmcp-server-openapi-server.mdx b/docs/python-sdk/fastmcp-server-openapi-server.mdx index 77a452f9f..2cae5e9af 100644 --- a/docs/python-sdk/fastmcp-server-openapi-server.mdx +++ b/docs/python-sdk/fastmcp-server-openapi-server.mdx @@ -6,15 +6,38 @@ sidebarTitle: server # `fastmcp.server.openapi.server` -FastMCP server implementation for OpenAPI integration. +FastMCPOpenAPI - backwards compatibility wrapper. + +This class is deprecated. Use FastMCP with OpenAPIProvider instead: + + from fastmcp import FastMCP + from fastmcp.server.providers.openapi import OpenAPIProvider + import httpx + + client = httpx.AsyncClient(base_url="https://api.example.com") + provider = OpenAPIProvider(openapi_spec=spec, client=client) + mcp = FastMCP("My API Server", providers=[provider]) + ## Classes -### `FastMCPOpenAPI` +### `FastMCPOpenAPI` FastMCP server implementation that creates components from an OpenAPI schema. -This class parses an OpenAPI specification and creates appropriate FastMCP components -(Tools, Resources, ResourceTemplates) based on route mappings. +.. deprecated:: + Use FastMCP with OpenAPIProvider instead. This class will be + removed in a future version. + +Example (deprecated): + ```python + from fastmcp.server.openapi import FastMCPOpenAPI + import httpx + + server = FastMCPOpenAPI( + openapi_spec=spec, + client=httpx.AsyncClient(), + ) + ``` diff --git a/docs/python-sdk/fastmcp-server-providers-__init__.mdx b/docs/python-sdk/fastmcp-server-providers-__init__.mdx new file mode 100644 index 000000000..277e67e60 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-__init__.mdx @@ -0,0 +1,34 @@ +--- +title: __init__ +sidebarTitle: __init__ +--- + +# `fastmcp.server.providers` + + +Providers for dynamic MCP components. + +This module provides the `Provider` abstraction for providing tools, +resources, and prompts dynamically at runtime. + +Example: + ```python + from fastmcp import FastMCP + from fastmcp.server.providers import Provider + from fastmcp.tools import Tool + + class DatabaseProvider(Provider): + def __init__(self, db_url: str): + self.db = Database(db_url) + + async def list_tools(self) -> list[Tool]: + rows = await self.db.fetch("SELECT * FROM tools") + return [self._make_tool(row) for row in rows] + + async def get_tool(self, name: str) -> Tool | None: + row = await self.db.fetchone("SELECT * FROM tools WHERE name = ?", name) + return self._make_tool(row) if row else None + + mcp = FastMCP("Server", providers=[DatabaseProvider(db_url)]) + ``` + diff --git a/docs/python-sdk/fastmcp-server-providers-base.mdx b/docs/python-sdk/fastmcp-server-providers-base.mdx new file mode 100644 index 000000000..d7af88d69 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-base.mdx @@ -0,0 +1,264 @@ +--- +title: base +sidebarTitle: base +--- + +# `fastmcp.server.providers.base` + + +Base Provider class for dynamic MCP components. + +This module provides the `Provider` abstraction for providing tools, +resources, and prompts dynamically at runtime. + +Example: + ```python + from fastmcp import FastMCP + from fastmcp.server.providers import Provider + from fastmcp.tools import Tool + + class DatabaseProvider(Provider): + def __init__(self, db_url: str): + super().__init__() + self.db = Database(db_url) + + async def list_tools(self) -> list[Tool]: + rows = await self.db.fetch("SELECT * FROM tools") + return [self._make_tool(row) for row in rows] + + async def get_tool(self, name: str) -> Tool | None: + row = await self.db.fetchone("SELECT * FROM tools WHERE name = ?", name) + return self._make_tool(row) if row else None + + mcp = FastMCP("Server", providers=[DatabaseProvider(db_url)]) + ``` + + +## Classes + +### `Provider` + + +Base class for dynamic component providers. + +Subclass and override whichever methods you need. Default implementations +return empty lists / None, so you only need to implement what your provider +supports. + + +**Methods:** + +#### `with_transforms` + +```python +with_transforms(self) -> Provider +``` + +Apply transformations to this provider's components. + +Returns a TransformingProvider that wraps this provider and applies +the specified transformations. Can be chained - each call creates a +new wrapper that composes with the previous. + +**Args:** +- `namespace`: Prefix for tools/prompts ("namespace_name"), path segment +for resources ("protocol\://namespace/path"). +- `tool_renames`: Map of original_name → final_name. Tools in this map +use the specified name instead of namespace prefixing. + +**Returns:** +- A TransformingProvider wrapping this provider. + + +#### `with_namespace` + +```python +with_namespace(self, namespace: str) -> Provider +``` + +Shorthand for with_transforms(namespace=...). + +**Args:** +- `namespace`: The namespace to apply. + +**Returns:** +- A TransformingProvider wrapping this provider. + + +#### `list_tools` + +```python +list_tools(self) -> Sequence[Tool] +``` + +Return all available tools. + +Override to provide tools dynamically. + + +#### `get_tool` + +```python +get_tool(self, name: str) -> Tool | None +``` + +Get a specific tool by name. + +Default implementation lists all tools and finds by name. +Override for more efficient single-tool lookup. + +**Returns:** +- The Tool if found, or None to continue searching other providers. + + +#### `list_resources` + +```python +list_resources(self) -> Sequence[Resource] +``` + +Return all available resources. + +Override to provide resources dynamically. + + +#### `get_resource` + +```python +get_resource(self, uri: str) -> Resource | None +``` + +Get a specific resource by URI. + +Default implementation lists all resources and finds by URI. +Override for more efficient single-resource lookup. + +**Returns:** +- The Resource if found, or None to continue searching other providers. + + +#### `list_resource_templates` + +```python +list_resource_templates(self) -> Sequence[ResourceTemplate] +``` + +Return all available resource templates. + +Override to provide resource templates dynamically. + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str) -> ResourceTemplate | None +``` + +Get a resource template that matches the given URI. + +Default implementation lists all templates and finds one whose pattern +matches the URI. +Override for more efficient lookup. + +**Returns:** +- The ResourceTemplate if a matching one is found, or None to continue searching. + + +#### `list_prompts` + +```python +list_prompts(self) -> Sequence[Prompt] +``` + +Return all available prompts. + +Override to provide prompts dynamically. + + +#### `get_prompt` + +```python +get_prompt(self, name: str) -> Prompt | None +``` + +Get a specific prompt by name. + +Default implementation lists all prompts and finds by name. +Override for more efficient single-prompt lookup. + +**Returns:** +- The Prompt if found, or None to continue searching other providers. + + +#### `get_component` + +```python +get_component(self, key: str) -> Tool | Resource | ResourceTemplate | Prompt | None +``` + +Get a component by its prefixed key. + +**Args:** +- `key`: The prefixed key (e.g., "tool\:name", "resource\:uri", "template\:uri"). + +**Returns:** +- The component if found, or None to continue searching other providers. + + +#### `get_tasks` + +```python +get_tasks(self) -> Sequence[FastMCPComponent] +``` + +Return components that should be registered as background tasks. + +Override to customize which components are task-eligible. +Default calls list_* methods and filters for function-based components +with task_config.mode != 'forbidden'. + +Used by the server during startup to register functions with Docket. + + +#### `lifespan` + +```python +lifespan(self) -> AsyncIterator[None] +``` + +User-overridable lifespan for custom setup and teardown. + +Override this method to perform provider-specific initialization +like opening database connections, setting up external resources, +or other state management needed for the provider's lifetime. + +The lifespan scope matches the server's lifespan - code before yield +runs at startup, code after yield runs at shutdown. + + +#### `enable` + +```python +enable(self) -> None +``` + +Enable components by removing from blocklist, or set allowlist with only=True. + +**Args:** +- `keys`: Keys to enable (e.g., "tool\:my_tool"). +- `tags`: Tags to enable - components with these tags will be enabled. +- `only`: If True, switches to allowlist mode - ONLY show these keys/tags. + + +#### `disable` + +```python +disable(self) -> None +``` + +Disable components by adding to the blocklist. + +**Args:** +- `keys`: Keys to disable (e.g., "tool\:my_tool"). +- `tags`: Tags to disable - components with these tags will be disabled. + diff --git a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx new file mode 100644 index 000000000..a93457ff5 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx @@ -0,0 +1,328 @@ +--- +title: fastmcp_provider +sidebarTitle: fastmcp_provider +--- + +# `fastmcp.server.providers.fastmcp_provider` + + +FastMCPProvider for wrapping FastMCP servers as providers. + +This module provides the `FastMCPProvider` class that wraps a FastMCP server +and exposes its components through the Provider interface. + +It also provides FastMCPProvider* component classes that delegate execution to +the wrapped server's middleware, ensuring middleware runs when components are +executed. + + +## Classes + +### `FastMCPProviderTool` + + +Tool that delegates execution to a wrapped server's middleware. + +When `run()` is called, this tool invokes the wrapped server's +`_call_tool_middleware()` method, ensuring the server's middleware +chain is executed. + + +**Methods:** + +#### `wrap` + +```python +wrap(cls, server: Any, tool: Tool) -> FastMCPProviderTool +``` + +Wrap a Tool to delegate execution to the server's middleware. + + +#### `run` + +```python +run(self, arguments: dict[str, Any]) -> ToolResult | mcp.types.CreateTaskResult +``` + +Delegate to child server's middleware chain. + +This runs BEFORE any backgrounding decision - the actual underlying +tool will check contextvars and submit to Docket if appropriate. + + +### `FastMCPProviderResource` + + +Resource that delegates reading to a wrapped server's middleware. + +When `read()` is called, this resource invokes the wrapped server's +`_read_resource_middleware()` method, ensuring the server's middleware +chain is executed. + + +**Methods:** + +#### `wrap` + +```python +wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource +``` + +Wrap a Resource to delegate reading to the server's middleware. + + +#### `read` + +```python +read(self) -> ResourceContent | mcp.types.CreateTaskResult +``` + +Delegate to child server's middleware. + +When called from a Docket worker (background task), there's no FastMCP +context set up, so we create one for the child server. + +Note: The _docket_fn_key contextvar is intentionally NOT updated here. +The parent set it to the full namespaced key (e.g., data://c/gc/value) +which is what the function is registered under in Docket. All provider +layers pass this through unchanged so the eventual resource._read() +uses the correct Docket lookup key. + + +### `FastMCPProviderPrompt` + + +Prompt that delegates rendering to a wrapped server's middleware. + +When `render()` is called, this prompt invokes the wrapped server's +`_get_prompt_content_middleware()` method, ensuring the server's middleware +chain is executed. + + +**Methods:** + +#### `wrap` + +```python +wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt +``` + +Wrap a Prompt to delegate rendering to the server's middleware. + + +#### `render` + +```python +render(self, arguments: dict[str, Any] | None = None) -> PromptResult | mcp.types.CreateTaskResult +``` + +Delegate to child server's middleware. + +When called from a Docket worker (background task), there's no FastMCP +context set up, so we create one for the child server. + +Note: The _docket_fn_key contextvar is intentionally NOT updated here. +The parent set it to the full namespaced name (e.g., c_gc_greet) which +is what the function is registered under in Docket. All provider layers +pass this through unchanged so the eventual prompt._render() uses the +correct Docket lookup key. + + +### `FastMCPProviderResourceTemplate` + + +Resource template that creates FastMCPProviderResources. + +When `create_resource()` is called, this template creates a +FastMCPProviderResource that will invoke the wrapped server's middleware +when read. + + +**Methods:** + +#### `wrap` + +```python +wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTemplate +``` + +Wrap a ResourceTemplate to create FastMCPProviderResources. + + +#### `create_resource` + +```python +create_resource(self, uri: str, params: dict[str, Any]) -> Resource +``` + +Create a FastMCPProviderResource for the given URI. + +The `uri` is the external/transformed URI (e.g., with namespace prefix). +We use `_original_uri_template` with `params` to construct the internal +URI that the nested server understands. + + +#### `read` + +```python +read(self, arguments: dict[str, Any]) -> str | bytes +``` + +Read the resource content for background task execution. + +Creates a resource from this template and reads its content. +This method is called by Docket during background task execution. + + +#### `register_with_docket` + +```python +register_with_docket(self, docket: Docket) -> None +``` + +No-op: the child's actual template is registered via get_tasks(). + + +#### `add_to_docket` + +```python +add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution +``` + +Schedule this template for background execution via docket. + +The child's FunctionResourceTemplate.fn is registered (via get_tasks), +and it expects splatted **kwargs, so we splat params here. + + +### `FastMCPProvider` + + +Provider that wraps a FastMCP server. + +This provider enables mounting one FastMCP server onto another, exposing +the mounted server's tools, resources, and prompts through the parent +server. + +Components returned by this provider are wrapped in FastMCPProvider* +classes that delegate execution to the wrapped server's middleware chain. +This ensures middleware runs when components are executed. + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self) -> Sequence[Tool] +``` + +List all tools from the mounted server as FastMCPProviderTools. + +Calls the nested server's middleware to list tools, then wraps +each tool as a FastMCPProviderTool that delegates execution to the +nested server's middleware. + + +#### `get_tool` + +```python +get_tool(self, name: str) -> Tool | None +``` + +Get a tool by name as a FastMCPProviderTool. + + +#### `list_resources` + +```python +list_resources(self) -> Sequence[Resource] +``` + +List all resources from the mounted server as FastMCPProviderResources. + +Calls the nested server's middleware to list resources, then wraps +each resource as a FastMCPProviderResource that delegates reading to the +nested server's middleware. + + +#### `get_resource` + +```python +get_resource(self, uri: str) -> Resource | None +``` + +Get a concrete resource by URI as a FastMCPProviderResource. + + +#### `list_resource_templates` + +```python +list_resource_templates(self) -> Sequence[ResourceTemplate] +``` + +List all resource templates from the mounted server. + +Returns FastMCPProviderResourceTemplate instances that create +FastMCPProviderResources when materialized. + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str) -> ResourceTemplate | None +``` + +Get a resource template that matches the given URI. + + +#### `list_prompts` + +```python +list_prompts(self) -> Sequence[Prompt] +``` + +List all prompts from the mounted server as FastMCPProviderPrompts. + +Returns FastMCPProviderPrompt instances that delegate rendering to the +wrapped server's middleware. + + +#### `get_prompt` + +```python +get_prompt(self, name: str) -> Prompt | None +``` + +Get a prompt by name as a FastMCPProviderPrompt. + + +#### `get_tasks` + +```python +get_tasks(self) -> Sequence[FastMCPComponent] +``` + +Return task-eligible components from the mounted server. + +Returns the child's ACTUAL components (not wrapped) so their actual +functions get registered with Docket. TransformingProvider.get_tasks() +handles namespace transformation of keys. + +Iterates through all providers in the wrapped server (including its +LocalProvider) to collect task-eligible components. + + +#### `lifespan` + +```python +lifespan(self) -> AsyncIterator[None] +``` + +Start the mounted server's user lifespan. + +This starts only the wrapped server's user-defined lifespan, NOT its +full _lifespan_manager() (which includes Docket). The parent server's +Docket handles all background tasks. + diff --git a/docs/python-sdk/fastmcp-server-providers-local_provider.mdx b/docs/python-sdk/fastmcp-server-providers-local_provider.mdx new file mode 100644 index 000000000..40c4141e1 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-local_provider.mdx @@ -0,0 +1,372 @@ +--- +title: local_provider +sidebarTitle: local_provider +--- + +# `fastmcp.server.providers.local_provider` + + +LocalProvider for locally-defined MCP components. + +This module provides the `LocalProvider` class that manages tools, resources, +templates, and prompts registered via decorators or direct methods. + +LocalProvider can be used standalone and attached to multiple servers: + +```python +from fastmcp.server.providers import LocalProvider + +# Create a reusable provider with tools +provider = LocalProvider() + +@provider.tool +def greet(name: str) -> str: + return f"Hello, {name}!" + +# Attach to any server +from fastmcp import FastMCP +server1 = FastMCP("Server1", providers=[provider]) +server2 = FastMCP("Server2", providers=[provider]) +``` + + +## Classes + +### `LocalProvider` + + +Provider for locally-defined components. + +Supports decorator-based registration (`@provider.tool`, `@provider.resource`, +`@provider.prompt`) and direct object registration methods. + +When used standalone, LocalProvider uses default settings. When attached +to a FastMCP server via the server's decorators, server-level settings +like `_tool_serializer` and `_support_tasks_by_default` are injected. + + +**Methods:** + +#### `add_tool` + +```python +add_tool(self, tool: Tool) -> Tool +``` + +Add a tool to this provider's storage. + + +#### `remove_tool` + +```python +remove_tool(self, name: str) -> None +``` + +Remove a tool from this provider's storage. + + +#### `add_resource` + +```python +add_resource(self, resource: Resource) -> Resource +``` + +Add a resource to this provider's storage. + + +#### `remove_resource` + +```python +remove_resource(self, uri: str) -> None +``` + +Remove a resource from this provider's storage. + + +#### `add_template` + +```python +add_template(self, template: ResourceTemplate) -> ResourceTemplate +``` + +Add a resource template to this provider's storage. + + +#### `remove_template` + +```python +remove_template(self, uri_template: str) -> None +``` + +Remove a resource template from this provider's storage. + + +#### `add_prompt` + +```python +add_prompt(self, prompt: Prompt) -> Prompt +``` + +Add a prompt to this provider's storage. + + +#### `remove_prompt` + +```python +remove_prompt(self, name: str) -> None +``` + +Remove a prompt from this provider's storage. + + +#### `add_tool_transformation` + +```python +add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None +``` + +Add a tool transformation. + +**Args:** +- `tool_name`: The name of the tool to transform. +- `transformation`: The transformation configuration. + + +#### `get_tool_transformation` + +```python +get_tool_transformation(self, tool_name: str) -> ToolTransformConfig | None +``` + +Get a tool transformation. + +**Args:** +- `tool_name`: The name of the tool. + +**Returns:** +- The transformation config, or None if not found. + + +#### `remove_tool_transformation` + +```python +remove_tool_transformation(self, tool_name: str) -> None +``` + +Remove a tool transformation. + +**Args:** +- `tool_name`: The name of the tool. + + +#### `list_tools` + +```python +list_tools(self) -> Sequence[Tool] +``` + +Return all visible tools with transformations applied. + + +#### `get_tool` + +```python +get_tool(self, name: str) -> Tool | None +``` + +Get a tool by name, with transformations applied. + + +#### `list_resources` + +```python +list_resources(self) -> Sequence[Resource] +``` + +Return all visible resources. + + +#### `get_resource` + +```python +get_resource(self, uri: str) -> Resource | None +``` + +Get a resource by URI if visible. + + +#### `list_resource_templates` + +```python +list_resource_templates(self) -> Sequence[ResourceTemplate] +``` + +Return all visible resource templates. + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str) -> ResourceTemplate | None +``` + +Get a resource template that matches the given URI if visible. + + +#### `list_prompts` + +```python +list_prompts(self) -> Sequence[Prompt] +``` + +Return all visible prompts. + + +#### `get_prompt` + +```python +get_prompt(self, name: str) -> Prompt | None +``` + +Get a prompt by name if visible. + + +#### `get_component` + +```python +get_component(self, key: str) -> Tool | Resource | ResourceTemplate | Prompt | None +``` + +Get a component by its prefixed key. + +Efficient O(1) lookup in the unified components dict. + + +#### `get_tasks` + +```python +get_tasks(self) -> Sequence[FastMCPComponent] +``` + +Return components eligible for background task execution. + +Returns components that have task_config.mode != 'forbidden'. +This includes both FunctionTool/Resource/Prompt instances created via +decorators and custom Tool/Resource/Prompt subclasses. + + +#### `tool` + +```python +tool(self, name_or_fn: AnyFunction) -> FunctionTool +``` + +#### `tool` + +```python +tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool] +``` + +#### `tool` + +```python +tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool] +``` + +Decorator to register a tool. + +This decorator supports multiple calling patterns: +- @provider.tool (without parentheses) +- @provider.tool() (with empty parentheses) +- @provider.tool("custom_name") (with name as first argument) +- @provider.tool(name="custom_name") (with name as keyword argument) +- provider.tool(function, name="custom_name") (direct function call) + +**Args:** +- `name_or_fn`: Either a function (when used as @tool), a string name, or None +- `name`: Optional name for the tool (keyword-only, alternative to name_or_fn) +- `title`: Optional title for the tool +- `description`: Optional description of what the tool does +- `icons`: Optional icons for the tool +- `tags`: Optional set of tags for categorizing the tool +- `output_schema`: Optional JSON schema for the tool's output +- `annotations`: Optional annotations about the tool's behavior +- `exclude_args`: Optional list of argument names to exclude from the tool schema +- `meta`: Optional meta information about the tool +- `enabled`: Whether the tool is enabled (default True). If False, adds to blocklist. +- `task`: Optional task configuration for background execution +- `serializer`: Optional serializer for the tool result + +**Returns:** +- The registered FunctionTool or a decorator function. + + +#### `resource` + +```python +resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate] +``` + +Decorator to register a function as a resource. + +If the URI contains parameters (e.g. "resource://{param}") or the function +has parameters, it will be registered as a template resource. + +**Args:** +- `uri`: URI for the resource (e.g. "resource\://my-resource" or "resource\://{param}") +- `name`: Optional name for the resource +- `title`: Optional title for the resource +- `description`: Optional description of the resource +- `icons`: Optional icons for the resource +- `mime_type`: Optional MIME type for the resource +- `tags`: Optional set of tags for categorizing the resource +- `enabled`: Whether the resource is enabled (default True). If False, adds to blocklist. +- `annotations`: Optional annotations about the resource's behavior +- `meta`: Optional meta information about the resource +- `task`: Optional task configuration for background execution + +**Returns:** +- A decorator function. + + +#### `prompt` + +```python +prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt +``` + +#### `prompt` + +```python +prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt] +``` + +#### `prompt` + +```python +prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt] +``` + +Decorator to register a prompt. + +This decorator supports multiple calling patterns: +- @provider.prompt (without parentheses) +- @provider.prompt() (with empty parentheses) +- @provider.prompt("custom_name") (with name as first argument) +- @provider.prompt(name="custom_name") (with name as keyword argument) +- provider.prompt(function, name="custom_name") (direct function call) + +**Args:** +- `name_or_fn`: Either a function (when used as @prompt), a string name, or None +- `name`: Optional name for the prompt (keyword-only, alternative to name_or_fn) +- `title`: Optional title for the prompt +- `description`: Optional description of what the prompt does +- `icons`: Optional icons for the prompt +- `tags`: Optional set of tags for categorizing the prompt +- `enabled`: Whether the prompt is enabled (default True). If False, adds to blocklist. +- `meta`: Optional meta information about the prompt +- `task`: Optional task configuration for background execution + +**Returns:** +- The registered FunctionPrompt or a decorator function. + diff --git a/docs/python-sdk/fastmcp-server-providers-openapi-__init__.mdx b/docs/python-sdk/fastmcp-server-providers-openapi-__init__.mdx new file mode 100644 index 000000000..bd79a038b --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-openapi-__init__.mdx @@ -0,0 +1,23 @@ +--- +title: __init__ +sidebarTitle: __init__ +--- + +# `fastmcp.server.providers.openapi` + + +OpenAPI provider for FastMCP. + +This module provides OpenAPI integration for FastMCP through the Provider pattern. + +Example: + ```python + from fastmcp import FastMCP + from fastmcp.server.providers.openapi import OpenAPIProvider + import httpx + + client = httpx.AsyncClient(base_url="https://api.example.com") + provider = OpenAPIProvider(openapi_spec=spec, client=client) + mcp = FastMCP("API Server", providers=[provider]) + ``` + diff --git a/docs/python-sdk/fastmcp-server-providers-openapi-components.mdx b/docs/python-sdk/fastmcp-server-providers-openapi-components.mdx new file mode 100644 index 000000000..fa5728a3b --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-openapi-components.mdx @@ -0,0 +1,62 @@ +--- +title: components +sidebarTitle: components +--- + +# `fastmcp.server.providers.openapi.components` + + +OpenAPI component classes: Tool, Resource, and ResourceTemplate. + +## Classes + +### `OpenAPITool` + + +Tool implementation for OpenAPI endpoints. + + +**Methods:** + +#### `run` + +```python +run(self, arguments: dict[str, Any]) -> ToolResult +``` + +Execute the HTTP request using RequestDirector. + + +### `OpenAPIResource` + + +Resource implementation for OpenAPI endpoints. + + +**Methods:** + +#### `read` + +```python +read(self) -> ResourceContent +``` + +Fetch the resource data by making an HTTP request. + + +### `OpenAPIResourceTemplate` + + +Resource template implementation for OpenAPI endpoints. + + +**Methods:** + +#### `create_resource` + +```python +create_resource(self, uri: str, params: dict[str, Any], context: Context | None = None) -> Resource +``` + +Create a resource with the given parameters. + diff --git a/docs/python-sdk/fastmcp-server-providers-openapi-provider.mdx b/docs/python-sdk/fastmcp-server-providers-openapi-provider.mdx new file mode 100644 index 000000000..2df5a6449 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-openapi-provider.mdx @@ -0,0 +1,94 @@ +--- +title: provider +sidebarTitle: provider +--- + +# `fastmcp.server.providers.openapi.provider` + + +OpenAPIProvider for creating MCP components from OpenAPI specifications. + +## Classes + +### `OpenAPIProvider` + + +Provider that creates MCP components from an OpenAPI specification. + +Components are created eagerly during initialization by parsing the OpenAPI +spec. Each component makes HTTP calls to the described API endpoints. + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self) -> Sequence[Tool] +``` + +Return all tools created from the OpenAPI spec. + + +#### `get_tool` + +```python +get_tool(self, name: str) -> Tool | None +``` + +Get a tool by name. + + +#### `list_resources` + +```python +list_resources(self) -> Sequence[Resource] +``` + +Return all resources created from the OpenAPI spec. + + +#### `get_resource` + +```python +get_resource(self, uri: str) -> Resource | None +``` + +Get a resource by URI. + + +#### `list_resource_templates` + +```python +list_resource_templates(self) -> Sequence[ResourceTemplate] +``` + +Return all resource templates created from the OpenAPI spec. + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str) -> ResourceTemplate | None +``` + +Get a resource template that matches the given URI. + + +#### `list_prompts` + +```python +list_prompts(self) -> Sequence[Prompt] +``` + +Return empty list - OpenAPI doesn't create prompts. + + +#### `get_tasks` + +```python +get_tasks(self) -> Sequence[FastMCPComponent] +``` + +Return empty list - OpenAPI components don't support tasks. + diff --git a/docs/python-sdk/fastmcp-server-providers-openapi-routing.mdx b/docs/python-sdk/fastmcp-server-providers-openapi-routing.mdx new file mode 100644 index 000000000..6c0f8b3c7 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-openapi-routing.mdx @@ -0,0 +1,23 @@ +--- +title: routing +sidebarTitle: routing +--- + +# `fastmcp.server.providers.openapi.routing` + + +Route mapping logic for OpenAPI operations. + +## Classes + +### `MCPType` + + +Type of FastMCP component to create from a route. + + +### `RouteMap` + + +Mapping configuration for HTTP routes to FastMCP component types. + diff --git a/docs/python-sdk/fastmcp-server-providers-proxy.mdx b/docs/python-sdk/fastmcp-server-providers-proxy.mdx new file mode 100644 index 000000000..866109ca9 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-proxy.mdx @@ -0,0 +1,322 @@ +--- +title: proxy +sidebarTitle: proxy +--- + +# `fastmcp.server.providers.proxy` + + +ProxyProvider for proxying to remote MCP servers. + +This module provides the `ProxyProvider` class that proxies components from +a remote MCP server via a client factory. It also provides proxy component +classes that forward execution to remote servers. + + +## Functions + +### `default_proxy_roots_handler` + +```python +default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanContextT]) -> RootsList +``` + + +Forward list roots request from remote server to proxy's connected clients. + + +### `default_proxy_sampling_handler` + +```python +default_proxy_sampling_handler(messages: list[mcp.types.SamplingMessage], params: mcp.types.CreateMessageRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> mcp.types.CreateMessageResult +``` + + +Forward sampling request from remote server to proxy's connected clients. + + +### `default_proxy_elicitation_handler` + +```python +default_proxy_elicitation_handler(message: str, response_type: type, params: mcp.types.ElicitRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> ElicitResult +``` + + +Forward elicitation request from remote server to proxy's connected clients. + + +### `default_proxy_log_handler` + +```python +default_proxy_log_handler(message: LogMessage) -> None +``` + + +Forward log notification from remote server to proxy's connected clients. + + +### `default_proxy_progress_handler` + +```python +default_proxy_progress_handler(progress: float, total: float | None, message: str | None) -> None +``` + + +Forward progress notification from remote server to proxy's connected clients. + + +## Classes + +### `ProxyTool` + + +A Tool that represents and executes a tool on a remote server. + + +**Methods:** + +#### `model_copy` + +```python +model_copy(self, **kwargs: Any) -> ProxyTool +``` + +Override to preserve _backend_name when name changes. + + +#### `from_mcp_tool` + +```python +from_mcp_tool(cls, client_factory: ClientFactoryT, mcp_tool: mcp.types.Tool) -> ProxyTool +``` + +Factory method to create a ProxyTool from a raw MCP tool schema. + + +#### `run` + +```python +run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResult +``` + +Executes the tool by making a call through the client. + + +### `ProxyResource` + + +A Resource that represents and reads a resource from a remote server. + + +**Methods:** + +#### `model_copy` + +```python +model_copy(self, **kwargs: Any) -> ProxyResource +``` + +Override to preserve _backend_uri when uri changes. + + +#### `from_mcp_resource` + +```python +from_mcp_resource(cls, client_factory: ClientFactoryT, mcp_resource: mcp.types.Resource) -> ProxyResource +``` + +Factory method to create a ProxyResource from a raw MCP resource schema. + + +#### `read` + +```python +read(self) -> ResourceContent +``` + +Read the resource content from the remote server. + + +### `ProxyTemplate` + + +A ResourceTemplate that represents and creates resources from a remote server template. + + +**Methods:** + +#### `model_copy` + +```python +model_copy(self, **kwargs: Any) -> ProxyTemplate +``` + +Override to preserve _backend_uri_template when uri_template changes. + + +#### `from_mcp_template` + +```python +from_mcp_template(cls, client_factory: ClientFactoryT, mcp_template: mcp.types.ResourceTemplate) -> ProxyTemplate +``` + +Factory method to create a ProxyTemplate from a raw MCP template schema. + + +#### `create_resource` + +```python +create_resource(self, uri: str, params: dict[str, Any], context: Context | None = None) -> ProxyResource +``` + +Create a resource from the template by calling the remote server. + + +### `ProxyPrompt` + + +A Prompt that represents and renders a prompt from a remote server. + + +**Methods:** + +#### `model_copy` + +```python +model_copy(self, **kwargs: Any) -> ProxyPrompt +``` + +Override to preserve _backend_name when name changes. + + +#### `from_mcp_prompt` + +```python +from_mcp_prompt(cls, client_factory: ClientFactoryT, mcp_prompt: mcp.types.Prompt) -> ProxyPrompt +``` + +Factory method to create a ProxyPrompt from a raw MCP prompt schema. + + +#### `render` + +```python +render(self, arguments: dict[str, Any]) -> PromptResult +``` + +Render the prompt by making a call through the client. + + +### `ProxyProvider` + + +Provider that proxies to a remote MCP server via a client factory. + +This provider fetches components from a remote server and returns Proxy* +component instances that forward execution to the remote server. + +All components returned by this provider have task_config.mode="forbidden" +because tasks cannot be executed through a proxy. + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self) -> Sequence[Tool] +``` + +List all tools from the remote server. + + +#### `list_resources` + +```python +list_resources(self) -> Sequence[Resource] +``` + +List all resources from the remote server. + + +#### `list_resource_templates` + +```python +list_resource_templates(self) -> Sequence[ResourceTemplate] +``` + +List all resource templates from the remote server. + + +#### `list_prompts` + +```python +list_prompts(self) -> Sequence[Prompt] +``` + +List all prompts from the remote server. + + +#### `get_tasks` + +```python +get_tasks(self) -> Sequence[FastMCPComponent] +``` + +Return empty list since proxy components don't support tasks. + +Override the base implementation to avoid calling list_tools() during +server lifespan initialization, which would open the client before any +context is set. All Proxy* components have task_config.mode="forbidden". + + +### `FastMCPProxy` + + +A FastMCP server that acts as a proxy to a remote MCP-compliant server. + +This is a convenience wrapper that creates a FastMCP server with a +ProxyProvider. For more control, use FastMCP with add_provider(ProxyProvider(...)). + + +### `ProxyClient` + + +A proxy client that forwards advanced interactions between a remote MCP server and the proxy's connected clients. + +Supports forwarding roots, sampling, elicitation, logging, and progress. + + +### `StatefulProxyClient` + + +A proxy client that provides a stateful client factory for the proxy server. + +The stateful proxy client bound its copy to the server session. +And it will be disconnected when the session is exited. + +This is useful to proxy a stateful mcp server such as the Playwright MCP server. +Note that it is essential to ensure that the proxy server itself is also stateful. + + +**Methods:** + +#### `clear` + +```python +clear(self) +``` + +Clear all cached clients and force disconnect them. + + +#### `new_stateful` + +```python +new_stateful(self) -> Client[ClientTransportT] +``` + +Create a new stateful proxy client instance with the same configuration. + +Use this method as the client factory for stateful proxy server. + diff --git a/docs/python-sdk/fastmcp-server-providers-transforming.mdx b/docs/python-sdk/fastmcp-server-providers-transforming.mdx new file mode 100644 index 000000000..94952eac2 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-transforming.mdx @@ -0,0 +1,117 @@ +--- +title: transforming +sidebarTitle: transforming +--- + +# `fastmcp.server.providers.transforming` + + +TransformingProvider for applying component transformations. + +This module provides the `TransformingProvider` class that wraps any Provider +and applies transformations like namespace prefixes and tool renames. + + +## Classes + +### `TransformingProvider` + + +Wraps any provider and applies component transformations. + +Users typically use `provider.with_transforms()` rather than instantiating +this class directly. Multiple `.with_transforms()` calls stack - each +creates a new wrapper that composes with the previous. + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self) -> Sequence[Tool] +``` + +List tools with transformations applied. + + +#### `get_tool` + +```python +get_tool(self, name: str) -> Tool | None +``` + +Get tool by transformed name. + + +#### `list_resources` + +```python +list_resources(self) -> Sequence[Resource] +``` + +List resources with URI transformations applied. + + +#### `get_resource` + +```python +get_resource(self, uri: str) -> Resource | None +``` + +Get resource by transformed URI. + + +#### `list_resource_templates` + +```python +list_resource_templates(self) -> Sequence[ResourceTemplate] +``` + +List resource templates with URI transformations applied. + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str) -> ResourceTemplate | None +``` + +Get resource template by transformed URI. + + +#### `list_prompts` + +```python +list_prompts(self) -> Sequence[Prompt] +``` + +List prompts with transformations applied. + + +#### `get_prompt` + +```python +get_prompt(self, name: str) -> Prompt | None +``` + +Get prompt by transformed name. + + +#### `get_tasks` + +```python +get_tasks(self) -> Sequence[FastMCPComponent] +``` + +Get tasks with transformations applied to all components. + + +#### `lifespan` + +```python +lifespan(self) -> AsyncIterator[None] +``` + +Delegate lifespan to wrapped provider. + diff --git a/docs/python-sdk/fastmcp-server-proxy.mdx b/docs/python-sdk/fastmcp-server-proxy.mdx index 9abe6e123..a9200635c 100644 --- a/docs/python-sdk/fastmcp-server-proxy.mdx +++ b/docs/python-sdk/fastmcp-server-proxy.mdx @@ -5,335 +5,10 @@ sidebarTitle: proxy # `fastmcp.server.proxy` -## Functions -### `default_proxy_roots_handler` +Backwards compatibility - import from fastmcp.server.providers.proxy instead. -```python -default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanContextT]) -> RootsList -``` - - -A handler that forwards the list roots request from the remote server to the proxy's connected clients and relays the response back to the remote server. - - -## Classes - -### `ProxyManagerMixin` - - -A mixin for proxy managers to provide a unified client retrieval method. - - -### `ProxyToolManager` - - -A ToolManager that sources its tools from a remote client in addition to local and mounted tools. - - -**Methods:** - -#### `get_tools` - -```python -get_tools(self) -> dict[str, Tool] -``` - -Gets the unfiltered tool inventory including local, mounted, and proxy tools. - - -#### `list_tools` - -```python -list_tools(self) -> list[Tool] -``` - -Gets the filtered list of tools including local, mounted, and proxy tools. - - -#### `call_tool` - -```python -call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult -``` - -Calls a tool, trying local/mounted first, then proxy if not found. - - -### `ProxyResourceManager` - - -A ResourceManager that sources its resources from a remote client in addition to local and mounted resources. - - -**Methods:** - -#### `get_resources` - -```python -get_resources(self) -> dict[str, Resource] -``` - -Gets the unfiltered resource inventory including local, mounted, and proxy resources. - - -#### `get_resource_templates` - -```python -get_resource_templates(self) -> dict[str, ResourceTemplate] -``` - -Gets the unfiltered template inventory including local, mounted, and proxy templates. - - -#### `list_resources` - -```python -list_resources(self) -> list[Resource] -``` - -Gets the filtered list of resources including local, mounted, and proxy resources. - - -#### `list_resource_templates` - -```python -list_resource_templates(self) -> list[ResourceTemplate] -``` - -Gets the filtered list of templates including local, mounted, and proxy templates. - - -#### `read_resource` - -```python -read_resource(self, uri: AnyUrl | str) -> str | bytes -``` - -Reads a resource, trying local/mounted first, then proxy if not found. - - -### `ProxyPromptManager` - - -A PromptManager that sources its prompts from a remote client in addition to local and mounted prompts. - - -**Methods:** - -#### `get_prompts` - -```python -get_prompts(self) -> dict[str, Prompt] -``` - -Gets the unfiltered prompt inventory including local, mounted, and proxy prompts. - - -#### `list_prompts` - -```python -list_prompts(self) -> list[Prompt] -``` - -Gets the filtered list of prompts including local, mounted, and proxy prompts. - - -#### `render_prompt` - -```python -render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult -``` - -Renders a prompt, trying local/mounted first, then proxy if not found. - - -### `ProxyTool` - - -A Tool that represents and executes a tool on a remote server. - - -**Methods:** - -#### `from_mcp_tool` - -```python -from_mcp_tool(cls, client: Client, mcp_tool: mcp.types.Tool) -> ProxyTool -``` - -Factory method to create a ProxyTool from a raw MCP tool schema. - - -#### `run` - -```python -run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResult -``` - -Executes the tool by making a call through the client. - - -### `ProxyResource` - - -A Resource that represents and reads a resource from a remote server. - - -**Methods:** - -#### `from_mcp_resource` - -```python -from_mcp_resource(cls, client: Client, mcp_resource: mcp.types.Resource) -> ProxyResource -``` - -Factory method to create a ProxyResource from a raw MCP resource schema. - - -#### `read` - -```python -read(self) -> str | bytes -``` - -Read the resource content from the remote server. - - -### `ProxyTemplate` - - -A ResourceTemplate that represents and creates resources from a remote server template. - - -**Methods:** - -#### `from_mcp_template` - -```python -from_mcp_template(cls, client: Client, mcp_template: mcp.types.ResourceTemplate) -> ProxyTemplate -``` - -Factory method to create a ProxyTemplate from a raw MCP template schema. - - -#### `create_resource` - -```python -create_resource(self, uri: str, params: dict[str, Any], context: Context | None = None) -> ProxyResource -``` - -Create a resource from the template by calling the remote server. - - -### `ProxyPrompt` - - -A Prompt that represents and renders a prompt from a remote server. - - -**Methods:** - -#### `from_mcp_prompt` - -```python -from_mcp_prompt(cls, client: Client, mcp_prompt: mcp.types.Prompt) -> ProxyPrompt -``` - -Factory method to create a ProxyPrompt from a raw MCP prompt schema. - - -#### `render` - -```python -render(self, arguments: dict[str, Any]) -> list[PromptMessage] -``` - -Render the prompt by making a call through the client. - - -### `FastMCPProxy` - - -A FastMCP server that acts as a proxy to a remote MCP-compliant server. -It uses specialized managers that fulfill requests via a client factory. - - -### `ProxyClient` - - -A proxy client that forwards advanced interactions between a remote MCP server and the proxy's connected clients. -Supports forwarding roots, sampling, elicitation, logging, and progress. - - -**Methods:** - -#### `default_sampling_handler` - -```python -default_sampling_handler(cls, messages: list[mcp.types.SamplingMessage], params: mcp.types.CreateMessageRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> mcp.types.CreateMessageResult -``` - -A handler that forwards the sampling request from the remote server to the proxy's connected clients and relays the response back to the remote server. - - -#### `default_elicitation_handler` - -```python -default_elicitation_handler(cls, message: str, response_type: type, params: mcp.types.ElicitRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> ElicitResult -``` - -A handler that forwards the elicitation request from the remote server to the proxy's connected clients and relays the response back to the remote server. - - -#### `default_log_handler` - -```python -default_log_handler(cls, message: LogMessage) -> None -``` - -A handler that forwards the log notification from the remote server to the proxy's connected clients. - - -#### `default_progress_handler` - -```python -default_progress_handler(cls, progress: float, total: float | None, message: str | None) -> None -``` - -A handler that forwards the progress notification from the remote server to the proxy's connected clients. - - -### `StatefulProxyClient` - - -A proxy client that provides a stateful client factory for the proxy server. - -The stateful proxy client bound its copy to the server session. -And it will be disconnected when the session is exited. - -This is useful to proxy a stateful mcp server such as the Playwright MCP server. -Note that it is essential to ensure that the proxy server itself is also stateful. - - -**Methods:** - -#### `clear` - -```python -clear(self) -``` - -Clear all cached clients and force disconnect them. - - -#### `new_stateful` - -```python -new_stateful(self) -> Client[ClientTransportT] -``` - -Create a new stateful proxy client instance with the same configuration. - -Use this method as the client factory for stateful proxy server. +This module re-exports all proxy-related classes from their new location +at fastmcp.server.providers.proxy. Direct imports from this module are +deprecated and will be removed in a future version. diff --git a/docs/python-sdk/fastmcp-server-sampling-__init__.mdx b/docs/python-sdk/fastmcp-server-sampling-__init__.mdx new file mode 100644 index 000000000..0b0533971 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-sampling-__init__.mdx @@ -0,0 +1,9 @@ +--- +title: __init__ +sidebarTitle: __init__ +--- + +# `fastmcp.server.sampling` + + +Sampling module for FastMCP servers. diff --git a/docs/python-sdk/fastmcp-server-sampling-run.mdx b/docs/python-sdk/fastmcp-server-sampling-run.mdx new file mode 100644 index 000000000..16ea08a8f --- /dev/null +++ b/docs/python-sdk/fastmcp-server-sampling-run.mdx @@ -0,0 +1,116 @@ +--- +title: run +sidebarTitle: run +--- + +# `fastmcp.server.sampling.run` + + +Sampling types and helper functions for FastMCP servers. + +## Functions + +### `determine_handler_mode` + +```python +determine_handler_mode(context: Context, needs_tools: bool) -> bool +``` + + +Determine whether to use fallback handler or client for sampling. + +**Args:** +- `context`: The MCP context. +- `needs_tools`: Whether the sampling request requires tool support. + +**Returns:** +- True if fallback handler should be used, False to use client. + +**Raises:** +- `ValueError`: If client lacks required capability and no fallback configured. + + +### `call_sampling_handler` + +```python +call_sampling_handler(context: Context, messages: list[SamplingMessage]) -> CreateMessageResult | CreateMessageResultWithTools +``` + + +Make LLM call using the fallback handler. + +Note: This function expects the caller (sample_step) to have validated that +sampling_handler is set via determine_handler_mode(). The checks below are +safeguards against internal misuse. + + +### `execute_tools` + +```python +execute_tools(tool_calls: list[ToolUseContent], tool_map: dict[str, SamplingTool], mask_error_details: bool = False) -> list[ToolResultContent] +``` + + +Execute tool calls and return results. + +**Args:** +- `tool_calls`: List of tool use requests from the LLM. +- `tool_map`: Mapping from tool name to SamplingTool. +- `mask_error_details`: If True, mask detailed error messages from tool execution. +When masked, only generic error messages are returned to the LLM. +Tools can explicitly raise ToolError to bypass masking when they want +to provide specific error messages to the LLM. + +**Returns:** +- List of tool result content blocks. + + +## Classes + +### `SamplingResult` + + +Result of a sampling operation. + +**Attributes:** +- `text`: The text representation of the result (raw text or JSON for structured). +- `result`: The typed result (str for text, parsed object for structured output). +- `history`: All messages exchanged during sampling. + + +### `SampleStep` + + +Result of a single sampling call. + +Represents what the LLM returned in this step plus the message history. + + +**Methods:** + +#### `is_tool_use` + +```python +is_tool_use(self) -> bool +``` + +True if the LLM is requesting tool execution. + + +#### `text` + +```python +text(self) -> str | None +``` + +Extract text from the response, if available. + + +#### `tool_calls` + +```python +tool_calls(self) -> list[ToolUseContent] +``` + +Get the list of tool calls from the response. + diff --git a/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx b/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx new file mode 100644 index 000000000..cdcead1a4 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx @@ -0,0 +1,76 @@ +--- +title: sampling_tool +sidebarTitle: sampling_tool +--- + +# `fastmcp.server.sampling.sampling_tool` + + +SamplingTool for use during LLM sampling requests. + +## Classes + +### `SamplingTool` + + +A tool that can be used during LLM sampling. + +SamplingTools bundle a tool's schema (name, description, parameters) with +an executor function, enabling servers to execute agentic workflows where +the LLM can request tool calls during sampling. + +In most cases, pass functions directly to ctx.sample(): + + def search(query: str) -> str: + '''Search the web.''' + return web_search(query) + + result = await context.sample( + messages="Find info about Python", + tools=[search], # Plain functions work directly + ) + +Create a SamplingTool explicitly when you need custom name/description: + + tool = SamplingTool.from_function(search, name="web_search") + + +**Methods:** + +#### `run` + +```python +run(self, arguments: dict[str, Any] | None = None) -> Any +``` + +Execute the tool with the given arguments. + +**Args:** +- `arguments`: Dictionary of arguments to pass to the tool function. + +**Returns:** +- The result of executing the tool function. + + +#### `from_function` + +```python +from_function(cls, fn: Callable[..., Any]) -> SamplingTool +``` + +Create a SamplingTool from a function. + +The function's signature is analyzed to generate a JSON schema for +the tool's parameters. Type hints are used to determine parameter types. + +**Args:** +- `fn`: The function to create a tool from. +- `name`: Optional name override. Defaults to the function's name. +- `description`: Optional description override. Defaults to the function's docstring. + +**Returns:** +- A SamplingTool wrapping the function. + +**Raises:** +- `ValueError`: If the function is a lambda without a name override. + diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx index 8ab3dbc75..535d593e3 100644 --- a/docs/python-sdk/fastmcp-server-server.mdx +++ b/docs/python-sdk/fastmcp-server-server.mdx @@ -10,7 +10,7 @@ FastMCP - A more ergonomic interface for MCP servers. ## Functions -### `default_lifespan` +### `default_lifespan` ```python default_lifespan(server: FastMCP[LifespanResultT]) -> AsyncIterator[Any] @@ -26,151 +26,55 @@ Default lifespan context manager that does nothing. - An empty dictionary as the lifespan result. -### `add_resource_prefix` - -```python -add_resource_prefix(uri: str, prefix: str) -> str -``` - - -Add a prefix to a resource URI using path formatting (resource://prefix/path). - -**Args:** -- `uri`: The original resource URI -- `prefix`: The prefix to add - -**Returns:** -- The resource URI with the prefix added - -**Examples:** - -```python -add_resource_prefix("resource://path/to/resource", "prefix") -"resource://prefix/path/to/resource" -``` -With absolute path: -```python -add_resource_prefix("resource:///absolute/path", "prefix") -"resource://prefix//absolute/path" -``` - -**Raises:** -- `ValueError`: If the URI doesn't match the expected protocol\://path format - - -### `remove_resource_prefix` - -```python -remove_resource_prefix(uri: str, prefix: str) -> str -``` - - -Remove a prefix from a resource URI. - -**Args:** -- `uri`: The resource URI with a prefix -- `prefix`: The prefix to remove - -**Returns:** -- The resource URI with the prefix removed - -**Examples:** - -```python -remove_resource_prefix("resource://prefix/path/to/resource", "prefix") -"resource://path/to/resource" -``` -With absolute path: -```python -remove_resource_prefix("resource://prefix//absolute/path", "prefix") -"resource:///absolute/path" -``` - -**Raises:** -- `ValueError`: If the URI doesn't match the expected protocol\://path format - - -### `has_resource_prefix` - -```python -has_resource_prefix(uri: str, prefix: str) -> bool -``` - - -Check if a resource URI has a specific prefix. - -**Args:** -- `uri`: The resource URI to check -- `prefix`: The prefix to look for - -**Returns:** -- True if the URI has the specified prefix, False otherwise - -**Examples:** - -```python -has_resource_prefix("resource://prefix/path/to/resource", "prefix") -True -``` -With other path: -```python -has_resource_prefix("resource://other/path/to/resource", "prefix") -False -``` - -**Raises:** -- `ValueError`: If the URI doesn't match the expected protocol\://path format - - ## Classes -### `FastMCP` +### `FastMCP` **Methods:** -#### `settings` +#### `settings` ```python settings(self) -> Settings ``` -#### `name` +#### `name` ```python name(self) -> str ``` -#### `instructions` +#### `instructions` ```python instructions(self) -> str | None ``` -#### `instructions` +#### `instructions` ```python instructions(self, value: str | None) -> None ``` -#### `version` +#### `version` ```python version(self) -> str | None ``` -#### `website_url` +#### `website_url` ```python website_url(self) -> str | None ``` -#### `icons` +#### `icons` ```python icons(self) -> list[mcp.types.Icon] ``` -#### `docket` +#### `docket` ```python docket(self) -> Docket | None @@ -181,7 +85,7 @@ Get the Docket instance if Docket support is enabled. Returns None if Docket is not enabled or server hasn't been started yet. -#### `run_async` +#### `run_async` ```python run_async(self, transport: Transport | None = None, show_banner: bool = True, **transport_kwargs: Any) -> None @@ -193,7 +97,7 @@ Run the FastMCP server asynchronously. - `transport`: Transport protocol to use ("stdio", "sse", or "streamable-http") -#### `run` +#### `run` ```python run(self, transport: Transport | None = None, show_banner: bool = True, **transport_kwargs: Any) -> None @@ -202,79 +106,177 @@ run(self, transport: Transport | None = None, show_banner: bool = True, **transp Run the FastMCP server. Note this is a synchronous function. **Args:** -- `transport`: Transport protocol to use ("stdio", "sse", or "streamable-http") +- `transport`: Transport protocol to use ("http", "stdio", "sse", or "streamable-http") -#### `add_middleware` +#### `add_middleware` ```python add_middleware(self, middleware: Middleware) -> None ``` -#### `get_tools` +#### `add_provider` + +```python +add_provider(self, provider: Provider) -> None +``` + +Add a provider for dynamic tools, resources, and prompts. + +Providers are queried in registration order. The first provider to return +a non-None result wins. Static components (registered via decorators) +always take precedence over providers. + +**Args:** +- `provider`: A Provider instance that will provide components dynamically. + + +#### `enable` + +```python +enable(self) -> None +``` + +Enable components by removing from blocklist, or set allowlist with only=True. + +**Args:** +- `keys`: Keys to enable (e.g., ``"tool\:my_tool"``). +- `tags`: Tags to enable - components with these tags will be enabled. +- `only`: If True, switches to allowlist mode - ONLY show these keys/tags. +This clears existing allowlists and sets default visibility to False. + + +#### `disable` + +```python +disable(self) -> None +``` + +Disable components by adding to the blocklist. + +**Args:** +- `keys`: Keys to disable (e.g., ``"tool\:my_tool"``). +- `tags`: Tags to disable - components with these tags will be disabled. + + +#### `get_tools` ```python get_tools(self) -> dict[str, Tool] ``` -Get all tools (unfiltered), including mounted servers, indexed by key. +Get all enabled tools from providers, indexed by name. + +Iterates through all providers (LocalProvider first) and collects tools. +First provider wins for duplicate names. Filters by server blocklist. -#### `get_tool` +#### `get_tool` ```python -get_tool(self, key: str) -> Tool +get_tool(self, name: str) -> Tool ``` -#### `get_resources` +Get an enabled tool by name. + +Iterates through all providers (LocalProvider first) to find the tool. +First provider wins. Returns only if enabled. + + +#### `get_resources` ```python get_resources(self) -> dict[str, Resource] ``` -Get all resources (unfiltered), including mounted servers, indexed by key. +Get all enabled resources from providers, indexed by URI. + +Iterates through all providers (LocalProvider first) and collects resources. +First provider wins for duplicate URIs. Filters by server blocklist. -#### `get_resource` +#### `get_resource` ```python -get_resource(self, key: str) -> Resource +get_resource(self, uri: str) -> Resource ``` -#### `get_resource_templates` +Get an enabled resource by URI. + +Iterates through all providers (LocalProvider first) to find the resource. +First provider wins. Returns only if enabled. + + +#### `get_resource_templates` ```python get_resource_templates(self) -> dict[str, ResourceTemplate] ``` -Get all resource templates (unfiltered), including mounted servers, indexed by key. +Get all enabled resource templates from providers, indexed by uri_template. + +Iterates through all providers (LocalProvider first) and collects templates. +First provider wins for duplicate uri_templates. Filters by server blocklist. -#### `get_resource_template` +#### `get_resource_template` ```python -get_resource_template(self, key: str) -> ResourceTemplate +get_resource_template(self, uri: str) -> ResourceTemplate ``` -Get a registered resource template by key. +Get an enabled resource template that matches the given URI. + +Iterates through all providers (LocalProvider first) to find the template. +First provider wins. Returns only if enabled. -#### `get_prompts` +#### `get_prompts` ```python get_prompts(self) -> dict[str, Prompt] ``` -Get all prompts (unfiltered), including mounted servers, indexed by key. +Get all enabled prompts from providers, indexed by name. + +Iterates through all providers (LocalProvider first) and collects prompts. +First provider wins for duplicate names. Filters by server blocklist. -#### `get_prompt` +#### `get_prompt` ```python -get_prompt(self, key: str) -> Prompt +get_prompt(self, name: str) -> Prompt ``` -#### `custom_route` +Get an enabled prompt by name. + +Iterates through all providers (LocalProvider first) to find the prompt. +First provider wins. Returns only if enabled. + + +#### `get_component` + +```python +get_component(self, key: str) -> Tool | Resource | ResourceTemplate | Prompt +``` + +Get a component by its prefixed key. + +Iterates through all providers (LocalProvider first) to find the component. +First provider wins. + +**Args:** +- `key`: The prefixed key (e.g., "tool\:name", "resource\:uri", "template\:uri"). + +**Returns:** +- The component if found. + +**Raises:** +- `NotFoundError`: If no component is found with the given key. + + +#### `custom_route` ```python custom_route(self, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True) -> Callable[[Callable[[Request], Awaitable[Response]]], Callable[[Request], Awaitable[Response]]] @@ -295,7 +297,7 @@ Starlette's reverse URL lookup feature) - `include_in_schema`: Whether to include in OpenAPI schema, defaults to True -#### `add_tool` +#### `add_tool` ```python add_tool(self, tool: Tool) -> Tool @@ -313,7 +315,7 @@ with the Context type annotation. See the @tool decorator for examples. - The tool instance that was added to the server. -#### `remove_tool` +#### `remove_tool` ```python remove_tool(self, name: str) -> None @@ -328,7 +330,7 @@ Remove a tool from the server. - `NotFoundError`: If the tool is not found -#### `add_tool_transformation` +#### `add_tool_transformation` ```python add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None @@ -337,7 +339,7 @@ add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfi Add a tool transformation. -#### `remove_tool_transformation` +#### `remove_tool_transformation` ```python remove_tool_transformation(self, tool_name: str) -> None @@ -346,22 +348,22 @@ remove_tool_transformation(self, tool_name: str) -> None Remove a tool transformation. -#### `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 +tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool] ``` Decorator to register a tool. @@ -385,10 +387,8 @@ This decorator supports multiple calling patterns: - `output_schema`: Optional JSON schema for the tool's output - `annotations`: Optional annotations about the tool's behavior - `exclude_args`: Optional list of argument names to exclude from the tool schema. -Note\: `exclude_args` will be deprecated in FastMCP 2.14 in favor of dependency -injection with `Depends()` for better lifecycle management. +Deprecated\: Use `Depends()` for dependency injection instead. - `meta`: Optional meta information about the tool -- `enabled`: Optional boolean to enable or disable the tool **Examples:** @@ -416,7 +416,7 @@ server.tool(my_function, name="custom_name") ``` -#### `add_resource` +#### `add_resource` ```python add_resource(self, resource: Resource) -> Resource @@ -431,7 +431,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 @@ -446,7 +446,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] @@ -473,7 +473,6 @@ has parameters, it will be registered as a template resource. - `description`: Optional description of the resource - `mime_type`: Optional MIME type for the resource - `tags`: Optional set of tags for categorizing the resource -- `enabled`: Optional boolean to enable or disable the resource - `annotations`: Optional annotations about the resource's behavior - `meta`: Optional meta information about the resource @@ -506,7 +505,7 @@ async def get_weather(city: str) -> str: ``` -#### `add_prompt` +#### `add_prompt` ```python add_prompt(self, prompt: Prompt) -> Prompt @@ -521,22 +520,22 @@ 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 +prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt] ``` Decorator to register a prompt. @@ -557,7 +556,6 @@ Decorator to register a prompt. name: Optional name for the prompt (keyword-only, alternative to name_or_fn) description: Optional description of what the prompt does tags: Optional set of tags for categorizing the prompt - enabled: Optional boolean to enable or disable the prompt meta: Optional meta information about the prompt Examples: @@ -611,7 +609,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) -> None @@ -624,7 +622,7 @@ Run the server using stdio transport. - `log_level`: Log level for the server -#### `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) -> None @@ -644,7 +642,7 @@ Run the server using HTTP transport. - `stateless_http`: Whether to use stateless HTTP (defaults to settings.stateless_http) -#### `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 @@ -670,13 +668,13 @@ streamable-http transport. - A Starlette application configured with the specified transport -#### `mount` +#### `mount` ```python -mount(self, server: FastMCP[LifespanResultT], prefix: str | None = None, as_proxy: bool | None = None) -> None +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 ``` -Mount another FastMCP server on this server with an optional prefix. +Mount another FastMCP server on this server with an optional namespace. Unlike importing (with import_server), mounting establishes a dynamic connection between servers. When a client interacts with a mounted server's objects through @@ -684,44 +682,40 @@ the parent server, requests are forwarded to the mounted server in real-time. This means changes to the mounted server are immediately reflected when accessed through the parent. -When a server is mounted with a prefix: -- Tools from the mounted server are accessible with prefixed names. - Example: If server has a tool named "get_weather", it will be available as "prefix_get_weather". -- Resources are accessible with prefixed URIs. +When a server is mounted with a namespace: +- Tools from the mounted server are accessible with namespaced names. + Example: If server has a tool named "get_weather", it will be available as "namespace_get_weather". +- Resources are accessible with namespaced URIs. Example: If server has a resource with URI "weather://forecast", it will be available as - "weather://prefix/forecast". -- Templates are accessible with prefixed URI templates. + "weather://namespace/forecast". +- Templates are accessible with namespaced URI templates. Example: If server has a template with URI "weather://location/{id}", it will be available - as "weather://prefix/location/{id}". -- Prompts are accessible with prefixed names. + as "weather://namespace/location/{id}". +- Prompts are accessible with namespaced names. Example: If server has a prompt named "weather_prompt", it will be available as - "prefix_weather_prompt". + "namespace_weather_prompt". -When a server is mounted without a prefix (prefix=None), its tools, resources, templates, +When a server is mounted without a namespace (namespace=None), its tools, resources, templates, and prompts are accessible with their original names. Multiple servers can be mounted -without prefixes, and they will be tried in order until a match is found. +without namespaces, and they will be tried in order until a match is found. -There are two modes for mounting servers: -1. Direct mounting (default when server has no custom lifespan): The parent server - directly accesses the mounted server's objects in-memory for better performance. - In this mode, no client lifecycle events occur on the mounted server, including - lifespan execution. - -2. Proxy mounting (default when server has a custom lifespan): The parent server - treats the mounted server as a separate entity and communicates with it via a - Client transport. This preserves all client-facing behaviors, including lifespan - execution, but with slightly higher overhead. +The mounted server's lifespan is executed when the parent server starts, and its +middleware chain is invoked for all operations (tool calls, resource reads, prompts). **Args:** - `server`: The FastMCP server to mount. -- `prefix`: Optional prefix to use for the mounted server's objects. If None, +- `namespace`: Optional namespace to use for the mounted server's objects. If None, the server's objects are accessible with their original names. -- `as_proxy`: Whether to treat the mounted server as a proxy. If None (default), -automatically determined based on whether the server has a custom lifespan -(True if it has a custom lifespan, False otherwise). +- `as_proxy`: Deprecated. Mounted servers now always have their lifespan and +middleware invoked. To create a proxy server, use FastMCP.as_proxy() +explicitly before mounting. +- `tool_names`: Optional mapping of original tool names to custom names. Use this +to override namespaced names. Keys are the original tool names from the +mounted server. +- `prefix`: Deprecated. Use namespace instead. -#### `import_server` +#### `import_server` ```python import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None @@ -730,6 +724,10 @@ import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) Import the MCP objects from another FastMCP server into this one, optionally with a given prefix. +.. deprecated:: + Use :meth:`mount` instead. ``import_server`` will be removed in a + future version. + Note that when a server is *imported*, its objects are immediately registered to the importing server. This is a one-time operation and future changes to the imported server will not be reflected in the @@ -758,25 +756,55 @@ 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, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI +from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, 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 ``` Create a FastMCP server from an OpenAPI specification. +**Args:** +- `openapi_spec`: OpenAPI schema as a dictionary +- `client`: httpx AsyncClient for making HTTP requests +- `name`: Name for the MCP server +- `route_maps`: Optional list of RouteMap objects defining route mappings +- `route_map_fn`: Optional callable for advanced route type mapping +- `mcp_component_fn`: Optional callable for component customization +- `mcp_names`: Optional dictionary mapping operationId to component names +- `tags`: Optional set of tags to add to all components +- `timeout`: Optional timeout (in seconds) for all requests +- `**settings`: Additional settings passed to FastMCP -#### `from_fastapi` +**Returns:** +- A FastMCP server with an OpenAPIProvider attached. + + +#### `from_fastapi` ```python -from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI +from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | 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 ``` Create a FastMCP server from a FastAPI application. +**Args:** +- `app`: FastAPI application instance +- `name`: Name for the MCP server (defaults to app.title) +- `route_maps`: Optional list of RouteMap objects defining route mappings +- `route_map_fn`: Optional callable for advanced route type mapping +- `mcp_component_fn`: Optional callable for component customization +- `mcp_names`: Optional dictionary mapping operationId to component names +- `httpx_client_kwargs`: Optional kwargs passed to httpx.AsyncClient +- `tags`: Optional set of tags to add to all components +- `timeout`: Optional timeout (in seconds) for all requests +- `**settings`: Additional settings passed to FastMCP -#### `as_proxy` +**Returns:** +- A FastMCP server with an OpenAPIProvider attached. + + +#### `as_proxy` ```python as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy @@ -790,10 +818,8 @@ 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 ``` - -### `MountedServer` diff --git a/docs/python-sdk/fastmcp-server-tasks-config.mdx b/docs/python-sdk/fastmcp-server-tasks-config.mdx index cac8b9254..01ceba275 100644 --- a/docs/python-sdk/fastmcp-server-tasks-config.mdx +++ b/docs/python-sdk/fastmcp-server-tasks-config.mdx @@ -14,7 +14,7 @@ handle task-augmented execution as specified in SEP-1686. ## Classes -### `TaskConfig` +### `TaskConfig` Configuration for MCP background task execution (SEP-1686). @@ -31,7 +31,7 @@ Controls how a component handles task-augmented requests: **Methods:** -#### `from_bool` +#### `from_bool` ```python from_bool(cls, value: bool) -> TaskConfig @@ -46,7 +46,19 @@ Convert boolean task flag to TaskConfig. - TaskConfig with appropriate mode. -#### `validate_function` +#### `supports_tasks` + +```python +supports_tasks(self) -> bool +``` + +Check if this component supports task execution. + +**Returns:** +- True if mode is "optional" or "required", False if "forbidden". + + +#### `validate_function` ```python validate_function(self, fn: Callable[..., Any], name: str) -> None diff --git a/docs/python-sdk/fastmcp-server-tasks-converters.mdx b/docs/python-sdk/fastmcp-server-tasks-converters.mdx deleted file mode 100644 index 94118c394..000000000 --- a/docs/python-sdk/fastmcp-server-tasks-converters.mdx +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: converters -sidebarTitle: converters ---- - -# `fastmcp.server.tasks.converters` - - -SEP-1686 task result converters. - -Converts raw task return values to MCP result types. - - -## Functions - -### `convert_tool_result` - -```python -convert_tool_result(server: FastMCP, raw_value: Any, tool_name: str, client_task_id: str) -> mcp.types.CallToolResult -``` - - -Convert raw tool return value to MCP CallToolResult. - -Replicates the serialization logic from tool.run() to properly handle -output_schema, structured content, etc. - -**Args:** -- `server`: FastMCP server instance -- `raw_value`: The raw return value from user's tool function -- `tool_name`: Name of the tool (to get output_schema and serializer) -- `client_task_id`: Client task ID for related-task metadata - -**Returns:** -- CallToolResult with properly formatted content and structured content - - -### `convert_prompt_result` - -```python -convert_prompt_result(server: FastMCP, raw_value: Any, prompt_name: str, client_task_id: str) -> mcp.types.GetPromptResult -``` - - -Convert raw prompt return value to MCP GetPromptResult. - -The user function returns raw values (strings, dicts, lists) that need -to be converted to PromptMessage objects. - -**Args:** -- `server`: FastMCP server instance -- `raw_value`: The raw return value from user's prompt function -- `prompt_name`: Name of the prompt -- `client_task_id`: Client task ID for related-task metadata - -**Returns:** -- GetPromptResult with properly formatted messages - - -### `convert_resource_result` - -```python -convert_resource_result(server: FastMCP, raw_value: Any, uri: str, client_task_id: str) -> dict[str, Any] -``` - - -Convert raw resource return value to MCP resource contents dict. - -**Args:** -- `server`: FastMCP server instance -- `raw_value`: The raw return value from user's resource function (str or bytes) -- `uri`: Resource URI (for the contents response) -- `client_task_id`: Client task ID for related-task metadata - -**Returns:** -- Dict with 'contents' key containing list of resource contents - diff --git a/docs/python-sdk/fastmcp-server-tasks-handlers.mdx b/docs/python-sdk/fastmcp-server-tasks-handlers.mdx index 423f3bdea..e633a193c 100644 --- a/docs/python-sdk/fastmcp-server-tasks-handlers.mdx +++ b/docs/python-sdk/fastmcp-server-tasks-handlers.mdx @@ -13,66 +13,31 @@ Handles queuing tool/prompt/resource executions to Docket as background tasks. ## Functions -### `handle_tool_as_task` +### `submit_to_docket` ```python -handle_tool_as_task(server: FastMCP, tool_name: str, arguments: dict[str, Any], task_meta: dict[str, Any]) -> mcp.types.CallToolResult +submit_to_docket(task_type: Literal['tool', 'resource', 'template', 'prompt'], key: str, component: Tool | Resource | ResourceTemplate | Prompt, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult ``` -Handle tool execution as background task (SEP-1686). +Submit any component to Docket for background execution (SEP-1686). -Queues the user's actual function to Docket (preserving signature for DI), -stores raw return values, converts to MCP types on retrieval. +Unified handler for all component types. Called by component's internal +methods (_run, _read, _render) when task metadata is present and mode allows. + +Queues the component's method to Docket, stores raw return values, +and converts to MCP types on retrieval. + +Note: Client-requested TTL in task_meta is intentionally ignored. +Server-side TTL policy (docket.execution_ttl) takes precedence for +consistent task lifecycle management. **Args:** -- `server`: FastMCP server instance -- `tool_name`: Name of the tool to execute -- `arguments`: Tool arguments -- `task_meta`: Task metadata from request (contains ttl) +- `task_type`: Component type for task key construction +- `key`: The component key as seen by MCP layer (with namespace prefix) +- `component`: The component instance (Tool, Resource, ResourceTemplate, Prompt) +- `arguments`: Arguments/params (None for Resource which has no args) **Returns:** -- Task stub with task metadata in _meta - - -### `handle_prompt_as_task` - -```python -handle_prompt_as_task(server: FastMCP, prompt_name: str, arguments: dict[str, Any] | None, task_meta: dict[str, Any]) -> mcp.types.GetPromptResult -``` - - -Handle prompt execution as background task (SEP-1686). - -Queues the user's actual function to Docket (preserving signature for DI). - -**Args:** -- `server`: FastMCP server instance -- `prompt_name`: Name of the prompt to execute -- `arguments`: Prompt arguments -- `task_meta`: Task metadata from request (contains ttl) - -**Returns:** -- Task stub with task metadata in _meta - - -### `handle_resource_as_task` - -```python -handle_resource_as_task(server: FastMCP, uri: str, resource, task_meta: dict[str, Any]) -> mcp.types.ServerResult -``` - - -Handle resource read as background task (SEP-1686). - -Queues the user's actual function to Docket. - -**Args:** -- `server`: FastMCP server instance -- `uri`: Resource URI -- `resource`: Resource or ResourceTemplate object -- `task_meta`: Task metadata from request (contains ttl) - -**Returns:** -- ServerResult with ReadResourceResult stub +- Task stub with proper Task object diff --git a/docs/python-sdk/fastmcp-server-tasks-protocol.mdx b/docs/python-sdk/fastmcp-server-tasks-requests.mdx similarity index 75% rename from docs/python-sdk/fastmcp-server-tasks-protocol.mdx rename to docs/python-sdk/fastmcp-server-tasks-requests.mdx index 6d355b824..912fc9cc5 100644 --- a/docs/python-sdk/fastmcp-server-tasks-protocol.mdx +++ b/docs/python-sdk/fastmcp-server-tasks-requests.mdx @@ -1,19 +1,20 @@ --- -title: protocol -sidebarTitle: protocol +title: requests +sidebarTitle: requests --- -# `fastmcp.server.tasks.protocol` +# `fastmcp.server.tasks.requests` -SEP-1686 task protocol handlers. +SEP-1686 task request handlers. -Implements MCP task protocol methods: tasks/get, tasks/result, tasks/list, tasks/cancel, tasks/delete. +Handles MCP task protocol requests: tasks/get, tasks/result, tasks/list, tasks/cancel. +These handlers query and manage existing tasks (contrast with handlers.py which creates tasks). ## Functions -### `tasks_get_handler` +### `tasks_get_handler` ```python tasks_get_handler(server: FastMCP, params: dict[str, Any]) -> GetTaskResult @@ -30,7 +31,7 @@ Handle MCP 'tasks/get' request (SEP-1686). - Task status response with spec-compliant fields -### `tasks_result_handler` +### `tasks_result_handler` ```python tasks_result_handler(server: FastMCP, params: dict[str, Any]) -> Any @@ -49,7 +50,7 @@ Converts raw task return values to MCP types based on task type. - MCP result (CallToolResult, GetPromptResult, or ReadResourceResult) -### `tasks_list_handler` +### `tasks_list_handler` ```python tasks_list_handler(server: FastMCP, params: dict[str, Any]) -> ListTasksResult @@ -68,7 +69,7 @@ Note: With client-side tracking, this returns minimal info. - Response with tasks list and pagination -### `tasks_cancel_handler` +### `tasks_cancel_handler` ```python tasks_cancel_handler(server: FastMCP, params: dict[str, Any]) -> CancelTaskResult diff --git a/docs/python-sdk/fastmcp-server-tasks-routing.mdx b/docs/python-sdk/fastmcp-server-tasks-routing.mdx new file mode 100644 index 000000000..7402e77ff --- /dev/null +++ b/docs/python-sdk/fastmcp-server-tasks-routing.mdx @@ -0,0 +1,37 @@ +--- +title: routing +sidebarTitle: routing +--- + +# `fastmcp.server.tasks.routing` + + +Task routing helper for MCP components. + +Provides unified task mode enforcement and docket routing logic. + + +## Functions + +### `check_background_task` + +```python +check_background_task(component: Tool | Resource | ResourceTemplate | Prompt, task_type: TaskType, key: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult | None +``` + + +Check task mode and submit to background if requested. + +**Args:** +- `component`: The MCP component +- `task_type`: Type of task ("tool", "resource", "template", "prompt") +- `key`: Docket registration key (caller resolves from contextvar + fallback) +- `arguments`: Arguments for tool/prompt/template execution + +**Returns:** +- CreateTaskResult if submitted to docket, None for sync execution + +**Raises:** +- `McpError`: If mode="required" but no task metadata, or mode="forbidden" + but task metadata is present + diff --git a/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx b/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx index 78f06cf81..1b4331212 100644 --- a/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx +++ b/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx @@ -17,7 +17,7 @@ to clients when their tasks change state. ### `subscribe_to_task_updates` ```python -subscribe_to_task_updates(task_id: str, task_key: str, session: ServerSession, docket: Docket) -> None +subscribe_to_task_updates(task_id: str, task_key: str, session: ServerSession, docket: Docket, poll_interval_ms: int = 5000) -> None ``` @@ -32,4 +32,5 @@ client polling frequency. - `task_key`: Internal Docket execution key (includes session, type, component) - `session`: MCP ServerSession for sending notifications - `docket`: Docket instance for subscribing to execution events +- `poll_interval_ms`: Poll interval in milliseconds to include in notifications diff --git a/docs/python-sdk/fastmcp-tools-tool.mdx b/docs/python-sdk/fastmcp-tools-tool.mdx index d6fc3accc..141e4c942 100644 --- a/docs/python-sdk/fastmcp-tools-tool.mdx +++ b/docs/python-sdk/fastmcp-tools-tool.mdx @@ -7,7 +7,7 @@ sidebarTitle: tool ## Functions -### `default_serializer` +### `default_serializer` ```python default_serializer(data: Any) -> str @@ -15,17 +15,17 @@ default_serializer(data: Any) -> str ## Classes -### `ToolResult` +### `ToolResult` **Methods:** -#### `to_mcp_result` +#### `to_mcp_result` ```python to_mcp_result(self) -> list[ContentBlock] | tuple[list[ContentBlock], dict[str, Any]] | CallToolResult ``` -### `Tool` +### `Tool` Internal tool registration info. @@ -33,19 +33,7 @@ Internal tool registration info. **Methods:** -#### `enable` - -```python -enable(self) -> None -``` - -#### `disable` - -```python -disable(self) -> None -``` - -#### `to_mcp_tool` +#### `to_mcp_tool` ```python to_mcp_tool(self, **overrides: Any) -> MCPTool @@ -54,16 +42,16 @@ to_mcp_tool(self, **overrides: Any) -> MCPTool Convert the FastMCP tool to an MCP tool. -#### `from_function` +#### `from_function` ```python -from_function(fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None, task: bool | TaskConfig | None = None) -> FunctionTool +from_function(fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionTool ``` Create a Tool from a function. -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any]) -> ToolResult @@ -78,17 +66,54 @@ implemented by subclasses. (list of ContentBlocks, dict of structured output). -#### `from_tool` +#### `convert_result` + +```python +convert_result(self, raw_value: Any) -> ToolResult +``` + +Convert a raw result to ToolResult. + +Handles ToolResult passthrough and converts raw values using the tool's +attributes (serializer, output_schema) for proper conversion. + + +#### `register_with_docket` + +```python +register_with_docket(self, docket: Docket) -> None +``` + +Register this tool with docket for background execution. + + +#### `add_to_docket` + +```python +add_to_docket(self, docket: Docket, arguments: dict[str, Any], **kwargs: Any) -> Execution +``` + +Schedule this tool for background execution via docket. + +**Args:** +- `docket`: The Docket instance +- `arguments`: Tool arguments +- `fn_key`: Function lookup key in Docket registry (defaults to self.key) +- `task_key`: Redis storage key for the result +- `**kwargs`: Additional kwargs passed to docket.add() + + +#### `from_tool` ```python from_tool(cls, tool: Tool) -> TransformedTool ``` -### `FunctionTool` +### `FunctionTool` **Methods:** -#### `to_mcp_tool` +#### `to_mcp_tool` ```python to_mcp_tool(self, **overrides: Any) -> MCPTool @@ -99,16 +124,16 @@ Convert the FastMCP tool to an MCP tool. Extends the base implementation to add task execution mode if enabled. -#### `from_function` +#### `from_function` ```python -from_function(cls, fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None, task: bool | TaskConfig | None = None) -> FunctionTool +from_function(cls, fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, icons: list[Icon] | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: ToolResultSerializerType | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionTool ``` Create a Tool from a function. -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any]) -> ToolResult @@ -117,11 +142,41 @@ run(self, arguments: dict[str, Any]) -> ToolResult Run the tool with arguments. -### `ParsedFunction` +#### `register_with_docket` + +```python +register_with_docket(self, docket: Docket) -> None +``` + +Register this tool with docket for background execution. + +FunctionTool registers the underlying function, which has the user's +Depends parameters for docket to resolve. + + +#### `add_to_docket` + +```python +add_to_docket(self, docket: Docket, arguments: dict[str, Any], **kwargs: Any) -> Execution +``` + +Schedule this tool for background execution via docket. + +FunctionTool splats the arguments dict since .fn expects **kwargs. + +**Args:** +- `docket`: The Docket instance +- `arguments`: Tool arguments +- `fn_key`: Function lookup key in Docket registry (defaults to self.key) +- `task_key`: Redis storage key for the result +- `**kwargs`: Additional kwargs passed to docket.add() + + +### `ParsedFunction` **Methods:** -#### `from_function` +#### `from_function` ```python from_function(cls, fn: Callable[..., Any], exclude_args: list[str] | None = None, validate: bool = True, wrap_non_object_output_schema: bool = True) -> ParsedFunction diff --git a/docs/python-sdk/fastmcp-tools-tool_manager.mdx b/docs/python-sdk/fastmcp-tools-tool_manager.mdx deleted file mode 100644 index 592b18d58..000000000 --- a/docs/python-sdk/fastmcp-tools-tool_manager.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: tool_manager -sidebarTitle: tool_manager ---- - -# `fastmcp.tools.tool_manager` - -## Classes - -### `ToolManager` - - -Manages FastMCP tools. - - -**Methods:** - -#### `has_tool` - -```python -has_tool(self, key: str) -> bool -``` - -Check if a tool exists. - - -#### `get_tool` - -```python -get_tool(self, key: str) -> Tool -``` - -Get tool by key. - - -#### `get_tools` - -```python -get_tools(self) -> dict[str, Tool] -``` - -Gets the complete, unfiltered inventory of local tools. - - -#### `add_tool_from_fn` - -```python -add_tool_from_fn(self, fn: Callable[..., Any], name: str | None = None, description: str | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, serializer: Callable[[Any], str] | None = None, exclude_args: list[str] | None = None) -> Tool -``` - -Add a tool to the server. - - -#### `add_tool` - -```python -add_tool(self, tool: Tool) -> Tool -``` - -Register a tool with the server. - - -#### `add_tool_transformation` - -```python -add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None -``` - -Add a tool transformation. - - -#### `get_tool_transformation` - -```python -get_tool_transformation(self, tool_name: str) -> ToolTransformConfig | None -``` - -Get a tool transformation. - - -#### `remove_tool_transformation` - -```python -remove_tool_transformation(self, tool_name: str) -> None -``` - -Remove a tool transformation. - - -#### `remove_tool` - -```python -remove_tool(self, key: str) -> None -``` - -Remove a tool from the server. - -**Args:** -- `key`: The key of the tool to remove - -**Raises:** -- `NotFoundError`: If the tool is not found - - -#### `call_tool` - -```python -call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult -``` - -Internal API for servers: Finds and calls a tool, respecting the -filtered protocol path. - diff --git a/docs/python-sdk/fastmcp-tools-tool_transform.mdx b/docs/python-sdk/fastmcp-tools-tool_transform.mdx index 8586fb4fc..ba171fcb7 100644 --- a/docs/python-sdk/fastmcp-tools-tool_transform.mdx +++ b/docs/python-sdk/fastmcp-tools-tool_transform.mdx @@ -62,7 +62,7 @@ y=2)` will call the parent tool with `x=1` and `y=2`. - `RuntimeError`: If called outside a transformed tool context. -### `apply_transformations_to_tools` +### `apply_transformations_to_tools` ```python apply_transformations_to_tools(tools: dict[str, Tool], transformations: dict[str, ToolTransformConfig]) -> dict[str, Tool] @@ -72,6 +72,9 @@ apply_transformations_to_tools(tools: dict[str, Tool], transformations: dict[str Apply a list of transformations to a list of tools. Tools that do not have any transformations are left unchanged. +Note: tools dict is keyed by prefixed key (e.g., "tool:my_tool"), +but transformations are keyed by tool name (e.g., "my_tool"). + ## Classes @@ -84,6 +87,16 @@ This class allows fine-grained control over how individual arguments are transfo when creating a new tool from an existing one. You can rename arguments, change their descriptions, add default values, or hide them from clients while passing constants. +**Attributes:** +- `name`: New name for the argument. Use None to keep original name, or ... for no change. +- `description`: New description for the argument. Use None to remove description, or ... for no change. +- `default`: New default value for the argument. Use ... for no change. +- `default_factory`: Callable that returns a default value. Cannot be used with default. +- `type`: New type for the argument. Use ... for no change. +- `hide`: If True, hide this argument from clients but pass a constant value to parent. +- `required`: If True, make argument required (remove default). Use ... for no change. +- `examples`: Examples for the argument. Use ... for no change. + **Examples:** Rename argument 'old_name' to 'new_name' @@ -168,6 +181,13 @@ or can include a custom function that uses forward() to call the parent tool with transformed arguments. Output schemas and structured outputs are automatically inherited from the parent tool but can be overridden or disabled. +**Attributes:** +- `parent_tool`: The original tool that this tool was transformed from. +- `fn`: The function to execute when this tool is called (either the forwarding +function for pure transformations or a custom user function). +- `forwarding_fn`: Internal function that handles argument transformation and +validation when forward() is called from custom functions. + **Methods:** @@ -193,7 +213,7 @@ functions. #### `from_tool` ```python -from_tool(cls, tool: Tool, name: str | None = None, title: str | NotSetT | None = NotSet, description: str | NotSetT | None = NotSet, tags: set[str] | None = None, transform_fn: Callable[..., Any] | None = None, transform_args: dict[str, ArgTransform] | None = None, annotations: ToolAnnotations | NotSetT | None = NotSet, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: Callable[[Any], str] | NotSetT | None = NotSet, meta: dict[str, Any] | NotSetT | None = NotSet, enabled: bool | None = None) -> TransformedTool +from_tool(cls, tool: Tool, name: str | None = None, title: str | NotSetT | None = NotSet, description: str | NotSetT | None = NotSet, tags: set[str] | None = None, transform_fn: Callable[..., Any] | None = None, transform_args: dict[str, ArgTransform] | None = None, annotations: ToolAnnotations | NotSetT | None = NotSet, output_schema: dict[str, Any] | NotSetT | None = NotSet, serializer: Callable[[Any], str] | NotSetT | None = NotSet, meta: dict[str, Any] | NotSetT | None = NotSet) -> TransformedTool ``` Create a transformed tool from a parent tool. @@ -272,7 +292,7 @@ async def custom_output(**kwargs) -> ToolResult: ``` -### `ToolTransformConfig` +### `ToolTransformConfig` Provides a way to transform a tool. @@ -280,7 +300,7 @@ Provides a way to transform a tool. **Methods:** -#### `apply` +#### `apply` ```python apply(self, tool: Tool) -> TransformedTool diff --git a/docs/python-sdk/fastmcp-utilities-components.mdx b/docs/python-sdk/fastmcp-utilities-components.mdx index d27c20282..08879acdf 100644 --- a/docs/python-sdk/fastmcp-utilities-components.mdx +++ b/docs/python-sdk/fastmcp-utilities-components.mdx @@ -7,9 +7,9 @@ sidebarTitle: components ## Classes -### `FastMCPMeta` +### `FastMCPMeta` -### `FastMCPComponent` +### `FastMCPComponent` Base class for FastMCP tools, prompts, resources, and resource templates. @@ -17,19 +17,36 @@ Base class for FastMCP tools, prompts, resources, and resource templates. **Methods:** -#### `key` +#### `make_key` + +```python +make_key(cls, identifier: str) -> str +``` + +Construct the lookup key for this component type. + +**Args:** +- `identifier`: The raw identifier (name for tools/prompts, uri for resources) + +**Returns:** +- A prefixed key like "tool:name" or "resource:uri" + + +#### `key` ```python key(self) -> str ``` -The key of the component. This is used for internal bookkeeping -and may reflect e.g. prefixes or other identifiers. You should not depend on -keys having a certain value, as the same tool loaded from different -hierarchies of servers may have different keys. +The globally unique lookup key for this component. + +Format: "{key_prefix}:{identifier}" e.g. "tool:my_tool", "resource:file://x.txt" + +Subclasses should override this to use their specific identifier. +Base implementation uses name. -#### `get_meta` +#### `get_meta` ```python get_meta(self, include_fastmcp_meta: bool | None = None) -> dict[str, Any] | None @@ -41,39 +58,25 @@ If include_fastmcp_meta is True, a `_fastmcp` key will be added to the meta, containing a `tags` field with the tags of the component. -#### `model_copy` - -```python -model_copy(self) -> Self -``` - -Create a copy of the component. - -**Args:** -- `update`: A dictionary of fields to update. -- `deep`: Whether to deep copy the component. -- `key`: The key to use for the copy. - - -#### `enable` +#### `enable` ```python enable(self) -> None ``` -Enable the component. +Removed in 3.0. Use server.enable(keys=[...]) instead. -#### `disable` +#### `disable` ```python disable(self) -> None ``` -Disable the component. +Removed in 3.0. Use server.disable(keys=[...]) instead. -#### `copy` +#### `copy` ```python copy(self) -> Self @@ -82,40 +85,31 @@ copy(self) -> Self Create a copy of the component. -### `MirroredComponent` - - -Base class for components that are mirrored from a remote server. - -Mirrored components cannot be enabled or disabled directly. Call copy() first -to create a local version you can modify. - - -**Methods:** - -#### `enable` +#### `register_with_docket` ```python -enable(self) -> None +register_with_docket(self, docket: Docket) -> None ``` -Enable the component. +Register this component with docket for background execution. + +No-ops if task_config.mode is "forbidden". Subclasses override to +register their callable (self.run, self.read, self.render, or self.fn). -#### `disable` +#### `add_to_docket` ```python -disable(self) -> None +add_to_docket(self, docket: Docket, *args: Any, **kwargs: Any) -> Execution ``` -Disable the component. +Schedule this component for background execution via docket. +Subclasses override this to handle their specific calling conventions: +- Tool: add_to_docket(docket, arguments: dict, **kwargs) +- Resource: add_to_docket(docket, **kwargs) +- ResourceTemplate: add_to_docket(docket, params: dict, **kwargs) +- Prompt: add_to_docket(docket, arguments: dict | None, **kwargs) -#### `copy` - -```python -copy(self) -> Self -``` - -Create a copy of the component that can be modified. +The **kwargs are passed through to docket.add() (e.g., key=task_key). diff --git a/docs/python-sdk/fastmcp-utilities-inspect.mdx b/docs/python-sdk/fastmcp-utilities-inspect.mdx index ab1c8744c..01bc77b39 100644 --- a/docs/python-sdk/fastmcp-utilities-inspect.mdx +++ b/docs/python-sdk/fastmcp-utilities-inspect.mdx @@ -10,7 +10,7 @@ Utilities for inspecting FastMCP instances. ## Functions -### `inspect_fastmcp_v2` +### `inspect_fastmcp_v2` ```python inspect_fastmcp_v2(mcp: FastMCP[Any]) -> FastMCPInfo @@ -26,7 +26,7 @@ Extract information from a FastMCP v2.x instance. - FastMCPInfo dataclass containing the extracted information -### `inspect_fastmcp_v1` +### `inspect_fastmcp_v1` ```python inspect_fastmcp_v1(mcp: FastMCP1x) -> FastMCPInfo @@ -42,7 +42,7 @@ Extract information from a FastMCP v1.x instance using a Client. - FastMCPInfo dataclass containing the extracted information -### `inspect_fastmcp` +### `inspect_fastmcp` ```python inspect_fastmcp(mcp: FastMCP[Any] | FastMCP1x) -> FastMCPInfo @@ -61,7 +61,7 @@ and uses the appropriate extraction method. - FastMCPInfo dataclass containing the extracted information -### `format_fastmcp_info` +### `format_fastmcp_info` ```python format_fastmcp_info(info: FastMCPInfo) -> bytes @@ -73,7 +73,7 @@ Format FastMCPInfo as FastMCP-specific JSON. This includes FastMCP-specific fields like tags, enabled, annotations, etc. -### `format_mcp_info` +### `format_mcp_info` ```python format_mcp_info(mcp: FastMCP[Any] | FastMCP1x) -> bytes @@ -86,7 +86,7 @@ Uses Client to get the standard MCP protocol format with camelCase fields. Includes version metadata at the top level. -### `format_info` +### `format_info` ```python format_info(mcp: FastMCP[Any] | FastMCP1x, format: InspectFormat | Literal['fastmcp', 'mcp'], info: FastMCPInfo | None = None) -> bytes @@ -112,31 +112,31 @@ Format server information according to the specified format. Information about a tool. -### `PromptInfo` +### `PromptInfo` Information about a prompt. -### `ResourceInfo` +### `ResourceInfo` Information about a resource. -### `TemplateInfo` +### `TemplateInfo` Information about a resource template. -### `FastMCPInfo` +### `FastMCPInfo` Information extracted from a FastMCP instance. -### `InspectFormat` +### `InspectFormat` Output format for inspect command. diff --git a/docs/python-sdk/fastmcp-utilities-visibility.mdx b/docs/python-sdk/fastmcp-utilities-visibility.mdx new file mode 100644 index 000000000..ade14110e --- /dev/null +++ b/docs/python-sdk/fastmcp-utilities-visibility.mdx @@ -0,0 +1,86 @@ +--- +title: visibility +sidebarTitle: visibility +--- + +# `fastmcp.utilities.visibility` + + +Visibility filtering for FastMCP components. + +This module provides the VisibilityFilter class which handles blocklist and +allowlist logic for controlling component visibility at both the provider +and server levels. + + +## Classes + +### `VisibilityFilter` + + +Manages component visibility with blocklist and allowlist support. + +Both servers and providers use this class to control which components +are visible. Visibility is hierarchical: if a component is hidden at +any level (provider or server), it's hidden to the client. + +Filtering logic (blocklist wins over allowlist): +1. If component key is in _disabled_keys → HIDDEN +2. If any component tag is in _disabled_tags → HIDDEN +3. If _default_enabled is False and component not in allowlist → HIDDEN +4. Otherwise → VISIBLE + +The `only=True` flag on enable() switches to allowlist mode: +- Sets _default_enabled = False +- Clears existing allowlists +- Adds specified keys/tags to allowlist + + +**Methods:** + +#### `disable` + +```python +disable(self) -> None +``` + +Add to blocklist (hide components). + +**Args:** +- `keys`: Component keys to hide (e.g., "tool\:my_tool", "resource\:file\://x") +- `tags`: Tags to hide - any component with these tags will be hidden + + +#### `enable` + +```python +enable(self) -> None +``` + +Remove from blocklist, or set allowlist with only=True. + +**Args:** +- `keys`: Component keys to show +- `tags`: Tags to show +- `only`: If True, switches to allowlist mode - ONLY show these keys/tags. +This sets default visibility to False, clears existing allowlists, +and adds the specified keys/tags to the allowlist. + + +#### `reset` + +```python +reset(self) -> None +``` + +Reset to default state (everything enabled, no filters). + + +#### `is_enabled` + +```python +is_enabled(self, component: FastMCPComponent) -> bool +``` + +Check if component is enabled. Blocklist wins over allowlist. +