From 1700bc360bb37554f16168f0c6b981f84d4244a7 Mon Sep 17 00:00:00 2001 From: "marvin-context-protocol[bot]" <225465937+marvin-context-protocol[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 21:28:11 -0500 Subject: [PATCH] chore: Update SDK documentation (#2834) Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com> --- docs/docs.json | 50 ++- docs/python-sdk/fastmcp-cli-cli.mdx | 12 +- docs/python-sdk/fastmcp-client-client.mdx | 88 ++--- docs/python-sdk/fastmcp-client-telemetry.mdx | 23 ++ docs/python-sdk/fastmcp-client-transports.mdx | 63 ++-- docs/python-sdk/fastmcp-decorators.mdx | 39 +++ docs/python-sdk/fastmcp-dependencies.mdx | 4 + docs/python-sdk/fastmcp-exceptions.mdx | 6 + docs/python-sdk/fastmcp-fs-__init__.mdx | 43 --- docs/python-sdk/fastmcp-fs-decorators.mdx | 156 --------- docs/python-sdk/fastmcp-fs-provider.mdx | 111 ------ docs/python-sdk/fastmcp-mcp_config.mdx | 32 +- .../fastmcp-prompts-function_prompt.mdx | 106 ++++++ docs/python-sdk/fastmcp-prompts-prompt.mdx | 85 +---- .../fastmcp-resources-function_resource.mdx | 93 +++++ .../python-sdk/fastmcp-resources-resource.mdx | 75 +--- .../python-sdk/fastmcp-resources-template.mdx | 52 +-- .../fastmcp-server-auth-authorization.mdx | 139 ++++++++ ...cp-server-auth-providers-introspection.mdx | 14 +- docs/python-sdk/fastmcp-server-context.mdx | 143 +++++--- .../fastmcp-server-dependencies.mdx | 321 +++++++++++++----- .../python-sdk/fastmcp-server-elicitation.mdx | 6 +- docs/python-sdk/fastmcp-server-http.mdx | 18 +- docs/python-sdk/fastmcp-server-low_level.mdx | 19 +- ...astmcp-server-middleware-authorization.mdx | 116 +++++++ .../fastmcp-server-middleware-ping.mdx | 32 ++ .../fastmcp-server-providers-aggregate.mdx | 139 ++++++++ .../fastmcp-server-providers-base.mdx | 137 ++++---- ...tmcp-server-providers-fastmcp_provider.mdx | 118 ++++--- .../fastmcp-server-providers-filesystem.mdx | 128 +++++++ ...server-providers-filesystem_discovery.mdx} | 29 +- ...astmcp-server-providers-local_provider.mdx | 189 ++++++----- ...tmcp-server-providers-openapi-provider.mdx | 24 +- .../fastmcp-server-providers-proxy.mdx | 88 +++-- .../fastmcp-server-providers-transforming.mdx | 117 ------- docs/python-sdk/fastmcp-server-server.mdx | 287 +++++++++------- .../fastmcp-server-tasks-capabilities.mdx | 15 +- .../fastmcp-server-tasks-config.mdx | 19 +- .../fastmcp-server-tasks-requests.mdx | 10 +- .../fastmcp-server-tasks-subscriptions.mdx | 4 +- docs/python-sdk/fastmcp-server-telemetry.mdx | 56 +++ .../fastmcp-server-transforms-__init__.mdx | 196 +++++++++++ .../fastmcp-server-transforms-namespace.mdx | 96 ++++++ ...stmcp-server-transforms-tool_transform.mdx | 40 +++ ...stmcp-server-transforms-version_filter.mdx | 85 +++++ .../fastmcp-server-transforms-visibility.mdx | 158 +++++++++ docs/python-sdk/fastmcp-telemetry.mdx | 95 ++++++ .../fastmcp-tools-function_parsing.mdx | 21 ++ .../fastmcp-tools-function_tool.mdx | 108 ++++++ docs/python-sdk/fastmcp-tools-tool.mdx | 95 +----- .../fastmcp-tools-tool_transform.mdx | 25 +- .../fastmcp-utilities-async_utils.mdx | 15 +- docs/python-sdk/fastmcp-utilities-cli.mdx | 6 +- .../fastmcp-utilities-components.mdx | 35 +- .../fastmcp-utilities-json_schema_type.mdx | 4 +- docs/python-sdk/fastmcp-utilities-logging.mdx | 2 +- .../fastmcp-utilities-version_check.mdx | 40 +++ .../python-sdk/fastmcp-utilities-versions.mdx | 190 +++++++++++ .../fastmcp-utilities-visibility.mdx | 86 ----- 59 files changed, 3060 insertions(+), 1443 deletions(-) create mode 100644 docs/python-sdk/fastmcp-client-telemetry.mdx create mode 100644 docs/python-sdk/fastmcp-decorators.mdx delete mode 100644 docs/python-sdk/fastmcp-fs-__init__.mdx delete mode 100644 docs/python-sdk/fastmcp-fs-decorators.mdx delete mode 100644 docs/python-sdk/fastmcp-fs-provider.mdx create mode 100644 docs/python-sdk/fastmcp-prompts-function_prompt.mdx create mode 100644 docs/python-sdk/fastmcp-resources-function_resource.mdx create mode 100644 docs/python-sdk/fastmcp-server-auth-authorization.mdx create mode 100644 docs/python-sdk/fastmcp-server-middleware-authorization.mdx create mode 100644 docs/python-sdk/fastmcp-server-middleware-ping.mdx create mode 100644 docs/python-sdk/fastmcp-server-providers-aggregate.mdx create mode 100644 docs/python-sdk/fastmcp-server-providers-filesystem.mdx rename docs/python-sdk/{fastmcp-fs-discovery.mdx => fastmcp-server-providers-filesystem_discovery.mdx} (55%) delete mode 100644 docs/python-sdk/fastmcp-server-providers-transforming.mdx create mode 100644 docs/python-sdk/fastmcp-server-telemetry.mdx create mode 100644 docs/python-sdk/fastmcp-server-transforms-__init__.mdx create mode 100644 docs/python-sdk/fastmcp-server-transforms-namespace.mdx create mode 100644 docs/python-sdk/fastmcp-server-transforms-tool_transform.mdx create mode 100644 docs/python-sdk/fastmcp-server-transforms-version_filter.mdx create mode 100644 docs/python-sdk/fastmcp-server-transforms-visibility.mdx create mode 100644 docs/python-sdk/fastmcp-telemetry.mdx create mode 100644 docs/python-sdk/fastmcp-tools-function_parsing.mdx create mode 100644 docs/python-sdk/fastmcp-tools-function_tool.mdx create mode 100644 docs/python-sdk/fastmcp-utilities-version_check.mdx create mode 100644 docs/python-sdk/fastmcp-utilities-versions.mdx delete mode 100644 docs/python-sdk/fastmcp-utilities-visibility.mdx diff --git a/docs/docs.json b/docs/docs.json index 5b1c59f23..f6b0649d1 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -20,7 +20,10 @@ "primary": "#2d00f7" }, "contextual": { - "options": ["copy", "view"] + "options": [ + "copy", + "view" + ] }, "description": "The fast, Pythonic way to build MCP servers and clients.", "errors": { @@ -163,7 +166,10 @@ { "group": "Essentials", "icon": "cube", - "pages": ["clients/client", "clients/transports"] + "pages": [ + "clients/client", + "clients/transports" + ] }, { "group": "Core Operations", @@ -190,7 +196,10 @@ { "group": "Authentication", "icon": "user-shield", - "pages": ["clients/auth/oauth", "clients/auth/bearer"] + "pages": [ + "clients/auth/oauth", + "clients/auth/bearer" + ] } ] }, @@ -200,7 +209,10 @@ { "group": "Providers", "icon": "globe", - "pages": ["integrations/fastapi", "integrations/openapi"] + "pages": [ + "integrations/fastapi", + "integrations/openapi" + ] }, { "group": "Authentication", @@ -279,10 +291,12 @@ "anchor": "Python SDK", "icon": "python", "pages": [ + "python-sdk/fastmcp-decorators", "python-sdk/fastmcp-dependencies", "python-sdk/fastmcp-exceptions", "python-sdk/fastmcp-mcp_config", "python-sdk/fastmcp-settings", + "python-sdk/fastmcp-telemetry", { "group": "fastmcp.cli", "pages": [ @@ -338,6 +352,7 @@ ] }, "python-sdk/fastmcp-client-tasks", + "python-sdk/fastmcp-client-telemetry", "python-sdk/fastmcp-client-transports" ] }, @@ -345,6 +360,7 @@ "group": "fastmcp.prompts", "pages": [ "python-sdk/fastmcp-prompts-__init__", + "python-sdk/fastmcp-prompts-function_prompt", "python-sdk/fastmcp-prompts-prompt" ] }, @@ -352,6 +368,7 @@ "group": "fastmcp.resources", "pages": [ "python-sdk/fastmcp-resources-__init__", + "python-sdk/fastmcp-resources-function_resource", "python-sdk/fastmcp-resources-resource", "python-sdk/fastmcp-resources-template", "python-sdk/fastmcp-resources-types" @@ -366,6 +383,7 @@ "pages": [ "python-sdk/fastmcp-server-auth-__init__", "python-sdk/fastmcp-server-auth-auth", + "python-sdk/fastmcp-server-auth-authorization", "python-sdk/fastmcp-server-auth-jwt_issuer", "python-sdk/fastmcp-server-auth-middleware", "python-sdk/fastmcp-server-auth-oauth_proxy", @@ -405,10 +423,12 @@ "group": "middleware", "pages": [ "python-sdk/fastmcp-server-middleware-__init__", + "python-sdk/fastmcp-server-middleware-authorization", "python-sdk/fastmcp-server-middleware-caching", "python-sdk/fastmcp-server-middleware-error_handling", "python-sdk/fastmcp-server-middleware-logging", "python-sdk/fastmcp-server-middleware-middleware", + "python-sdk/fastmcp-server-middleware-ping", "python-sdk/fastmcp-server-middleware-rate_limiting", "python-sdk/fastmcp-server-middleware-timing", "python-sdk/fastmcp-server-middleware-tool_injection" @@ -427,8 +447,11 @@ "group": "providers", "pages": [ "python-sdk/fastmcp-server-providers-__init__", + "python-sdk/fastmcp-server-providers-aggregate", "python-sdk/fastmcp-server-providers-base", "python-sdk/fastmcp-server-providers-fastmcp_provider", + "python-sdk/fastmcp-server-providers-filesystem", + "python-sdk/fastmcp-server-providers-filesystem_discovery", "python-sdk/fastmcp-server-providers-local_provider", { "group": "openapi", @@ -439,8 +462,7 @@ "python-sdk/fastmcp-server-providers-openapi-routing" ] }, - "python-sdk/fastmcp-server-providers-proxy", - "python-sdk/fastmcp-server-providers-transforming" + "python-sdk/fastmcp-server-providers-proxy" ] }, "python-sdk/fastmcp-server-proxy", @@ -465,6 +487,17 @@ "python-sdk/fastmcp-server-tasks-routing", "python-sdk/fastmcp-server-tasks-subscriptions" ] + }, + "python-sdk/fastmcp-server-telemetry", + { + "group": "transforms", + "pages": [ + "python-sdk/fastmcp-server-transforms-__init__", + "python-sdk/fastmcp-server-transforms-namespace", + "python-sdk/fastmcp-server-transforms-tool_transform", + "python-sdk/fastmcp-server-transforms-version_filter", + "python-sdk/fastmcp-server-transforms-visibility" + ] } ] }, @@ -472,6 +505,8 @@ "group": "fastmcp.tools", "pages": [ "python-sdk/fastmcp-tools-__init__", + "python-sdk/fastmcp-tools-function_parsing", + "python-sdk/fastmcp-tools-function_tool", "python-sdk/fastmcp-tools-tool", "python-sdk/fastmcp-tools-tool_transform" ] @@ -535,7 +570,8 @@ "python-sdk/fastmcp-utilities-tests", "python-sdk/fastmcp-utilities-types", "python-sdk/fastmcp-utilities-ui", - "python-sdk/fastmcp-utilities-visibility" + "python-sdk/fastmcp-utilities-version_check", + "python-sdk/fastmcp-utilities-versions" ] } ] diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx index cb0c4be1b..759a4324d 100644 --- a/docs/python-sdk/fastmcp-cli-cli.mdx +++ b/docs/python-sdk/fastmcp-cli-cli.mdx @@ -10,7 +10,7 @@ FastMCP CLI tools using Cyclopts. ## Functions -### `with_argv` +### `with_argv` ```python with_argv(args: list[str] | None) @@ -27,7 +27,7 @@ Args are provided without the script name, so we preserve sys.argv[0] and replace the rest. -### `version` +### `version` ```python version() @@ -37,7 +37,7 @@ version() Display version information and platform details. -### `dev` +### `dev` ```python dev(server_spec: str | None = None) -> None @@ -50,7 +50,7 @@ Run an MCP server with the MCP Inspector for development. - `server_spec`: Python file to run, optionally with \:object suffix, or None to auto-detect fastmcp.json -### `run` +### `run` ```python run(server_spec: str | None = None, *server_args: str) -> None @@ -74,7 +74,7 @@ fastmcp run server.py -- --config config.json --debug - `server_spec`: Python file, object specification (file\:obj), config file, URL, or None to auto-detect -### `inspect` +### `inspect` ```python inspect(server_spec: str | None = None) -> None @@ -105,7 +105,7 @@ fastmcp inspect # auto-detect fastmcp.json - `server_spec`: Python file to inspect, optionally with \:object suffix, or fastmcp.json -### `prepare` +### `prepare` ```python prepare(config_path: Annotated[str | None, cyclopts.Parameter(help='Path to fastmcp.json configuration file')] = None, output_dir: Annotated[str | None, cyclopts.Parameter(help='Directory to create the persistent environment in')] = None, skip_source: Annotated[bool, cyclopts.Parameter(help='Skip source preparation (e.g., git clone)')] = False) -> None diff --git a/docs/python-sdk/fastmcp-client-client.mdx b/docs/python-sdk/fastmcp-client-client.mdx index a638d3940..9bdf9108a 100644 --- a/docs/python-sdk/fastmcp-client-client.mdx +++ b/docs/python-sdk/fastmcp-client-client.mdx @@ -7,7 +7,7 @@ sidebarTitle: client ## Classes -### `ClientSessionState` +### `ClientSessionState` Holds all session-related state for a Client instance. @@ -16,13 +16,13 @@ This allows clean separation of configuration (which is copied) from session state (which should be fresh for each new client instance). -### `CallToolResult` +### `CallToolResult` Parsed result from a tool call. -### `Client` +### `Client` MCP client that delegates connection management to a Transport instance. @@ -85,7 +85,7 @@ async with client: **Methods:** -#### `session` +#### `session` ```python session(self) -> ClientSession @@ -94,7 +94,7 @@ session(self) -> ClientSession Get the current active session. Raises RuntimeError if not connected. -#### `initialize_result` +#### `initialize_result` ```python initialize_result(self) -> mcp.types.InitializeResult | None @@ -103,7 +103,7 @@ initialize_result(self) -> mcp.types.InitializeResult | None Get the result of the initialization request. -#### `set_roots` +#### `set_roots` ```python set_roots(self, roots: RootsList | RootsHandler) -> None @@ -112,7 +112,7 @@ set_roots(self, roots: RootsList | RootsHandler) -> None Set the roots for the client. This does not automatically call `send_roots_list_changed`. -#### `set_sampling_callback` +#### `set_sampling_callback` ```python set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabilities: mcp.types.SamplingCapability | None = None) -> None @@ -121,7 +121,7 @@ set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabil Set the sampling callback for the client. -#### `set_elicitation_callback` +#### `set_elicitation_callback` ```python set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None @@ -130,7 +130,7 @@ set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None Set the elicitation callback for the client. -#### `is_connected` +#### `is_connected` ```python is_connected(self) -> bool @@ -139,7 +139,7 @@ is_connected(self) -> bool Check if the client is currently connected. -#### `new` +#### `new` ```python new(self) -> Client[ClientTransportT] @@ -155,7 +155,7 @@ share state with the original client. - A new Client instance with the same configuration but disconnected state. -#### `initialize` +#### `initialize` ```python initialize(self, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.InitializeResult @@ -183,13 +183,13 @@ capabilities, protocol version, and optional instructions. - `RuntimeError`: If the client is not connected or initialization times out. -#### `close` +#### `close` ```python close(self) ``` -#### `ping` +#### `ping` ```python ping(self) -> bool @@ -198,7 +198,7 @@ ping(self) -> bool Send a ping request. -#### `cancel` +#### `cancel` ```python cancel(self, request_id: str | int, reason: str | None = None) -> None @@ -207,7 +207,7 @@ cancel(self, request_id: str | int, reason: str | None = None) -> None Send a cancellation notification for an in-progress request. -#### `progress` +#### `progress` ```python progress(self, progress_token: str | int, progress: float, total: float | None = None, message: str | None = None) -> None @@ -216,7 +216,7 @@ progress(self, progress_token: str | int, progress: float, total: float | None = Send a progress notification. -#### `set_logging_level` +#### `set_logging_level` ```python set_logging_level(self, level: mcp.types.LoggingLevel) -> None @@ -225,7 +225,7 @@ set_logging_level(self, level: mcp.types.LoggingLevel) -> None Send a logging/setLevel request. -#### `send_roots_list_changed` +#### `send_roots_list_changed` ```python send_roots_list_changed(self) -> None @@ -234,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 @@ -251,7 +251,7 @@ containing the list of resources and any additional metadata. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> list[mcp.types.Resource] @@ -267,7 +267,7 @@ Retrieve a list of resources available on the server. - `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 @@ -284,7 +284,7 @@ containing the list of resource templates and any additional metadata. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `list_resource_templates` +#### `list_resource_templates` ```python list_resource_templates(self) -> list[mcp.types.ResourceTemplate] @@ -300,7 +300,7 @@ Retrieve a list of resource templates available on the server. - `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 @@ -321,19 +321,19 @@ containing the resource contents and any additional metadata. - `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 @@ -356,7 +356,7 @@ A list of content objects if task=False, or a ResourceTask object if task=True. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `list_prompts_mcp` +#### `list_prompts_mcp` ```python list_prompts_mcp(self) -> mcp.types.ListPromptsResult @@ -373,7 +373,7 @@ containing the list of prompts and any additional metadata. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `list_prompts` +#### `list_prompts` ```python list_prompts(self) -> list[mcp.types.Prompt] @@ -389,7 +389,7 @@ Retrieve a list of prompts available on the server. - `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 @@ -411,19 +411,19 @@ containing the prompt messages and any additional metadata. - `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 @@ -447,7 +447,7 @@ or a PromptTask object if task=True. - `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 @@ -470,7 +470,7 @@ containing the completion and any additional metadata. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `complete` +#### `complete` ```python complete(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.Completion @@ -492,7 +492,7 @@ include with the completion request. Defaults to None. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `list_tools_mcp` +#### `list_tools_mcp` ```python list_tools_mcp(self) -> mcp.types.ListToolsResult @@ -509,7 +509,7 @@ containing the list of tools and any additional metadata. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `list_tools` +#### `list_tools` ```python list_tools(self) -> list[mcp.types.Tool] @@ -525,7 +525,7 @@ Retrieve a list of tools available on the server. - `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 @@ -555,19 +555,19 @@ containing the tool result and any additional metadata. - `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 @@ -606,7 +606,7 @@ raw result object. - `RuntimeError`: If called while the client is not connected. -#### `get_task_status` +#### `get_task_status` ```python get_task_status(self, task_id: str) -> GetTaskResult @@ -627,7 +627,7 @@ Sends a 'tasks/get' MCP protocol request over the existing transport. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `get_task_result` +#### `get_task_result` ```python get_task_result(self, task_id: str) -> Any @@ -649,7 +649,7 @@ Returns the raw result - callers should parse it appropriately. - `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] @@ -675,7 +675,7 @@ querying status for locally tracked task IDs. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `cancel_task` +#### `cancel_task` ```python cancel_task(self, task_id: str) -> mcp.types.CancelTaskResult @@ -697,7 +697,7 @@ and transition to cancelled state. - `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-telemetry.mdx b/docs/python-sdk/fastmcp-client-telemetry.mdx new file mode 100644 index 000000000..42ec72e93 --- /dev/null +++ b/docs/python-sdk/fastmcp-client-telemetry.mdx @@ -0,0 +1,23 @@ +--- +title: telemetry +sidebarTitle: telemetry +--- + +# `fastmcp.client.telemetry` + + +Client-side telemetry helpers. + +## Functions + +### `client_span` + +```python +client_span(name: str, method: str, component_key: str, session_id: str | None = None, resource_uri: str | None = None) -> Generator[Span, None, None] +``` + + +Create a CLIENT span with standard MCP attributes. + +Automatically records any exception on the span and sets error status. + diff --git a/docs/python-sdk/fastmcp-client-transports.mdx b/docs/python-sdk/fastmcp-client-transports.mdx index c9f748a32..bdf965c95 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 @@ -57,13 +57,13 @@ transport = infer_transport(config) ## Classes -### `SessionKwargs` +### `SessionKwargs` 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,16 @@ close(self) Close the transport. -### `SSETransport` +#### `get_session_id` + +```python +get_session_id(self) -> str | None +``` + +Get the session ID for this transport, if available. + + +### `SSETransport` Transport implementation that connects to an MCP server via Server-Sent Events. @@ -110,13 +119,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. @@ -124,25 +133,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. @@ -153,67 +162,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. @@ -226,13 +235,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. @@ -284,13 +293,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-decorators.mdx b/docs/python-sdk/fastmcp-decorators.mdx new file mode 100644 index 000000000..b57712ad6 --- /dev/null +++ b/docs/python-sdk/fastmcp-decorators.mdx @@ -0,0 +1,39 @@ +--- +title: decorators +sidebarTitle: decorators +--- + +# `fastmcp.decorators` + + +Shared decorator utilities for FastMCP. + +## Functions + +### `resolve_task_config` + +```python +resolve_task_config(task: bool | TaskConfig | None) -> bool | TaskConfig +``` + + +Resolve task config, defaulting None to False. + + +### `get_fastmcp_meta` + +```python +get_fastmcp_meta(fn: Any) -> Any | None +``` + + +Extract FastMCP metadata from a function, handling bound methods and wrappers. + + +## Classes + +### `HasFastMCPMeta` + + +Protocol for callables decorated with FastMCP metadata. + diff --git a/docs/python-sdk/fastmcp-dependencies.mdx b/docs/python-sdk/fastmcp-dependencies.mdx index d53c37027..e803029c3 100644 --- a/docs/python-sdk/fastmcp-dependencies.mdx +++ b/docs/python-sdk/fastmcp-dependencies.mdx @@ -12,3 +12,7 @@ This module re-exports dependency injection symbols from Docket and FastMCP to provide a clean, centralized import location for all dependency-related functionality. +DI features (Depends, CurrentContext, CurrentFastMCP) work without pydocket +using a vendored DI engine. Only task-related dependencies (CurrentDocket, +CurrentWorker) and background task execution require fastmcp[tasks]. + diff --git a/docs/python-sdk/fastmcp-exceptions.mdx b/docs/python-sdk/fastmcp-exceptions.mdx index 26e62012a..78d2e0110 100644 --- a/docs/python-sdk/fastmcp-exceptions.mdx +++ b/docs/python-sdk/fastmcp-exceptions.mdx @@ -63,3 +63,9 @@ Object not found. Object is disabled. + +### `AuthorizationError` + + +Error when authorization check fails. + diff --git a/docs/python-sdk/fastmcp-fs-__init__.mdx b/docs/python-sdk/fastmcp-fs-__init__.mdx deleted file mode 100644 index d49a61f5b..000000000 --- a/docs/python-sdk/fastmcp-fs-__init__.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: __init__ -sidebarTitle: __init__ ---- - -# `fastmcp.fs` - - -Filesystem-based component discovery for FastMCP. - -This module provides decorators and a provider for discovering MCP components -from the filesystem. Files are scanned for functions decorated with @tool, -@resource, or @prompt, and automatically registered with the server. - -Example: - ```python - # server.py - from fastmcp import FastMCP - from fastmcp.fs import FileSystemProvider - - mcp = FastMCP("MyServer", providers=[FileSystemProvider("mcp/")]) - ``` - - ```python - # mcp/tools/greet.py - from fastmcp.fs import tool - - @tool - def greet(name: str) -> str: - '''Greet someone by name.''' - return f"Hello, {name}!" - ``` - - ```python - # mcp/resources/config.py - from fastmcp.fs import resource - - @resource("config://app") - def get_config() -> dict: - '''Get application configuration.''' - return {"version": "1.0"} - ``` - diff --git a/docs/python-sdk/fastmcp-fs-decorators.mdx b/docs/python-sdk/fastmcp-fs-decorators.mdx deleted file mode 100644 index 45ade0981..000000000 --- a/docs/python-sdk/fastmcp-fs-decorators.mdx +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: decorators -sidebarTitle: decorators ---- - -# `fastmcp.fs.decorators` - - -Decorators for marking functions in filesystem-based discovery. - -These decorators mark functions with metadata so that FileSystemProvider -can discover and register them. Unlike LocalProvider's decorators, these -do NOT register components immediately - they just store metadata on the -function for later discovery. - -Example: - ```python - # mcp/tools/greet.py - from fastmcp.fs import tool - - @tool - def greet(name: str) -> str: - '''Greet someone by name.''' - return f"Hello, {name}!" - - @tool(name="custom-greet", tags={"greeting"}) - def my_greet(name: str) -> str: - return f"Hi, {name}!" - ``` - - -## Functions - -### `get_fs_meta` - -```python -get_fs_meta(fn: Any) -> FSMeta | None -``` - - -Get filesystem metadata from a function if it has been decorated. - - -### `has_fs_meta` - -```python -has_fs_meta(fn: Any) -> bool -``` - - -Check if a function has filesystem metadata. - - -### `tool` - -```python -tool(fn: AnyFunction | str | None = None) -> Any -``` - - -Mark a function as a tool for filesystem-based discovery. - -This decorator stores metadata on the function but does NOT register it. -FileSystemProvider discovers marked functions when scanning directories. - -Supports multiple calling patterns: -- @tool (without parentheses) -- @tool() (with empty parentheses) -- @tool("custom_name") (with name as first argument) -- @tool(name="custom_name") (with keyword arguments) - -**Args:** -- `fn`: The function to decorate, or a name string, or None -- `name`: Optional name for the tool (defaults to function name) -- `title`: Optional title for display -- `description`: Optional description (defaults to docstring) -- `icons`: Optional icons for the tool -- `tags`: Optional tags for categorization -- `output_schema`: Optional JSON schema for output -- `annotations`: Optional tool annotations -- `meta`: Optional metadata dict - - -### `resource` - -```python -resource(uri: str) -> Any -``` - - -Mark a function as a resource for filesystem-based discovery. - -This decorator stores metadata on the function but does NOT register it. -FileSystemProvider discovers marked functions when scanning directories. - -Unlike @tool and @prompt, @resource REQUIRES a URI argument. - -**Args:** -- `uri`: URI for the resource (e.g., "config\://app" or "users\://{user_id}") -- `name`: Optional name for the resource -- `title`: Optional title for display -- `description`: Optional description (defaults to docstring) -- `icons`: Optional icons for the resource -- `mime_type`: Optional MIME type -- `tags`: Optional tags for categorization -- `annotations`: Optional resource annotations -- `meta`: Optional metadata dict - - -### `prompt` - -```python -prompt(fn: AnyFunction | str | None = None) -> Any -``` - - -Mark a function as a prompt for filesystem-based discovery. - -This decorator stores metadata on the function but does NOT register it. -FileSystemProvider discovers marked functions when scanning directories. - -Supports multiple calling patterns: -- @prompt (without parentheses) -- @prompt() (with empty parentheses) -- @prompt("custom_name") (with name as first argument) -- @prompt(name="custom_name") (with keyword arguments) - -**Args:** -- `fn`: The function to decorate, or a name string, or None -- `name`: Optional name for the prompt (defaults to function name) -- `title`: Optional title for display -- `description`: Optional description (defaults to docstring) -- `icons`: Optional icons for the prompt -- `tags`: Optional tags for categorization -- `meta`: Optional metadata dict - - -## Classes - -### `ToolMeta` - - -Metadata stored on functions decorated with @tool. - - -### `ResourceMeta` - - -Metadata stored on functions decorated with @resource. - - -### `PromptMeta` - - -Metadata stored on functions decorated with @prompt. - diff --git a/docs/python-sdk/fastmcp-fs-provider.mdx b/docs/python-sdk/fastmcp-fs-provider.mdx deleted file mode 100644 index 84bb30a4c..000000000 --- a/docs/python-sdk/fastmcp-fs-provider.mdx +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: provider -sidebarTitle: provider ---- - -# `fastmcp.fs.provider` - - -FileSystemProvider for filesystem-based component discovery. - -FileSystemProvider scans a directory for Python files, imports them, and -registers any functions decorated with @tool, @resource, or @prompt. - -Example: - ```python - from fastmcp import FastMCP - from fastmcp.fs import FileSystemProvider - - mcp = FastMCP("MyServer", providers=[FileSystemProvider("mcp/")]) - ``` - - -## Classes - -### `FileSystemProvider` - - -Provider that discovers components from the filesystem. - -Scans a directory for Python files and registers functions decorated -with @tool, @resource, or @prompt from fastmcp.fs. - -**Args:** -- `root`: Root directory to scan. Defaults to current directory. -- `reload`: If True, re-scan files on every request (dev mode). -Defaults to False (scan once at init, cache results). - - -**Methods:** - -#### `list_tools` - -```python -list_tools(self) -> Sequence[Tool] -``` - -Return all tools, reloading if in reload mode. - - -#### `get_tool` - -```python -get_tool(self, name: str) -> Tool | None -``` - -Get a tool by name, reloading if in reload mode. - - -#### `list_resources` - -```python -list_resources(self) -> Sequence[Resource] -``` - -Return all resources, reloading if in reload mode. - - -#### `get_resource` - -```python -get_resource(self, uri: str) -> Resource | None -``` - -Get a resource by URI, reloading if in reload mode. - - -#### `list_resource_templates` - -```python -list_resource_templates(self) -> Sequence[ResourceTemplate] -``` - -Return all resource templates, reloading if in reload mode. - - -#### `get_resource_template` - -```python -get_resource_template(self, uri: str) -> ResourceTemplate | None -``` - -Get a resource template, reloading if in reload mode. - - -#### `list_prompts` - -```python -list_prompts(self) -> Sequence[Prompt] -``` - -Return all prompts, reloading if in reload mode. - - -#### `get_prompt` - -```python -get_prompt(self, name: str) -> Prompt | None -``` - -Get a prompt by name, reloading if in reload mode. - diff --git a/docs/python-sdk/fastmcp-mcp_config.mdx b/docs/python-sdk/fastmcp-mcp_config.mdx index 9b30dad85..87ed568a0 100644 --- a/docs/python-sdk/fastmcp-mcp_config.mdx +++ b/docs/python-sdk/fastmcp-mcp_config.mdx @@ -42,7 +42,7 @@ infer_transport_type_from_url(url: str | AnyUrl) -> Literal['http', 'sse'] Infer the appropriate transport type from the given URL. -### `update_config_file` +### `update_config_file` ```python update_config_file(file_path: Path, server_name: str, server_config: CanonicalMCPServerTypes) -> None @@ -57,7 +57,7 @@ worry about transforming server objects here. ## Classes -### `StdioMCPServer` +### `StdioMCPServer` MCP server configuration for stdio transport. @@ -67,19 +67,19 @@ This is the canonical configuration format for MCP servers using stdio transport **Methods:** -#### `to_transport` +#### `to_transport` ```python to_transport(self) -> StdioTransport ``` -### `TransformingStdioMCPServer` +### `TransformingStdioMCPServer` A Stdio server with tool transforms. -### `RemoteMCPServer` +### `RemoteMCPServer` MCP server configuration for HTTP/SSE transport. @@ -89,19 +89,19 @@ This is the canonical configuration format for MCP servers using remote transpor **Methods:** -#### `to_transport` +#### `to_transport` ```python to_transport(self) -> StreamableHttpTransport | SSETransport ``` -### `TransformingRemoteMCPServer` +### `TransformingRemoteMCPServer` A Remote server with tool transforms. -### `MCPConfig` +### `MCPConfig` A configuration object for MCP Servers that conforms to the canonical MCP configuration format @@ -113,7 +113,7 @@ For an MCPConfig that is strictly canonical, see the `CanonicalMCPConfig` class. **Methods:** -#### `wrap_servers_at_root` +#### `wrap_servers_at_root` ```python wrap_servers_at_root(cls, values: dict[str, Any]) -> dict[str, Any] @@ -122,7 +122,7 @@ wrap_servers_at_root(cls, values: dict[str, Any]) -> dict[str, Any] If there's no mcpServers key but there are server configs at root, wrap them. -#### `add_server` +#### `add_server` ```python add_server(self, name: str, server: MCPServerTypes) -> None @@ -131,7 +131,7 @@ add_server(self, name: str, server: MCPServerTypes) -> None Add or update a server in the configuration. -#### `from_dict` +#### `from_dict` ```python from_dict(cls, config: dict[str, Any]) -> Self @@ -140,7 +140,7 @@ from_dict(cls, config: dict[str, Any]) -> Self Parse MCP configuration from dictionary format. -#### `to_dict` +#### `to_dict` ```python to_dict(self) -> dict[str, Any] @@ -149,7 +149,7 @@ to_dict(self) -> dict[str, Any] Convert MCPConfig to dictionary format, preserving all fields. -#### `write_to_file` +#### `write_to_file` ```python write_to_file(self, file_path: Path) -> None @@ -158,7 +158,7 @@ write_to_file(self, file_path: Path) -> None Write configuration to JSON file. -#### `from_file` +#### `from_file` ```python from_file(cls, file_path: Path) -> Self @@ -167,7 +167,7 @@ from_file(cls, file_path: Path) -> Self Load configuration from JSON file. -### `CanonicalMCPConfig` +### `CanonicalMCPConfig` Canonical MCP configuration format. @@ -178,7 +178,7 @@ The format is designed to be client-agnostic and extensible for future use cases **Methods:** -#### `add_server` +#### `add_server` ```python add_server(self, name: str, server: CanonicalMCPServerTypes) -> None diff --git a/docs/python-sdk/fastmcp-prompts-function_prompt.mdx b/docs/python-sdk/fastmcp-prompts-function_prompt.mdx new file mode 100644 index 000000000..c8e48ef9c --- /dev/null +++ b/docs/python-sdk/fastmcp-prompts-function_prompt.mdx @@ -0,0 +1,106 @@ +--- +title: function_prompt +sidebarTitle: function_prompt +--- + +# `fastmcp.prompts.function_prompt` + + +Standalone @prompt decorator for FastMCP. + +## Functions + +### `prompt` + +```python +prompt(name_or_fn: str | Callable[..., Any] | None = None) -> Any +``` + + +Standalone decorator to mark a function as an MCP prompt. + +Returns the original function with metadata attached. Register with a server +using mcp.add_prompt(). + + +## Classes + +### `DecoratedPrompt` + + +Protocol for functions decorated with @prompt. + + +### `PromptMeta` + + +Metadata attached to functions by the @prompt decorator. + + +### `FunctionPrompt` + + +A prompt that is a function. + + +**Methods:** + +#### `from_function` + +```python +from_function(cls, fn: Callable[..., Any]) -> FunctionPrompt +``` + +Create a Prompt from a function. + +**Args:** +- `fn`: The function to wrap +- `metadata`: PromptMeta object with all configuration. If provided, +individual parameters must not be passed. +- `name, title, etc.`: Individual parameters for backwards compatibility. +Cannot be used together with metadata parameter. + +The function can return: +- str: wrapped as single user Message +- list\[Message | str]: converted to list\[Message] +- PromptResult: used directly + + +#### `render` + +```python +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.mdx b/docs/python-sdk/fastmcp-prompts-prompt.mdx index 8516742dd..f4ef6c85e 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. ## Classes -### `Message` +### `Message` Wrapper for prompt message with auto-serialization. @@ -21,7 +21,7 @@ Accepts any content - strings pass through, other types **Methods:** -#### `to_mcp_prompt_message` +#### `to_mcp_prompt_message` ```python to_mcp_prompt_message(self) -> PromptMessage @@ -30,13 +30,13 @@ to_mcp_prompt_message(self) -> PromptMessage Convert to MCP PromptMessage. -### `PromptArgument` +### `PromptArgument` An argument that can be passed to a prompt. -### `PromptResult` +### `PromptResult` Canonical result type for prompt rendering. @@ -47,7 +47,7 @@ roles, and metadata at both the message and result level. **Methods:** -#### `to_mcp_prompt_result` +#### `to_mcp_prompt_result` ```python to_mcp_prompt_result(self) -> GetPromptResult @@ -56,7 +56,7 @@ to_mcp_prompt_result(self) -> GetPromptResult Convert to MCP GetPromptResult. -### `Prompt` +### `Prompt` A prompt template that can be rendered with parameters. @@ -64,7 +64,7 @@ A prompt template that can be rendered with parameters. **Methods:** -#### `to_mcp_prompt` +#### `to_mcp_prompt` ```python to_mcp_prompt(self, **overrides: Any) -> SDKPrompt @@ -73,10 +73,10 @@ to_mcp_prompt(self, **overrides: Any) -> SDKPrompt Convert the prompt to an MCP prompt. -#### `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, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt +from_function(cls, fn: Callable[..., Any]) -> FunctionPrompt ``` Create a Prompt from a function. @@ -87,7 +87,7 @@ The function can return: - PromptResult: used directly -#### `render` +#### `render` ```python render(self, arguments: dict[str, Any] | None = None) -> str | list[Message | str] | PromptResult @@ -101,7 +101,7 @@ Subclasses must implement this method. Return one of: - PromptResult: Used directly -#### `convert_result` +#### `convert_result` ```python convert_result(self, raw_value: Any) -> PromptResult @@ -113,7 +113,7 @@ Convert a raw return value to PromptResult. - `TypeError`: for unsupported types -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None @@ -122,7 +122,7 @@ register_with_docket(self, docket: Docket) -> None Register this prompt with docket for background execution. -#### `add_to_docket` +#### `add_to_docket` ```python add_to_docket(self, docket: Docket, arguments: dict[str, Any] | None, **kwargs: Any) -> Execution @@ -138,63 +138,8 @@ Schedule this prompt for background execution via docket. - `**kwargs`: Additional kwargs passed to docket.add() -### `FunctionPrompt` - - -A prompt that is a function. - - -**Methods:** - -#### `from_function` +#### `get_span_attributes` ```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, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionPrompt +get_span_attributes(self) -> dict[str, Any] ``` - -Create a Prompt from a function. - -The function can return: -- str: wrapped as single user Message -- list\[Message | str]: converted to list\[Message] -- PromptResult: used directly - - -#### `render` - -```python -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-resources-function_resource.mdx b/docs/python-sdk/fastmcp-resources-function_resource.mdx new file mode 100644 index 000000000..ad184b53c --- /dev/null +++ b/docs/python-sdk/fastmcp-resources-function_resource.mdx @@ -0,0 +1,93 @@ +--- +title: function_resource +sidebarTitle: function_resource +--- + +# `fastmcp.resources.function_resource` + + +Standalone @resource decorator for FastMCP. + +## Functions + +### `resource` + +```python +resource(uri: str) -> Callable[[F], F] +``` + + +Standalone decorator to mark a function as an MCP resource. + +Returns the original function with metadata attached. Register with a server +using mcp.add_resource(). + + +## Classes + +### `DecoratedResource` + + +Protocol for functions decorated with @resource. + + +### `ResourceMeta` + + +Metadata attached to functions by the @resource decorator. + + +### `FunctionResource` + + +A resource that defers data loading by wrapping a function. + +The function is only called when the resource is read, allowing for lazy loading +of potentially expensive data. This is particularly useful when listing resources, +as the function won't be called until the resource is actually accessed. + +The function can return: +- str for text content (default) +- bytes for binary content +- other types will be converted to JSON + + +**Methods:** + +#### `from_function` + +```python +from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl | None = None) -> FunctionResource +``` + +Create a FunctionResource from a function. + +**Args:** +- `fn`: The function to wrap +- `uri`: The URI for the resource (required if metadata not provided) +- `metadata`: ResourceMeta object with all configuration. If provided, +individual parameters must not be passed. +- `name, title, etc.`: Individual parameters for backwards compatibility. +Cannot be used together with metadata parameter. + + +#### `read` + +```python +read(self) -> str | bytes | ResourceResult +``` + +Read the resource by calling the wrapped function. + + +#### `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.mdx b/docs/python-sdk/fastmcp-resources-resource.mdx index bbd17a04f..94c92ee31 100644 --- a/docs/python-sdk/fastmcp-resources-resource.mdx +++ b/docs/python-sdk/fastmcp-resources-resource.mdx @@ -10,7 +10,7 @@ Base classes and interfaces for FastMCP resources. ## Classes -### `ResourceContent` +### `ResourceContent` Wrapper for resource content with optional MIME type and metadata. @@ -21,7 +21,7 @@ other types (dict, list, BaseModel, etc.) are automatically JSON-serialized. **Methods:** -#### `to_mcp_resource_contents` +#### `to_mcp_resource_contents` ```python to_mcp_resource_contents(self, uri: AnyUrl | str) -> mcp.types.TextResourceContents | mcp.types.BlobResourceContents @@ -36,7 +36,7 @@ Convert to MCP resource contents type. - TextResourceContents for str content, BlobResourceContents for bytes -### `ResourceResult` +### `ResourceResult` Canonical result type for resource reads. @@ -47,7 +47,7 @@ per-item MIME types, and metadata at both the item and result level. **Methods:** -#### `to_mcp_result` +#### `to_mcp_result` ```python to_mcp_result(self, uri: AnyUrl | str) -> mcp.types.ReadResourceResult @@ -62,7 +62,7 @@ Convert to MCP ReadResourceResult. - MCP ReadResourceResult with converted contents -### `Resource` +### `Resource` Base class for all resources. @@ -70,13 +70,13 @@ Base class for all resources. **Methods:** -#### `from_function` +#### `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, 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) -> FunctionResource ``` -#### `set_default_mime_type` +#### `set_default_mime_type` ```python set_default_mime_type(cls, mime_type: str | None) -> str @@ -85,7 +85,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 @@ -94,7 +94,7 @@ set_default_name(self) -> Self Set default name from URI if not provided. -#### `read` +#### `read` ```python read(self) -> str | bytes | ResourceResult @@ -108,7 +108,7 @@ Subclasses implement this to return resource data. Supported return types: - ResourceResult: Full control over contents and result-level meta -#### `convert_result` +#### `convert_result` ```python convert_result(self, raw_value: Any) -> ResourceResult @@ -124,7 +124,7 @@ Handles ResourceResult passthrough and converts raw values using ResourceResult's normalization. -#### `to_mcp_resource` +#### `to_mcp_resource` ```python to_mcp_resource(self, **overrides: Any) -> SDKResource @@ -133,7 +133,7 @@ to_mcp_resource(self, **overrides: Any) -> SDKResource Convert the resource to an SDKResource. -#### `key` +#### `key` ```python key(self) -> str @@ -142,7 +142,7 @@ key(self) -> str The globally unique lookup key for this resource. -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None @@ -151,7 +151,7 @@ register_with_docket(self, docket: Docket) -> None Register this resource with docket for background execution. -#### `add_to_docket` +#### `add_to_docket` ```python add_to_docket(self, docket: Docket, **kwargs: Any) -> Execution @@ -166,49 +166,8 @@ Schedule this resource for background execution via docket. - `**kwargs`: Additional kwargs passed to docket.add() -### `FunctionResource` - - -A resource that defers data loading by wrapping a function. - -The function is only called when the resource is read, allowing for lazy loading -of potentially expensive data. This is particularly useful when listing resources, -as the function won't be called until the resource is actually accessed. - -The function can return: -- str for text content (default) -- bytes for binary content -- other types will be converted to JSON - - -**Methods:** - -#### `from_function` +#### `get_span_attributes` ```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, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResource +get_span_attributes(self) -> dict[str, Any] ``` - -Create a FunctionResource from a function. - - -#### `read` - -```python -read(self) -> str | bytes | ResourceResult -``` - -Read the resource by calling the wrapped function. - - -#### `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-template.mdx b/docs/python-sdk/fastmcp-resources-template.mdx index e93d9f4be..30ce6b464 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,13 +59,13 @@ A template for dynamically creating resources. **Methods:** -#### `from_function` +#### `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, annotations: Annotations | None = None, meta: dict[str, Any] | None = None, task: bool | TaskConfig | None = None) -> FunctionResourceTemplate +from_function(fn: Callable[..., Any], uri_template: str, name: str | None = None, version: str | int | 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, auth: AuthCheckCallable | list[AuthCheckCallable] | None = None) -> FunctionResourceTemplate ``` -#### `set_default_mime_type` +#### `set_default_mime_type` ```python set_default_mime_type(cls, mime_type: str | None) -> str @@ -74,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 @@ -83,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 | ResourceResult @@ -92,7 +92,7 @@ read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult Read the resource content. -#### `convert_result` +#### `convert_result` ```python convert_result(self, raw_value: Any) -> ResourceResult @@ -108,7 +108,7 @@ Handles ResourceResult passthrough and converts raw values using ResourceResult's normalization. -#### `create_resource` +#### `create_resource` ```python create_resource(self, uri: str, params: dict[str, Any]) -> Resource @@ -120,7 +120,7 @@ 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) -> SDKResourceTemplate @@ -129,7 +129,7 @@ to_mcp_template(self, **overrides: Any) -> SDKResourceTemplate Convert the resource template to an SDKResourceTemplate. -#### `from_mcp_template` +#### `from_mcp_template` ```python from_mcp_template(cls, mcp_template: SDKResourceTemplate) -> ResourceTemplate @@ -138,7 +138,7 @@ from_mcp_template(cls, mcp_template: SDKResourceTemplate) -> ResourceTemplate Creates a FastMCP ResourceTemplate from a raw MCP ResourceTemplate object. -#### `key` +#### `key` ```python key(self) -> str @@ -147,7 +147,7 @@ key(self) -> str The globally unique lookup key for this template. -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None @@ -156,7 +156,7 @@ register_with_docket(self, docket: Docket) -> None Register this template with docket for background execution. -#### `add_to_docket` +#### `add_to_docket` ```python add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution @@ -172,7 +172,13 @@ Schedule this template for background execution via docket. - `**kwargs`: Additional kwargs passed to docket.add() -### `FunctionResourceTemplate` +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +### `FunctionResourceTemplate` A template for dynamically creating resources. @@ -180,7 +186,7 @@ A template for dynamically creating resources. **Methods:** -#### `create_resource` +#### `create_resource` ```python create_resource(self, uri: str, params: dict[str, Any]) -> Resource @@ -189,7 +195,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 | ResourceResult @@ -198,7 +204,7 @@ read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult Read the resource content. -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None @@ -210,7 +216,7 @@ FunctionResourceTemplate registers the underlying function, which has the user's Depends parameters for docket to resolve. -#### `add_to_docket` +#### `add_to_docket` ```python add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution @@ -228,10 +234,10 @@ FunctionResourceTemplate splats the params dict since .fn expects **kwargs. - `**kwargs`: Additional kwargs passed to docket.add() -#### `from_function` +#### `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 +from_function(cls, fn: Callable[..., Any], uri_template: str, name: str | None = None, version: str | int | 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, auth: AuthCheckCallable | list[AuthCheckCallable] | None = None) -> FunctionResourceTemplate ``` Create a template from a function. diff --git a/docs/python-sdk/fastmcp-server-auth-authorization.mdx b/docs/python-sdk/fastmcp-server-auth-authorization.mdx new file mode 100644 index 000000000..d8e0611a9 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-auth-authorization.mdx @@ -0,0 +1,139 @@ +--- +title: authorization +sidebarTitle: authorization +--- + +# `fastmcp.server.auth.authorization` + + +Authorization checks for FastMCP components. + +This module provides callable-based authorization for tools, resources, and prompts. +Auth checks are functions that receive an AuthContext and return True to allow access +or False to deny. + +Auth checks can also raise exceptions: +- AuthorizationError: Propagates with the custom message for explicit denial +- Other exceptions: Masked for security (logged, treated as auth failure) + +Example: + ```python + from fastmcp import FastMCP + from fastmcp.server.auth import require_auth, require_scopes + + mcp = FastMCP() + + @mcp.tool(auth=require_auth) + def protected_tool(): ... + + @mcp.resource("data://secret", auth=require_scopes("read")) + def secret_data(): ... + + @mcp.prompt(auth=require_auth) + def admin_prompt(): ... + ``` + + +## Functions + +### `require_auth` + +```python +require_auth(ctx: AuthContext) -> bool +``` + + +Require any valid authentication. + +Returns True if the request has a valid token, False otherwise. + + +### `require_scopes` + +```python +require_scopes(*scopes: str) -> AuthCheck +``` + + +Require specific OAuth scopes. + +Returns an auth check that requires ALL specified scopes to be present +in the token (AND logic). + +**Args:** +- `*scopes`: One or more scope strings that must all be present. + + +### `restrict_tag` + +```python +restrict_tag(tag: str) -> AuthCheck +``` + + +Restrict components with a specific tag to require certain scopes. + +If the component has the specified tag, the token must have ALL the +required scopes. If the component doesn't have the tag, access is allowed. + +**Args:** +- `tag`: The tag that triggers the scope requirement. +- `scopes`: List of scopes required when the tag is present. + + +### `run_auth_checks` + +```python +run_auth_checks(checks: AuthCheck | list[AuthCheck], ctx: AuthContext) -> bool +``` + + +Run auth checks with AND logic. + +All checks must pass for authorization to succeed. + +Auth checks can: +- Return True to allow access +- Return False to deny access +- Raise AuthorizationError to deny with a custom message (propagates) +- Raise other exceptions (masked for security, treated as denial) + +**Args:** +- `checks`: A single check function or list of check functions. +- `ctx`: The auth context to pass to each check. + +**Returns:** +- True if all checks pass, False if any check fails. + +**Raises:** +- `AuthorizationError`: If an auth check explicitly raises it. + + +## Classes + +### `AuthContext` + + +Context passed to auth check callables. + +This object is passed to each auth check function and provides +access to the current authentication token and the component being accessed. + +**Attributes:** +- `token`: The current access token, or None if unauthenticated. +- `component`: The component (tool, resource, or prompt) being accessed. +- `tool`: Backwards-compatible alias for component when it's a Tool. + + +**Methods:** + +#### `tool` + +```python +tool(self) -> Tool | None +``` + +Backwards-compatible access to the component as a Tool. + +Returns the component if it's a Tool, None otherwise. + diff --git a/docs/python-sdk/fastmcp-server-auth-providers-introspection.mdx b/docs/python-sdk/fastmcp-server-auth-providers-introspection.mdx index 2a0d2e22d..32943d6b2 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-introspection.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-introspection.mdx @@ -31,7 +31,7 @@ Example: ## Classes -### `IntrospectionTokenVerifier` +### `IntrospectionTokenVerifier` OAuth 2.0 Token Introspection verifier (RFC 7662). @@ -40,8 +40,11 @@ This verifier validates opaque tokens by calling an OAuth 2.0 token introspectio endpoint. Unlike JWT verification which is stateless, token introspection requires a network call to the authorization server for each token validation. -The verifier authenticates to the introspection endpoint using HTTP Basic Auth -with the provided client_id and client_secret, as specified in RFC 7662. +The verifier authenticates to the introspection endpoint using either: +- HTTP Basic Auth (client_secret_basic, default): credentials in Authorization header +- POST body authentication (client_secret_post): credentials in request body + +Both methods are specified in RFC 6749 (OAuth 2.0) and RFC 7662 (Token Introspection). Use this when: - Your authorization server issues opaque (non-JWT) tokens @@ -52,7 +55,7 @@ Use this when: **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -61,7 +64,8 @@ verify_token(self, token: str) -> AccessToken | None Verify a bearer token using OAuth 2.0 Token Introspection (RFC 7662). This method makes a POST request to the introspection endpoint with the token, -authenticated using HTTP Basic Auth with the client credentials. +authenticated using the configured client authentication method (client_secret_basic +or client_secret_post). **Args:** - `token`: The opaque token string to validate diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx index 91e4c1195..822efb8c6 100644 --- a/docs/python-sdk/fastmcp-server-context.mdx +++ b/docs/python-sdk/fastmcp-server-context.mdx @@ -7,7 +7,27 @@ sidebarTitle: context ## Functions -### `set_context` +### `set_transport` + +```python +set_transport(transport: TransportType) -> Token[TransportType | None] +``` + + +Set the current transport type. Returns token for reset. + + +### `reset_transport` + +```python +reset_transport(token: Token[TransportType | None]) -> None +``` + + +Reset transport to previous value. + + +### `set_context` ```python set_context(context: Context) -> Generator[Context, None, None] @@ -15,7 +35,7 @@ set_context(context: Context) -> Generator[Context, None, None] ## Classes -### `LogData` +### `LogData` Data object for passing log arguments to client-side handlers. @@ -24,7 +44,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. @@ -53,18 +73,22 @@ async def my_tool(x: int, ctx: Context) -> str: request_id = ctx.request_id client_id = ctx.client_id - # Manage state across the request - ctx.set_state("key", "value") - value = ctx.get_state("key") + # Manage state across the session (persists across requests) + await ctx.set_state("key", "value") + value = await ctx.get_state("key") return str(x) ``` State Management: -Context objects maintain a state dictionary that can be used to store and share -data across middleware and tool calls within a request. When a new context -is created (nested contexts), it inherits a copy of its parent's state, ensuring -that modifications in child contexts don't affect parent contexts. +Context provides session-scoped state that persists across requests within +the same MCP session. State is automatically keyed by session, ensuring +isolation between different clients. + +State set during `on_initialize` middleware will persist to subsequent tool +calls when using the same session object (STDIO, SSE, single-server HTTP). +For distributed/serverless HTTP deployments where different machines handle +the init and tool calls, state is isolated by the mcp-session-id header. The context parameter name can be anything as long as it's annotated with Context. The context is optional - tools that don't need it can omit the parameter. @@ -72,7 +96,7 @@ The context is optional - tools that don't need it can omit the parameter. **Methods:** -#### `fastmcp` +#### `fastmcp` ```python fastmcp(self) -> FastMCP @@ -81,7 +105,7 @@ fastmcp(self) -> FastMCP Get the FastMCP instance. -#### `request_context` +#### `request_context` ```python request_context(self) -> RequestContext[ServerSession, Any, Request] | None @@ -110,7 +134,7 @@ async def on_request(self, context, call_next): ``` -#### `lifespan_context` +#### `lifespan_context` ```python lifespan_context(self) -> dict[str, Any] @@ -133,7 +157,7 @@ def my_tool(ctx: Context) -> str: ``` -#### `report_progress` +#### `report_progress` ```python report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None @@ -146,7 +170,7 @@ Report progress for the current operation. - `total`: Optional total value e.g. 100 -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> list[SDKResource] @@ -158,7 +182,7 @@ List all available resources from the server. - List of Resource objects available on the server -#### `list_prompts` +#### `list_prompts` ```python list_prompts(self) -> list[SDKPrompt] @@ -170,7 +194,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 @@ -186,7 +210,7 @@ Get a prompt by name with optional arguments. - The prompt result -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: str | AnyUrl) -> ResourceResult @@ -201,7 +225,7 @@ Read a resource by URI. - ResourceResult with contents -#### `log` +#### `log` ```python log(self, message: str, level: LoggingLevel | None = None, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -219,7 +243,19 @@ Messages sent to Clients are also logged to the `fastmcp.server.context.to_clien - `extra`: Optional mapping for additional arguments -#### `client_id` +#### `transport` + +```python +transport(self) -> TransportType | None +``` + +Get the current transport type. + +Returns the transport type used to run this server: "stdio", "sse", +or "streamable-http". Returns None if called outside of a server context. + + +#### `client_id` ```python client_id(self) -> str | None @@ -228,7 +264,7 @@ client_id(self) -> str | None Get the client ID if available. -#### `request_id` +#### `request_id` ```python request_id(self) -> str @@ -239,7 +275,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 @@ -256,7 +292,7 @@ the same client session. - for other transports. -#### `session` +#### `session` ```python session(self) -> ServerSession @@ -267,7 +303,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 @@ -278,7 +314,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 @@ -289,7 +325,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 @@ -300,7 +336,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 @@ -311,7 +347,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] @@ -320,7 +356,7 @@ list_roots(self) -> list[Root] List the roots available to the server, as indicated by the client. -#### `send_notification` +#### `send_notification` ```python send_notification(self, notification: mcp.types.ServerNotificationType) -> None @@ -336,7 +372,7 @@ for the background flusher. - `notification`: An MCP notification instance (e.g., ToolListChangedNotification()) -#### `send_notification_sync` +#### `send_notification_sync` ```python send_notification_sync(self, notification: mcp.types.ServerNotificationType) -> None @@ -351,7 +387,7 @@ sent within ~1 second by the background flusher. - `notification`: An MCP notification instance (e.g., ToolListChangedNotification()) -#### `close_sse_stream` +#### `close_sse_stream` ```python close_sse_stream(self) -> None @@ -369,7 +405,7 @@ Instead of holding a connection open for minutes, you can periodically close and let the client reconnect. -#### `sample_step` +#### `sample_step` ```python sample_step(self, messages: str | Sequence[str | SamplingMessage]) -> SampleStep @@ -406,7 +442,7 @@ Tools can raise ToolError to bypass masking. - - .text: The text content (if any) -#### `sample` +#### `sample` ```python sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ResultT] @@ -415,7 +451,7 @@ sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ Overload: With result_type, returns SamplingResult[ResultT]. -#### `sample` +#### `sample` ```python sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[str] @@ -424,7 +460,7 @@ sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ Overload: Without result_type, returns SamplingResult[str]. -#### `sample` +#### `sample` ```python sample(self, messages: str | Sequence[str | SamplingMessage]) -> SamplingResult[ResultT] | SamplingResult[str] @@ -466,43 +502,43 @@ Tools can raise ToolError to bypass masking. - - .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: dict[str, dict[str, str]]) -> AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation ``` -#### `elicit` +#### `elicit` ```python elicit(self, message: str, response_type: list[list[str]]) -> AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation ``` -#### `elicit` +#### `elicit` ```python elicit(self, message: str, response_type: list[dict[str, dict[str, str]]]) -> AcceptedElicitation[list[str]] | DeclinedElicitation | CancelledElicitation ``` -#### `elicit` +#### `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 @@ -531,20 +567,35 @@ 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 ``` -Set a value in the context state. +Set a value in the session-scoped state store. + +Values persist across requests within the same MCP session. +The key is automatically prefixed with the session identifier. +State expires after 1 day to prevent unbounded memory growth. -#### `get_state` +#### `get_state` ```python get_state(self, key: str) -> Any ``` -Get a value from the context state. Returns None if the key is not found. +Get a value from the session-scoped state store. + +Returns None if the key is not found. + + +#### `delete_state` + +```python +delete_state(self, key: str) -> None +``` + +Delete a value from the session-scoped state store. diff --git a/docs/python-sdk/fastmcp-server-dependencies.mdx b/docs/python-sdk/fastmcp-server-dependencies.mdx index 125ba2ecb..2eebf8f5d 100644 --- a/docs/python-sdk/fastmcp-server-dependencies.mdx +++ b/docs/python-sdk/fastmcp-server-dependencies.mdx @@ -5,9 +5,139 @@ sidebarTitle: dependencies # `fastmcp.server.dependencies` + +Dependency injection for FastMCP. + +DI features (Depends, CurrentContext, CurrentFastMCP) work without pydocket +using a vendored DI engine. Only task-related dependencies (CurrentDocket, +CurrentWorker) and background task execution require fastmcp[tasks]. + + ## Functions -### `without_injected_parameters` +### `is_docket_available` + +```python +is_docket_available() -> bool +``` + + +Check if pydocket is installed. + + +### `require_docket` + +```python +require_docket(feature: str) -> None +``` + + +Raise ImportError with install instructions if docket not available. + +**Args:** +- `feature`: Description of what requires docket (e.g., "`task=True`", + "CurrentDocket()"). Will be included in the error message. + + +### `transform_context_annotations` + +```python +transform_context_annotations(fn: Callable[..., Any]) -> Callable[..., Any] +``` + + +Transform ctx: Context into ctx: Context = CurrentContext(). + +Transforms ALL params typed as Context to use Docket's DI system, +unless they already have a Dependency-based default (like CurrentContext()). + +This unifies the legacy type annotation DI with Docket's Depends() system, +allowing both patterns to work through a single resolution path. + +Note: Only POSITIONAL_OR_KEYWORD parameters are reordered (params with defaults +after those without). KEYWORD_ONLY parameters keep their position since Python +allows them to have defaults in any order. + +**Args:** +- `fn`: Function to transform + +**Returns:** +- Function with modified signature (same function object, updated __signature__) + + +### `get_context` + +```python +get_context() -> Context +``` + + +Get the current FastMCP Context instance directly. + + +### `get_server` + +```python +get_server() -> FastMCP +``` + + +Get the current FastMCP server instance directly. + +**Returns:** +- The active FastMCP server + +**Raises:** +- `RuntimeError`: If no server in context + + +### `get_http_request` + +```python +get_http_request() -> Request +``` + + +Get the current HTTP request. + +Tries MCP SDK's request_ctx first, then falls back to FastMCP's HTTP context. + + +### `get_http_headers` + +```python +get_http_headers(include_all: bool = False) -> dict[str, str] +``` + + +Extract headers from the current HTTP request if available. + +Never raises an exception, even if there is no active HTTP request (in which case +an empty dict is returned). + +By default, strips problematic headers like `content-length` that cause issues +if forwarded to downstream clients. If `include_all` is True, all headers are returned. + + +### `get_access_token` + +```python +get_access_token() -> AccessToken | None +``` + + +Get the FastMCP access token from the current context. + +This function first tries to get the token from the current HTTP request's scope, +which is more reliable for long-lived connections where the SDK's auth_context_var +may become stale after token refresh. Falls back to the SDK's context var if no +request is available. + +**Returns:** +- The access token if an authenticated user is available, None otherwise. + + +### `without_injected_parameters` ```python without_injected_parameters(fn: Callable[..., Any]) -> Callable[..., Any] @@ -21,6 +151,10 @@ making it safe to use with Pydantic TypeAdapter for schema generation and validation. The wrapper internally handles all dependency resolution and Context injection when called. +Handles: +- Legacy Context injection (always works) +- Depends() injection (always works - uses docket or vendored DI engine) + **Args:** - `fn`: Original function with Context and/or dependencies @@ -28,37 +162,33 @@ 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] ``` -Resolve dependencies and inject Context for a FastMCP function. +Resolve dependencies for a FastMCP function. This function: 1. Filters out any dependency parameter names from user arguments (security) -2. Resolves Docket dependencies -3. Injects Context if needed -4. Merges everything together +2. Resolves Depends() parameters via the DI system The filtering prevents external callers from overriding injected parameters by providing values for dependency parameter names. This is a security feature. +Note: Context injection is handled via transform_context_annotations() which +converts `ctx: Context` to `ctx: Context = Depends(get_context)` at registration +time, so all injection goes through the unified DI system. + **Args:** - `fn`: The function to resolve dependencies for - `arguments`: User arguments (may contain keys that match dependency names, which will be filtered out) -### `get_context` - -```python -get_context() -> Context -``` - -### `CurrentContext` +### `CurrentContext` ```python CurrentContext() -> Context @@ -77,7 +207,7 @@ current MCP operation (tool/resource/prompt call). - `RuntimeError`: If no active context found (during resolution) -### `CurrentDocket` +### `CurrentDocket` ```python CurrentDocket() -> Docket @@ -94,9 +224,10 @@ automatically creates for background task scheduling. **Raises:** - `RuntimeError`: If not within a FastMCP server context +- `ImportError`: If fastmcp[tasks] not installed -### `CurrentWorker` +### `CurrentWorker` ```python CurrentWorker() -> Worker @@ -113,12 +244,13 @@ automatically creates for background task processing. **Raises:** - `RuntimeError`: If not within a FastMCP server context +- `ImportError`: If fastmcp[tasks] not installed -### `CurrentFastMCP` +### `CurrentFastMCP` ```python -CurrentFastMCP() +CurrentFastMCP() -> FastMCP ``` @@ -133,95 +265,47 @@ This dependency provides access to the active FastMCP server. - `RuntimeError`: If no server in context (during resolution) -### `get_server` - -```python -get_server() -``` - - -Get the current FastMCP server instance directly. - -**Returns:** -- The active FastMCP server - -**Raises:** -- `RuntimeError`: If no server in context - - -### `get_http_request` - -```python -get_http_request() -> Request -``` - -### `get_http_headers` - -```python -get_http_headers(include_all: bool = False) -> dict[str, str] -``` - - -Extract headers from the current HTTP request if available. - -Never raises an exception, even if there is no active HTTP request (in which case -an empty dict is returned). - -By default, strips problematic headers like `content-length` that cause issues if forwarded to downstream clients. -If `include_all` is True, all headers are returned. - - -### `get_access_token` - -```python -get_access_token() -> AccessToken | None -``` - - -Get the FastMCP access token from the current context. - -This function first tries to get the token from the current HTTP request's scope, -which is more reliable for long-lived connections where the SDK's auth_context_var -may become stale after token refresh. Falls back to the SDK's context var if no -request is available. - -**Returns:** -- The access token if an authenticated user is available, None otherwise. - - ## Classes -### `InMemoryProgress` +### `ProgressLike` -In-memory progress tracker for immediate tool execution. +Protocol for progress tracking interface. -Provides the same interface as Progress but stores state in memory -instead of Redis. Useful for testing and immediate execution where -progress doesn't need to be observable across processes. +Defines the common interface between InMemoryProgress (server context) +and Docket's Progress (worker context). **Methods:** -#### `current` +#### `current` ```python current(self) -> int | None ``` -#### `total` +Current progress value. + + +#### `total` ```python total(self) -> int ``` -#### `message` +Total/target progress value. + + +#### `message` ```python message(self) -> str | None ``` -#### `set_total` +Current progress message. + + +#### `set_total` ```python set_total(self, total: int) -> None @@ -230,7 +314,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 +323,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,15 +332,74 @@ set_message(self, message: str | None) -> None Update the progress status message. -### `Progress` +### `InMemoryProgress` + + +In-memory progress tracker for immediate tool execution. + +Provides the same interface as Docket's Progress but stores state in memory +instead of Redis. Useful for testing and immediate execution where +progress doesn't need to be observable across processes. + + +**Methods:** + +#### `current` + +```python +current(self) -> int | None +``` + +#### `total` + +```python +total(self) -> int +``` + +#### `message` + +```python +message(self) -> str | None +``` + +#### `set_total` + +```python +set_total(self, total: int) -> None +``` + +Set the total/target value for progress tracking. + + +#### `increment` + +```python +increment(self, amount: int = 1) -> None +``` + +Atomically increment the current progress value. + + +#### `set_message` + +```python +set_message(self, message: str | None) -> None +``` + +Update the progress status message. + + +### `Progress` FastMCP Progress dependency that works in both server and worker contexts. -Extends Docket's Progress to handle two execution modes: -- In Docket worker: Uses the execution's progress (standard Docket behavior) -- In FastMCP server: Uses in-memory progress (not observable remotely) +Handles three execution modes: +- In Docket worker: Uses the execution's progress (observable via Redis) +- In FastMCP server with Docket: Falls back to in-memory progress +- In FastMCP server without Docket: Uses in-memory progress This allows tools to use Progress() regardless of whether they're called -immediately or as background tasks. +immediately or as background tasks, and regardless of whether pydocket +is installed. diff --git a/docs/python-sdk/fastmcp-server-elicitation.mdx b/docs/python-sdk/fastmcp-server-elicitation.mdx index c8c3267d0..47b1d0c4c 100644 --- a/docs/python-sdk/fastmcp-server-elicitation.mdx +++ b/docs/python-sdk/fastmcp-server-elicitation.mdx @@ -28,7 +28,7 @@ Supports multiple syntaxes: - Other types (dataclass, BaseModel): use directly -### `handle_elicit_accept` +### `handle_elicit_accept` ```python handle_elicit_accept(config: ElicitConfig, content: Any) -> AcceptedElicitation[Any] @@ -45,7 +45,7 @@ Handle an accepted elicitation response. - AcceptedElicitation with the extracted/validated data -### `get_elicitation_schema` +### `get_elicitation_schema` ```python get_elicitation_schema(response_type: type[T]) -> dict[str, Any] @@ -58,7 +58,7 @@ Get the schema for an elicitation response. - `response_type`: The type of the response -### `validate_elicitation_json_schema` +### `validate_elicitation_json_schema` ```python validate_elicitation_json_schema(schema: dict[str, Any]) -> None diff --git a/docs/python-sdk/fastmcp-server-http.mdx b/docs/python-sdk/fastmcp-server-http.mdx index 8aaf2c934..64e82d57d 100644 --- a/docs/python-sdk/fastmcp-server-http.mdx +++ b/docs/python-sdk/fastmcp-server-http.mdx @@ -7,13 +7,13 @@ sidebarTitle: http ## Functions -### `set_http_request` +### `set_http_request` ```python set_http_request(request: Request) -> Generator[Request, None, None] ``` -### `create_base_app` +### `create_base_app` ```python create_base_app(routes: list[BaseRoute], middleware: list[Middleware], debug: bool = False, lifespan: Callable | None = None) -> StarletteWithLifespan @@ -32,7 +32,7 @@ Create a base Starlette app with common middleware and routes. - A Starlette application -### `create_sse_app` +### `create_sse_app` ```python create_sse_app(server: FastMCP[LifespanResultT], message_path: str, sse_path: str, auth: AuthProvider | None = None, debug: bool = False, routes: list[BaseRoute] | None = None, middleware: list[Middleware] | None = None) -> StarletteWithLifespan @@ -54,7 +54,7 @@ Returns: A Starlette application with RequestContextMiddleware -### `create_streamable_http_app` +### `create_streamable_http_app` ```python create_streamable_http_app(server: FastMCP[LifespanResultT], streamable_http_path: str, event_store: EventStore | None = None, retry_interval: int | None = None, auth: AuthProvider | None = None, json_response: bool = False, stateless_http: bool = False, debug: bool = False, routes: list[BaseRoute] | None = None, middleware: list[Middleware] | None = None) -> StarletteWithLifespan @@ -83,24 +83,24 @@ disconnections. Requires event_store to be set. Defaults to SDK default. ## Classes -### `StreamableHTTPASGIApp` +### `StreamableHTTPASGIApp` ASGI application wrapper for Streamable HTTP server transport. -### `StarletteWithLifespan` +### `StarletteWithLifespan` **Methods:** -#### `lifespan` +#### `lifespan` ```python lifespan(self) -> Lifespan[Starlette] ``` -### `RequestContextMiddleware` +### `RequestContextMiddleware` -Middleware that stores each request in a ContextVar +Middleware that stores each request in a ContextVar and sets transport type. diff --git a/docs/python-sdk/fastmcp-server-low_level.mdx b/docs/python-sdk/fastmcp-server-low_level.mdx index 40ef65ff1..4a2212305 100644 --- a/docs/python-sdk/fastmcp-server-low_level.mdx +++ b/docs/python-sdk/fastmcp-server-low_level.mdx @@ -43,7 +43,20 @@ Get the FastMCP instance. create_initialization_options(self, notification_options: NotificationOptions | None = None, experimental_capabilities: dict[str, dict[str, Any]] | None = None, **kwargs: Any) -> InitializationOptions ``` -#### `run` +#### `get_capabilities` + +```python +get_capabilities(self, notification_options: NotificationOptions, experimental_capabilities: dict[str, dict[str, Any]]) -> mcp.types.ServerCapabilities +``` + +Override to set capabilities.tasks as a first-class field per SEP-1686. + +This ensures task capabilities appear in capabilities.tasks instead of +capabilities.experimental.tasks, which is required by the MCP spec and +enables proper task detection by clients like VS Code Copilot 1.107+. + + +#### `run` ```python run(self, read_stream: MemoryObjectReceiveStream[SessionMessage | Exception], write_stream: MemoryObjectSendStream[SessionMessage], initialization_options: InitializationOptions, raise_exceptions: bool = False, stateless: bool = False) @@ -52,7 +65,7 @@ run(self, read_stream: MemoryObjectReceiveStream[SessionMessage | Exception], wr Overrides the run method to use the MiddlewareServerSession. -#### `read_resource` +#### `read_resource` ```python read_resource(self) -> Callable[[Callable[[AnyUrl], Awaitable[mcp.types.ReadResourceResult | mcp.types.CreateTaskResult]]], Callable[[AnyUrl], Awaitable[mcp.types.ReadResourceResult | mcp.types.CreateTaskResult]]] @@ -67,7 +80,7 @@ This decorator can be removed once the MCP SDK adds native CreateTaskResult supp for resources. -#### `get_prompt` +#### `get_prompt` ```python get_prompt(self) -> Callable[[Callable[[str, dict[str, Any] | None], Awaitable[mcp.types.GetPromptResult | mcp.types.CreateTaskResult]]], Callable[[str, dict[str, Any] | None], Awaitable[mcp.types.GetPromptResult | mcp.types.CreateTaskResult]]] diff --git a/docs/python-sdk/fastmcp-server-middleware-authorization.mdx b/docs/python-sdk/fastmcp-server-middleware-authorization.mdx new file mode 100644 index 000000000..f5a41afdc --- /dev/null +++ b/docs/python-sdk/fastmcp-server-middleware-authorization.mdx @@ -0,0 +1,116 @@ +--- +title: authorization +sidebarTitle: authorization +--- + +# `fastmcp.server.middleware.authorization` + + +Authorization middleware for FastMCP. + +This module provides middleware-based authorization using callable auth checks. +AuthMiddleware applies auth checks globally to all components on the server. + +Example: + ```python + from fastmcp import FastMCP + from fastmcp.server.auth import require_auth, require_scopes, restrict_tag + from fastmcp.server.middleware import AuthMiddleware + + # Require auth for all components + mcp = FastMCP(middleware=[ + AuthMiddleware(auth=require_auth) + ]) + + # Tag-based: components tagged "admin" require "admin" scope + mcp = FastMCP(middleware=[ + AuthMiddleware(auth=restrict_tag("admin", scopes=["admin"])) + ]) + ``` + + +## Classes + +### `AuthMiddleware` + + +Global authorization middleware using callable checks. + +This middleware applies auth checks to all components (tools, resources, +prompts) on the server. It uses the same callable API as component-level +auth checks. + +The middleware: +- Filters tools/resources/prompts from list responses based on auth checks +- Checks auth before tool execution, resource read, and prompt render +- Skips all auth checks for STDIO transport (no OAuth concept) + +**Args:** +- `auth`: A single auth check function or list of check functions. +All checks must pass for authorization to succeed (AND logic). + + +**Methods:** + +#### `on_list_tools` + +```python +on_list_tools(self, context: MiddlewareContext[mt.ListToolsRequest], call_next: CallNext[mt.ListToolsRequest, Sequence[Tool]]) -> Sequence[Tool] +``` + +Filter tools/list response based on auth checks. + + +#### `on_call_tool` + +```python +on_call_tool(self, context: MiddlewareContext[mt.CallToolRequestParams], call_next: CallNext[mt.CallToolRequestParams, ToolResult]) -> ToolResult +``` + +Check auth before tool execution. + + +#### `on_list_resources` + +```python +on_list_resources(self, context: MiddlewareContext[mt.ListResourcesRequest], call_next: CallNext[mt.ListResourcesRequest, Sequence[Resource]]) -> Sequence[Resource] +``` + +Filter resources/list response based on auth checks. + + +#### `on_read_resource` + +```python +on_read_resource(self, context: MiddlewareContext[mt.ReadResourceRequestParams], call_next: CallNext[mt.ReadResourceRequestParams, ResourceResult]) -> ResourceResult +``` + +Check auth before resource read. + + +#### `on_list_resource_templates` + +```python +on_list_resource_templates(self, context: MiddlewareContext[mt.ListResourceTemplatesRequest], call_next: CallNext[mt.ListResourceTemplatesRequest, Sequence[ResourceTemplate]]) -> Sequence[ResourceTemplate] +``` + +Filter resource templates/list response based on auth checks. + + +#### `on_list_prompts` + +```python +on_list_prompts(self, context: MiddlewareContext[mt.ListPromptsRequest], call_next: CallNext[mt.ListPromptsRequest, Sequence[Prompt]]) -> Sequence[Prompt] +``` + +Filter prompts/list response based on auth checks. + + +#### `on_get_prompt` + +```python +on_get_prompt(self, context: MiddlewareContext[mt.GetPromptRequestParams], call_next: CallNext[mt.GetPromptRequestParams, PromptResult]) -> PromptResult +``` + +Check auth before prompt render. + diff --git a/docs/python-sdk/fastmcp-server-middleware-ping.mdx b/docs/python-sdk/fastmcp-server-middleware-ping.mdx new file mode 100644 index 000000000..fe81c216d --- /dev/null +++ b/docs/python-sdk/fastmcp-server-middleware-ping.mdx @@ -0,0 +1,32 @@ +--- +title: ping +sidebarTitle: ping +--- + +# `fastmcp.server.middleware.ping` + + +Ping middleware for keeping client connections alive. + +## Classes + +### `PingMiddleware` + + +Middleware that sends periodic pings to keep client connections alive. + +Starts a background ping task on first message from each session. The task +sends server-to-client pings at the configured interval until the session +ends. + + +**Methods:** + +#### `on_message` + +```python +on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any +``` + +Start ping task on first message from a session. + diff --git a/docs/python-sdk/fastmcp-server-providers-aggregate.mdx b/docs/python-sdk/fastmcp-server-providers-aggregate.mdx new file mode 100644 index 000000000..61b90c87f --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-aggregate.mdx @@ -0,0 +1,139 @@ +--- +title: aggregate +sidebarTitle: aggregate +--- + +# `fastmcp.server.providers.aggregate` + + +AggregateProvider for combining multiple providers into one. + +This module provides `AggregateProvider` which presents multiple providers +as a single unified provider. Used internally by FastMCP for aggregating +components from all providers. + + +## Classes + +### `AggregateProvider` + + +Presents multiple providers as a single provider. + +Components are aggregated from all providers. For get_* operations, +providers are queried in parallel and the highest version is returned. + +Errors from individual providers are logged and skipped (graceful degradation). + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self) -> Sequence[Tool] +``` + +List all tools from all providers (with transforms applied). + + +#### `get_tool` + +```python +get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None +``` + +Get tool by name. + +**Args:** +- `name`: The tool name. +- `version`: If None, returns highest version across all providers. +If specified, returns highest version matching the spec from any provider. + + +#### `list_resources` + +```python +list_resources(self) -> Sequence[Resource] +``` + +List all resources from all providers (with transforms applied). + + +#### `get_resource` + +```python +get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None +``` + +Get resource by URI. + +**Args:** +- `uri`: The resource URI. +- `version`: If None, returns highest version across all providers. +If specified, returns highest version matching the spec from any provider. + + +#### `list_resource_templates` + +```python +list_resource_templates(self) -> Sequence[ResourceTemplate] +``` + +List all resource templates from all providers (with transforms applied). + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None +``` + +Get resource template by URI. + +**Args:** +- `uri`: The template URI to match. +- `version`: If None, returns highest version across all providers. +If specified, returns highest version matching the spec from any provider. + + +#### `list_prompts` + +```python +list_prompts(self) -> Sequence[Prompt] +``` + +List all prompts from all providers (with transforms applied). + + +#### `get_prompt` + +```python +get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None +``` + +Get prompt by name. + +**Args:** +- `name`: The prompt name. +- `version`: If None, returns highest version across all providers. +If specified, returns highest version matching the spec from any provider. + + +#### `get_tasks` + +```python +get_tasks(self) -> Sequence[FastMCPComponent] +``` + +Get all task-eligible components from all providers. + + +#### `lifespan` + +```python +lifespan(self) -> AsyncIterator[None] +``` + +Combine lifespans of all providers. + diff --git a/docs/python-sdk/fastmcp-server-providers-base.mdx b/docs/python-sdk/fastmcp-server-providers-base.mdx index 12c036a08..623c24e21 100644 --- a/docs/python-sdk/fastmcp-server-providers-base.mdx +++ b/docs/python-sdk/fastmcp-server-providers-base.mdx @@ -36,7 +36,7 @@ Example: ## Classes -### `Provider` +### `Provider` Base class for dynamic component providers. @@ -48,44 +48,22 @@ supports. **Methods:** -#### `with_transforms` +#### `add_transform` ```python -with_transforms(self) -> Provider +add_transform(self, transform: Transform) -> None ``` -Apply transformations to this provider's components. +Add a transform to this provider. -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. +Transforms modify components (tools, resources, prompts) as they flow +through the provider. They're applied in order - first added is innermost. **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. +- `transform`: The transform to add. -#### `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` +#### `list_tools` ```python list_tools(self) -> Sequence[Tool] @@ -93,25 +71,31 @@ list_tools(self) -> Sequence[Tool] Return all available tools. -Override to provide tools dynamically. +Override to provide tools dynamically. Returns ALL versions of all tools. +The server handles deduplication to show one tool per name. -#### `get_tool` +#### `get_tool` ```python -get_tool(self, name: str) -> Tool | None +get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None ``` Get a specific tool by name. -Default implementation lists all tools and finds by name. -Override for more efficient single-tool lookup. +Default implementation filters list_tools() and picks the highest version +that matches the spec. + +**Args:** +- `name`: The tool name. +- `version`: Optional version filter. If None, returns highest version. + If specified, returns highest version matching the spec. **Returns:** - The Tool if found, or None to continue searching other providers. -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> Sequence[Resource] @@ -119,25 +103,30 @@ list_resources(self) -> Sequence[Resource] Return all available resources. -Override to provide resources dynamically. +Override to provide resources dynamically. Returns ALL versions of all resources. +The server handles deduplication to show one resource per URI. -#### `get_resource` +#### `get_resource` ```python -get_resource(self, uri: str) -> Resource | None +get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None ``` Get a specific resource by URI. -Default implementation lists all resources and finds by URI. -Override for more efficient single-resource lookup. +Default implementation filters list_resources() and returns highest +version matching the spec. + +**Args:** +- `uri`: The resource URI. +- `version`: Optional version filter. If None, returns highest version. **Returns:** - The Resource if found, or None to continue searching other providers. -#### `list_resource_templates` +#### `list_resource_templates` ```python list_resource_templates(self) -> Sequence[ResourceTemplate] @@ -145,26 +134,30 @@ list_resource_templates(self) -> Sequence[ResourceTemplate] Return all available resource templates. -Override to provide resource templates dynamically. +Override to provide resource templates dynamically. Returns ALL versions. +The server handles deduplication. -#### `get_resource_template` +#### `get_resource_template` ```python -get_resource_template(self, uri: str) -> ResourceTemplate | None +get_resource_template(self, uri: str, version: VersionSpec | None = None) -> 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. +Default implementation lists all templates, finds those whose pattern +matches the URI, and returns the highest version matching the spec. + +**Args:** +- `uri`: The URI to match against templates. +- `version`: Optional version filter. If None, returns highest version. **Returns:** - The ResourceTemplate if a matching one is found, or None to continue searching. -#### `list_prompts` +#### `list_prompts` ```python list_prompts(self) -> Sequence[Prompt] @@ -172,40 +165,30 @@ list_prompts(self) -> Sequence[Prompt] Return all available prompts. -Override to provide prompts dynamically. +Override to provide prompts dynamically. Returns ALL versions of all prompts. +The server handles deduplication to show one prompt per name. -#### `get_prompt` +#### `get_prompt` ```python -get_prompt(self, name: str) -> Prompt | None +get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None ``` Get a specific prompt by name. -Default implementation lists all prompts and finds by name. -Override for more efficient single-prompt lookup. +Default implementation filters list_prompts() and picks the highest version +matching the spec. + +**Args:** +- `name`: The prompt name. +- `version`: Optional version filter. If None, returns highest version. **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` +#### `get_tasks` ```python get_tasks(self) -> Sequence[FastMCPComponent] @@ -214,13 +197,13 @@ 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 components -with task_config.mode != 'forbidden'. +Default calls list_* methods, applies provider transforms, and filters +for components with task_config.mode != 'forbidden'. Used by the server during startup to register functions with Docket. -#### `lifespan` +#### `lifespan` ```python lifespan(self) -> AsyncIterator[None] @@ -236,7 +219,7 @@ The lifespan scope matches the server's lifespan - code before yield runs at startup, code after yield runs at shutdown. -#### `enable` +#### `enable` ```python enable(self) -> None @@ -245,12 +228,12 @@ 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"). +- `keys`: Keys to enable (e.g., "tool\:my_tool@" for unversioned, "tool\:my_tool@1.0" for versioned). - `tags`: Tags to enable - components with these tags will be enabled. - `only`: If True, switches to allowlist mode - ONLY show these keys/tags. -#### `disable` +#### `disable` ```python disable(self) -> None @@ -259,6 +242,6 @@ disable(self) -> None Disable components by adding to the blocklist. **Args:** -- `keys`: Keys to disable (e.g., "tool\:my_tool"). +- `keys`: Keys to disable (e.g., "tool\:my_tool@" for unversioned, "tool\:my_tool@1.0" for versioned). - `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 index 32f940c04..b12db1ca1 100644 --- a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx +++ b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx @@ -18,7 +18,7 @@ executed. ## Classes -### `FastMCPProviderTool` +### `FastMCPProviderTool` Tool that delegates execution to a wrapped server's middleware. @@ -30,7 +30,7 @@ chain is executed. **Methods:** -#### `wrap` +#### `wrap` ```python wrap(cls, server: Any, tool: Tool) -> FastMCPProviderTool @@ -39,19 +39,25 @@ wrap(cls, server: Any, tool: Tool) -> FastMCPProviderTool Wrap a Tool to delegate execution to the server's middleware. -#### `run` +#### `run` ```python -run(self, arguments: dict[str, Any]) -> ToolResult | mcp.types.CreateTaskResult +run(self, arguments: dict[str, Any]) -> ToolResult ``` -Not implemented - use _run() which delegates to child server. +Delegate to child server's call_tool() without task_meta. -FastMCPProviderTool._run() handles all execution by delegating -to the child server's call_tool() with task_meta. +This is called when the tool is used within a TransformedTool +forwarding function or other contexts where task_meta is not available. -### `FastMCPProviderResource` +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +### `FastMCPProviderResource` Resource that delegates reading to a wrapped server's read_resource(). @@ -62,7 +68,7 @@ When `read()` is called, this resource invokes the wrapped server's **Methods:** -#### `wrap` +#### `wrap` ```python wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource @@ -71,7 +77,13 @@ wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource Wrap a Resource to delegate reading to the server's middleware. -### `FastMCPProviderPrompt` +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +### `FastMCPProviderPrompt` Prompt that delegates rendering to a wrapped server's render_prompt(). @@ -82,7 +94,7 @@ When `render()` is called, this prompt invokes the wrapped server's **Methods:** -#### `wrap` +#### `wrap` ```python wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt @@ -91,19 +103,25 @@ wrap(cls, server: Any, prompt: Prompt) -> FastMCPProviderPrompt Wrap a Prompt to delegate rendering to the server's middleware. -#### `render` +#### `render` ```python -render(self, arguments: dict[str, Any] | None = None) -> PromptResult | mcp.types.CreateTaskResult +render(self, arguments: dict[str, Any] | None = None) -> PromptResult ``` -Not implemented - use _render() which delegates to child server. +Delegate to child server's render_prompt() without task_meta. -FastMCPProviderPrompt._render() handles all execution by delegating -to the child server's render_prompt() with task_meta. +This is called when the prompt is used within a transformed context +or other contexts where task_meta is not available. -### `FastMCPProviderResourceTemplate` +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +### `FastMCPProviderResourceTemplate` Resource template that creates FastMCPProviderResources. @@ -115,7 +133,7 @@ when read. **Methods:** -#### `wrap` +#### `wrap` ```python wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTemplate @@ -124,7 +142,7 @@ wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTem Wrap a ResourceTemplate to create FastMCPProviderResources. -#### `create_resource` +#### `create_resource` ```python create_resource(self, uri: str, params: dict[str, Any]) -> Resource @@ -137,7 +155,7 @@ We use `_original_uri_template` with `params` to construct the internal URI that the nested server understands. -#### `read` +#### `read` ```python read(self, arguments: dict[str, Any]) -> str | bytes | ResourceResult @@ -149,7 +167,7 @@ Reads the resource via the wrapped server and returns the ResourceResult. This method is called by Docket during background task execution. -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None @@ -158,7 +176,7 @@ register_with_docket(self, docket: Docket) -> None No-op: the child's actual template is registered via get_tasks(). -#### `add_to_docket` +#### `add_to_docket` ```python add_to_docket(self, docket: Docket, params: dict[str, Any], **kwargs: Any) -> Execution @@ -170,7 +188,13 @@ The child's FunctionResourceTemplate.fn is registered (via get_tasks), and it expects splatted **kwargs, so we splat params here. -### `FastMCPProvider` +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +### `FastMCPProvider` Provider that wraps a FastMCP server. @@ -186,7 +210,7 @@ This ensures middleware runs when components are executed. **Methods:** -#### `list_tools` +#### `list_tools` ```python list_tools(self) -> Sequence[Tool] @@ -199,16 +223,19 @@ each tool as a FastMCPProviderTool that delegates execution to the nested server's middleware. -#### `get_tool` +#### `get_tool` ```python -get_tool(self, name: str) -> Tool | None +get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None ``` Get a tool by name as a FastMCPProviderTool. +Passes the full VersionSpec to the nested server, which handles both +exact version matching and range filtering. -#### `list_resources` + +#### `list_resources` ```python list_resources(self) -> Sequence[Resource] @@ -221,16 +248,19 @@ each resource as a FastMCPProviderResource that delegates reading to the nested server's middleware. -#### `get_resource` +#### `get_resource` ```python -get_resource(self, uri: str) -> Resource | None +get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None ``` Get a concrete resource by URI as a FastMCPProviderResource. +Passes the full VersionSpec to the nested server, which handles both +exact version matching and range filtering. -#### `list_resource_templates` + +#### `list_resource_templates` ```python list_resource_templates(self) -> Sequence[ResourceTemplate] @@ -242,16 +272,19 @@ Returns FastMCPProviderResourceTemplate instances that create FastMCPProviderResources when materialized. -#### `get_resource_template` +#### `get_resource_template` ```python -get_resource_template(self, uri: str) -> ResourceTemplate | None +get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None ``` Get a resource template that matches the given URI. +Passes the full VersionSpec to the nested server, which handles both +exact version matching and range filtering. -#### `list_prompts` + +#### `list_prompts` ```python list_prompts(self) -> Sequence[Prompt] @@ -263,16 +296,19 @@ Returns FastMCPProviderPrompt instances that delegate rendering to the wrapped server's middleware. -#### `get_prompt` +#### `get_prompt` ```python -get_prompt(self, name: str) -> Prompt | None +get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None ``` Get a prompt by name as a FastMCPProviderPrompt. +Passes the full VersionSpec to the nested server, which handles both +exact version matching and range filtering. -#### `get_tasks` + +#### `get_tasks` ```python get_tasks(self) -> Sequence[FastMCPComponent] @@ -281,14 +317,12 @@ 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. +functions get registered with Docket. Uses _source_get_tasks() to get +components with child server's transforms applied, then applies this +provider's transforms for correct registration keys. -#### `lifespan` +#### `lifespan` ```python lifespan(self) -> AsyncIterator[None] diff --git a/docs/python-sdk/fastmcp-server-providers-filesystem.mdx b/docs/python-sdk/fastmcp-server-providers-filesystem.mdx new file mode 100644 index 000000000..55e9b342c --- /dev/null +++ b/docs/python-sdk/fastmcp-server-providers-filesystem.mdx @@ -0,0 +1,128 @@ +--- +title: filesystem +sidebarTitle: filesystem +--- + +# `fastmcp.server.providers.filesystem` + + +FileSystemProvider for filesystem-based component discovery. + +FileSystemProvider scans a directory for Python files, imports them, and +registers any Tool, Resource, ResourceTemplate, or Prompt objects found. + +Components are created using the standalone decorators from fastmcp.tools, +fastmcp.resources, and fastmcp.prompts: + +Example: + ```python + # In mcp/tools.py + from fastmcp.tools import tool + + @tool + def greet(name: str) -> str: + return f"Hello, {name}!" + + # In main.py + from pathlib import Path + + from fastmcp import FastMCP + from fastmcp.server.providers import FileSystemProvider + + mcp = FastMCP("MyServer", providers=[FileSystemProvider(Path(__file__).parent / "mcp")]) + ``` + + +## Classes + +### `FileSystemProvider` + + +Provider that discovers components from the filesystem. + +Scans a directory for Python files and registers any Tool, Resource, +ResourceTemplate, or Prompt objects found. Components are created using +the standalone decorators: +- @tool from fastmcp.tools +- @resource from fastmcp.resources +- @prompt from fastmcp.prompts + +**Args:** +- `root`: Root directory to scan. Defaults to current directory. +- `reload`: If True, re-scan files on every request (dev mode). +Defaults to False (scan once at init, cache results). + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self) -> Sequence[Tool] +``` + +Return all tools, reloading if in reload mode. + + +#### `get_tool` + +```python +get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None +``` + +Get a tool by name, reloading if in reload mode. + + +#### `list_resources` + +```python +list_resources(self) -> Sequence[Resource] +``` + +Return all resources, reloading if in reload mode. + + +#### `get_resource` + +```python +get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None +``` + +Get a resource by URI, reloading if in reload mode. + + +#### `list_resource_templates` + +```python +list_resource_templates(self) -> Sequence[ResourceTemplate] +``` + +Return all resource templates, reloading if in reload mode. + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None +``` + +Get a resource template, reloading if in reload mode. + + +#### `list_prompts` + +```python +list_prompts(self) -> Sequence[Prompt] +``` + +Return all prompts, reloading if in reload mode. + + +#### `get_prompt` + +```python +get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None +``` + +Get a prompt by name, reloading if in reload mode. + diff --git a/docs/python-sdk/fastmcp-fs-discovery.mdx b/docs/python-sdk/fastmcp-server-providers-filesystem_discovery.mdx similarity index 55% rename from docs/python-sdk/fastmcp-fs-discovery.mdx rename to docs/python-sdk/fastmcp-server-providers-filesystem_discovery.mdx index 4d6720be4..0a02129c9 100644 --- a/docs/python-sdk/fastmcp-fs-discovery.mdx +++ b/docs/python-sdk/fastmcp-server-providers-filesystem_discovery.mdx @@ -1,9 +1,9 @@ --- -title: discovery -sidebarTitle: discovery +title: filesystem_discovery +sidebarTitle: filesystem_discovery --- -# `fastmcp.fs.discovery` +# `fastmcp.server.providers.filesystem_discovery` File discovery and module import utilities for filesystem-based routing. @@ -11,12 +11,12 @@ File discovery and module import utilities for filesystem-based routing. This module provides functions to: 1. Discover Python files in a directory tree 2. Import modules (as packages if __init__.py exists, else directly) -3. Extract decorated functions from imported modules +3. Extract decorated components (Tool, Resource, Prompt objects) from imported modules ## Functions -### `discover_files` +### `discover_files` ```python discover_files(root: Path) -> list[Path] @@ -34,7 +34,7 @@ Excludes __init__.py files (they're for package structure, not components). - List of .py file paths, sorted for deterministic order. -### `import_module_from_file` +### `import_module_from_file` ```python import_module_from_file(file_path: Path) -> ModuleType @@ -57,26 +57,27 @@ imports directly using spec_from_file_location. - `ImportError`: If the module cannot be imported. -### `extract_components` +### `extract_components` ```python -extract_components(module: ModuleType) -> list[tuple[Any, FSMeta]] +extract_components(module: ModuleType) -> list[FastMCPComponent] ``` -Extract all decorated functions from a module. +Extract all MCP components from a module. -Scans all module attributes for functions that have been decorated -with @tool, @resource, or @prompt. +Scans all module attributes for instances of Tool, Resource, +ResourceTemplate, or Prompt objects created by standalone decorators, +or functions decorated with @tool/@resource/@prompt that have __fastmcp__ metadata. **Args:** - `module`: The imported module to scan. **Returns:** -- List of (function, metadata) tuples for each decorated function. +- List of component objects (Tool, Resource, ResourceTemplate, Prompt). -### `discover_and_import` +### `discover_and_import` ```python discover_and_import(root: Path) -> DiscoveryResult @@ -96,7 +97,7 @@ This is the main entry point for filesystem-based discovery. ## Classes -### `DiscoveryResult` +### `DiscoveryResult` Result of filesystem discovery. diff --git a/docs/python-sdk/fastmcp-server-providers-local_provider.mdx b/docs/python-sdk/fastmcp-server-providers-local_provider.mdx index f002b48b1..247d9e1ba 100644 --- a/docs/python-sdk/fastmcp-server-providers-local_provider.mdx +++ b/docs/python-sdk/fastmcp-server-providers-local_provider.mdx @@ -47,43 +47,61 @@ like `_tool_serializer` and `_support_tasks_by_default` are injected. **Methods:** -#### `add_tool` +#### `add_tool` ```python -add_tool(self, tool: Tool) -> Tool +add_tool(self, tool: Tool | Callable[..., Any]) -> Tool ``` Add a tool to this provider's storage. +Accepts either a Tool object or a decorated function with __fastmcp__ metadata. -#### `remove_tool` + +#### `remove_tool` ```python -remove_tool(self, name: str) -> None +remove_tool(self, name: str, version: str | None = None) -> None ``` -Remove a tool from this provider's storage. +Remove tool(s) from this provider's storage. + +**Args:** +- `name`: The tool name. +- `version`: If None, removes ALL versions. If specified, removes only that version. + +**Raises:** +- `KeyError`: If no matching tool is found. -#### `add_resource` +#### `add_resource` ```python -add_resource(self, resource: Resource) -> Resource +add_resource(self, resource: Resource | ResourceTemplate | Callable[..., Any]) -> Resource | ResourceTemplate ``` Add a resource to this provider's storage. +Accepts either a Resource/ResourceTemplate object or a decorated function with __fastmcp__ metadata. -#### `remove_resource` + +#### `remove_resource` ```python -remove_resource(self, uri: str) -> None +remove_resource(self, uri: str, version: str | None = None) -> None ``` -Remove a resource from this provider's storage. +Remove resource(s) from this provider's storage. + +**Args:** +- `uri`: The resource URI. +- `version`: If None, removes ALL versions. If specified, removes only that version. + +**Raises:** +- `KeyError`: If no matching resource is found. -#### `add_template` +#### `add_template` ```python add_template(self, template: ResourceTemplate) -> ResourceTemplate @@ -92,92 +110,72 @@ add_template(self, template: ResourceTemplate) -> ResourceTemplate Add a resource template to this provider's storage. -#### `remove_template` +#### `remove_template` ```python -remove_template(self, uri_template: str) -> None +remove_template(self, uri_template: str, version: str | None = None) -> None ``` -Remove a resource template from this provider's storage. +Remove resource template(s) from this provider's storage. + +**Args:** +- `uri_template`: The template URI pattern. +- `version`: If None, removes ALL versions. If specified, removes only that version. + +**Raises:** +- `KeyError`: If no matching template is found. -#### `add_prompt` +#### `add_prompt` ```python -add_prompt(self, prompt: Prompt) -> Prompt +add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt ``` Add a prompt to this provider's storage. +Accepts either a Prompt object or a decorated function with __fastmcp__ metadata. -#### `remove_prompt` + +#### `remove_prompt` ```python -remove_prompt(self, name: str) -> None +remove_prompt(self, name: str, version: str | None = None) -> 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. +Remove prompt(s) from this provider's storage. **Args:** -- `tool_name`: The name of the tool to transform. -- `transformation`: The transformation configuration. +- `name`: The prompt name. +- `version`: If None, removes ALL versions. If specified, removes only that version. + +**Raises:** +- `KeyError`: If no matching prompt is found. -#### `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` +#### `list_tools` ```python list_tools(self) -> Sequence[Tool] ``` -Return all visible tools with transformations applied. +Return all visible tools. -#### `get_tool` +#### `get_tool` ```python -get_tool(self, name: str) -> Tool | None +get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None ``` -Get a tool by name, with transformations applied. +Get a tool by name. + +**Args:** +- `name`: The tool name. +- `version`: Optional version filter. If None, returns highest version. -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> Sequence[Resource] @@ -186,16 +184,20 @@ list_resources(self) -> Sequence[Resource] Return all visible resources. -#### `get_resource` +#### `get_resource` ```python -get_resource(self, uri: str) -> Resource | None +get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None ``` -Get a resource by URI if visible. +Get a resource by URI. + +**Args:** +- `uri`: The resource URI. +- `version`: Optional version filter. If None, returns highest version. -#### `list_resource_templates` +#### `list_resource_templates` ```python list_resource_templates(self) -> Sequence[ResourceTemplate] @@ -204,16 +206,20 @@ list_resource_templates(self) -> Sequence[ResourceTemplate] Return all visible resource templates. -#### `get_resource_template` +#### `get_resource_template` ```python -get_resource_template(self, uri: str) -> ResourceTemplate | None +get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None ``` -Get a resource template that matches the given URI if visible. +Get a resource template that matches the given URI. + +**Args:** +- `uri`: The URI to match against templates. +- `version`: Optional version filter. If None, returns highest version. -#### `list_prompts` +#### `list_prompts` ```python list_prompts(self) -> Sequence[Prompt] @@ -222,27 +228,20 @@ list_prompts(self) -> Sequence[Prompt] Return all visible prompts. -#### `get_prompt` +#### `get_prompt` ```python -get_prompt(self, name: str) -> Prompt | None +get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None ``` -Get a prompt by name if visible. +Get a prompt by name. + +**Args:** +- `name`: The prompt name. +- `version`: Optional version filter. If None, returns highest version. -#### `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` +#### `get_tasks` ```python get_tasks(self) -> Sequence[FastMCPComponent] @@ -255,19 +254,19 @@ This includes both FunctionTool/Resource/Prompt instances created via decorators and custom Tool/Resource/Prompt subclasses. -#### `tool` +#### `tool` ```python tool(self, name_or_fn: AnyFunction) -> FunctionTool ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool] ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool] @@ -301,10 +300,10 @@ This decorator supports multiple calling patterns: - The registered FunctionTool or a decorator function. -#### `resource` +#### `resource` ```python -resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate] +resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate | AnyFunction] ``` Decorator to register a function as a resource. @@ -324,24 +323,25 @@ has parameters, it will be registered as a template resource. - `annotations`: Optional annotations about the resource's behavior - `meta`: Optional meta information about the resource - `task`: Optional task configuration for background execution +- `auth`: Optional authorization checks for the resource **Returns:** - A decorator function. -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt ``` -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt] ``` -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt] @@ -366,6 +366,7 @@ This decorator supports multiple calling patterns: - `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 +- `auth`: Optional authorization checks for the prompt **Returns:** - The registered FunctionPrompt or a decorator function. diff --git a/docs/python-sdk/fastmcp-server-providers-openapi-provider.mdx b/docs/python-sdk/fastmcp-server-providers-openapi-provider.mdx index 2df5a6449..2e262c525 100644 --- a/docs/python-sdk/fastmcp-server-providers-openapi-provider.mdx +++ b/docs/python-sdk/fastmcp-server-providers-openapi-provider.mdx @@ -10,7 +10,7 @@ OpenAPIProvider for creating MCP components from OpenAPI specifications. ## Classes -### `OpenAPIProvider` +### `OpenAPIProvider` Provider that creates MCP components from an OpenAPI specification. @@ -21,7 +21,7 @@ spec. Each component makes HTTP calls to the described API endpoints. **Methods:** -#### `list_tools` +#### `list_tools` ```python list_tools(self) -> Sequence[Tool] @@ -30,16 +30,16 @@ list_tools(self) -> Sequence[Tool] Return all tools created from the OpenAPI spec. -#### `get_tool` +#### `get_tool` ```python -get_tool(self, name: str) -> Tool | None +get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None ``` Get a tool by name. -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> Sequence[Resource] @@ -48,16 +48,16 @@ list_resources(self) -> Sequence[Resource] Return all resources created from the OpenAPI spec. -#### `get_resource` +#### `get_resource` ```python -get_resource(self, uri: str) -> Resource | None +get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None ``` Get a resource by URI. -#### `list_resource_templates` +#### `list_resource_templates` ```python list_resource_templates(self) -> Sequence[ResourceTemplate] @@ -66,16 +66,16 @@ list_resource_templates(self) -> Sequence[ResourceTemplate] Return all resource templates created from the OpenAPI spec. -#### `get_resource_template` +#### `get_resource_template` ```python -get_resource_template(self, uri: str) -> ResourceTemplate | None +get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None ``` Get a resource template that matches the given URI. -#### `list_prompts` +#### `list_prompts` ```python list_prompts(self) -> Sequence[Prompt] @@ -84,7 +84,7 @@ list_prompts(self) -> Sequence[Prompt] Return empty list - OpenAPI doesn't create prompts. -#### `get_tasks` +#### `get_tasks` ```python get_tasks(self) -> Sequence[FastMCPComponent] diff --git a/docs/python-sdk/fastmcp-server-providers-proxy.mdx b/docs/python-sdk/fastmcp-server-providers-proxy.mdx index 90e779647..55aca8243 100644 --- a/docs/python-sdk/fastmcp-server-providers-proxy.mdx +++ b/docs/python-sdk/fastmcp-server-providers-proxy.mdx @@ -15,7 +15,7 @@ classes that forward execution to remote servers. ## Functions -### `default_proxy_roots_handler` +### `default_proxy_roots_handler` ```python default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanContextT]) -> RootsList @@ -25,7 +25,7 @@ default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanConte Forward list roots request from remote server to proxy's connected clients. -### `default_proxy_sampling_handler` +### `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 @@ -35,7 +35,7 @@ default_proxy_sampling_handler(messages: list[mcp.types.SamplingMessage], params Forward sampling request from remote server to proxy's connected clients. -### `default_proxy_elicitation_handler` +### `default_proxy_elicitation_handler` ```python default_proxy_elicitation_handler(message: str, response_type: type, params: mcp.types.ElicitRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> ElicitResult @@ -45,7 +45,7 @@ default_proxy_elicitation_handler(message: str, response_type: type, params: mcp Forward elicitation request from remote server to proxy's connected clients. -### `default_proxy_log_handler` +### `default_proxy_log_handler` ```python default_proxy_log_handler(message: LogMessage) -> None @@ -55,7 +55,7 @@ default_proxy_log_handler(message: LogMessage) -> None Forward log notification from remote server to proxy's connected clients. -### `default_proxy_progress_handler` +### `default_proxy_progress_handler` ```python default_proxy_progress_handler(progress: float, total: float | None, message: str | None) -> None @@ -67,7 +67,7 @@ Forward progress notification from remote server to proxy's connected clients. ## Classes -### `ProxyTool` +### `ProxyTool` A Tool that represents and executes a tool on a remote server. @@ -75,7 +75,7 @@ A Tool that represents and executes a tool on a remote server. **Methods:** -#### `model_copy` +#### `model_copy` ```python model_copy(self, **kwargs: Any) -> ProxyTool @@ -84,7 +84,7 @@ model_copy(self, **kwargs: Any) -> ProxyTool Override to preserve _backend_name when name changes. -#### `from_mcp_tool` +#### `from_mcp_tool` ```python from_mcp_tool(cls, client_factory: ClientFactoryT, mcp_tool: mcp.types.Tool) -> ProxyTool @@ -93,7 +93,7 @@ from_mcp_tool(cls, client_factory: ClientFactoryT, mcp_tool: mcp.types.Tool) -> Factory method to create a ProxyTool from a raw MCP tool schema. -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResult @@ -102,7 +102,13 @@ run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResu Executes the tool by making a call through the client. -### `ProxyResource` +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +### `ProxyResource` A Resource that represents and reads a resource from a remote server. @@ -110,7 +116,7 @@ A Resource that represents and reads a resource from a remote server. **Methods:** -#### `model_copy` +#### `model_copy` ```python model_copy(self, **kwargs: Any) -> ProxyResource @@ -119,7 +125,7 @@ model_copy(self, **kwargs: Any) -> ProxyResource Override to preserve _backend_uri when uri changes. -#### `from_mcp_resource` +#### `from_mcp_resource` ```python from_mcp_resource(cls, client_factory: ClientFactoryT, mcp_resource: mcp.types.Resource) -> ProxyResource @@ -128,7 +134,7 @@ from_mcp_resource(cls, client_factory: ClientFactoryT, mcp_resource: mcp.types.R Factory method to create a ProxyResource from a raw MCP resource schema. -#### `read` +#### `read` ```python read(self) -> ResourceResult @@ -137,7 +143,13 @@ read(self) -> ResourceResult Read the resource content from the remote server. -### `ProxyTemplate` +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +### `ProxyTemplate` A ResourceTemplate that represents and creates resources from a remote server template. @@ -145,7 +157,7 @@ A ResourceTemplate that represents and creates resources from a remote server te **Methods:** -#### `model_copy` +#### `model_copy` ```python model_copy(self, **kwargs: Any) -> ProxyTemplate @@ -154,7 +166,7 @@ model_copy(self, **kwargs: Any) -> ProxyTemplate Override to preserve _backend_uri_template when uri_template changes. -#### `from_mcp_template` +#### `from_mcp_template` ```python from_mcp_template(cls, client_factory: ClientFactoryT, mcp_template: mcp.types.ResourceTemplate) -> ProxyTemplate @@ -163,7 +175,7 @@ from_mcp_template(cls, client_factory: ClientFactoryT, mcp_template: mcp.types.R Factory method to create a ProxyTemplate from a raw MCP template schema. -#### `create_resource` +#### `create_resource` ```python create_resource(self, uri: str, params: dict[str, Any], context: Context | None = None) -> ProxyResource @@ -172,7 +184,13 @@ create_resource(self, uri: str, params: dict[str, Any], context: Context | None Create a resource from the template by calling the remote server. -### `ProxyPrompt` +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +### `ProxyPrompt` A Prompt that represents and renders a prompt from a remote server. @@ -180,7 +198,7 @@ A Prompt that represents and renders a prompt from a remote server. **Methods:** -#### `model_copy` +#### `model_copy` ```python model_copy(self, **kwargs: Any) -> ProxyPrompt @@ -189,7 +207,7 @@ model_copy(self, **kwargs: Any) -> ProxyPrompt Override to preserve _backend_name when name changes. -#### `from_mcp_prompt` +#### `from_mcp_prompt` ```python from_mcp_prompt(cls, client_factory: ClientFactoryT, mcp_prompt: mcp.types.Prompt) -> ProxyPrompt @@ -198,7 +216,7 @@ from_mcp_prompt(cls, client_factory: ClientFactoryT, mcp_prompt: mcp.types.Promp Factory method to create a ProxyPrompt from a raw MCP prompt schema. -#### `render` +#### `render` ```python render(self, arguments: dict[str, Any]) -> PromptResult @@ -207,7 +225,13 @@ render(self, arguments: dict[str, Any]) -> PromptResult Render the prompt by making a call through the client. -### `ProxyProvider` +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +### `ProxyProvider` Provider that proxies to a remote MCP server via a client factory. @@ -221,7 +245,7 @@ because tasks cannot be executed through a proxy. **Methods:** -#### `list_tools` +#### `list_tools` ```python list_tools(self) -> Sequence[Tool] @@ -230,7 +254,7 @@ list_tools(self) -> Sequence[Tool] List all tools from the remote server. -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> Sequence[Resource] @@ -239,7 +263,7 @@ list_resources(self) -> Sequence[Resource] List all resources from the remote server. -#### `list_resource_templates` +#### `list_resource_templates` ```python list_resource_templates(self) -> Sequence[ResourceTemplate] @@ -248,7 +272,7 @@ list_resource_templates(self) -> Sequence[ResourceTemplate] List all resource templates from the remote server. -#### `list_prompts` +#### `list_prompts` ```python list_prompts(self) -> Sequence[Prompt] @@ -257,7 +281,7 @@ list_prompts(self) -> Sequence[Prompt] List all prompts from the remote server. -#### `get_tasks` +#### `get_tasks` ```python get_tasks(self) -> Sequence[FastMCPComponent] @@ -270,7 +294,7 @@ server lifespan initialization, which would open the client before any context is set. All Proxy* components have task_config.mode="forbidden". -### `FastMCPProxy` +### `FastMCPProxy` A FastMCP server that acts as a proxy to a remote MCP-compliant server. @@ -279,7 +303,7 @@ This is a convenience wrapper that creates a FastMCP server with a ProxyProvider. For more control, use FastMCP with add_provider(ProxyProvider(...)). -### `ProxyClient` +### `ProxyClient` A proxy client that forwards advanced interactions between a remote MCP server and the proxy's connected clients. @@ -287,7 +311,7 @@ A proxy client that forwards advanced interactions between a remote MCP server a Supports forwarding roots, sampling, elicitation, logging, and progress. -### `StatefulProxyClient` +### `StatefulProxyClient` A proxy client that provides a stateful client factory for the proxy server. @@ -301,7 +325,7 @@ Note that it is essential to ensure that the proxy server itself is also statefu **Methods:** -#### `clear` +#### `clear` ```python clear(self) @@ -310,7 +334,7 @@ clear(self) Clear all cached clients and force disconnect them. -#### `new_stateful` +#### `new_stateful` ```python new_stateful(self) -> Client[ClientTransportT] diff --git a/docs/python-sdk/fastmcp-server-providers-transforming.mdx b/docs/python-sdk/fastmcp-server-providers-transforming.mdx deleted file mode 100644 index 94952eac2..000000000 --- a/docs/python-sdk/fastmcp-server-providers-transforming.mdx +++ /dev/null @@ -1,117 +0,0 @@ ---- -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-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx index da73702c3..0268f02b6 100644 --- a/docs/python-sdk/fastmcp-server-server.mdx +++ b/docs/python-sdk/fastmcp-server-server.mdx @@ -10,7 +10,7 @@ FastMCP - A more ergonomic interface for MCP servers. ## Functions -### `default_lifespan` +### `default_lifespan` ```python default_lifespan(server: FastMCP[LifespanResultT]) -> AsyncIterator[Any] @@ -26,7 +26,7 @@ Default lifespan context manager that does nothing. - An empty dictionary as the lifespan result. -### `create_proxy` +### `create_proxy` ```python create_proxy(target: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy @@ -54,53 +54,59 @@ use `FastMCPProxy` or `ProxyProvider` directly from `fastmcp.server.providers.pr ## Classes -### `FastMCP` +### `StateValue` + + +Wrapper for stored context state values. + + +### `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 @@ -111,7 +117,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 | None = None, **transport_kwargs: Any) -> None @@ -125,7 +131,7 @@ Run the FastMCP server asynchronously. FASTMCP_SHOW_SERVER_BANNER setting (default\: True). -#### `run` +#### `run` ```python run(self, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None @@ -139,13 +145,13 @@ Run the FastMCP server. Note this is a synchronous function. FASTMCP_SHOW_SERVER_BANNER setting (default\: True). -#### `add_middleware` +#### `add_middleware` ```python add_middleware(self, middleware: Middleware) -> None ``` -#### `add_provider` +#### `add_provider` ```python add_provider(self, provider: Provider) -> None @@ -161,7 +167,46 @@ always take precedence over providers. - `provider`: A Provider instance that will provide components dynamically. -#### `enable` +#### `add_transform` + +```python +add_transform(self, transform: Transform) -> None +``` + +Add a server-level transform. + +Server-level transforms are applied after all providers are aggregated. +They transform tools, resources, and prompts from ALL providers. + +**Args:** +- `transform`: The transform to add. + + +#### `add_tool_transformation` + +```python +add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None +``` + +Add a tool transformation. + +.. deprecated:: + Use ``add_transform(ToolTransform({...}))`` instead. + + +#### `remove_tool_transformation` + +```python +remove_tool_transformation(self, _tool_name: str) -> None +``` + +Remove a tool transformation. + +.. deprecated:: + Tool transformations are now immutable. Use visibility controls instead. + + +#### `enable` ```python enable(self) -> None @@ -170,13 +215,13 @@ 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"``). +- `keys`: Keys to enable (e.g., ``"tool\:my_tool@"`` for unversioned, ``"tool\:my_tool@1.0"`` for versioned). - `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` +#### `disable` ```python disable(self) -> None @@ -185,11 +230,11 @@ disable(self) -> None Disable components by adding to the blocklist. **Args:** -- `keys`: Keys to disable (e.g., ``"tool\:my_tool"``). +- `keys`: Keys to disable (e.g., ``"tool\:my_tool@"`` for unversioned, ``"tool\:my_tool@1.0"`` for versioned). - `tags`: Tags to disable - components with these tags will be disabled. -#### `get_tools` +#### `get_tools` ```python get_tools(self) -> list[Tool] @@ -197,27 +242,34 @@ get_tools(self) -> list[Tool] Get all enabled tools from providers. -Queries all providers in parallel and collects tools. -First provider wins for duplicate keys. Filters by server blocklist. +Queries all providers via the root provider (which applies provider transforms, +server transforms, and visibility filtering). First provider wins for duplicate keys. **Args:** - `run_middleware`: If True, apply the middleware chain before returning results. Used by MCP handlers and mounted servers. -#### `get_tool` +#### `get_tool` ```python -get_tool(self, name: str) -> Tool +get_tool(self, name: str, version: VersionSpec | str | None = None) -> Tool ``` Get an enabled tool by name. -Queries all providers in parallel to find the tool. -First provider wins. Returns only if enabled. +Queries providers with full transform chain (provider transforms + server transforms + visibility). +Returns only if enabled and authorized. + +**Args:** +- `name`: The tool name. +- `version`: Version filter. Can be\: +- None\: returns highest version +- str\: returns exact version match +- VersionSpec\: returns best match within spec (highest matching) -#### `get_resources` +#### `get_resources` ```python get_resources(self) -> list[Resource] @@ -225,27 +277,34 @@ get_resources(self) -> list[Resource] Get all enabled resources from providers. -Queries all providers in parallel and collects resources. -First provider wins for duplicate keys. Filters by server blocklist. +Queries all providers via the root provider (which applies provider transforms, +server transforms, and visibility filtering). First provider wins for duplicate keys. **Args:** - `run_middleware`: If True, apply the middleware chain before returning results. Used by MCP handlers and mounted servers. -#### `get_resource` +#### `get_resource` ```python -get_resource(self, uri: str) -> Resource +get_resource(self, uri: str, version: VersionSpec | str | None = None) -> Resource ``` Get an enabled resource by URI. -Queries all providers in parallel to find the resource. -First provider wins. Returns only if enabled. +Queries providers with full transform chain (provider transforms + server transforms + visibility). +Returns only if enabled and authorized. + +**Args:** +- `uri`: The resource URI. +- `version`: Version filter. Can be\: +- None\: returns highest version +- str\: returns exact version match +- VersionSpec\: returns best match within spec (highest matching) -#### `get_resource_templates` +#### `get_resource_templates` ```python get_resource_templates(self) -> list[ResourceTemplate] @@ -253,27 +312,34 @@ get_resource_templates(self) -> list[ResourceTemplate] Get all enabled resource templates from providers. -Queries all providers in parallel and collects templates. -First provider wins for duplicate keys. Filters by server blocklist. +Queries all providers via the root provider (which applies provider transforms, +server transforms, and visibility filtering). First provider wins for duplicate keys. **Args:** - `run_middleware`: If True, apply the middleware chain before returning results. Used by MCP handlers and mounted servers. -#### `get_resource_template` +#### `get_resource_template` ```python -get_resource_template(self, uri: str) -> ResourceTemplate +get_resource_template(self, uri: str, version: VersionSpec | str | None = None) -> ResourceTemplate ``` Get an enabled resource template that matches the given URI. -Queries all providers in parallel to find the template. -First provider wins. Returns only if enabled. +Queries providers with full transform chain (provider transforms + server transforms + visibility). +Returns only if enabled and authorized. + +**Args:** +- `uri`: The template URI to match. +- `version`: Version filter. Can be\: +- None\: returns highest version +- str\: returns exact version match +- VersionSpec\: returns best match within spec (highest matching) -#### `get_prompts` +#### `get_prompts` ```python get_prompts(self) -> list[Prompt] @@ -281,60 +347,46 @@ get_prompts(self) -> list[Prompt] Get all enabled prompts from providers. -Queries all providers in parallel and collects prompts. -First provider wins for duplicate keys. Filters by server blocklist. +Queries all providers via the root provider (which applies provider transforms, +server transforms, and visibility filtering). First provider wins for duplicate keys. **Args:** - `run_middleware`: If True, apply the middleware chain before returning results. Used by MCP handlers and mounted servers. -#### `get_prompt` +#### `get_prompt` ```python -get_prompt(self, name: str) -> Prompt +get_prompt(self, name: str, version: VersionSpec | str | None = None) -> Prompt ``` Get an enabled prompt by name. -Queries all providers in parallel 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. - -Queries all providers in parallel to find the component. -First provider wins. +Queries providers with full transform chain (provider transforms + server transforms + visibility). +Returns only if enabled and authorized. **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. +- `name`: The prompt name. +- `version`: Version filter. Can be\: +- None\: returns highest version +- str\: returns exact version match +- VersionSpec\: returns best match within spec (highest matching) -#### `call_tool` +#### `call_tool` ```python call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult ``` -#### `call_tool` +#### `call_tool` ```python call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult ``` -#### `call_tool` +#### `call_tool` ```python call_tool(self, name: str, arguments: dict[str, Any] | None = None) -> ToolResult | mcp.types.CreateTaskResult @@ -363,19 +415,19 @@ return ToolResult. - `ValidationError`: If arguments fail validation -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: str) -> ResourceResult ``` -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: str) -> mcp.types.CreateTaskResult ``` -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: str) -> ResourceResult | mcp.types.CreateTaskResult @@ -403,19 +455,19 @@ return ResourceResult. - `ResourceError`: If resource read fails -#### `render_prompt` +#### `render_prompt` ```python render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult ``` -#### `render_prompt` +#### `render_prompt` ```python render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> mcp.types.CreateTaskResult ``` -#### `render_prompt` +#### `render_prompt` ```python render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> PromptResult | mcp.types.CreateTaskResult @@ -444,7 +496,7 @@ return PromptResult. - `PromptError`: If prompt rendering fails -#### `custom_route` +#### `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]]] @@ -465,10 +517,10 @@ 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 +add_tool(self, tool: Tool | Callable[..., Any]) -> Tool ``` Add a tool to the server. @@ -477,58 +529,41 @@ The tool function can optionally request a Context object by adding a parameter with the Context type annotation. See the @tool decorator for examples. **Args:** -- `tool`: The Tool instance to register +- `tool`: The Tool instance or @tool-decorated function to register **Returns:** - The tool instance that was added to the server. -#### `remove_tool` +#### `remove_tool` ```python -remove_tool(self, name: str) -> None +remove_tool(self, name: str, version: str | None = None) -> None ``` -Remove a tool from the server. +Remove tool(s) from the server. **Args:** -- `name`: The name of the tool to remove +- `name`: The name of the tool to remove. +- `version`: If None, removes ALL versions. If specified, removes only that version. **Raises:** -- `NotFoundError`: If the tool is not found +- `NotFoundError`: If no matching tool is found. -#### `add_tool_transformation` - -```python -add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None -``` - -Add a tool transformation. - - -#### `remove_tool_transformation` - -```python -remove_tool_transformation(self, tool_name: str) -> None -``` - -Remove a tool transformation. - - -#### `tool` +#### `tool` ```python tool(self, name_or_fn: AnyFunction) -> FunctionTool ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool] ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool] @@ -584,22 +619,22 @@ server.tool(my_function, name="custom_name") ``` -#### `add_resource` +#### `add_resource` ```python -add_resource(self, resource: Resource) -> Resource +add_resource(self, resource: Resource | Callable[..., Any]) -> Resource | ResourceTemplate ``` Add a resource to the server. **Args:** -- `resource`: A Resource instance to add +- `resource`: A Resource instance or @resource-decorated function to add **Returns:** - The resource instance that was added to the server. -#### `add_template` +#### `add_template` ```python add_template(self, template: ResourceTemplate) -> ResourceTemplate @@ -614,10 +649,10 @@ 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] +resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate | AnyFunction] ``` Decorator to register a function as a resource. @@ -673,34 +708,34 @@ async def get_weather(city: str) -> str: ``` -#### `add_prompt` +#### `add_prompt` ```python -add_prompt(self, prompt: Prompt) -> Prompt +add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt ``` Add a prompt to the server. **Args:** -- `prompt`: A Prompt instance to add +- `prompt`: A Prompt instance or @prompt-decorated function to add **Returns:** - The prompt instance that was added to the server. -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt ``` -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt] ``` -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt] @@ -777,7 +812,7 @@ Decorator to register a prompt. ``` -#### `run_stdio_async` +#### `run_stdio_async` ```python run_stdio_async(self, show_banner: bool = True, log_level: str | None = None, stateless: bool = False) -> None @@ -791,7 +826,7 @@ Run the server using stdio transport. - `stateless`: Whether to run in stateless mode (no session initialization) -#### `run_http_async` +#### `run_http_async` ```python run_http_async(self, show_banner: bool = True, transport: Literal['http', 'streamable-http', 'sse'] = 'http', host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, stateless: bool | None = None) -> None @@ -812,7 +847,7 @@ Run the server using HTTP transport. - `stateless`: Alias for stateless_http for CLI consistency -#### `http_app` +#### `http_app` ```python http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http', event_store: EventStore | None = None, retry_interval: int | None = None) -> StarletteWithLifespan @@ -838,7 +873,7 @@ streamable-http transport. - A Starlette application configured with the specified transport -#### `mount` +#### `mount` ```python mount(self, server: FastMCP[LifespanResultT], namespace: str | None = None, as_proxy: bool | None = None, tool_names: dict[str, str] | None = None, prefix: str | None = None) -> None @@ -885,7 +920,7 @@ mounted server. - `prefix`: Deprecated. Use namespace instead. -#### `import_server` +#### `import_server` ```python import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None @@ -926,7 +961,7 @@ templates, and prompts are imported with their original names. objects are imported with their original names. -#### `from_openapi` +#### `from_openapi` ```python from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, name: str = 'OpenAPI Server', route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self @@ -950,7 +985,7 @@ Create a FastMCP server from an OpenAPI specification. - A FastMCP server with an OpenAPIProvider attached. -#### `from_fastapi` +#### `from_fastapi` ```python from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | None = None, route_map_fn: OpenAPIRouteMapFn | None = None, mcp_component_fn: OpenAPIComponentFn | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, timeout: float | None = None, **settings: Any) -> Self @@ -974,7 +1009,7 @@ Create a FastMCP server from a FastAPI application. - A FastMCP server with an OpenAPIProvider attached. -#### `as_proxy` +#### `as_proxy` ```python as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy @@ -992,7 +1027,7 @@ instance or any value accepted as the `transport` argument of `fastmcp.client.Client` constructor. -#### `generate_name` +#### `generate_name` ```python generate_name(cls, name: str | None = None) -> str diff --git a/docs/python-sdk/fastmcp-server-tasks-capabilities.mdx b/docs/python-sdk/fastmcp-server-tasks-capabilities.mdx index 6b8c78e3e..77c1467d3 100644 --- a/docs/python-sdk/fastmcp-server-tasks-capabilities.mdx +++ b/docs/python-sdk/fastmcp-server-tasks-capabilities.mdx @@ -10,15 +10,20 @@ SEP-1686 task capabilities declaration. ## Functions -### `get_task_capabilities` +### `get_task_capabilities` ```python -get_task_capabilities() -> dict[str, Any] +get_task_capabilities() -> ServerTasksCapability | None ``` -Return the SEP-1686 task capabilities structure. +Return the SEP-1686 task capabilities. -This is the standard capabilities map advertised to clients, -declaring support for list, cancel, and request operations. +Returns task capabilities as a first-class ServerCapabilities field, +declaring support for list, cancel, and request operations per SEP-1686. + +Returns None if pydocket is not installed (no task support). + +Note: prompts/resources are passed via extra_data since the SDK types +don't include them yet (FastMCP supports them ahead of the spec). diff --git a/docs/python-sdk/fastmcp-server-tasks-config.mdx b/docs/python-sdk/fastmcp-server-tasks-config.mdx index 129fe896c..2dbbc63dd 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 -### `TaskMeta` +### `TaskMeta` Metadata for task-augmented execution requests. @@ -27,7 +27,7 @@ the operation should be submitted as a background task. - `fn_key`: Docket routing key. Auto-derived from component name if None. -### `TaskConfig` +### `TaskConfig` Configuration for MCP background task execution (SEP-1686). @@ -44,7 +44,7 @@ Controls how a component handles task-augmented requests: **Methods:** -#### `from_bool` +#### `from_bool` ```python from_bool(cls, value: bool) -> TaskConfig @@ -59,7 +59,7 @@ Convert boolean task flag to TaskConfig. - TaskConfig with appropriate mode. -#### `supports_tasks` +#### `supports_tasks` ```python supports_tasks(self) -> bool @@ -71,7 +71,7 @@ Check if this component supports task execution. - True if mode is "optional" or "required", False if "forbidden". -#### `validate_function` +#### `validate_function` ```python validate_function(self, fn: Callable[..., Any], name: str) -> None @@ -79,13 +79,18 @@ validate_function(self, fn: Callable[..., Any], name: str) -> None Validate that function is compatible with this task config. -Task execution requires async functions. Raises ValueError if mode -is "optional" or "required" but function is synchronous. +Task execution requires: +1. fastmcp[tasks] to be installed (pydocket) +2. Async functions + +Raises ImportError if mode is "optional" or "required" but pydocket +is not installed. Raises ValueError if function is synchronous. **Args:** - `fn`: The function to validate (handles callable classes and staticmethods). - `name`: Name for error messages. **Raises:** +- `ImportError`: If task execution is enabled but pydocket not installed. - `ValueError`: If task execution is enabled but function is sync. diff --git a/docs/python-sdk/fastmcp-server-tasks-requests.mdx b/docs/python-sdk/fastmcp-server-tasks-requests.mdx index 75fe1ca67..50f77596a 100644 --- a/docs/python-sdk/fastmcp-server-tasks-requests.mdx +++ b/docs/python-sdk/fastmcp-server-tasks-requests.mdx @@ -11,10 +11,12 @@ SEP-1686 task request handlers. 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). +This module requires fastmcp[tasks] (pydocket). It is only imported when docket is available. + ## Functions -### `tasks_get_handler` +### `tasks_get_handler` ```python tasks_get_handler(server: FastMCP, params: dict[str, Any]) -> GetTaskResult @@ -31,7 +33,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 @@ -50,7 +52,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 @@ -69,7 +71,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-subscriptions.mdx b/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx index 1b4331212..1b611ea9c 100644 --- a/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx +++ b/docs/python-sdk/fastmcp-server-tasks-subscriptions.mdx @@ -11,10 +11,12 @@ Task subscription helpers for sending MCP notifications (SEP-1686). Subscribes to Docket execution state changes and sends notifications/tasks/status to clients when their tasks change state. +This module requires fastmcp[tasks] (pydocket). It is only imported when docket is available. + ## Functions -### `subscribe_to_task_updates` +### `subscribe_to_task_updates` ```python subscribe_to_task_updates(task_id: str, task_key: str, session: ServerSession, docket: Docket, poll_interval_ms: int = 5000) -> None diff --git a/docs/python-sdk/fastmcp-server-telemetry.mdx b/docs/python-sdk/fastmcp-server-telemetry.mdx new file mode 100644 index 000000000..a842c468d --- /dev/null +++ b/docs/python-sdk/fastmcp-server-telemetry.mdx @@ -0,0 +1,56 @@ +--- +title: telemetry +sidebarTitle: telemetry +--- + +# `fastmcp.server.telemetry` + + +Server-side telemetry helpers. + +## Functions + +### `get_auth_span_attributes` + +```python +get_auth_span_attributes() -> dict[str, str] +``` + + +Get auth attributes for the current request, if authenticated. + + +### `get_session_span_attributes` + +```python +get_session_span_attributes() -> dict[str, str] +``` + + +Get session attributes for the current request. + + +### `server_span` + +```python +server_span(name: str, method: str, server_name: str, component_type: str, component_key: str, resource_uri: str | None = None) -> Generator[Span, None, None] +``` + + +Create a SERVER span with standard MCP attributes and auth context. + +Automatically records any exception on the span and sets error status. + + +### `delegate_span` + +```python +delegate_span(name: str, provider_type: str, component_key: str) -> Generator[Span, None, None] +``` + + +Create an INTERNAL span for provider delegation. + +Used by FastMCPProvider when delegating to mounted servers. +Automatically records any exception on the span and sets error status. + diff --git a/docs/python-sdk/fastmcp-server-transforms-__init__.mdx b/docs/python-sdk/fastmcp-server-transforms-__init__.mdx new file mode 100644 index 000000000..6b7e5db17 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-transforms-__init__.mdx @@ -0,0 +1,196 @@ +--- +title: __init__ +sidebarTitle: __init__ +--- + +# `fastmcp.server.transforms` + + +Transform system for component transformations. + +Transforms modify components (tools, resources, prompts) using a middleware pattern. +Each transform wraps the next in the chain via `call_next`, allowing transforms to +intercept, modify, or replace component queries. + +Unlike middleware (which operates on requests), transforms are observable by the +system for task registration, tag filtering, and component introspection. + +Example: + ```python + from fastmcp import FastMCP + from fastmcp.server.transforms import Namespace + + server = FastMCP("Server") + mount = server.mount(other_server) + mount.add_transform(Namespace("api")) # Tools become api_toolname + ``` + + +## Classes + +### `GetToolNext` + + +Protocol for get_tool call_next functions. + + +### `GetResourceNext` + + +Protocol for get_resource call_next functions. + + +### `GetResourceTemplateNext` + + +Protocol for get_resource_template call_next functions. + + +### `GetPromptNext` + + +Protocol for get_prompt call_next functions. + + +### `Transform` + + +Base class for component transformations. + +Transforms use a middleware pattern with `call_next` to chain operations. +Each transform can intercept, modify, or pass through component queries. + +For list operations, call `call_next()` to get components from downstream, +then transform the result. For get operations, optionally transform the +name/uri before calling `call_next`, then transform the result. + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self, call_next: ListToolsNext) -> Sequence[Tool] +``` + +List tools with transformation applied. + +**Args:** +- `call_next`: Callable to get tools from downstream transforms/provider. + +**Returns:** +- Transformed sequence of tools. + + +#### `get_tool` + +```python +get_tool(self, name: str, call_next: GetToolNext) -> Tool | None +``` + +Get a tool by name. + +**Args:** +- `name`: The requested tool name (may be transformed). +- `call_next`: Callable to get tool from downstream. +- `version`: Optional version filter to apply. + +**Returns:** +- The tool if found, None otherwise. + + +#### `list_resources` + +```python +list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource] +``` + +List resources with transformation applied. + +**Args:** +- `call_next`: Callable to get resources from downstream transforms/provider. + +**Returns:** +- Transformed sequence of resources. + + +#### `get_resource` + +```python +get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None +``` + +Get a resource by URI. + +**Args:** +- `uri`: The requested resource URI (may be transformed). +- `call_next`: Callable to get resource from downstream. +- `version`: Optional version filter to apply. + +**Returns:** +- The resource if found, None otherwise. + + +#### `list_resource_templates` + +```python +list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate] +``` + +List resource templates with transformation applied. + +**Args:** +- `call_next`: Callable to get templates from downstream transforms/provider. + +**Returns:** +- Transformed sequence of resource templates. + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None +``` + +Get a resource template by URI. + +**Args:** +- `uri`: The requested template URI (may be transformed). +- `call_next`: Callable to get template from downstream. +- `version`: Optional version filter to apply. + +**Returns:** +- The resource template if found, None otherwise. + + +#### `list_prompts` + +```python +list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt] +``` + +List prompts with transformation applied. + +**Args:** +- `call_next`: Callable to get prompts from downstream transforms/provider. + +**Returns:** +- Transformed sequence of prompts. + + +#### `get_prompt` + +```python +get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None +``` + +Get a prompt by name. + +**Args:** +- `name`: The requested prompt name (may be transformed). +- `call_next`: Callable to get prompt from downstream. +- `version`: Optional version filter to apply. + +**Returns:** +- The prompt if found, None otherwise. + diff --git a/docs/python-sdk/fastmcp-server-transforms-namespace.mdx b/docs/python-sdk/fastmcp-server-transforms-namespace.mdx new file mode 100644 index 000000000..0260e3a2e --- /dev/null +++ b/docs/python-sdk/fastmcp-server-transforms-namespace.mdx @@ -0,0 +1,96 @@ +--- +title: namespace +sidebarTitle: namespace +--- + +# `fastmcp.server.transforms.namespace` + + +Namespace transform for prefixing component names. + +## Classes + +### `Namespace` + + +Prefixes component names with a namespace. + +- Tools: name → namespace_name +- Prompts: name → namespace_name +- Resources: protocol://path → protocol://namespace/path +- Resource Templates: same as resources + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self, call_next: ListToolsNext) -> Sequence[Tool] +``` + +Prefix tool names with namespace. + + +#### `get_tool` + +```python +get_tool(self, name: str, call_next: GetToolNext) -> Tool | None +``` + +Get tool by namespaced name. + + +#### `list_resources` + +```python +list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource] +``` + +Add namespace path segment to resource URIs. + + +#### `get_resource` + +```python +get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None +``` + +Get resource by namespaced URI. + + +#### `list_resource_templates` + +```python +list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate] +``` + +Add namespace path segment to template URIs. + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None +``` + +Get resource template by namespaced URI. + + +#### `list_prompts` + +```python +list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt] +``` + +Prefix prompt names with namespace. + + +#### `get_prompt` + +```python +get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None +``` + +Get prompt by namespaced name. + diff --git a/docs/python-sdk/fastmcp-server-transforms-tool_transform.mdx b/docs/python-sdk/fastmcp-server-transforms-tool_transform.mdx new file mode 100644 index 000000000..417e18f77 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-transforms-tool_transform.mdx @@ -0,0 +1,40 @@ +--- +title: tool_transform +sidebarTitle: tool_transform +--- + +# `fastmcp.server.transforms.tool_transform` + + +Transform for applying tool transformations. + +## Classes + +### `ToolTransform` + + +Applies tool transformations to modify tool schemas. + +Wraps ToolTransformConfig to apply argument renames, schema changes, +hidden arguments, and other transformations at the transform level. + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self, call_next: ListToolsNext) -> Sequence[Tool] +``` + +Apply transforms to matching tools. + + +#### `get_tool` + +```python +get_tool(self, name: str, call_next: GetToolNext) -> Tool | None +``` + +Get tool by transformed name. + diff --git a/docs/python-sdk/fastmcp-server-transforms-version_filter.mdx b/docs/python-sdk/fastmcp-server-transforms-version_filter.mdx new file mode 100644 index 000000000..7a2e43431 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-transforms-version_filter.mdx @@ -0,0 +1,85 @@ +--- +title: version_filter +sidebarTitle: version_filter +--- + +# `fastmcp.server.transforms.version_filter` + + +Version filter transform for filtering components by version range. + +## Classes + +### `VersionFilter` + + +Filters components by version range. + +When applied to a provider or server, only components within the version +range are visible. Within that filtered set, the highest version of each +component is exposed to clients (standard deduplication behavior). + +Parameters mirror comparison operators for clarity: + + # Versions < 3.0 (v1 and v2) + server.add_transform(VersionFilter(version_lt="3.0")) + + # Versions >= 2.0 and < 3.0 (only v2.x) + server.add_transform(VersionFilter(version_gte="2.0", version_lt="3.0")) + +Works with any version string - PEP 440 (1.0, 2.0) or dates (2025-01-01). + +**Args:** +- `version_gte`: Versions >= this value pass through. +- `version_lt`: Versions < this value pass through. + + +**Methods:** + +#### `list_tools` + +```python +list_tools(self, call_next: ListToolsNext) -> Sequence[Tool] +``` + +#### `get_tool` + +```python +get_tool(self, name: str, call_next: GetToolNext) -> Tool | None +``` + +#### `list_resources` + +```python +list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource] +``` + +#### `get_resource` + +```python +get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None +``` + +#### `list_resource_templates` + +```python +list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate] +``` + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None +``` + +#### `list_prompts` + +```python +list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt] +``` + +#### `get_prompt` + +```python +get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None +``` diff --git a/docs/python-sdk/fastmcp-server-transforms-visibility.mdx b/docs/python-sdk/fastmcp-server-transforms-visibility.mdx new file mode 100644 index 000000000..25ef0478d --- /dev/null +++ b/docs/python-sdk/fastmcp-server-transforms-visibility.mdx @@ -0,0 +1,158 @@ +--- +title: visibility +sidebarTitle: visibility +--- + +# `fastmcp.server.transforms.visibility` + + +Visibility transform for filtering components based on enable/disable settings. + +This module provides the `Visibility` class which manages component visibility +with blocklist and allowlist support. Components can be hidden by key or tag, +and the visibility state is mutable - changes take effect on subsequent queries. + + +## Classes + +### `Visibility` + + +Filters components based on visibility settings. + +Manages blocklist and allowlist logic for controlling component visibility. +Both servers and providers use this class. 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. + + +#### `list_tools` + +```python +list_tools(self, call_next: ListToolsNext) -> Sequence[Tool] +``` + +Filter tools by visibility. + + +#### `get_tool` + +```python +get_tool(self, name: str, call_next: GetToolNext) -> Tool | None +``` + +Get tool if enabled, None otherwise. + + +#### `list_resources` + +```python +list_resources(self, call_next: ListResourcesNext) -> Sequence[Resource] +``` + +Filter resources by visibility. + + +#### `get_resource` + +```python +get_resource(self, uri: str, call_next: GetResourceNext) -> Resource | None +``` + +Get resource if enabled, None otherwise. + + +#### `list_resource_templates` + +```python +list_resource_templates(self, call_next: ListResourceTemplatesNext) -> Sequence[ResourceTemplate] +``` + +Filter resource templates by visibility. + + +#### `get_resource_template` + +```python +get_resource_template(self, uri: str, call_next: GetResourceTemplateNext) -> ResourceTemplate | None +``` + +Get resource template if enabled, None otherwise. + + +#### `list_prompts` + +```python +list_prompts(self, call_next: ListPromptsNext) -> Sequence[Prompt] +``` + +Filter prompts by visibility. + + +#### `get_prompt` + +```python +get_prompt(self, name: str, call_next: GetPromptNext) -> Prompt | None +``` + +Get prompt if enabled, None otherwise. + diff --git a/docs/python-sdk/fastmcp-telemetry.mdx b/docs/python-sdk/fastmcp-telemetry.mdx new file mode 100644 index 000000000..805e9940d --- /dev/null +++ b/docs/python-sdk/fastmcp-telemetry.mdx @@ -0,0 +1,95 @@ +--- +title: telemetry +sidebarTitle: telemetry +--- + +# `fastmcp.telemetry` + + +OpenTelemetry instrumentation for FastMCP. + +This module provides native OpenTelemetry integration for FastMCP servers and clients. +It uses only the opentelemetry-api package, so telemetry is a no-op unless the user +installs an OpenTelemetry SDK and configures exporters. + +Example usage with SDK: + ```python + from opentelemetry import trace + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor + + # Configure the SDK (user responsibility) + provider = TracerProvider() + provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter())) + trace.set_tracer_provider(provider) + + # Now FastMCP will emit traces + from fastmcp import FastMCP + mcp = FastMCP("my-server") + ``` + + +## Functions + +### `get_tracer` + +```python +get_tracer(version: str | None = None) -> Tracer +``` + + +Get the FastMCP tracer for creating spans. + +**Args:** +- `version`: Optional version string for the instrumentation + +**Returns:** +- A tracer instance. Returns a no-op tracer if no SDK is configured. + + +### `inject_trace_context` + +```python +inject_trace_context(meta: dict[str, Any] | None = None) -> dict[str, Any] | None +``` + + +Inject current trace context into a meta dict for MCP request propagation. + +**Args:** +- `meta`: Optional existing meta dict to merge with trace context + +**Returns:** +- A new dict containing the original meta (if any) plus trace context keys, +- or None if no trace context to inject and meta was None + + +### `record_span_error` + +```python +record_span_error(span: Span, exception: BaseException) -> None +``` + + +Record an exception on a span and set error status. + + +### `extract_trace_context` + +```python +extract_trace_context(meta: dict[str, Any] | None) -> Context +``` + + +Extract trace context from an MCP request meta dict. + +If already in a valid trace (e.g., from HTTP propagation), the existing +trace context is preserved and meta is not used. + +**Args:** +- `meta`: The meta dict from an MCP request (ctx.request_context.meta) + +**Returns:** +- An OpenTelemetry Context with the extracted trace context, +- or the current context if no trace context found or already in a trace + diff --git a/docs/python-sdk/fastmcp-tools-function_parsing.mdx b/docs/python-sdk/fastmcp-tools-function_parsing.mdx new file mode 100644 index 000000000..2f69d1548 --- /dev/null +++ b/docs/python-sdk/fastmcp-tools-function_parsing.mdx @@ -0,0 +1,21 @@ +--- +title: function_parsing +sidebarTitle: function_parsing +--- + +# `fastmcp.tools.function_parsing` + + +Function introspection and schema generation for FastMCP tools. + +## Classes + +### `ParsedFunction` + +**Methods:** + +#### `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-function_tool.mdx b/docs/python-sdk/fastmcp-tools-function_tool.mdx new file mode 100644 index 000000000..6196d8484 --- /dev/null +++ b/docs/python-sdk/fastmcp-tools-function_tool.mdx @@ -0,0 +1,108 @@ +--- +title: function_tool +sidebarTitle: function_tool +--- + +# `fastmcp.tools.function_tool` + + +Standalone @tool decorator for FastMCP. + +## Functions + +### `tool` + +```python +tool(name_or_fn: str | Callable[..., Any] | None = None) -> Any +``` + + +Standalone decorator to mark a function as an MCP tool. + +Returns the original function with metadata attached. Register with a server +using mcp.add_tool(). + + +## Classes + +### `DecoratedTool` + + +Protocol for functions decorated with @tool. + + +### `ToolMeta` + + +Metadata attached to functions by the @tool decorator. + + +### `FunctionTool` + +**Methods:** + +#### `to_mcp_tool` + +```python +to_mcp_tool(self, **overrides: Any) -> mcp.types.Tool +``` + +Convert the FastMCP tool to an MCP tool. + +Extends the base implementation to add task execution mode if enabled. + + +#### `from_function` + +```python +from_function(cls, fn: Callable[..., Any]) -> FunctionTool +``` + +Create a FunctionTool from a function. + +**Args:** +- `fn`: The function to wrap +- `metadata`: ToolMeta object with all configuration. If provided, +individual parameters must not be passed. +- `name, title, etc.`: Individual parameters for backwards compatibility. +Cannot be used together with metadata parameter. + + +#### `run` + +```python +run(self, arguments: dict[str, Any]) -> ToolResult +``` + +Run the tool with arguments. + + +#### `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() + diff --git a/docs/python-sdk/fastmcp-tools-tool.mdx b/docs/python-sdk/fastmcp-tools-tool.mdx index c5e5e1c3a..c347cd480 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,7 +33,7 @@ Internal tool registration info. **Methods:** -#### `to_mcp_tool` +#### `to_mcp_tool` ```python to_mcp_tool(self, **overrides: Any) -> MCPTool @@ -42,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, task: bool | TaskConfig | None = None) -> FunctionTool +from_function(cls, fn: Callable[..., Any]) -> FunctionTool ``` Create a Tool from a function. -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any]) -> ToolResult @@ -66,7 +66,7 @@ implemented by subclasses. (list of ContentBlocks, dict of structured output). -#### `convert_result` +#### `convert_result` ```python convert_result(self, raw_value: Any) -> ToolResult @@ -78,7 +78,7 @@ Handles ToolResult passthrough and converts raw values using the tool's attributes (serializer, output_schema) for proper conversion. -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None @@ -87,7 +87,7 @@ register_with_docket(self, docket: Docket) -> None Register this tool with docket for background execution. -#### `add_to_docket` +#### `add_to_docket` ```python add_to_docket(self, docket: Docket, arguments: dict[str, Any], **kwargs: Any) -> Execution @@ -103,81 +103,14 @@ Schedule this tool for background execution via docket. - `**kwargs`: Additional kwargs passed to docket.add() -#### `from_tool` +#### `from_tool` ```python from_tool(cls, tool: Tool) -> TransformedTool ``` -### `FunctionTool` - -**Methods:** - -#### `to_mcp_tool` +#### `get_span_attributes` ```python -to_mcp_tool(self, **overrides: Any) -> MCPTool -``` - -Convert the FastMCP tool to an MCP tool. - -Extends the base implementation to add task execution mode if enabled. - - -#### `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, task: bool | TaskConfig | None = None) -> FunctionTool -``` - -Create a Tool from a function. - - -#### `run` - -```python -run(self, arguments: dict[str, Any]) -> ToolResult -``` - -Run the tool with arguments. - - -#### `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` - -```python -from_function(cls, fn: Callable[..., Any], exclude_args: list[str] | None = None, validate: bool = True, wrap_non_object_output_schema: bool = True) -> ParsedFunction +get_span_attributes(self) -> dict[str, Any] ``` diff --git a/docs/python-sdk/fastmcp-tools-tool_transform.mdx b/docs/python-sdk/fastmcp-tools-tool_transform.mdx index 0288596ac..052ab7192 100644 --- a/docs/python-sdk/fastmcp-tools-tool_transform.mdx +++ b/docs/python-sdk/fastmcp-tools-tool_transform.mdx @@ -7,7 +7,7 @@ sidebarTitle: tool_transform ## Functions -### `forward` +### `forward` ```python forward(**kwargs: Any) -> ToolResult @@ -36,7 +36,7 @@ tool has args `a` and `b`, and an `transform_args` was provided that maps `x` to - `TypeError`: If provided arguments don't match the transformed schema. -### `forward_raw` +### `forward_raw` ```python forward_raw(**kwargs: Any) -> ToolResult @@ -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] @@ -78,7 +78,7 @@ but transformations are keyed by tool name (e.g., "my_tool"). ## Classes -### `ArgTransform` +### `ArgTransform` Configuration for transforming a parent tool's argument. @@ -150,7 +150,7 @@ ArgTransform(name="new_name", description="New desc", default=None, type=int) ``` -### `ArgTransformConfig` +### `ArgTransformConfig` A model for requesting a single argument transform. @@ -158,7 +158,7 @@ A model for requesting a single argument transform. **Methods:** -#### `to_arg_transform` +#### `to_arg_transform` ```python to_arg_transform(self) -> ArgTransform @@ -167,7 +167,7 @@ to_arg_transform(self) -> ArgTransform Convert the argument transform to a FastMCP argument transform. -### `TransformedTool` +### `TransformedTool` A tool that is transformed from another tool. @@ -191,7 +191,7 @@ validation when forward() is called from custom functions. **Methods:** -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any]) -> ToolResult @@ -210,10 +210,10 @@ functions. - ToolResult object containing content and optional structured output. -#### `from_tool` +#### `from_tool` ```python -from_tool(cls, tool: Tool, name: str | None = None, title: str | 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 +from_tool(cls, tool: Tool, name: str | None = None, version: str | NotSetT | None = NotSet, 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. @@ -224,6 +224,7 @@ Create a transformed tool from a parent tool. to call the parent tool. Functions with **kwargs receive transformed argument names. - `name`: New name for the tool. Defaults to parent tool's name. +- `version`: New version for the tool. Defaults to parent tool's version. - `title`: New title for the tool. Defaults to parent tool's title. - `transform_args`: Optional transformations for parent tool arguments. Only specified arguments are transformed, others pass through unchanged\: @@ -292,7 +293,7 @@ async def custom_output(**kwargs) -> ToolResult: ``` -### `ToolTransformConfig` +### `ToolTransformConfig` Provides a way to transform a tool. @@ -300,7 +301,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-async_utils.mdx b/docs/python-sdk/fastmcp-utilities-async_utils.mdx index 7a44351b6..f5f24019f 100644 --- a/docs/python-sdk/fastmcp-utilities-async_utils.mdx +++ b/docs/python-sdk/fastmcp-utilities-async_utils.mdx @@ -10,7 +10,20 @@ Async utilities for FastMCP. ## Functions -### `gather` +### `call_sync_fn_in_threadpool` + +```python +call_sync_fn_in_threadpool(fn: Callable[..., Any], *args: Any, **kwargs: Any) -> Any +``` + + +Call a sync function in a threadpool to avoid blocking the event loop. + +Uses anyio.to_thread.run_sync which properly propagates contextvars, +making this safe for functions that depend on context (like dependency injection). + + +### `gather` ```python gather(*awaitables: Awaitable[T]) -> list[T] | list[T | BaseException] diff --git a/docs/python-sdk/fastmcp-utilities-cli.mdx b/docs/python-sdk/fastmcp-utilities-cli.mdx index 2eb792220..455655637 100644 --- a/docs/python-sdk/fastmcp-utilities-cli.mdx +++ b/docs/python-sdk/fastmcp-utilities-cli.mdx @@ -7,7 +7,7 @@ sidebarTitle: cli ## Functions -### `is_already_in_uv_subprocess` +### `is_already_in_uv_subprocess` ```python is_already_in_uv_subprocess() -> bool @@ -17,7 +17,7 @@ is_already_in_uv_subprocess() -> bool Check if we're already running in a FastMCP uv subprocess. -### `load_and_merge_config` +### `load_and_merge_config` ```python load_and_merge_config(server_spec: str | None, **cli_overrides) -> tuple[MCPServerConfig, str] @@ -37,7 +37,7 @@ run, inspect, and dev commands. - Tuple of (MCPServerConfig, resolved_server_spec) -### `log_server_banner` +### `log_server_banner` ```python log_server_banner(server: FastMCP[Any]) -> None diff --git a/docs/python-sdk/fastmcp-utilities-components.mdx b/docs/python-sdk/fastmcp-utilities-components.mdx index 08879acdf..cc2b90446 100644 --- a/docs/python-sdk/fastmcp-utilities-components.mdx +++ b/docs/python-sdk/fastmcp-utilities-components.mdx @@ -9,7 +9,7 @@ sidebarTitle: components ### `FastMCPMeta` -### `FastMCPComponent` +### `FastMCPComponent` Base class for FastMCP tools, prompts, resources, and resource templates. @@ -17,7 +17,7 @@ Base class for FastMCP tools, prompts, resources, and resource templates. **Methods:** -#### `make_key` +#### `make_key` ```python make_key(cls, identifier: str) -> str @@ -32,7 +32,7 @@ Construct the lookup key for this component type. - A prefixed key like "tool:name" or "resource:uri" -#### `key` +#### `key` ```python key(self) -> str @@ -40,13 +40,17 @@ key(self) -> str The globally unique lookup key for this component. -Format: "{key_prefix}:{identifier}" e.g. "tool:my_tool", "resource:file://x.txt" +Format: "{key_prefix}:{identifier}@{version}" or "{key_prefix}:{identifier}@" +e.g. "tool:my_tool@v2", "tool:my_tool@", "resource:file://x.txt@" + +The @ suffix is ALWAYS present to enable unambiguous parsing of keys +(URIs may contain @ characters, so we always include the delimiter). 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 @@ -58,7 +62,7 @@ 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. -#### `enable` +#### `enable` ```python enable(self) -> None @@ -67,7 +71,7 @@ enable(self) -> None Removed in 3.0. Use server.enable(keys=[...]) instead. -#### `disable` +#### `disable` ```python disable(self) -> None @@ -76,7 +80,7 @@ disable(self) -> None Removed in 3.0. Use server.disable(keys=[...]) instead. -#### `copy` +#### `copy` ```python copy(self) -> Self @@ -85,7 +89,7 @@ copy(self) -> Self Create a copy of the component. -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None @@ -97,7 +101,7 @@ No-ops if task_config.mode is "forbidden". Subclasses override to register their callable (self.run, self.read, self.render, or self.fn). -#### `add_to_docket` +#### `add_to_docket` ```python add_to_docket(self, docket: Docket, *args: Any, **kwargs: Any) -> Execution @@ -113,3 +117,14 @@ Subclasses override this to handle their specific calling conventions: The **kwargs are passed through to docket.add() (e.g., key=task_key). + +#### `get_span_attributes` + +```python +get_span_attributes(self) -> dict[str, Any] +``` + +Return span attributes for telemetry. + +Subclasses should call super() and merge their specific attributes. + diff --git a/docs/python-sdk/fastmcp-utilities-json_schema_type.mdx b/docs/python-sdk/fastmcp-utilities-json_schema_type.mdx index 50fba7654..59b66f2ec 100644 --- a/docs/python-sdk/fastmcp-utilities-json_schema_type.mdx +++ b/docs/python-sdk/fastmcp-utilities-json_schema_type.mdx @@ -42,7 +42,7 @@ Example: ## Functions -### `json_schema_to_type` +### `json_schema_to_type` ```python json_schema_to_type(schema: Mapping[str, Any], name: str | None = None) -> type @@ -107,4 +107,4 @@ class Name: ## Classes -### `JSONSchema` +### `JSONSchema` diff --git a/docs/python-sdk/fastmcp-utilities-logging.mdx b/docs/python-sdk/fastmcp-utilities-logging.mdx index ef3264dbb..1fffe465c 100644 --- a/docs/python-sdk/fastmcp-utilities-logging.mdx +++ b/docs/python-sdk/fastmcp-utilities-logging.mdx @@ -41,7 +41,7 @@ Configure logging for FastMCP. - `rich_kwargs`: the parameters to use for creating RichHandler -### `temporary_log_level` +### `temporary_log_level` ```python temporary_log_level(level: str | None, logger: logging.Logger | None = None, enable_rich_tracebacks: bool | None = None, **rich_kwargs: Any) diff --git a/docs/python-sdk/fastmcp-utilities-version_check.mdx b/docs/python-sdk/fastmcp-utilities-version_check.mdx new file mode 100644 index 000000000..a88805fb2 --- /dev/null +++ b/docs/python-sdk/fastmcp-utilities-version_check.mdx @@ -0,0 +1,40 @@ +--- +title: version_check +sidebarTitle: version_check +--- + +# `fastmcp.utilities.version_check` + + +Version checking utilities for FastMCP. + +## Functions + +### `get_latest_version` + +```python +get_latest_version(include_prereleases: bool = False) -> str | None +``` + + +Get the latest version of FastMCP from PyPI, using cache when available. + +**Args:** +- `include_prereleases`: If True, include pre-release versions. + +**Returns:** +- The latest version string, or None if unavailable. + + +### `check_for_newer_version` + +```python +check_for_newer_version() -> str | None +``` + + +Check if a newer version of FastMCP is available. + +**Returns:** +- The latest version string if newer than current, None otherwise. + diff --git a/docs/python-sdk/fastmcp-utilities-versions.mdx b/docs/python-sdk/fastmcp-utilities-versions.mdx new file mode 100644 index 000000000..9adb00b50 --- /dev/null +++ b/docs/python-sdk/fastmcp-utilities-versions.mdx @@ -0,0 +1,190 @@ +--- +title: versions +sidebarTitle: versions +--- + +# `fastmcp.utilities.versions` + + +Version comparison utilities for component versioning. + +This module provides utilities for comparing component versions. Versions are +strings that are first attempted to be parsed as PEP 440 versions (using the +`packaging` library), falling back to lexicographic string comparison. + +Examples: + - "1", "2", "10" → parsed as PEP 440, compared semantically (1 < 2 < 10) + - "1.0", "2.0" → parsed as PEP 440 + - "v1.0" → 'v' prefix stripped, parsed as "1.0" + - "2025-01-15" → not valid PEP 440, compared as strings + - None → sorts lowest (unversioned components) + + +## Functions + +### `parse_version_key` + +```python +parse_version_key(version: str | None) -> VersionKey +``` + + +Parse a version string into a sortable key. + +**Args:** +- `version`: The version string, or None for unversioned. + +**Returns:** +- A VersionKey suitable for sorting. + + +### `version_sort_key` + +```python +version_sort_key(component: FastMCPComponent) -> VersionKey +``` + + +Get a sort key for a component based on its version. + +Use with sorted() or max() to order components by version. + +**Args:** +- `component`: The component to get a sort key for. + +**Returns:** +- A sortable VersionKey. + + +### `compare_versions` + +```python +compare_versions(a: str | None, b: str | None) -> int +``` + + +Compare two version strings. + +**Args:** +- `a`: First version string (or None). +- `b`: Second version string (or None). + +**Returns:** +- -1 if a < b, 0 if a == b, 1 if a > b. + + +### `is_version_greater` + +```python +is_version_greater(a: str | None, b: str | None) -> bool +``` + + +Check if version a is greater than version b. + +**Args:** +- `a`: First version string (or None). +- `b`: Second version string (or None). + +**Returns:** +- True if a > b, False otherwise. + + +### `max_version` + +```python +max_version(a: str | None, b: str | None) -> str | None +``` + + +Return the greater of two versions. + +**Args:** +- `a`: First version string (or None). +- `b`: Second version string (or None). + +**Returns:** +- The greater version, or None if both are None. + + +### `min_version` + +```python +min_version(a: str | None, b: str | None) -> str | None +``` + + +Return the lesser of two versions. + +**Args:** +- `a`: First version string (or None). +- `b`: Second version string (or None). + +**Returns:** +- The lesser version, or None if both are None. + + +## Classes + +### `VersionSpec` + + +Specification for filtering components by version. + +Used by transforms and providers to filter components to a specific +version or version range. Unversioned components (version=None) always +match any spec. + +**Args:** +- `gte`: If set, only versions >= this value match. +- `lt`: If set, only versions < this value match. +- `eq`: If set, only this exact version matches (gte/lt ignored). + + +**Methods:** + +#### `matches` + +```python +matches(self, version: str | None) -> bool +``` + +Check if a version matches this spec. + +**Args:** +- `version`: The version to check, or None for unversioned. + +**Returns:** +- True if the version matches the spec. + + +#### `intersect` + +```python +intersect(self, other: VersionSpec | None) -> VersionSpec +``` + +Return a spec that satisfies both this spec and other. + +Used by transforms to combine caller constraints with filter constraints. +For example, if a VersionFilter has lt="3.0" and caller requests eq="1.0", +the intersection validates "1.0" is in range and returns the exact spec. + +**Args:** +- `other`: Another spec to intersect with, or None. + +**Returns:** +- A VersionSpec that matches only versions satisfying both specs. + + +### `VersionKey` + + +A comparable version key that handles None, PEP 440 versions, and strings. + +Comparison order: +1. None (unversioned) sorts lowest +2. PEP 440 versions sort by semantic version order +3. Invalid versions (strings) sort lexicographically +4. When comparing PEP 440 vs string, PEP 440 comes first + diff --git a/docs/python-sdk/fastmcp-utilities-visibility.mdx b/docs/python-sdk/fastmcp-utilities-visibility.mdx deleted file mode 100644 index ade14110e..000000000 --- a/docs/python-sdk/fastmcp-utilities-visibility.mdx +++ /dev/null @@ -1,86 +0,0 @@ ---- -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. -