diff --git a/docs/docs.json b/docs/docs.json index de6369d10..b7f26ab6b 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -301,6 +301,8 @@ "pages": [ "python-sdk/fastmcp-cli-__init__", "python-sdk/fastmcp-cli-cli", + "python-sdk/fastmcp-cli-client", + "python-sdk/fastmcp-cli-discovery", { "group": "install", "pages": [ @@ -311,7 +313,8 @@ "python-sdk/fastmcp-cli-install-gemini_cli", "python-sdk/fastmcp-cli-install-goose", "python-sdk/fastmcp-cli-install-mcp_json", - "python-sdk/fastmcp-cli-install-shared" + "python-sdk/fastmcp-cli-install-shared", + "python-sdk/fastmcp-cli-install-stdio" ] }, "python-sdk/fastmcp-cli-run", @@ -400,6 +403,7 @@ "group": "fastmcp.server", "pages": [ "python-sdk/fastmcp-server-__init__", + "python-sdk/fastmcp-server-apps", { "group": "auth", "pages": [ @@ -547,6 +551,7 @@ "python-sdk/fastmcp-server-tasks-__init__", "python-sdk/fastmcp-server-tasks-capabilities", "python-sdk/fastmcp-server-tasks-config", + "python-sdk/fastmcp-server-tasks-elicitation", "python-sdk/fastmcp-server-tasks-handlers", "python-sdk/fastmcp-server-tasks-keys", "python-sdk/fastmcp-server-tasks-requests", diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx index 759a4324d..df21e8105 100644 --- a/docs/python-sdk/fastmcp-cli-cli.mdx +++ b/docs/python-sdk/fastmcp-cli-cli.mdx @@ -10,7 +10,7 @@ FastMCP CLI tools using Cyclopts. ## Functions -### `with_argv` +### `with_argv` ```python with_argv(args: list[str] | None) @@ -27,7 +27,7 @@ Args are provided without the script name, so we preserve sys.argv[0] and replace the rest. -### `version` +### `version` ```python version() @@ -37,7 +37,7 @@ version() Display version information and platform details. -### `dev` +### `dev` ```python dev(server_spec: str | None = None) -> None @@ -50,7 +50,7 @@ Run an MCP server with the MCP Inspector for development. - `server_spec`: Python file to run, optionally with \:object suffix, or None to auto-detect fastmcp.json -### `run` +### `run` ```python run(server_spec: str | None = None, *server_args: str) -> None @@ -74,7 +74,7 @@ fastmcp run server.py -- --config config.json --debug - `server_spec`: Python file, object specification (file\:obj), config file, URL, or None to auto-detect -### `inspect` +### `inspect` ```python inspect(server_spec: str | None = None) -> None @@ -105,7 +105,7 @@ fastmcp inspect # auto-detect fastmcp.json - `server_spec`: Python file to inspect, optionally with \:object suffix, or fastmcp.json -### `prepare` +### `prepare` ```python prepare(config_path: Annotated[str | None, cyclopts.Parameter(help='Path to fastmcp.json configuration file')] = None, output_dir: Annotated[str | None, cyclopts.Parameter(help='Directory to create the persistent environment in')] = None, skip_source: Annotated[bool, cyclopts.Parameter(help='Skip source preparation (e.g., git clone)')] = False) -> None diff --git a/docs/python-sdk/fastmcp-cli-client.mdx b/docs/python-sdk/fastmcp-cli-client.mdx new file mode 100644 index 000000000..e256d90bc --- /dev/null +++ b/docs/python-sdk/fastmcp-cli-client.mdx @@ -0,0 +1,133 @@ +--- +title: client +sidebarTitle: client +--- + +# `fastmcp.cli.client` + + +Client-side CLI commands for querying and invoking MCP servers. + +## Functions + +### `resolve_server_spec` + +```python +resolve_server_spec(server_spec: str | None) -> str | dict[str, Any] | ClientTransport +``` + + +Turn CLI inputs into something ``Client()`` accepts. + +Exactly one of ``server_spec`` or ``command`` should be provided. + +Resolution order for ``server_spec``: +1. URLs (``http://``, ``https://``) — passed through as-is. + If ``--transport`` is ``sse``, the URL is rewritten to end with ``/sse`` + so ``infer_transport`` picks the right transport. +2. Existing file paths, or strings ending in ``.py``/``.js``/``.json``. +3. Anything else — name-based resolution via ``resolve_name``. + +When ``command`` is provided, the string is shell-split into a +``StdioTransport(command, args)``. + + +### `coerce_value` + +```python +coerce_value(raw: str, schema: dict[str, Any]) -> Any +``` + + +Coerce a string CLI value according to a JSON-Schema type hint. + + +### `parse_tool_arguments` + +```python +parse_tool_arguments(raw_args: tuple[str, ...], input_json: str | None, input_schema: dict[str, Any]) -> dict[str, Any] +``` + + +Build a tool-call argument dict from CLI inputs. + +A single JSON object argument is treated as the full argument dict. +``--input-json`` provides the base dict; ``key=value`` pairs override. +Values are coerced using the tool's ``inputSchema``. + + +### `format_tool_signature` + +```python +format_tool_signature(tool: mcp.types.Tool) -> str +``` + + +Build ``name(param: type, ...) -> return_type`` from a tool's JSON schemas. + + +### `list_command` + +```python +list_command(server_spec: Annotated[str | None, cyclopts.Parameter(help='Server URL, Python file, MCPConfig JSON, or .js file')] = None) -> None +``` + + +List tools available on an MCP server. + +**Examples:** + +fastmcp list http://localhost:8000/mcp +fastmcp list server.py +fastmcp list mcp.json --json +fastmcp list --command 'npx -y @mcp/server' --resources +fastmcp list http://server/mcp --transport sse + + +### `call_command` + +```python +call_command(server_spec: Annotated[str | None, cyclopts.Parameter(help='Server URL, Python file, MCPConfig JSON, or .js file')] = None, target: Annotated[str, cyclopts.Parameter(help='Tool name, resource URI, or prompt name (with --prompt)')] = '', *arguments: str) -> None +``` + + +Call a tool, read a resource, or get a prompt on an MCP server. + +By default the target is treated as a tool name. If the target +contains ``://`` it is treated as a resource URI. Pass ``--prompt`` +to treat it as a prompt name. + +Arguments are passed as key=value pairs. Use --input-json for complex +or nested arguments. + +**Examples:** + +fastmcp call server.py greet name=World +fastmcp call server.py resource://docs/readme +fastmcp call server.py analyze --prompt data='[1,2,3]' +fastmcp call http://server/mcp create --input-json '{"tags": ["a","b"]}' + + +### `discover_command` + +```python +discover_command() -> None +``` + + +Discover MCP servers configured in editor and project configs. + +Scans Claude Desktop, Claude Code, Cursor, Gemini CLI, Goose, and +project-level mcp.json files for MCP server definitions. + +Discovered server names can be used directly with ``fastmcp list`` +and ``fastmcp call`` instead of specifying a URL or file path. + +**Examples:** + +fastmcp discover +fastmcp discover --source claude-code +fastmcp discover --source cursor --source gemini --json +fastmcp list weather +fastmcp call cursor:weather get_forecast city=London + diff --git a/docs/python-sdk/fastmcp-cli-discovery.mdx b/docs/python-sdk/fastmcp-cli-discovery.mdx new file mode 100644 index 000000000..3cc6866bd --- /dev/null +++ b/docs/python-sdk/fastmcp-cli-discovery.mdx @@ -0,0 +1,71 @@ +--- +title: discovery +sidebarTitle: discovery +--- + +# `fastmcp.cli.discovery` + + +Discover MCP servers configured in editor config files. + +Scans filesystem-readable config files from editors like Claude Desktop, +Claude Code, Cursor, Gemini CLI, and Goose, as well as project-level +``mcp.json`` files. Each discovered server can be resolved by name +(or ``source:name``) so the CLI can connect without requiring a URL +or file path. + + +## Functions + +### `discover_servers` + +```python +discover_servers(start_dir: Path | None = None) -> list[DiscoveredServer] +``` + + +Run all scanners and return the combined results. + +Duplicate names across sources are preserved — callers can +use :pyattr:`DiscoveredServer.qualified_name` to disambiguate. + + +### `resolve_name` + +```python +resolve_name(name: str, start_dir: Path | None = None) -> ClientTransport +``` + + +Resolve a server name (or ``source:name``) to a transport. + +Raises :class:`ValueError` when the name is not found or is ambiguous. + + +## Classes + +### `DiscoveredServer` + + +A single MCP server found in an editor or project config. + + +**Methods:** + +#### `qualified_name` + +```python +qualified_name(self) -> str +``` + +Fully qualified ``source:name`` identifier. + + +#### `transport_summary` + +```python +transport_summary(self) -> str +``` + +Human-readable one-liner describing the transport. + diff --git a/docs/python-sdk/fastmcp-cli-install-cursor.mdx b/docs/python-sdk/fastmcp-cli-install-cursor.mdx index 40c0c5c6a..adb8b0bfd 100644 --- a/docs/python-sdk/fastmcp-cli-install-cursor.mdx +++ b/docs/python-sdk/fastmcp-cli-install-cursor.mdx @@ -10,7 +10,7 @@ Cursor integration for FastMCP install using Cyclopts. ## Functions -### `generate_cursor_deeplink` +### `generate_cursor_deeplink` ```python generate_cursor_deeplink(server_name: str, server_config: StdioMCPServer) -> str @@ -27,14 +27,14 @@ Generate a Cursor deeplink for installing the MCP server. - Deeplink URL that can be clicked to install the server -### `open_deeplink` +### `open_deeplink` ```python open_deeplink(deeplink: str) -> bool ``` -Attempt to open a deeplink URL using the system's default handler. +Attempt to open a Cursor deeplink URL using the system's default handler. **Args:** - `deeplink`: The deeplink URL to open @@ -43,7 +43,7 @@ Attempt to open a deeplink URL using the system's default handler. - True if the command succeeded, False otherwise -### `install_cursor_workspace` +### `install_cursor_workspace` ```python install_cursor_workspace(file: Path, server_object: str | None, name: str, workspace_path: Path) -> bool @@ -68,7 +68,7 @@ Install FastMCP server to workspace-specific Cursor configuration. - True if installation was successful, False otherwise -### `install_cursor` +### `install_cursor` ```python install_cursor(file: Path, server_object: str | None, name: str) -> bool @@ -93,7 +93,7 @@ Install FastMCP server in Cursor. - True if installation was successful, False otherwise -### `cursor_command` +### `cursor_command` ```python cursor_command(server_spec: str) -> None diff --git a/docs/python-sdk/fastmcp-cli-install-goose.mdx b/docs/python-sdk/fastmcp-cli-install-goose.mdx new file mode 100644 index 000000000..9db2bdf18 --- /dev/null +++ b/docs/python-sdk/fastmcp-cli-install-goose.mdx @@ -0,0 +1,67 @@ +--- +title: goose +sidebarTitle: goose +--- + +# `fastmcp.cli.install.goose` + + +Goose integration for FastMCP install using Cyclopts. + +## Functions + +### `generate_goose_deeplink` + +```python +generate_goose_deeplink(name: str, command: str, args: list[str]) -> str +``` + + +Generate a Goose deeplink for installing an MCP extension. + +**Args:** +- `name`: Human-readable display name for the extension. +- `command`: The executable command (e.g. "uv"). +- `args`: Arguments to the command. +- `description`: Short description shown in Goose. + +**Returns:** +- A goose://extension?... deeplink URL. + + +### `install_goose` + +```python +install_goose(file: Path, server_object: str | None, name: str) -> bool +``` + + +Install FastMCP server in Goose via deeplink. + +**Args:** +- `file`: Path to the server file. +- `server_object`: Optional server object name (for \:object suffix). +- `name`: Name for the extension in Goose. +- `with_packages`: Optional list of additional packages to install. +- `python_version`: Optional Python version to use. + +**Returns:** +- True if installation was successful, False otherwise. + + +### `goose_command` + +```python +goose_command(server_spec: str) -> None +``` + + +Install an MCP server in Goose. + +Uses uvx to run the server. Environment variables are not included +in the deeplink; use `fastmcp install mcp-json` to generate a full +config for manual installation. + +**Args:** +- `server_spec`: Python file to install, optionally with \:object suffix + diff --git a/docs/python-sdk/fastmcp-cli-install-shared.mdx b/docs/python-sdk/fastmcp-cli-install-shared.mdx index 337179267..1df969961 100644 --- a/docs/python-sdk/fastmcp-cli-install-shared.mdx +++ b/docs/python-sdk/fastmcp-cli-install-shared.mdx @@ -10,7 +10,7 @@ Shared utilities for install commands. ## Functions -### `parse_env_var` +### `parse_env_var` ```python parse_env_var(env_var: str) -> tuple[str, str] @@ -20,7 +20,7 @@ parse_env_var(env_var: str) -> tuple[str, str] Parse environment variable string in format KEY=VALUE. -### `process_common_args` +### `process_common_args` ```python process_common_args(server_spec: str, server_name: str | None, with_packages: list[str] | None, env_vars: list[str] | None, env_file: Path | None) -> tuple[Path, str | None, str, list[str], dict[str, str] | None] @@ -31,3 +31,20 @@ Process common arguments shared by all install commands. Handles both fastmcp.json config files and traditional file.py:object syntax. + +### `open_deeplink` + +```python +open_deeplink(url: str) -> bool +``` + + +Attempt to open a deeplink URL using the system's default handler. + +**Args:** +- `url`: The deeplink URL to open. +- `expected_scheme`: The URL scheme to validate (e.g. "cursor", "goose"). + +**Returns:** +- True if the command succeeded, False otherwise. + diff --git a/docs/python-sdk/fastmcp-cli-install-stdio.mdx b/docs/python-sdk/fastmcp-cli-install-stdio.mdx new file mode 100644 index 000000000..d7d7c28d4 --- /dev/null +++ b/docs/python-sdk/fastmcp-cli-install-stdio.mdx @@ -0,0 +1,50 @@ +--- +title: stdio +sidebarTitle: stdio +--- + +# `fastmcp.cli.install.stdio` + + +Stdio command generation for FastMCP install using Cyclopts. + +## Functions + +### `install_stdio` + +```python +install_stdio(file: Path, server_object: str | None) -> bool +``` + + +Generate the stdio command for running a FastMCP server. + +**Args:** +- `file`: Path to the server file +- `server_object`: Optional server object name (for \:object suffix) +- `with_editable`: Optional list of directories to install in editable mode +- `with_packages`: Optional list of additional packages to install +- `copy`: If True, copy to clipboard instead of printing to stdout +- `python_version`: Optional Python version to use +- `with_requirements`: Optional requirements file to install from +- `project`: Optional project directory to run within + +**Returns:** +- True if generation was successful, False otherwise + + +### `stdio_command` + +```python +stdio_command(server_spec: str) -> None +``` + + +Generate the stdio command for running a FastMCP server. + +Outputs the shell command that an MCP host would use to start this server +over stdio transport. Useful for manual configuration or debugging. + +**Args:** +- `server_spec`: Python file to run, optionally with \:object suffix + diff --git a/docs/python-sdk/fastmcp-cli-run.mdx b/docs/python-sdk/fastmcp-cli-run.mdx index c3192a611..4141cd3f1 100644 --- a/docs/python-sdk/fastmcp-cli-run.mdx +++ b/docs/python-sdk/fastmcp-cli-run.mdx @@ -10,7 +10,7 @@ FastMCP run command implementation with enhanced type hints. ## Functions -### `is_url` +### `is_url` ```python is_url(path: str) -> bool @@ -20,7 +20,7 @@ is_url(path: str) -> bool Check if a string is a URL. -### `create_client_server` +### `create_client_server` ```python create_client_server(url: str) -> Any @@ -36,7 +36,7 @@ Create a FastMCP server from a client URL. - A FastMCP server instance -### `create_mcp_config_server` +### `create_mcp_config_server` ```python create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None] @@ -46,7 +46,7 @@ create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None] Create a FastMCP server from a MCPConfig. -### `load_mcp_server_config` +### `load_mcp_server_config` ```python load_mcp_server_config(config_path: Path) -> MCPServerConfig @@ -62,7 +62,7 @@ Load a FastMCP configuration from a fastmcp.json file. - MCPServerConfig object -### `run_command` +### `run_command` ```python run_command(server_spec: str, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, server_args: list[str] | None = None, show_banner: bool = True, use_direct_import: bool = False, skip_source: bool = False, stateless: bool = False) -> None @@ -85,7 +85,7 @@ Run a MCP server or connect to a remote one. - `stateless`: Whether to run in stateless mode (no session) -### `run_v1_server_async` +### `run_v1_server_async` ```python run_v1_server_async(server: FastMCP1x, host: str | None = None, port: int | None = None, transport: TransportType | None = None) -> None @@ -101,7 +101,7 @@ Run a FastMCP 1.x server using async methods. - `transport`: Transport protocol to use -### `run_with_reload` +### `run_with_reload` ```python run_with_reload(cmd: list[str], reload_dirs: list[Path] | None = None, is_stdio: bool = False) -> None diff --git a/docs/python-sdk/fastmcp-client-transports-config.mdx b/docs/python-sdk/fastmcp-client-transports-config.mdx index d19f709f2..2e802df0a 100644 --- a/docs/python-sdk/fastmcp-client-transports-config.mdx +++ b/docs/python-sdk/fastmcp-client-transports-config.mdx @@ -19,7 +19,7 @@ object or dictionary matching the MCPConfig schema. It supports two key scenario 2. If the MCPConfig contains multiple servers, it creates a composite client by mounting all servers on a single FastMCP instance, with each server's name, by default, used as its mounting prefix. -In the multi-server case, tools are accessible with the prefix pattern `{server_name}_{tool_name}` +In the multiserver case, tools are accessible with the prefix pattern `{server_name}_{tool_name}` and resources with the pattern `protocol://{server_name}/path/to/resource`. This is particularly useful for creating clients that need to interact with multiple specialized diff --git a/docs/python-sdk/fastmcp-prompts-function_prompt.mdx b/docs/python-sdk/fastmcp-prompts-function_prompt.mdx index 3c543de88..edc9527f2 100644 --- a/docs/python-sdk/fastmcp-prompts-function_prompt.mdx +++ b/docs/python-sdk/fastmcp-prompts-function_prompt.mdx @@ -10,7 +10,7 @@ Standalone @prompt decorator for FastMCP. ## Functions -### `prompt` +### `prompt` ```python prompt(name_or_fn: str | Callable[..., Any] | None = None) -> Any @@ -25,19 +25,19 @@ using mcp.add_prompt(). ## Classes -### `DecoratedPrompt` +### `DecoratedPrompt` Protocol for functions decorated with @prompt. -### `PromptMeta` +### `PromptMeta` Metadata attached to functions by the @prompt decorator. -### `FunctionPrompt` +### `FunctionPrompt` A prompt that is a function. @@ -45,7 +45,7 @@ A prompt that is a function. **Methods:** -#### `from_function` +#### `from_function` ```python from_function(cls, fn: Callable[..., Any]) -> FunctionPrompt @@ -66,7 +66,7 @@ The function can return: - PromptResult: used directly -#### `render` +#### `render` ```python render(self, arguments: dict[str, Any] | None = None) -> PromptResult @@ -75,7 +75,7 @@ render(self, arguments: dict[str, Any] | None = None) -> PromptResult Render the prompt with arguments. -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None @@ -87,7 +87,7 @@ FunctionPrompt 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, arguments: dict[str, Any] | None, **kwargs: Any) -> Execution diff --git a/docs/python-sdk/fastmcp-prompts-prompt.mdx b/docs/python-sdk/fastmcp-prompts-prompt.mdx index 1541e9c58..b0e33f1e3 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,7 +73,7 @@ to_mcp_prompt(self, **overrides: Any) -> SDKPrompt Convert the prompt to an MCP prompt. -#### `from_function` +#### `from_function` ```python from_function(cls, fn: Callable[..., Any]) -> FunctionPrompt @@ -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,7 +138,7 @@ Schedule this prompt for background execution via docket. - `**kwargs`: Additional kwargs passed to docket.add() -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] diff --git a/docs/python-sdk/fastmcp-resources-function_resource.mdx b/docs/python-sdk/fastmcp-resources-function_resource.mdx index e7d710744..c5de76443 100644 --- a/docs/python-sdk/fastmcp-resources-function_resource.mdx +++ b/docs/python-sdk/fastmcp-resources-function_resource.mdx @@ -10,7 +10,7 @@ Standalone @resource decorator for FastMCP. ## Functions -### `resource` +### `resource` ```python resource(uri: str) -> Callable[[F], F] @@ -25,19 +25,19 @@ using mcp.add_resource(). ## Classes -### `DecoratedResource` +### `DecoratedResource` Protocol for functions decorated with @resource. -### `ResourceMeta` +### `ResourceMeta` Metadata attached to functions by the @resource decorator. -### `FunctionResource` +### `FunctionResource` A resource that defers data loading by wrapping a function. @@ -54,7 +54,7 @@ The function can return: **Methods:** -#### `from_function` +#### `from_function` ```python from_function(cls, fn: Callable[..., Any], uri: str | AnyUrl | None = None) -> FunctionResource @@ -71,7 +71,7 @@ individual parameters must not be passed. Cannot be used together with metadata parameter. -#### `read` +#### `read` ```python read(self) -> str | bytes | ResourceResult @@ -80,7 +80,7 @@ read(self) -> str | bytes | ResourceResult Read the resource by calling the wrapped function. -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None diff --git a/docs/python-sdk/fastmcp-resources-resource.mdx b/docs/python-sdk/fastmcp-resources-resource.mdx index b064ac47b..2c5972094 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(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 @@ -121,10 +121,17 @@ This is used in two contexts: 2. In tasks_result_handler() to convert Docket task results to ResourceResult Handles ResourceResult passthrough and converts raw values using -ResourceResult's normalization. +ResourceResult's normalization. When the raw value is a plain +string or bytes, the resource's own ``mime_type`` is forwarded so +that ``ui://`` resources (and others with non-default MIME types) +don't fall back to ``text/plain``. + +The resource's component-level ``meta`` (e.g. ``ui`` metadata for +MCP Apps CSP/permissions) is propagated to each content item so +that hosts can read it from the ``resources/read`` response. -#### `to_mcp_resource` +#### `to_mcp_resource` ```python to_mcp_resource(self, **overrides: Any) -> SDKResource @@ -133,7 +140,7 @@ to_mcp_resource(self, **overrides: Any) -> SDKResource Convert the resource to an SDKResource. -#### `key` +#### `key` ```python key(self) -> str @@ -142,7 +149,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 +158,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,7 +173,7 @@ Schedule this resource for background execution via docket. - `**kwargs`: Additional kwargs passed to docket.add() -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] diff --git a/docs/python-sdk/fastmcp-resources-template.mdx b/docs/python-sdk/fastmcp-resources-template.mdx index e1b932d88..e55bae102 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, 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,13 +172,13 @@ Schedule this template for background execution via docket. - `**kwargs`: Additional kwargs passed to docket.add() -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] ``` -### `FunctionResourceTemplate` +### `FunctionResourceTemplate` A template for dynamically creating resources. @@ -186,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 @@ -195,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 @@ -204,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 @@ -216,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 @@ -234,7 +234,7 @@ 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, 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 diff --git a/docs/python-sdk/fastmcp-server-apps.mdx b/docs/python-sdk/fastmcp-server-apps.mdx new file mode 100644 index 000000000..c72052339 --- /dev/null +++ b/docs/python-sdk/fastmcp-server-apps.mdx @@ -0,0 +1,87 @@ +--- +title: apps +sidebarTitle: apps +--- + +# `fastmcp.server.apps` + + +MCP Apps support — extension negotiation and typed UI metadata models. + +Provides constants and Pydantic models for the MCP Apps extension +(io.modelcontextprotocol/ui), enabling tools and resources to carry +UI metadata for clients that support interactive app rendering. + + +## Functions + +### `ui_to_meta_dict` + +```python +ui_to_meta_dict(ui: ToolUI | ResourceUI | dict[str, Any]) -> dict[str, Any] +``` + + +Convert a UI model or dict to the wire-format dict for ``meta["ui"]``. + + +### `resolve_ui_mime_type` + +```python +resolve_ui_mime_type(uri: str, explicit_mime_type: str | None) -> str | None +``` + + +Return the appropriate MIME type for a resource URI. + +For ``ui://`` scheme resources, defaults to ``UI_MIME_TYPE`` when no +explicit MIME type is provided. This ensures UI resources are correctly +identified regardless of how they're registered (via FastMCP.resource, +the standalone @resource decorator, or resource templates). + +**Args:** +- `uri`: The resource URI string +- `explicit_mime_type`: The MIME type explicitly provided by the user + +**Returns:** +- The resolved MIME type (explicit value, UI default, or None) + + +## Classes + +### `ResourceCSP` + + +Content Security Policy for MCP App resources. + +Declares which external origins the app is allowed to connect to or +load resources from. Hosts use these declarations to build the +``Content-Security-Policy`` header for the sandboxed iframe. + + +### `ResourcePermissions` + + +Iframe sandbox permissions for MCP App resources. + +Each field, when set (typically to ``{}``), requests that the host +grant the corresponding Permission Policy feature to the sandboxed +iframe. Hosts MAY honour these; apps should use JS feature detection +as a fallback. + + +### `ToolUI` + + +Typed ``_meta.ui`` for tools — links a tool to its UI resource. + +All fields use ``exclude_none`` serialization so only explicitly-set +values appear on the wire. Aliases match the MCP Apps wire format +(camelCase). + + +### `ResourceUI` + + +Typed ``_meta.ui`` for resources — rendering hints for UI-capable clients. + diff --git a/docs/python-sdk/fastmcp-server-auth-auth.mdx b/docs/python-sdk/fastmcp-server-auth-auth.mdx index 8f58e8be6..723b5a08f 100644 --- a/docs/python-sdk/fastmcp-server-auth-auth.mdx +++ b/docs/python-sdk/fastmcp-server-auth-auth.mdx @@ -164,7 +164,21 @@ Token verifiers typically don't provide authentication routes by default. **Methods:** -#### `verify_token` +#### `scopes_supported` + +```python +scopes_supported(self) -> list[str] +``` + +Scopes to advertise in OAuth metadata. + +Defaults to required_scopes. Override in subclasses when the +advertised scopes differ from the validation scopes (e.g., Azure AD +where tokens contain short-form scopes but clients request full URI +scopes). + + +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -173,7 +187,7 @@ verify_token(self, token: str) -> AccessToken | None Verify a bearer token and return access info if valid. -### `RemoteAuthProvider` +### `RemoteAuthProvider` Authentication provider for resource servers that verify tokens from known authorization servers. @@ -190,7 +204,7 @@ the authorization servers that issue valid tokens. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -199,7 +213,7 @@ verify_token(self, token: str) -> AccessToken | None Verify token using the configured token verifier. -#### `get_routes` +#### `get_routes` ```python get_routes(self, mcp_path: str | None = None) -> list[Route] @@ -210,7 +224,7 @@ Get routes for this provider. Creates protected resource metadata routes (RFC 9728). -### `OAuthProvider` +### `OAuthProvider` OAuth Authorization Server provider. @@ -221,7 +235,7 @@ authorization flows, token issuance, and token verification. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -239,7 +253,7 @@ to our existing load_access_token method. - AccessToken object if valid, None if invalid or expired -#### `get_routes` +#### `get_routes` ```python get_routes(self, mcp_path: str | None = None) -> list[Route] @@ -255,7 +269,7 @@ This method creates the full set of OAuth routes including: - List of OAuth routes -#### `get_well_known_routes` +#### `get_well_known_routes` ```python get_well_known_routes(self, mcp_path: str | None = None) -> list[Route] diff --git a/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx b/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx index cbaa6eb04..9b168337e 100644 --- a/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx +++ b/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx @@ -42,7 +42,7 @@ a key derived from the upstream client secret. #### `issue_access_token` ```python -issue_access_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int = 3600) -> str +issue_access_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int = 3600, upstream_claims: dict[str, Any] | None = None) -> str ``` Issue a minimal FastMCP access token. @@ -56,15 +56,16 @@ which contains actual user identity and authorization data. - `scopes`: Token scopes - `jti`: Unique token identifier (maps to upstream token) - `expires_in`: Token lifetime in seconds +- `upstream_claims`: Optional claims from upstream IdP token to include **Returns:** - Signed JWT token -#### `issue_refresh_token` +#### `issue_refresh_token` ```python -issue_refresh_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int) -> str +issue_refresh_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int, upstream_claims: dict[str, Any] | None = None) -> str ``` Issue a minimal FastMCP refresh token. @@ -78,12 +79,13 @@ token which contains actual user identity and authorization data. - `scopes`: Token scopes - `jti`: Unique token identifier (maps to upstream token) - `expires_in`: Token lifetime in seconds (should match upstream refresh expiry) +- `upstream_claims`: Optional claims from upstream IdP token to include **Returns:** - Signed JWT token -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> dict[str, Any] diff --git a/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx index 20f839f46..26f80c876 100644 --- a/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx +++ b/docs/python-sdk/fastmcp-server-auth-oauth_proxy-proxy.mdx @@ -26,7 +26,7 @@ production use with enterprise identity providers. ## Classes -### `OAuthProxy` +### `OAuthProxy` OAuth provider that presents a DCR-compliant interface while proxying to non-DCR IDPs. @@ -140,7 +140,7 @@ Handles provider-specific requirements: **Methods:** -#### `set_mcp_path` +#### `set_mcp_path` ```python set_mcp_path(self, mcp_path: str | None) -> None @@ -157,7 +157,7 @@ this specific MCP endpoint. - `mcp_path`: The path where the MCP endpoint is mounted (e.g., "/mcp") -#### `jwt_issuer` +#### `jwt_issuer` ```python jwt_issuer(self) -> JWTIssuer @@ -169,7 +169,7 @@ The JWT issuer is created when set_mcp_path() is called (via get_routes()). This property ensures a clear error if used before initialization. -#### `get_client` +#### `get_client` ```python get_client(self, client_id: str) -> OAuthClientInformationFull | None @@ -181,7 +181,7 @@ provided to the DCR client during registration, not the upstream client ID. For unregistered clients, returns None (which will raise an error in the SDK). -#### `register_client` +#### `register_client` ```python register_client(self, client_info: OAuthClientInformationFull) -> None @@ -195,7 +195,7 @@ redirect URI will likely be localhost or unknown to the proxied IDP. The proxied IDP only knows about this server's fixed redirect URI. -#### `authorize` +#### `authorize` ```python authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str @@ -213,7 +213,7 @@ If consent is disabled (require_authorization_consent=False), skip the consent s and redirect directly to the upstream IdP. -#### `load_authorization_code` +#### `load_authorization_code` ```python load_authorization_code(self, client: OAuthClientInformationFull, authorization_code: str) -> AuthorizationCode | None @@ -225,7 +225,7 @@ Look up our client code and return authorization code object with PKCE challenge for validation. -#### `exchange_authorization_code` +#### `exchange_authorization_code` ```python exchange_authorization_code(self, client: OAuthClientInformationFull, authorization_code: AuthorizationCode) -> OAuthToken @@ -243,7 +243,7 @@ Implements the token factory pattern: PKCE validation is handled by the MCP framework before this method is called. -#### `load_refresh_token` +#### `load_refresh_token` ```python load_refresh_token(self, client: OAuthClientInformationFull, refresh_token: str) -> RefreshToken | None @@ -255,7 +255,7 @@ Looks up by token hash and reconstructs the RefreshToken object. Validates that the token belongs to the requesting client. -#### `exchange_refresh_token` +#### `exchange_refresh_token` ```python exchange_refresh_token(self, client: OAuthClientInformationFull, refresh_token: RefreshToken, scopes: list[str]) -> OAuthToken @@ -272,7 +272,7 @@ Implements two-tier refresh: 6. Keep same FastMCP refresh token (unless upstream rotates) -#### `load_access_token` +#### `load_access_token` ```python load_access_token(self, token: str) -> AccessToken | None @@ -291,7 +291,7 @@ The FastMCP JWT is a reference token - all authorization data comes from validating the upstream token via the TokenVerifier. -#### `revoke_token` +#### `revoke_token` ```python revoke_token(self, token: AccessToken | RefreshToken) -> None @@ -304,7 +304,7 @@ For all tokens, attempts upstream revocation if endpoint is configured. Access token JTI mappings expire via TTL. -#### `get_routes` +#### `get_routes` ```python get_routes(self, mcp_path: str | None = None) -> list[Route] diff --git a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx index 411a17550..2e403a611 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx @@ -49,7 +49,7 @@ Setup: **Methods:** -#### `authorize` +#### `authorize` ```python authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str @@ -68,3 +68,55 @@ scopes to determine the resource/audience instead of a separate parameter. **Returns:** - Authorization URL to redirect the user to Azure AD + +### `AzureJWTVerifier` + + +JWT verifier pre-configured for Azure AD / Microsoft Entra ID. + +Auto-configures JWKS URI, issuer, audience, and scope handling from your +Azure app registration details. Designed for Managed Identity and other +token-verification-only scenarios where AzureProvider's full OAuth proxy +isn't needed. + +Handles Azure's scope format automatically: +- Validates tokens using short-form scopes (what Azure puts in ``scp`` claims) +- Advertises full-URI scopes in OAuth metadata (what clients need to request) + +Example:: + + from fastmcp.server.auth import RemoteAuthProvider + from fastmcp.server.auth.providers.azure import AzureJWTVerifier + from pydantic import AnyHttpUrl + + verifier = AzureJWTVerifier( + client_id="your-client-id", + tenant_id="your-tenant-id", + required_scopes=["access_as_user"], + ) + + auth = RemoteAuthProvider( + token_verifier=verifier, + authorization_servers=[ + AnyHttpUrl("https://login.microsoftonline.com/your-tenant-id/v2.0") + ], + base_url="https://my-server.com", + ) + + +**Methods:** + +#### `scopes_supported` + +```python +scopes_supported(self) -> list[str] +``` + +Return scopes with Azure URI prefix for OAuth metadata. + +Azure tokens contain short-form scopes (e.g., ``read``) in the ``scp`` +claim, but clients must request full URI scopes (e.g., +``api://client-id/read``) from the Azure authorization endpoint. This +property returns the full-URI form for OAuth metadata while +``required_scopes`` retains the short form for token validation. + diff --git a/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx b/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx index 9ea8f2701..9dd176f2e 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx @@ -82,7 +82,7 @@ Use this when: **Methods:** -#### `load_access_token` +#### `load_access_token` ```python load_access_token(self, token: str) -> AccessToken | None @@ -97,7 +97,7 @@ Validate a JWT bearer token and return an AccessToken when the token is valid. - AccessToken | None: An AccessToken populated from token claims if the token is valid; `None` if the token is expired, has an invalid signature or format, fails issuer/audience/scope validation, or any other validation error occurs. -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -115,7 +115,7 @@ to our existing load_access_token method. - AccessToken object if valid, None if invalid or expired -### `StaticTokenVerifier` +### `StaticTokenVerifier` Simple static token verifier for testing and development. @@ -136,7 +136,7 @@ WARNING: Never use this in production - tokens are stored in plain text! **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx index 1edf918c8..060f0c4d5 100644 --- a/docs/python-sdk/fastmcp-server-context.mdx +++ b/docs/python-sdk/fastmcp-server-context.mdx @@ -7,7 +7,7 @@ sidebarTitle: context ## Functions -### `set_transport` +### `set_transport` ```python set_transport(transport: TransportType) -> Token[TransportType | None] @@ -17,7 +17,7 @@ set_transport(transport: TransportType) -> Token[TransportType | None] Set the current transport type. Returns token for reset. -### `reset_transport` +### `reset_transport` ```python reset_transport(token: Token[TransportType | None]) -> None @@ -27,7 +27,7 @@ reset_transport(token: Token[TransportType | None]) -> None Reset transport to previous value. -### `set_context` +### `set_context` ```python set_context(context: Context) -> Generator[Context, None, None] @@ -35,7 +35,7 @@ set_context(context: Context) -> Generator[Context, None, None] ## Classes -### `LogData` +### `LogData` Data object for passing log arguments to client-side handlers. @@ -44,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. @@ -96,7 +96,31 @@ The context is optional - tools that don't need it can omit the parameter. **Methods:** -#### `fastmcp` +#### `is_background_task` + +```python +is_background_task(self) -> bool +``` + +True when this context is running in a background task (Docket worker). + +When True, certain operations like elicit() and sample() will use +task-aware implementations that can pause the task and wait for +client input. + + +#### `task_id` + +```python +task_id(self) -> str | None +``` + +Get the background task ID if running in a background task. + +Returns None if not running in a background task context. + + +#### `fastmcp` ```python fastmcp(self) -> FastMCP @@ -105,7 +129,7 @@ fastmcp(self) -> FastMCP Get the FastMCP instance. -#### `request_context` +#### `request_context` ```python request_context(self) -> RequestContext[ServerSession, Any, Request] | None @@ -134,7 +158,7 @@ async def on_request(self, context, call_next): ``` -#### `lifespan_context` +#### `lifespan_context` ```python lifespan_context(self) -> dict[str, Any] @@ -157,7 +181,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 @@ -170,7 +194,7 @@ Report progress for the current operation. - `total`: Optional total value e.g. 100 -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> list[SDKResource] @@ -182,7 +206,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] @@ -194,7 +218,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 @@ -210,7 +234,7 @@ Get a prompt by name with optional arguments. - The prompt result -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: str | AnyUrl) -> ResourceResult @@ -225,7 +249,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 @@ -243,7 +267,7 @@ Messages sent to Clients are also logged to the `fastmcp.server.context.to_clien - `extra`: Optional mapping for additional arguments -#### `transport` +#### `transport` ```python transport(self) -> TransportType | None @@ -255,7 +279,32 @@ 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` +#### `client_supports_extension` + +```python +client_supports_extension(self, extension_id: str) -> bool +``` + +Check whether the connected client supports a given MCP extension. + +Inspects the ``extensions`` extra field on ``ClientCapabilities`` +sent by the client during initialization. + +Returns ``False`` when no session is available (e.g., outside a +request context) or when the client did not advertise the extension. + +Example:: + + from fastmcp.server.apps import UI_EXTENSION_ID + + @mcp.tool + async def my_tool(ctx: Context) -> str: + if ctx.client_supports_extension(UI_EXTENSION_ID): + return "UI-capable client" + return "text-only client" + + +#### `client_id` ```python client_id(self) -> str | None @@ -264,7 +313,7 @@ client_id(self) -> str | None Get the client ID if available. -#### `request_id` +#### `request_id` ```python request_id(self) -> str @@ -275,7 +324,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 @@ -292,7 +341,7 @@ the same client session. - for other transports. -#### `session` +#### `session` ```python session(self) -> ServerSession @@ -300,10 +349,13 @@ session(self) -> ServerSession Access to the underlying session for advanced usage. -Raises RuntimeError if MCP request context is not available. +In request mode: Returns the session from the active request context. +In background task mode: Returns the session stored at Context creation. + +Raises RuntimeError if no session is available. -#### `debug` +#### `debug` ```python debug(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -314,7 +366,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 @@ -325,7 +377,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 @@ -336,7 +388,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 @@ -347,7 +399,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] @@ -356,7 +408,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 @@ -368,7 +420,7 @@ Send a notification to the client immediately. - `notification`: An MCP notification instance (e.g., ToolListChangedNotification()) -#### `close_sse_stream` +#### `close_sse_stream` ```python close_sse_stream(self) -> None @@ -386,7 +438,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 @@ -423,7 +475,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] @@ -432,7 +484,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] @@ -441,7 +493,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] @@ -483,43 +535,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 @@ -548,7 +600,7 @@ type or dataclass or BaseModel. If it is a primitive type, an object schema with a single "value" field will be generated. -#### `set_state` +#### `set_state` ```python set_state(self, key: str, value: Any) -> None @@ -561,7 +613,7 @@ 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 @@ -572,7 +624,7 @@ Get a value from the session-scoped state store. Returns None if the key is not found. -#### `delete_state` +#### `delete_state` ```python delete_state(self, key: str) -> None @@ -581,7 +633,7 @@ delete_state(self, key: str) -> None Delete a value from the session-scoped state store. -#### `enable_components` +#### `enable_components` ```python enable_components(self) -> None @@ -605,7 +657,7 @@ ResourceListChangedNotification, and PromptListChangedNotification. - `match_all`: If True, matches all components regardless of other criteria. -#### `disable_components` +#### `disable_components` ```python disable_components(self) -> None @@ -629,7 +681,7 @@ ResourceListChangedNotification, and PromptListChangedNotification. - `match_all`: If True, matches all components regardless of other criteria. -#### `reset_visibility` +#### `reset_visibility` ```python reset_visibility(self) -> None diff --git a/docs/python-sdk/fastmcp-server-dependencies.mdx b/docs/python-sdk/fastmcp-server-dependencies.mdx index 71d7a91f6..d718b2fc3 100644 --- a/docs/python-sdk/fastmcp-server-dependencies.mdx +++ b/docs/python-sdk/fastmcp-server-dependencies.mdx @@ -15,7 +15,57 @@ CurrentWorker) and background task execution require fastmcp[tasks]. ## Functions -### `is_docket_available` +### `get_task_context` + +```python +get_task_context() -> TaskContextInfo | None +``` + + +Get the current task context if running inside a background task worker. + +This function extracts task information from the Docket execution context. +Returns None if not running in a task context (e.g., foreground execution). + +**Returns:** +- TaskContextInfo with task_id and session_id, or None if not in a task. + + +### `register_task_session` + +```python +register_task_session(session_id: str, session: ServerSession) -> None +``` + + +Register a session for Context access in background tasks. + +Called automatically when a task is submitted to Docket. The session is +stored as a weakref so it doesn't prevent garbage collection when the +client disconnects. + +**Args:** +- `session_id`: The session identifier +- `session`: The ServerSession instance + + +### `get_task_session` + +```python +get_task_session(session_id: str) -> ServerSession | None +``` + + +Get a registered session by ID if still alive. + +**Args:** +- `session_id`: The session identifier + +**Returns:** +- The ServerSession if found and alive, None otherwise + + +### `is_docket_available` ```python is_docket_available() -> bool @@ -25,7 +75,7 @@ is_docket_available() -> bool Check if pydocket is installed. -### `require_docket` +### `require_docket` ```python require_docket(feature: str) -> None @@ -39,7 +89,7 @@ Raise ImportError with install instructions if docket not available. "CurrentDocket()"). Will be included in the error message. -### `transform_context_annotations` +### `transform_context_annotations` ```python transform_context_annotations(fn: Callable[..., Any]) -> Callable[..., Any] @@ -65,7 +115,7 @@ allows them to have defaults in any order. - Function with modified signature (same function object, updated __signature__) -### `get_context` +### `get_context` ```python get_context() -> Context @@ -75,7 +125,7 @@ get_context() -> Context Get the current FastMCP Context instance directly. -### `get_server` +### `get_server` ```python get_server() -> FastMCP @@ -91,7 +141,7 @@ Get the current FastMCP server instance directly. - `RuntimeError`: If no server in context -### `get_http_request` +### `get_http_request` ```python get_http_request() -> Request @@ -103,7 +153,7 @@ Get the current HTTP request. Tries MCP SDK's request_ctx first, then falls back to FastMCP's HTTP context. -### `get_http_headers` +### `get_http_headers` ```python get_http_headers(include_all: bool = False) -> dict[str, str] @@ -119,7 +169,7 @@ 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` +### `get_access_token` ```python get_access_token() -> AccessToken | None @@ -137,7 +187,7 @@ request is available. - The access token if an authenticated user is available, None otherwise. -### `without_injected_parameters` +### `without_injected_parameters` ```python without_injected_parameters(fn: Callable[..., Any]) -> Callable[..., Any] @@ -162,7 +212,7 @@ Handles: - 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] @@ -188,7 +238,7 @@ time, so all injection goes through the unified DI system. which will be filtered out) -### `CurrentContext` +### `CurrentContext` ```python CurrentContext() -> Context @@ -207,7 +257,7 @@ current MCP operation (tool/resource/prompt call). - `RuntimeError`: If no active context found (during resolution) -### `CurrentDocket` +### `CurrentDocket` ```python CurrentDocket() -> Docket @@ -227,7 +277,7 @@ automatically creates for background task scheduling. - `ImportError`: If fastmcp[tasks] not installed -### `CurrentWorker` +### `CurrentWorker` ```python CurrentWorker() -> Worker @@ -247,7 +297,7 @@ automatically creates for background task processing. - `ImportError`: If fastmcp[tasks] not installed -### `CurrentFastMCP` +### `CurrentFastMCP` ```python CurrentFastMCP() -> FastMCP @@ -265,7 +315,7 @@ This dependency provides access to the active FastMCP server. - `RuntimeError`: If no server in context (during resolution) -### `CurrentRequest` +### `CurrentRequest` ```python CurrentRequest() -> Request @@ -285,7 +335,7 @@ current HTTP request. Only available when running over HTTP transports - `RuntimeError`: If no HTTP request in context (e.g., STDIO transport) -### `CurrentHeaders` +### `CurrentHeaders` ```python CurrentHeaders() -> dict[str, str] @@ -302,7 +352,7 @@ safe to use in code that might run over any transport. - A dependency that resolves to a dictionary of header name -> value -### `CurrentAccessToken` +### `CurrentAccessToken` ```python CurrentAccessToken() -> AccessToken @@ -323,7 +373,16 @@ authenticated request. Raises an error if no authentication is present. ## Classes -### `ProgressLike` +### `TaskContextInfo` + + +Information about the current background task context. + +Returned by ``get_task_context()`` when running inside a Docket worker. +Contains identifiers needed to communicate with the MCP session. + + +### `ProgressLike` Protocol for progress tracking interface. @@ -334,7 +393,7 @@ and Docket's Progress (worker context). **Methods:** -#### `current` +#### `current` ```python current(self) -> int | None @@ -343,7 +402,7 @@ current(self) -> int | None Current progress value. -#### `total` +#### `total` ```python total(self) -> int @@ -352,7 +411,7 @@ total(self) -> int Total/target progress value. -#### `message` +#### `message` ```python message(self) -> str | None @@ -361,7 +420,7 @@ message(self) -> str | None Current progress message. -#### `set_total` +#### `set_total` ```python set_total(self, total: int) -> None @@ -370,7 +429,7 @@ set_total(self, total: int) -> None Set the total/target value for progress tracking. -#### `increment` +#### `increment` ```python increment(self, amount: int = 1) -> None @@ -379,7 +438,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 @@ -388,7 +447,7 @@ set_message(self, message: str | None) -> None Update the progress status message. -### `InMemoryProgress` +### `InMemoryProgress` In-memory progress tracker for immediate tool execution. @@ -400,25 +459,25 @@ progress doesn't need to be observable across processes. **Methods:** -#### `current` +#### `current` ```python current(self) -> int | None ``` -#### `total` +#### `total` ```python total(self) -> int ``` -#### `message` +#### `message` ```python message(self) -> str | None ``` -#### `set_total` +#### `set_total` ```python set_total(self, total: int) -> None @@ -427,7 +486,7 @@ set_total(self, total: int) -> None Set the total/target value for progress tracking. -#### `increment` +#### `increment` ```python increment(self, amount: int = 1) -> None @@ -436,7 +495,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 @@ -445,7 +504,7 @@ set_message(self, message: str | None) -> None Update the progress status message. -### `Progress` +### `Progress` FastMCP Progress dependency that works in both server and worker contexts. diff --git a/docs/python-sdk/fastmcp-server-low_level.mdx b/docs/python-sdk/fastmcp-server-low_level.mdx index 4a2212305..07445bac0 100644 --- a/docs/python-sdk/fastmcp-server-low_level.mdx +++ b/docs/python-sdk/fastmcp-server-low_level.mdx @@ -7,7 +7,7 @@ sidebarTitle: low_level ## Classes -### `MiddlewareServerSession` +### `MiddlewareServerSession` ServerSession that routes initialization requests through FastMCP middleware. @@ -15,7 +15,7 @@ ServerSession that routes initialization requests through FastMCP middleware. **Methods:** -#### `fastmcp` +#### `fastmcp` ```python fastmcp(self) -> FastMCP @@ -24,11 +24,23 @@ fastmcp(self) -> FastMCP Get the FastMCP instance. -### `LowLevelServer` +#### `client_supports_extension` + +```python +client_supports_extension(self, extension_id: str) -> bool +``` + +Check if the connected client supports a given MCP extension. + +Inspects the ``extensions`` extra field on ``ClientCapabilities`` +sent by the client during initialization. + + +### `LowLevelServer` **Methods:** -#### `fastmcp` +#### `fastmcp` ```python fastmcp(self) -> FastMCP @@ -37,13 +49,13 @@ fastmcp(self) -> FastMCP Get the FastMCP instance. -#### `create_initialization_options` +#### `create_initialization_options` ```python create_initialization_options(self, notification_options: NotificationOptions | None = None, experimental_capabilities: dict[str, dict[str, Any]] | None = None, **kwargs: Any) -> InitializationOptions ``` -#### `get_capabilities` +#### `get_capabilities` ```python get_capabilities(self, notification_options: NotificationOptions, experimental_capabilities: dict[str, dict[str, Any]]) -> mcp.types.ServerCapabilities @@ -56,7 +68,7 @@ capabilities.experimental.tasks, which is required by the MCP spec and enables proper task detection by clients like VS Code Copilot 1.107+. -#### `run` +#### `run` ```python run(self, read_stream: MemoryObjectReceiveStream[SessionMessage | Exception], write_stream: MemoryObjectSendStream[SessionMessage], initialization_options: InitializationOptions, raise_exceptions: bool = False, stateless: bool = False) @@ -65,7 +77,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]]] @@ -80,7 +92,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-error_handling.mdx b/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx index 5339b4a8c..be1218a20 100644 --- a/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx +++ b/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx @@ -21,7 +21,7 @@ proper MCP error responses. Also tracks error patterns for monitoring. **Methods:** -#### `on_message` +#### `on_message` ```python on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any @@ -30,7 +30,7 @@ on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any Handle errors for all messages. -#### `get_error_stats` +#### `get_error_stats` ```python get_error_stats(self) -> dict[str, int] @@ -39,7 +39,7 @@ get_error_stats(self) -> dict[str, int] Get error statistics for monitoring. -### `RetryMiddleware` +### `RetryMiddleware` Middleware that implements automatic retry logic for failed requests. @@ -50,7 +50,7 @@ backoff to avoid overwhelming the server or external dependencies. **Methods:** -#### `on_request` +#### `on_request` ```python on_request(self, context: MiddlewareContext, call_next: CallNext) -> Any diff --git a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx index 2059f6e17..f4fb6ed28 100644 --- a/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx +++ b/docs/python-sdk/fastmcp-server-providers-fastmcp_provider.mdx @@ -39,7 +39,7 @@ 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 @@ -51,13 +51,13 @@ This is called when the tool is used within a TransformedTool forwarding function or other contexts where task_meta is not available. -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] ``` -### `FastMCPProviderResource` +### `FastMCPProviderResource` Resource that delegates reading to a wrapped server's read_resource(). @@ -68,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 @@ -77,13 +77,13 @@ wrap(cls, server: Any, resource: Resource) -> FastMCPProviderResource Wrap a Resource to delegate reading to the server's middleware. -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] ``` -### `FastMCPProviderPrompt` +### `FastMCPProviderPrompt` Prompt that delegates rendering to a wrapped server's render_prompt(). @@ -94,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 @@ -103,7 +103,7 @@ 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 @@ -115,13 +115,13 @@ This is called when the prompt is used within a transformed context or other contexts where task_meta is not available. -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] ``` -### `FastMCPProviderResourceTemplate` +### `FastMCPProviderResourceTemplate` Resource template that creates FastMCPProviderResources. @@ -133,7 +133,7 @@ when read. **Methods:** -#### `wrap` +#### `wrap` ```python wrap(cls, server: Any, template: ResourceTemplate) -> FastMCPProviderResourceTemplate @@ -142,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 @@ -155,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 @@ -167,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 @@ -176,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 @@ -188,13 +188,13 @@ The child's FunctionResourceTemplate.fn is registered (via get_tasks), and it expects splatted **kwargs, so we splat params here. -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] ``` -### `FastMCPProvider` +### `FastMCPProvider` Provider that wraps a FastMCP server. @@ -210,7 +210,7 @@ This ensures middleware runs when components are executed. **Methods:** -#### `get_tasks` +#### `get_tasks` ```python get_tasks(self) -> Sequence[FastMCPComponent] @@ -224,7 +224,7 @@ 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-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx index 21db24fad..fc85ea732 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,65 +54,65 @@ use `FastMCPProxy` or `ProxyProvider` directly from `fastmcp.server.providers.pr ## Classes -### `StateValue` +### `StateValue` Wrapper for stored context state values. -### `FastMCP` +### `FastMCP` **Methods:** -#### `settings` +#### `settings` ```python settings(self) -> Settings ``` -#### `name` +#### `name` ```python name(self) -> str ``` -#### `instructions` +#### `instructions` ```python instructions(self) -> str | None ``` -#### `instructions` +#### `instructions` ```python instructions(self, value: str | None) -> None ``` -#### `version` +#### `version` ```python version(self) -> str | None ``` -#### `website_url` +#### `website_url` ```python website_url(self) -> str | None ``` -#### `icons` +#### `icons` ```python icons(self) -> list[mcp.types.Icon] ``` -#### `add_middleware` +#### `add_middleware` ```python add_middleware(self, middleware: Middleware) -> None ``` -#### `add_provider` +#### `add_provider` ```python add_provider(self, provider: Provider) -> None @@ -132,7 +132,7 @@ always take precedence over providers. - Prompts become "namespace_promptname" -#### `get_tasks` +#### `get_tasks` ```python get_tasks(self) -> Sequence[FastMCPComponent] @@ -144,7 +144,7 @@ Overrides AggregateProvider.get_tasks() to apply server-level transforms after aggregation. AggregateProvider handles provider-level namespacing. -#### `add_transform` +#### `add_transform` ```python add_transform(self, transform: Transform) -> None @@ -159,7 +159,7 @@ They transform tools, resources, and prompts from ALL providers. - `transform`: The transform to add. -#### `add_tool_transformation` +#### `add_tool_transformation` ```python add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None @@ -171,7 +171,7 @@ Add a tool transformation. Use ``add_transform(ToolTransform({...}))`` instead. -#### `remove_tool_transformation` +#### `remove_tool_transformation` ```python remove_tool_transformation(self, _tool_name: str) -> None @@ -183,7 +183,7 @@ Remove a tool transformation. Tool transformations are now immutable. Use enable/disable controls instead. -#### `list_tools` +#### `list_tools` ```python list_tools(self) -> Sequence[Tool] @@ -196,7 +196,7 @@ and middleware execution. Returns all versions (no deduplication). Protocol handlers deduplicate for MCP wire format. -#### `get_tool` +#### `get_tool` ```python get_tool(self, name: str, version: VersionSpec | None = None) -> Tool | None @@ -216,7 +216,7 @@ session transforms can override provider-level disables. - The tool if found and enabled, None otherwise. -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> Sequence[Resource] @@ -229,7 +229,7 @@ and middleware execution. Returns all versions (no deduplication). Protocol handlers deduplicate for MCP wire format. -#### `get_resource` +#### `get_resource` ```python get_resource(self, uri: str, version: VersionSpec | None = None) -> Resource | None @@ -248,7 +248,7 @@ transforms (including session-level) have been applied. - The resource if found and enabled, None otherwise. -#### `list_resource_templates` +#### `list_resource_templates` ```python list_resource_templates(self) -> Sequence[ResourceTemplate] @@ -261,7 +261,7 @@ auth filtering, and middleware execution. Returns all versions (no deduplication Protocol handlers deduplicate for MCP wire format. -#### `get_resource_template` +#### `get_resource_template` ```python get_resource_template(self, uri: str, version: VersionSpec | None = None) -> ResourceTemplate | None @@ -280,7 +280,7 @@ all transforms (including session-level) have been applied. - The template if found and enabled, None otherwise. -#### `list_prompts` +#### `list_prompts` ```python list_prompts(self) -> Sequence[Prompt] @@ -293,7 +293,7 @@ and middleware execution. Returns all versions (no deduplication). Protocol handlers deduplicate for MCP wire format. -#### `get_prompt` +#### `get_prompt` ```python get_prompt(self, name: str, version: VersionSpec | None = None) -> Prompt | None @@ -312,19 +312,19 @@ transforms (including session-level) have been applied. - The prompt if found and enabled, None otherwise. -#### `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 @@ -354,19 +354,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 @@ -395,19 +395,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 @@ -437,7 +437,7 @@ return PromptResult. - `PromptError`: If prompt rendering fails -#### `add_tool` +#### `add_tool` ```python add_tool(self, tool: Tool | Callable[..., Any]) -> Tool @@ -455,7 +455,7 @@ with the Context type annotation. See the @tool decorator for examples. - The tool instance that was added to the server. -#### `remove_tool` +#### `remove_tool` ```python remove_tool(self, name: str, version: str | None = None) -> None @@ -471,19 +471,19 @@ Remove tool(s) from the server. - `NotFoundError`: If no matching tool is found. -#### `tool` +#### `tool` ```python tool(self, name_or_fn: AnyFunction) -> FunctionTool ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool] ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool] @@ -539,7 +539,7 @@ server.tool(my_function, name="custom_name") ``` -#### `add_resource` +#### `add_resource` ```python add_resource(self, resource: Resource | Callable[..., Any]) -> Resource | ResourceTemplate @@ -554,7 +554,7 @@ Add a resource to the server. - The resource instance that was added to the server. -#### `add_template` +#### `add_template` ```python add_template(self, template: ResourceTemplate) -> ResourceTemplate @@ -569,7 +569,7 @@ Add a resource template to the server. - The template instance that was added to the server. -#### `resource` +#### `resource` ```python resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate | AnyFunction] @@ -628,7 +628,7 @@ async def get_weather(city: str) -> str: ``` -#### `add_prompt` +#### `add_prompt` ```python add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt @@ -643,19 +643,19 @@ Add a prompt to the server. - The prompt instance that was added to the server. -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: AnyFunction) -> FunctionPrompt ``` -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionPrompt] ``` -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt] @@ -732,7 +732,7 @@ Decorator to register a prompt. ``` -#### `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 @@ -779,7 +779,7 @@ mounted server. - `prefix`: Deprecated. Use namespace instead. -#### `import_server` +#### `import_server` ```python import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None @@ -820,7 +820,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 @@ -844,7 +844,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 @@ -868,7 +868,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 @@ -886,7 +886,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-config.mdx b/docs/python-sdk/fastmcp-server-tasks-config.mdx index 2dbbc63dd..cc78f7156 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 diff --git a/docs/python-sdk/fastmcp-server-tasks-elicitation.mdx b/docs/python-sdk/fastmcp-server-tasks-elicitation.mdx new file mode 100644 index 000000000..1b06baa8e --- /dev/null +++ b/docs/python-sdk/fastmcp-server-tasks-elicitation.mdx @@ -0,0 +1,74 @@ +--- +title: elicitation +sidebarTitle: elicitation +--- + +# `fastmcp.server.tasks.elicitation` + + +Background task elicitation support (SEP-1686). + +This module provides elicitation capabilities for background tasks running +in Docket workers. Unlike regular MCP requests, background tasks don't have +an active request context, so elicitation requires special handling: + +1. Set task status to "input_required" via Redis +2. Send notifications/tasks/updated with elicitation metadata +3. Wait for client to send input via tasks/sendInput +4. Resume task execution with the provided input + +This uses the public MCP SDK APIs where possible, with minimal use of +internal APIs for background task coordination. + + +## Functions + +### `elicit_for_task` + +```python +elicit_for_task(task_id: str, session: ServerSession, message: str, schema: dict[str, Any], fastmcp: FastMCP) -> mcp.types.ElicitResult +``` + + +Send an elicitation request from a background task. + +This function handles the complexity of eliciting user input when running +in a Docket worker context where there's no active MCP request. + +**Args:** +- `task_id`: The background task ID +- `session`: The MCP ServerSession for this task +- `message`: The message to display to the user +- `schema`: The JSON schema for the expected response +- `fastmcp`: The FastMCP server instance + +**Returns:** +- ElicitResult containing the user's response + +**Raises:** +- `RuntimeError`: If Docket is not available +- `McpError`: If the elicitation request fails + + +### `handle_task_input` + +```python +handle_task_input(task_id: str, session_id: str, action: str, content: dict[str, Any] | None, fastmcp: FastMCP) -> bool +``` + + +Handle input sent to a background task via tasks/sendInput. + +This is called when a client sends input in response to an elicitation +request from a background task. + +**Args:** +- `task_id`: The background task ID +- `session_id`: The MCP session ID +- `action`: The elicitation action ("accept", "decline", "cancel") +- `content`: The response content (for "accept" action) +- `fastmcp`: The FastMCP server instance + +**Returns:** +- True if the input was successfully stored, False otherwise + diff --git a/docs/python-sdk/fastmcp-tools-function_tool.mdx b/docs/python-sdk/fastmcp-tools-function_tool.mdx index 0e4b35333..bd66818a0 100644 --- a/docs/python-sdk/fastmcp-tools-function_tool.mdx +++ b/docs/python-sdk/fastmcp-tools-function_tool.mdx @@ -10,7 +10,7 @@ Standalone @tool decorator for FastMCP. ## Functions -### `tool` +### `tool` ```python tool(name_or_fn: str | Callable[..., Any] | None = None) -> Any @@ -25,23 +25,23 @@ using mcp.add_tool(). ## Classes -### `DecoratedTool` +### `DecoratedTool` Protocol for functions decorated with @tool. -### `ToolMeta` +### `ToolMeta` Metadata attached to functions by the @tool decorator. -### `FunctionTool` +### `FunctionTool` **Methods:** -#### `to_mcp_tool` +#### `to_mcp_tool` ```python to_mcp_tool(self, **overrides: Any) -> mcp.types.Tool @@ -52,7 +52,7 @@ Convert the FastMCP tool to an MCP tool. Extends the base implementation to add task execution mode if enabled. -#### `from_function` +#### `from_function` ```python from_function(cls, fn: Callable[..., Any]) -> FunctionTool @@ -68,7 +68,7 @@ individual parameters must not be passed. Cannot be used together with metadata parameter. -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any]) -> ToolResult @@ -77,7 +77,7 @@ run(self, arguments: dict[str, Any]) -> ToolResult Run the tool with arguments. -#### `register_with_docket` +#### `register_with_docket` ```python register_with_docket(self, docket: Docket) -> None @@ -89,7 +89,7 @@ FunctionTool 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, arguments: dict[str, Any], **kwargs: Any) -> Execution diff --git a/docs/python-sdk/fastmcp-tools-tool.mdx b/docs/python-sdk/fastmcp-tools-tool.mdx index 9acb15695..1068a7716 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,7 +42,7 @@ to_mcp_tool(self, **overrides: Any) -> MCPTool Convert the FastMCP tool to an MCP tool. -#### `from_function` +#### `from_function` ```python from_function(cls, fn: Callable[..., Any]) -> FunctionTool @@ -51,7 +51,7 @@ 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,13 +103,13 @@ 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 ``` -#### `get_span_attributes` +#### `get_span_attributes` ```python 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 8506d990e..dba6cf8a6 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,7 +210,7 @@ functions. - ToolResult object containing content and optional structured output. -#### `from_tool` +#### `from_tool` ```python 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 @@ -293,7 +293,7 @@ async def custom_output(**kwargs) -> ToolResult: ``` -### `ToolTransformConfig` +### `ToolTransformConfig` Provides a way to transform a tool. @@ -301,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-auth.mdx b/docs/python-sdk/fastmcp-utilities-auth.mdx index f30966e96..3e8271e9e 100644 --- a/docs/python-sdk/fastmcp-utilities-auth.mdx +++ b/docs/python-sdk/fastmcp-utilities-auth.mdx @@ -10,7 +10,49 @@ Authentication utility helpers. ## Functions -### `parse_scopes` +### `decode_jwt_header` + +```python +decode_jwt_header(token: str) -> dict[str, Any] +``` + + +Decode JWT header without signature verification. + +Useful for extracting the key ID (kid) for JWKS lookup. + +**Args:** +- `token`: JWT token string (header.payload.signature) + +**Returns:** +- Decoded header as a dictionary + +**Raises:** +- `ValueError`: If token is not a valid JWT format + + +### `decode_jwt_payload` + +```python +decode_jwt_payload(token: str) -> dict[str, Any] +``` + + +Decode JWT payload without signature verification. + +Use only for tokens received directly from trusted sources (e.g., IdP token endpoints). + +**Args:** +- `token`: JWT token string (header.payload.signature) + +**Returns:** +- Decoded payload as a dictionary + +**Raises:** +- `ValueError`: If token is not a valid JWT format + + +### `parse_scopes` ```python parse_scopes(value: Any) -> list[str] | None diff --git a/docs/python-sdk/fastmcp-utilities-lifespan.mdx b/docs/python-sdk/fastmcp-utilities-lifespan.mdx index 319dbc29c..cf347d794 100644 --- a/docs/python-sdk/fastmcp-utilities-lifespan.mdx +++ b/docs/python-sdk/fastmcp-utilities-lifespan.mdx @@ -13,7 +13,7 @@ Lifespan utilities for combining async context manager lifespans. ### `combine_lifespans` ```python -combine_lifespans(*lifespans: Callable[[AppT], AbstractAsyncContextManager[dict[str, Any] | None]]) -> Callable[[AppT], AbstractAsyncContextManager[dict[str, Any]]] +combine_lifespans(*lifespans: Callable[[AppT], AbstractAsyncContextManager[Mapping[str, Any] | None]]) -> Callable[[AppT], AbstractAsyncContextManager[dict[str, Any]]] ``` diff --git a/docs/python-sdk/fastmcp-utilities-skills.mdx b/docs/python-sdk/fastmcp-utilities-skills.mdx index 32aed81ca..ba1c9430f 100644 --- a/docs/python-sdk/fastmcp-utilities-skills.mdx +++ b/docs/python-sdk/fastmcp-utilities-skills.mdx @@ -10,7 +10,7 @@ Client utilities for discovering and downloading skills from MCP servers. ## Functions -### `list_skills` +### `list_skills` ```python list_skills(client: Client) -> list[SkillSummary] @@ -29,7 +29,7 @@ Discovers skills by finding resources with URIs matching the - List of SkillSummary objects with name, description, and URI -### `get_skill_manifest` +### `get_skill_manifest` ```python get_skill_manifest(client: Client, skill_name: str) -> SkillManifest @@ -49,7 +49,7 @@ Get the manifest for a specific skill. - `ValueError`: If manifest cannot be read or parsed -### `download_skill` +### `download_skill` ```python download_skill(client: Client, skill_name: str, target_dir: str | Path) -> Path @@ -95,19 +95,19 @@ Download all available skills from a server. ## Classes -### `SkillSummary` +### `SkillSummary` Summary information about a skill available on a server. -### `SkillFile` +### `SkillFile` Information about a file within a skill. -### `SkillManifest` +### `SkillManifest` Full manifest of a skill including all files.