diff --git a/docs/docs.json b/docs/docs.json index f8158e5c7..456d6b263 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -368,6 +368,7 @@ "group": "fastmcp.cli", "pages": [ "python-sdk/fastmcp-cli-__init__", + "python-sdk/fastmcp-cli-apps_dev", "python-sdk/fastmcp-cli-auth", "python-sdk/fastmcp-cli-cimd", "python-sdk/fastmcp-cli-cli", diff --git a/docs/python-sdk/fastmcp-cli-apps_dev.mdx b/docs/python-sdk/fastmcp-cli-apps_dev.mdx new file mode 100644 index 000000000..49cbed7fc --- /dev/null +++ b/docs/python-sdk/fastmcp-cli-apps_dev.mdx @@ -0,0 +1,47 @@ +--- +title: apps_dev +sidebarTitle: apps_dev +--- + +# `fastmcp.cli.apps_dev` + + +Dev server for previewing FastMCPApp UIs locally. + +Starts the user's MCP server on a configurable port, then starts a lightweight +Starlette dev server that: + + - Serves a Prefab-based tool picker at GET / + - Proxies /mcp to the user's server (avoids browser CORS restrictions) + - Serves the AppBridge host page at GET /launch + +The host page uses @modelcontextprotocol/ext-apps to connect to the MCP server +and render the selected UI tool inside an iframe. + +Startup sequence +---------------- +1. Download ext-apps app-bridge.js from npm and patch its bare + ``@modelcontextprotocol/sdk/…`` imports to use concrete esm.sh URLs. +2. Detect the exact Zod v4 module URL that esm.sh serves for that SDK version + and build an import-map entry that redirects the broken ``v4.mjs`` (which + only re-exports ``{z, default}``) to ``v4/classic/index.mjs`` (which + correctly exports every named Zod v4 function). Import maps apply to the + full module graph in the document, including cross-origin esm.sh modules. +3. Serve both the patched JS and the import-map JSON from the dev server. + + +## Functions + +### `run_dev_apps` + +```python +run_dev_apps(server_spec: str) -> None +``` + + +Start the full dev environment for a FastMCPApp server. + +Starts the user's MCP server on *mcp_port*, starts the Prefab dev UI +on *dev_port* (with an /mcp proxy to the user's server), then opens +the browser. + diff --git a/docs/python-sdk/fastmcp-cli-cli.mdx b/docs/python-sdk/fastmcp-cli-cli.mdx index 60804a298..b8bf7e0de 100644 --- a/docs/python-sdk/fastmcp-cli-cli.mdx +++ b/docs/python-sdk/fastmcp-cli-cli.mdx @@ -50,7 +50,23 @@ 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` +### `apps` + +```python +apps(server_spec: str) -> None +``` + + +Preview a FastMCPApp UI in the browser. + +Starts the MCP server from SERVER_SPEC on --mcp-port, launches a local +dev UI on --dev-port with a tool picker and AppBridge host, then opens +the browser automatically. + +Requires fastmcp[apps] to be installed (prefab-ui). + + +### `run` ```python run(server_spec: str | None = None, *server_args: str) -> None @@ -75,7 +91,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 @@ -106,7 +122,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-install-claude_code.mdx b/docs/python-sdk/fastmcp-cli-install-claude_code.mdx index 0a3393077..675faafc4 100644 --- a/docs/python-sdk/fastmcp-cli-install-claude_code.mdx +++ b/docs/python-sdk/fastmcp-cli-install-claude_code.mdx @@ -57,7 +57,7 @@ Install FastMCP server in Claude Code. - True if installation was successful, False otherwise -### `claude_code_command` +### `claude_code_command` ```python claude_code_command(server_spec: str) -> None diff --git a/docs/python-sdk/fastmcp-cli-install-gemini_cli.mdx b/docs/python-sdk/fastmcp-cli-install-gemini_cli.mdx index 9cb51f0f4..d80716460 100644 --- a/docs/python-sdk/fastmcp-cli-install-gemini_cli.mdx +++ b/docs/python-sdk/fastmcp-cli-install-gemini_cli.mdx @@ -54,7 +54,7 @@ Install FastMCP server in Gemini CLI. - True if installation was successful, False otherwise -### `gemini_cli_command` +### `gemini_cli_command` ```python gemini_cli_command(server_spec: str) -> None diff --git a/docs/python-sdk/fastmcp-cli-install-shared.mdx b/docs/python-sdk/fastmcp-cli-install-shared.mdx index a1fe2119c..b51b0a424 100644 --- a/docs/python-sdk/fastmcp-cli-install-shared.mdx +++ b/docs/python-sdk/fastmcp-cli-install-shared.mdx @@ -10,7 +10,19 @@ Shared utilities for install commands. ## Functions -### `parse_env_var` +### `validate_server_name` + +```python +validate_server_name(name: str) -> str +``` + + +Validate that a server name is safe for use as a subprocess argument. + +Raises SystemExit if the name contains shell metacharacters. + + +### `parse_env_var` ```python parse_env_var(env_var: str) -> tuple[str, str] @@ -20,7 +32,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] @@ -32,7 +44,7 @@ Process common arguments shared by all install commands. Handles both fastmcp.json config files and traditional file.py:object syntax. -### `open_deeplink` +### `open_deeplink` ```python open_deeplink(url: str) -> bool diff --git a/docs/python-sdk/fastmcp-client-client.mdx b/docs/python-sdk/fastmcp-client-client.mdx index 6c3ac689a..efbf56f08 100644 --- a/docs/python-sdk/fastmcp-client-client.mdx +++ b/docs/python-sdk/fastmcp-client-client.mdx @@ -7,7 +7,7 @@ sidebarTitle: client ## Classes -### `ClientSessionState` +### `ClientSessionState` Holds all session-related state for a Client instance. @@ -16,13 +16,13 @@ This allows clean separation of configuration (which is copied) from session state (which should be fresh for each new client instance). -### `CallToolResult` +### `CallToolResult` Parsed result from a tool call. -### `Client` +### `Client` MCP client that delegates connection management to a Transport instance. @@ -85,7 +85,7 @@ async with client: **Methods:** -#### `session` +#### `session` ```python session(self) -> ClientSession @@ -94,7 +94,7 @@ session(self) -> ClientSession Get the current active session. Raises RuntimeError if not connected. -#### `initialize_result` +#### `initialize_result` ```python initialize_result(self) -> mcp.types.InitializeResult | None @@ -103,7 +103,7 @@ initialize_result(self) -> mcp.types.InitializeResult | None Get the result of the initialization request. -#### `set_roots` +#### `set_roots` ```python set_roots(self, roots: RootsList | RootsHandler) -> None @@ -112,7 +112,7 @@ set_roots(self, roots: RootsList | RootsHandler) -> None Set the roots for the client. This does not automatically call `send_roots_list_changed`. -#### `set_sampling_callback` +#### `set_sampling_callback` ```python set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabilities: mcp.types.SamplingCapability | None = None) -> None @@ -121,7 +121,7 @@ set_sampling_callback(self, sampling_callback: SamplingHandler, sampling_capabil Set the sampling callback for the client. -#### `set_elicitation_callback` +#### `set_elicitation_callback` ```python set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None @@ -130,7 +130,7 @@ set_elicitation_callback(self, elicitation_callback: ElicitationHandler) -> None Set the elicitation callback for the client. -#### `is_connected` +#### `is_connected` ```python is_connected(self) -> bool @@ -139,7 +139,7 @@ is_connected(self) -> bool Check if the client is currently connected. -#### `new` +#### `new` ```python new(self) -> Client[ClientTransportT] @@ -155,7 +155,7 @@ share state with the original client. - A new Client instance with the same configuration but disconnected state. -#### `initialize` +#### `initialize` ```python initialize(self, timeout: datetime.timedelta | float | int | None = None) -> mcp.types.InitializeResult @@ -183,13 +183,13 @@ capabilities, protocol version, and optional instructions. - `RuntimeError`: If the client is not connected or initialization times out. -#### `close` +#### `close` ```python close(self) ``` -#### `ping` +#### `ping` ```python ping(self) -> bool @@ -198,7 +198,7 @@ ping(self) -> bool Send a ping request. -#### `cancel` +#### `cancel` ```python cancel(self, request_id: str | int, reason: str | None = None) -> None @@ -207,7 +207,7 @@ cancel(self, request_id: str | int, reason: str | None = None) -> None Send a cancellation notification for an in-progress request. -#### `progress` +#### `progress` ```python progress(self, progress_token: str | int, progress: float, total: float | None = None, message: str | None = None) -> None @@ -216,7 +216,7 @@ progress(self, progress_token: str | int, progress: float, total: float | None = Send a progress notification. -#### `set_logging_level` +#### `set_logging_level` ```python set_logging_level(self, level: mcp.types.LoggingLevel) -> None @@ -225,7 +225,7 @@ set_logging_level(self, level: mcp.types.LoggingLevel) -> None Send a logging/setLevel request. -#### `send_roots_list_changed` +#### `send_roots_list_changed` ```python send_roots_list_changed(self) -> None @@ -234,7 +234,7 @@ send_roots_list_changed(self) -> None Send a roots/list_changed notification. -#### `complete_mcp` +#### `complete_mcp` ```python complete_mcp(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.CompleteResult @@ -257,7 +257,7 @@ containing the completion and any additional metadata. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `complete` +#### `complete` ```python complete(self, ref: mcp.types.ResourceTemplateReference | mcp.types.PromptReference, argument: dict[str, str], context_arguments: dict[str, Any] | None = None) -> mcp.types.Completion @@ -279,7 +279,7 @@ include with the completion request. Defaults to None. - `McpError`: If the request results in a TimeoutError | JSONRPCError -#### `generate_name` +#### `generate_name` ```python generate_name(cls, name: str | None = None) -> str diff --git a/docs/python-sdk/fastmcp-client-transports-http.mdx b/docs/python-sdk/fastmcp-client-transports-http.mdx index a3375240e..6f819138c 100644 --- a/docs/python-sdk/fastmcp-client-transports-http.mdx +++ b/docs/python-sdk/fastmcp-client-transports-http.mdx @@ -10,7 +10,7 @@ Streamable HTTP transport for FastMCP Client. ## Classes -### `StreamableHttpTransport` +### `StreamableHttpTransport` Transport implementation that connects to an MCP server via Streamable HTTP Requests. @@ -18,19 +18,19 @@ Transport implementation that connects to an MCP server via Streamable HTTP Requ **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] ``` -#### `get_session_id` +#### `get_session_id` ```python get_session_id(self) -> str | None ``` -#### `close` +#### `close` ```python close(self) diff --git a/docs/python-sdk/fastmcp-client-transports-sse.mdx b/docs/python-sdk/fastmcp-client-transports-sse.mdx index 59c145401..a65dace46 100644 --- a/docs/python-sdk/fastmcp-client-transports-sse.mdx +++ b/docs/python-sdk/fastmcp-client-transports-sse.mdx @@ -10,7 +10,7 @@ Server-Sent Events (SSE) transport for FastMCP Client. ## Classes -### `SSETransport` +### `SSETransport` Transport implementation that connects to an MCP server via Server-Sent Events. @@ -18,7 +18,7 @@ Transport implementation that connects to an MCP server via Server-Sent Events. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] diff --git a/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx b/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx index 0553029eb..9dc66b06a 100644 --- a/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx +++ b/docs/python-sdk/fastmcp-experimental-transforms-code_mode.mdx @@ -47,7 +47,7 @@ leave that limit uncapped. run(self, code: str) -> Any ``` -### `Search` +### `Search` Discovery tool factory that searches the catalog by query. @@ -64,7 +64,7 @@ Defaults to BM25 ranking. The LLM can override this per call. ``None`` means no limit. -### `GetSchemas` +### `GetSchemas` Discovery tool factory that returns schemas for tools by name. @@ -78,7 +78,7 @@ types, and required markers. ``"full"`` returns the complete JSON schema. -### `GetTags` +### `GetTags` Discovery tool factory that lists tool tags from the catalog. @@ -93,7 +93,7 @@ without tags appear under ``"untagged"``. ``"full"`` lists all tools under each tag. -### `ListTools` +### `ListTools` Discovery tool factory that lists all tools in the catalog. @@ -106,7 +106,7 @@ Discovery tool factory that lists all tools in the catalog. ``"full"`` returns the complete JSON schema. -### `CodeMode` +### `CodeMode` Transform that collapses all tools into discovery + execute meta-tools. @@ -123,13 +123,13 @@ environment with ``call_tool(name, params)`` in scope. **Methods:** -#### `transform_tools` +#### `transform_tools` ```python transform_tools(self, tools: Sequence[Tool]) -> Sequence[Tool] ``` -#### `get_tool` +#### `get_tool` ```python get_tool(self, name: str, call_next: GetToolNext) -> Tool | None diff --git a/docs/python-sdk/fastmcp-resources-template.mdx b/docs/python-sdk/fastmcp-resources-template.mdx index 29766c944..06d8ef8ed 100644 --- a/docs/python-sdk/fastmcp-resources-template.mdx +++ b/docs/python-sdk/fastmcp-resources-template.mdx @@ -23,7 +23,7 @@ Extract query parameter names from RFC 6570 `{?param1,param2}` syntax. ### `build_regex` ```python -build_regex(template: str) -> re.Pattern +build_regex(template: str) -> re.Pattern[str] | None ``` @@ -34,8 +34,11 @@ Supports: - `{var*}` - wildcard path parameter (captures multiple segments) - `{?var1,var2}` - query parameters (ignored in path matching) +Returns None if the template produces an invalid regex (e.g. parameter +names with hyphens, leading digits, or duplicates from a remote server). -### `match_uri_template` + +### `match_uri_template` ```python match_uri_template(uri: str, uri_template: str) -> dict[str, str] | None @@ -51,7 +54,7 @@ Supports RFC 6570 URI templates: ## Classes -### `ResourceTemplate` +### `ResourceTemplate` A template for dynamically creating resources. @@ -59,13 +62,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: AuthCheck | list[AuthCheck] | None = None) -> FunctionResourceTemplate ``` -#### `set_default_mime_type` +#### `set_default_mime_type` ```python set_default_mime_type(cls, mime_type: str | None) -> str @@ -74,7 +77,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 +86,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 +95,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 +111,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 +123,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 +132,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 +141,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 +150,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 +159,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 +175,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 +189,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 +198,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 +207,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 +219,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 +237,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: AuthCheck | list[AuthCheck] | None = None) -> FunctionResourceTemplate diff --git a/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx b/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx index b30f3090b..9ca0d77ad 100644 --- a/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx +++ b/docs/python-sdk/fastmcp-server-auth-jwt_issuer.mdx @@ -15,7 +15,7 @@ This maintains proper OAuth 2.0 token audience boundaries. ## Functions -### `derive_jwt_key` +### `derive_jwt_key` ```python derive_jwt_key() -> bytes @@ -27,7 +27,7 @@ Derive JWT signing key from a high-entropy or low-entropy key material and serve ## Classes -### `JWTIssuer` +### `JWTIssuer` Issues and validates FastMCP-signed JWT tokens using HS256. @@ -39,7 +39,7 @@ a key derived from the upstream client secret. **Methods:** -#### `issue_access_token` +#### `issue_access_token` ```python issue_access_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int = 3600, upstream_claims: dict[str, Any] | None = None) -> str @@ -62,7 +62,7 @@ which contains actual user identity and authorization data. - 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, upstream_claims: dict[str, Any] | None = None) -> str @@ -85,18 +85,20 @@ token which contains actual user identity and authorization data. - Signed JWT token -#### `verify_token` +#### `verify_token` ```python -verify_token(self, token: str) -> dict[str, Any] +verify_token(self, token: str, expected_token_use: str = 'access') -> dict[str, Any] ``` Verify and decode a FastMCP token. -Validates JWT signature, expiration, issuer, and audience. +Validates JWT signature, expiration, issuer, audience, and token type. **Args:** - `token`: JWT token to verify +- `expected_token_use`: Expected token type ("access" or "refresh"). +Defaults to "access", which rejects refresh tokens. **Returns:** - Decoded token payload 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 8ac1885b2..d675dd066 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 @@ -182,7 +182,7 @@ For unregistered clients, returns None (which will raise an error in the SDK). CIMD clients (URL-based client IDs) are looked up and cached automatically. -#### `register_client` +#### `register_client` ```python register_client(self, client_info: OAuthClientInformationFull) -> None @@ -196,7 +196,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 @@ -214,7 +214,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 @@ -226,7 +226,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 @@ -244,7 +244,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 @@ -256,7 +256,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 @@ -273,7 +273,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 @@ -292,7 +292,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 @@ -305,7 +305,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-oidc_proxy.mdx b/docs/python-sdk/fastmcp-server-auth-oidc_proxy.mdx index a941099ae..a9160db17 100644 --- a/docs/python-sdk/fastmcp-server-auth-oidc_proxy.mdx +++ b/docs/python-sdk/fastmcp-server-auth-oidc_proxy.mdx @@ -19,7 +19,7 @@ This implementation is based on: ## Classes -### `OIDCConfiguration` +### `OIDCConfiguration` OIDC Configuration. @@ -27,7 +27,7 @@ OIDC Configuration. **Methods:** -#### `get_oidc_configuration` +#### `get_oidc_configuration` ```python get_oidc_configuration(cls, config_url: AnyHttpUrl) -> Self @@ -41,7 +41,7 @@ Get the OIDC configuration for the specified config URL. - `timeout_seconds`: HTTP request timeout in seconds -### `OIDCProxy` +### `OIDCProxy` OAuth provider that wraps OAuthProxy to provide configuration via an OIDC configuration URL. @@ -52,7 +52,7 @@ that is OIDC compliant. **Methods:** -#### `get_oidc_configuration` +#### `get_oidc_configuration` ```python get_oidc_configuration(self, config_url: AnyHttpUrl, strict: bool | None, timeout_seconds: int | None) -> OIDCConfiguration @@ -66,7 +66,7 @@ Gets the OIDC configuration for the specified configuration URL. - `timeout_seconds`: HTTP request timeout in seconds -#### `get_token_verifier` +#### `get_token_verifier` ```python get_token_verifier(self) -> TokenVerifier diff --git a/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx b/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx index 140ddd193..350d3f2e6 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx @@ -31,7 +31,7 @@ Example: ## Classes -### `Auth0Provider` +### `Auth0Provider` An Auth0 provider implementation for FastMCP. diff --git a/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx b/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx index fc8b111f6..c8d9ea795 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-aws.mdx @@ -31,7 +31,7 @@ Example: ## Classes -### `AWSCognitoTokenVerifier` +### `AWSCognitoTokenVerifier` Token verifier that filters claims to Cognito-specific subset. @@ -39,7 +39,7 @@ Token verifier that filters claims to Cognito-specific subset. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -48,7 +48,7 @@ verify_token(self, token: str) -> AccessToken | None Verify token and filter claims to Cognito-specific subset. -### `AWSCognitoProvider` +### `AWSCognitoProvider` Complete AWS Cognito OAuth provider for FastMCP. @@ -66,7 +66,7 @@ Features: **Methods:** -#### `get_token_verifier` +#### `get_token_verifier` ```python get_token_verifier(self) -> AWSCognitoTokenVerifier diff --git a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx index 4d3140c4a..77ef582c9 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-azure.mdx @@ -14,7 +14,7 @@ using the OAuth Proxy pattern for non-DCR OAuth flows. ## Functions -### `EntraOBOToken` +### `EntraOBOToken` ```python EntraOBOToken(scopes: list[str]) -> str @@ -78,7 +78,7 @@ Setup: **Methods:** -#### `authorize` +#### `authorize` ```python authorize(self, client: OAuthClientInformationFull, params: AuthorizationParams) -> str @@ -98,7 +98,7 @@ scopes to determine the resource/audience instead of a separate parameter. - Authorization URL to redirect the user to Azure AD -#### `get_obo_credential` +#### `get_obo_credential` ```python get_obo_credential(self, user_assertion: str) -> OnBehalfOfCredential @@ -120,7 +120,7 @@ calls multiple tools with the same scopes. - `ImportError`: If azure-identity is not installed (requires fastmcp[azure]). -#### `close_obo_credentials` +#### `close_obo_credentials` ```python close_obo_credentials(self) -> None @@ -129,7 +129,7 @@ close_obo_credentials(self) -> None Close all cached OBO credentials. -### `AzureJWTVerifier` +### `AzureJWTVerifier` JWT verifier pre-configured for Azure AD / Microsoft Entra ID. @@ -166,7 +166,7 @@ Example:: **Methods:** -#### `scopes_supported` +#### `scopes_supported` ```python scopes_supported(self) -> list[str] diff --git a/docs/python-sdk/fastmcp-server-auth-providers-discord.mdx b/docs/python-sdk/fastmcp-server-auth-providers-discord.mdx index d35dbf459..57d3b743b 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-discord.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-discord.mdx @@ -29,7 +29,7 @@ Example: ## Classes -### `DiscordTokenVerifier` +### `DiscordTokenVerifier` Token verifier for Discord OAuth tokens. @@ -40,7 +40,7 @@ by calling Discord's tokeninfo API to check if they're valid and get user info. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -49,7 +49,7 @@ verify_token(self, token: str) -> AccessToken | None Verify Discord OAuth token by calling Discord's tokeninfo API. -### `DiscordProvider` +### `DiscordProvider` Complete Discord OAuth provider for FastMCP. diff --git a/docs/python-sdk/fastmcp-server-auth-providers-github.mdx b/docs/python-sdk/fastmcp-server-auth-providers-github.mdx index 66a808136..03bd4e4c3 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-github.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-github.mdx @@ -29,7 +29,7 @@ Example: ## Classes -### `GitHubTokenVerifier` +### `GitHubTokenVerifier` Token verifier for GitHub OAuth tokens. @@ -40,7 +40,7 @@ by calling GitHub's API to check if they're valid and get user info. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -49,7 +49,7 @@ verify_token(self, token: str) -> AccessToken | None Verify GitHub OAuth token by calling GitHub API. -### `GitHubProvider` +### `GitHubProvider` Complete GitHub OAuth provider for FastMCP. diff --git a/docs/python-sdk/fastmcp-server-auth-providers-google.mdx b/docs/python-sdk/fastmcp-server-auth-providers-google.mdx index 880488438..b9568dbf9 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-google.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-google.mdx @@ -29,7 +29,7 @@ Example: ## Classes -### `GoogleTokenVerifier` +### `GoogleTokenVerifier` Token verifier for Google OAuth tokens. @@ -40,7 +40,7 @@ by calling Google's tokeninfo API to check if they're valid and get user info. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -49,7 +49,7 @@ verify_token(self, token: str) -> AccessToken | None Verify Google OAuth token by calling Google's tokeninfo API. -### `GoogleProvider` +### `GoogleProvider` Complete Google OAuth provider for FastMCP. diff --git a/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx b/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx index b88c7c49e..9f1be4fc1 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-oci.mdx @@ -87,7 +87,7 @@ Example: ## Classes -### `OCIProvider` +### `OCIProvider` An OCI IAM Domain provider implementation for FastMCP. diff --git a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx index 36dec25f5..32cb93e4c 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx @@ -18,7 +18,7 @@ Choose based on your WorkOS setup and authentication requirements. ## Classes -### `WorkOSTokenVerifier` +### `WorkOSTokenVerifier` Token verifier for WorkOS OAuth tokens. @@ -29,7 +29,7 @@ the /oauth2/userinfo endpoint to check validity and get user info. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -38,7 +38,7 @@ verify_token(self, token: str) -> AccessToken | None Verify WorkOS OAuth token by calling userinfo endpoint. -### `WorkOSProvider` +### `WorkOSProvider` Complete WorkOS OAuth provider for FastMCP. @@ -59,7 +59,7 @@ Setup Requirements: 4. Note your Client ID and Client Secret -### `AuthKitProvider` +### `AuthKitProvider` AuthKit metadata provider for DCR (Dynamic Client Registration). @@ -85,7 +85,7 @@ https://workos.com/docs/authkit/mcp/integrating/token-verification **Methods:** -#### `get_routes` +#### `get_routes` ```python get_routes(self, mcp_path: str | None = None) -> list[Route] diff --git a/docs/python-sdk/fastmcp-server-low_level.mdx b/docs/python-sdk/fastmcp-server-low_level.mdx index 7886475a8..7456a5940 100644 --- a/docs/python-sdk/fastmcp-server-low_level.mdx +++ b/docs/python-sdk/fastmcp-server-low_level.mdx @@ -15,7 +15,7 @@ ServerSession that routes initialization requests through FastMCP middleware. **Methods:** -#### `fastmcp` +#### `fastmcp` ```python fastmcp(self) -> FastMCP @@ -24,7 +24,7 @@ fastmcp(self) -> FastMCP Get the FastMCP instance. -#### `client_supports_extension` +#### `client_supports_extension` ```python client_supports_extension(self, extension_id: str) -> bool @@ -36,11 +36,11 @@ Inspects the ``extensions`` extra field on ``ClientCapabilities`` sent by the client during initialization. -### `LowLevelServer` +### `LowLevelServer` **Methods:** -#### `fastmcp` +#### `fastmcp` ```python fastmcp(self) -> FastMCP @@ -49,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 @@ -68,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) @@ -77,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]]] @@ -92,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-mixins-lifespan.mdx b/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx index 9d0eec22e..fe786652c 100644 --- a/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx +++ b/docs/python-sdk/fastmcp-server-mixins-lifespan.mdx @@ -10,7 +10,7 @@ Lifespan and Docket task infrastructure for FastMCP Server. ## Classes -### `LifespanMixin` +### `LifespanMixin` Mixin providing lifespan and Docket task infrastructure for FastMCP. @@ -18,7 +18,7 @@ Mixin providing lifespan and Docket task infrastructure for FastMCP. **Methods:** -#### `docket` +#### `docket` ```python docket(self: FastMCP) -> Docket | None diff --git a/docs/python-sdk/fastmcp-server-mixins-transport.mdx b/docs/python-sdk/fastmcp-server-mixins-transport.mdx index c5cc4e2fd..ad4e0b60e 100644 --- a/docs/python-sdk/fastmcp-server-mixins-transport.mdx +++ b/docs/python-sdk/fastmcp-server-mixins-transport.mdx @@ -10,7 +10,7 @@ Transport-related methods for FastMCP Server. ## Classes -### `TransportMixin` +### `TransportMixin` Mixin providing transport-related methods for FastMCP. @@ -20,7 +20,7 @@ Includes HTTP/stdio/SSE transport handling and custom HTTP routes. **Methods:** -#### `run_async` +#### `run_async` ```python run_async(self: FastMCP, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None @@ -34,7 +34,7 @@ Run the FastMCP server asynchronously. FASTMCP_SHOW_SERVER_BANNER setting (default\: True). -#### `run` +#### `run` ```python run(self: FastMCP, transport: Transport | None = None, show_banner: bool | None = None, **transport_kwargs: Any) -> None @@ -48,7 +48,7 @@ Run the FastMCP server. Note this is a synchronous function. FASTMCP_SHOW_SERVER_BANNER setting (default\: True). -#### `custom_route` +#### `custom_route` ```python custom_route(self: FastMCP, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True) -> Callable[[Callable[[Request], Awaitable[Response]]], Callable[[Request], Awaitable[Response]]] @@ -69,7 +69,7 @@ Starlette's reverse URL lookup feature) - `include_in_schema`: Whether to include in OpenAPI schema, defaults to True -#### `run_stdio_async` +#### `run_stdio_async` ```python run_stdio_async(self: FastMCP, show_banner: bool = True, log_level: str | None = None, stateless: bool = False) -> None @@ -83,7 +83,7 @@ Run the server using stdio transport. - `stateless`: Whether to run in stateless mode (no session initialization) -#### `run_http_async` +#### `run_http_async` ```python run_http_async(self: FastMCP, show_banner: bool = True, transport: Literal['http', 'streamable-http', 'sse'] = 'http', host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, stateless: bool | None = None) -> None @@ -104,7 +104,7 @@ Run the server using HTTP transport. - `stateless`: Alias for stateless_http for CLI consistency -#### `http_app` +#### `http_app` ```python http_app(self: FastMCP, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http', event_store: EventStore | None = None, retry_interval: int | None = None) -> StarletteWithLifespan diff --git a/docs/python-sdk/fastmcp-server-providers-proxy.mdx b/docs/python-sdk/fastmcp-server-providers-proxy.mdx index 96d9a5a9f..d612a9f37 100644 --- a/docs/python-sdk/fastmcp-server-providers-proxy.mdx +++ b/docs/python-sdk/fastmcp-server-providers-proxy.mdx @@ -15,7 +15,7 @@ classes that forward execution to remote servers. ## Functions -### `default_proxy_roots_handler` +### `default_proxy_roots_handler` ```python default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanContextT]) -> RootsList @@ -25,7 +25,7 @@ default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanConte Forward list roots request from remote server to proxy's connected clients. -### `default_proxy_sampling_handler` +### `default_proxy_sampling_handler` ```python default_proxy_sampling_handler(messages: list[mcp.types.SamplingMessage], params: mcp.types.CreateMessageRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> mcp.types.CreateMessageResult @@ -35,7 +35,7 @@ default_proxy_sampling_handler(messages: list[mcp.types.SamplingMessage], params Forward sampling request from remote server to proxy's connected clients. -### `default_proxy_elicitation_handler` +### `default_proxy_elicitation_handler` ```python default_proxy_elicitation_handler(message: str, response_type: type, params: mcp.types.ElicitRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> ElicitResult @@ -45,7 +45,7 @@ default_proxy_elicitation_handler(message: str, response_type: type, params: mcp Forward elicitation request from remote server to proxy's connected clients. -### `default_proxy_log_handler` +### `default_proxy_log_handler` ```python default_proxy_log_handler(message: LogMessage) -> None @@ -55,7 +55,7 @@ default_proxy_log_handler(message: LogMessage) -> None Forward log notification from remote server to proxy's connected clients. -### `default_proxy_progress_handler` +### `default_proxy_progress_handler` ```python default_proxy_progress_handler(progress: float, total: float | None, message: str | None) -> None @@ -67,7 +67,7 @@ Forward progress notification from remote server to proxy's connected clients. ## Classes -### `ProxyTool` +### `ProxyTool` A Tool that represents and executes a tool on a remote server. @@ -75,7 +75,7 @@ A Tool that represents and executes a tool on a remote server. **Methods:** -#### `model_copy` +#### `model_copy` ```python model_copy(self, **kwargs: Any) -> ProxyTool @@ -84,7 +84,7 @@ model_copy(self, **kwargs: Any) -> ProxyTool Override to preserve _backend_name when name changes. -#### `from_mcp_tool` +#### `from_mcp_tool` ```python from_mcp_tool(cls, client_factory: ClientFactoryT, mcp_tool: mcp.types.Tool) -> ProxyTool @@ -93,7 +93,7 @@ from_mcp_tool(cls, client_factory: ClientFactoryT, mcp_tool: mcp.types.Tool) -> Factory method to create a ProxyTool from a raw MCP tool schema. -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResult @@ -102,13 +102,13 @@ run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResu Executes the tool by making a call through the client. -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] ``` -### `ProxyResource` +### `ProxyResource` A Resource that represents and reads a resource from a remote server. @@ -116,7 +116,7 @@ A Resource that represents and reads a resource from a remote server. **Methods:** -#### `model_copy` +#### `model_copy` ```python model_copy(self, **kwargs: Any) -> ProxyResource @@ -125,7 +125,7 @@ model_copy(self, **kwargs: Any) -> ProxyResource Override to preserve _backend_uri when uri changes. -#### `from_mcp_resource` +#### `from_mcp_resource` ```python from_mcp_resource(cls, client_factory: ClientFactoryT, mcp_resource: mcp.types.Resource) -> ProxyResource @@ -134,7 +134,7 @@ from_mcp_resource(cls, client_factory: ClientFactoryT, mcp_resource: mcp.types.R Factory method to create a ProxyResource from a raw MCP resource schema. -#### `read` +#### `read` ```python read(self) -> ResourceResult @@ -143,13 +143,13 @@ read(self) -> ResourceResult Read the resource content from the remote server. -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] ``` -### `ProxyTemplate` +### `ProxyTemplate` A ResourceTemplate that represents and creates resources from a remote server template. @@ -157,7 +157,7 @@ A ResourceTemplate that represents and creates resources from a remote server te **Methods:** -#### `model_copy` +#### `model_copy` ```python model_copy(self, **kwargs: Any) -> ProxyTemplate @@ -166,7 +166,7 @@ model_copy(self, **kwargs: Any) -> ProxyTemplate Override to preserve _backend_uri_template when uri_template changes. -#### `from_mcp_template` +#### `from_mcp_template` ```python from_mcp_template(cls, client_factory: ClientFactoryT, mcp_template: mcp.types.ResourceTemplate) -> ProxyTemplate @@ -175,7 +175,7 @@ from_mcp_template(cls, client_factory: ClientFactoryT, mcp_template: mcp.types.R Factory method to create a ProxyTemplate from a raw MCP template schema. -#### `create_resource` +#### `create_resource` ```python create_resource(self, uri: str, params: dict[str, Any], context: Context | None = None) -> ProxyResource @@ -184,13 +184,13 @@ create_resource(self, uri: str, params: dict[str, Any], context: Context | None Create a resource from the template by calling the remote server. -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] ``` -### `ProxyPrompt` +### `ProxyPrompt` A Prompt that represents and renders a prompt from a remote server. @@ -198,7 +198,7 @@ A Prompt that represents and renders a prompt from a remote server. **Methods:** -#### `model_copy` +#### `model_copy` ```python model_copy(self, **kwargs: Any) -> ProxyPrompt @@ -207,7 +207,7 @@ model_copy(self, **kwargs: Any) -> ProxyPrompt Override to preserve _backend_name when name changes. -#### `from_mcp_prompt` +#### `from_mcp_prompt` ```python from_mcp_prompt(cls, client_factory: ClientFactoryT, mcp_prompt: mcp.types.Prompt) -> ProxyPrompt @@ -216,7 +216,7 @@ from_mcp_prompt(cls, client_factory: ClientFactoryT, mcp_prompt: mcp.types.Promp Factory method to create a ProxyPrompt from a raw MCP prompt schema. -#### `render` +#### `render` ```python render(self, arguments: dict[str, Any]) -> PromptResult @@ -225,13 +225,13 @@ render(self, arguments: dict[str, Any]) -> PromptResult Render the prompt by making a call through the client. -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] ``` -### `ProxyProvider` +### `ProxyProvider` Provider that proxies to a remote MCP server via a client factory. @@ -242,10 +242,20 @@ component instances that forward execution to the remote server. All components returned by this provider have task_config.mode="forbidden" because tasks cannot be executed through a proxy. +Component lists (tools, resources, templates, prompts) are cached so that +individual lookups (e.g. during ``call_tool``) can resolve from the cache +instead of opening a new backend connection. The cache stores the +backend's raw component metadata and is shared across all sessions; +per-session visibility and auth filtering are applied after cache lookup +by the server layer. The cache is refreshed whenever a ``list_*`` call +is made, and entries expire after ``cache_ttl`` seconds (default 300). +Set ``cache_ttl=0`` to disable caching. Disabling is recommended for +backends whose component lists change dynamically. + **Methods:** -#### `get_tasks` +#### `get_tasks` ```python get_tasks(self) -> Sequence[FastMCPComponent] @@ -258,7 +268,7 @@ server lifespan initialization, which would open the client before any context is set. All Proxy* components have task_config.mode="forbidden". -### `FastMCPProxy` +### `FastMCPProxy` A FastMCP server that acts as a proxy to a remote MCP-compliant server. @@ -267,7 +277,7 @@ This is a convenience wrapper that creates a FastMCP server with a ProxyProvider. For more control, use FastMCP with add_provider(ProxyProvider(...)). -### `ProxyClient` +### `ProxyClient` A proxy client that forwards advanced interactions between a remote MCP server and the proxy's connected clients. @@ -275,7 +285,7 @@ A proxy client that forwards advanced interactions between a remote MCP server a Supports forwarding roots, sampling, elicitation, logging, and progress. -### `StatefulProxyClient` +### `StatefulProxyClient` A proxy client that provides a stateful client factory for the proxy server. @@ -296,7 +306,7 @@ it to detect (and correct) staleness. **Methods:** -#### `clear` +#### `clear` ```python clear(self) @@ -305,7 +315,7 @@ clear(self) Clear all cached clients and force disconnect them. -#### `new_stateful` +#### `new_stateful` ```python new_stateful(self) -> Client[ClientTransportT] diff --git a/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx b/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx index cac91d36e..2a3590003 100644 --- a/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx +++ b/docs/python-sdk/fastmcp-server-sampling-sampling_tool.mdx @@ -10,7 +10,7 @@ SamplingTool for use during LLM sampling requests. ## Classes -### `SamplingTool` +### `SamplingTool` A tool that can be used during LLM sampling. @@ -37,7 +37,7 @@ Create a SamplingTool explicitly when you need custom name/description: **Methods:** -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any] | None = None) -> Any @@ -52,7 +52,7 @@ Execute the tool with the given arguments. - The result of executing the tool function. -#### `from_function` +#### `from_function` ```python from_function(cls, fn: Callable[..., Any]) -> SamplingTool @@ -79,7 +79,7 @@ concurrently. Defaults to False. - `ValueError`: If the function is a lambda without a name override. -#### `from_callable_tool` +#### `from_callable_tool` ```python from_callable_tool(cls, tool: FunctionTool | TransformedTool) -> SamplingTool diff --git a/docs/python-sdk/fastmcp-server-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx index dbfdf6e1c..deff347ad 100644 --- a/docs/python-sdk/fastmcp-server-server.mdx +++ b/docs/python-sdk/fastmcp-server-server.mdx @@ -26,7 +26,7 @@ Default lifespan context manager that does nothing. - An empty dictionary as the lifespan result. -### `create_proxy` +### `create_proxy` ```python create_proxy(target: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy @@ -64,43 +64,43 @@ Wrapper for stored context state values. **Methods:** -#### `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] ``` -#### `local_provider` +#### `local_provider` ```python local_provider(self) -> LocalProvider @@ -115,13 +115,13 @@ Use this to remove components: mcp.local_provider.remove_prompt("my_prompt") -#### `add_middleware` +#### `add_middleware` ```python add_middleware(self, middleware: Middleware) -> None ``` -#### `add_provider` +#### `add_provider` ```python add_provider(self, provider: Provider) -> None @@ -141,7 +141,7 @@ always take precedence over providers. - Prompts become "namespace_promptname" -#### `get_tasks` +#### `get_tasks` ```python get_tasks(self) -> Sequence[FastMCPComponent] @@ -153,7 +153,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 @@ -168,7 +168,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 @@ -180,7 +180,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 @@ -192,7 +192,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] @@ -205,7 +205,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 @@ -228,7 +228,7 @@ requested, falls back to the next-highest enabled version. - The tool if found and enabled, None otherwise. -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> Sequence[Resource] @@ -241,7 +241,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 @@ -263,7 +263,7 @@ requested, falls back to the next-highest enabled version. - The resource if found and enabled, None otherwise. -#### `list_resource_templates` +#### `list_resource_templates` ```python list_resource_templates(self) -> Sequence[ResourceTemplate] @@ -276,7 +276,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 @@ -298,7 +298,7 @@ requested, falls back to the next-highest enabled version. - The template if found and enabled, None otherwise. -#### `list_prompts` +#### `list_prompts` ```python list_prompts(self) -> Sequence[Prompt] @@ -311,7 +311,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 @@ -333,19 +333,19 @@ requested, falls back to the next-highest enabled version. - 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 @@ -375,19 +375,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 @@ -416,19 +416,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 @@ -458,7 +458,7 @@ return PromptResult. - `PromptError`: If prompt rendering fails -#### `add_tool` +#### `add_tool` ```python add_tool(self, tool: Tool | Callable[..., Any]) -> Tool @@ -476,7 +476,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 @@ -495,19 +495,19 @@ Remove tool(s) from the server. - `NotFoundError`: If no matching tool is found. -#### `tool` +#### `tool` ```python tool(self, name_or_fn: F) -> F ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | None = None) -> Callable[[F], F] ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool | partial[Callable[[AnyFunction], FunctionTool] | FunctionTool] @@ -563,7 +563,7 @@ server.tool(my_function, name="custom_name") ``` -#### `add_resource` +#### `add_resource` ```python add_resource(self, resource: Resource | Callable[..., Any]) -> Resource | ResourceTemplate @@ -578,7 +578,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 @@ -593,7 +593,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[[F], F] @@ -652,7 +652,7 @@ async def get_weather(city: str) -> str: ``` -#### `add_prompt` +#### `add_prompt` ```python add_prompt(self, prompt: Prompt | Callable[..., Any]) -> Prompt @@ -667,19 +667,19 @@ Add a prompt to the server. - The prompt instance that was added to the server. -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: F) -> F ``` -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: str | None = None) -> Callable[[F], F] ``` -#### `prompt` +#### `prompt` ```python prompt(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt | partial[Callable[[AnyFunction], FunctionPrompt] | FunctionPrompt] @@ -756,7 +756,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 @@ -803,7 +803,7 @@ mounted server. - `prefix`: Deprecated. Use namespace instead. -#### `import_server` +#### `import_server` ```python import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None) -> None @@ -844,7 +844,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 | None = None, 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, validate_output: bool = True, **settings: Any) -> Self @@ -873,7 +873,7 @@ response structure while still returning structured JSON. - 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, **settings: Any) -> Self @@ -897,7 +897,7 @@ Use this to configure timeout and other client settings. - 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 @@ -915,7 +915,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-requests.mdx b/docs/python-sdk/fastmcp-server-tasks-requests.mdx index 5cde802fc..a8b31a13d 100644 --- a/docs/python-sdk/fastmcp-server-tasks-requests.mdx +++ b/docs/python-sdk/fastmcp-server-tasks-requests.mdx @@ -52,7 +52,7 @@ Converts raw task return values to MCP types based on task type. - MCP result (CallToolResult, GetPromptResult, or ReadResourceResult) -### `tasks_list_handler` +### `tasks_list_handler` ```python tasks_list_handler(server: FastMCP, params: dict[str, Any]) -> ListTasksResult @@ -71,7 +71,7 @@ Note: With client-side tracking, this returns minimal info. - Response with tasks list and pagination -### `tasks_cancel_handler` +### `tasks_cancel_handler` ```python tasks_cancel_handler(server: FastMCP, params: dict[str, Any]) -> CancelTaskResult diff --git a/docs/python-sdk/fastmcp-server-transforms-prompts_as_tools.mdx b/docs/python-sdk/fastmcp-server-transforms-prompts_as_tools.mdx index f1656c263..dc3b659d0 100644 --- a/docs/python-sdk/fastmcp-server-transforms-prompts_as_tools.mdx +++ b/docs/python-sdk/fastmcp-server-transforms-prompts_as_tools.mdx @@ -11,6 +11,10 @@ Transform that exposes prompts as tools. This transform generates tools for listing and getting prompts, enabling clients that only support tools to access prompt functionality. +The generated tools route through `ctx.fastmcp` at runtime, so all server +middleware (auth, visibility, rate limiting, etc.) applies to prompt +operations exactly as it would for direct `prompts/get` calls. + Example: ```python from fastmcp import FastMCP @@ -24,23 +28,26 @@ Example: ## Classes -### `PromptsAsTools` +### `PromptsAsTools` Transform that adds tools for listing and getting prompts. Generates two tools: -- `list_prompts`: Lists all prompts from the provider +- `list_prompts`: Lists all prompts - `get_prompt`: Gets a specific prompt with optional arguments -The transform captures a provider reference at construction and queries it -for prompts when the generated tools are called. When used with FastMCP, -the provider's auth and visibility filtering is automatically applied. +The generated tools route through the server at runtime, so auth, +middleware, and visibility apply automatically. + +This transform should be applied to a FastMCP server instance, not +a raw Provider, because the generated tools need the server's +middleware chain for auth and visibility filtering. **Methods:** -#### `list_tools` +#### `list_tools` ```python list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool] @@ -49,7 +56,7 @@ list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool] Add prompt tools to the tool list. -#### `get_tool` +#### `get_tool` ```python get_tool(self, name: str, call_next: GetToolNext) -> Tool | None diff --git a/docs/python-sdk/fastmcp-server-transforms-resources_as_tools.mdx b/docs/python-sdk/fastmcp-server-transforms-resources_as_tools.mdx index 3b46e875c..50f0a0c95 100644 --- a/docs/python-sdk/fastmcp-server-transforms-resources_as_tools.mdx +++ b/docs/python-sdk/fastmcp-server-transforms-resources_as_tools.mdx @@ -11,6 +11,10 @@ Transform that exposes resources as tools. This transform generates tools for listing and reading resources, enabling clients that only support tools to access resource functionality. +The generated tools route through `ctx.fastmcp` at runtime, so all server +middleware (auth, visibility, rate limiting, etc.) applies to resource +operations exactly as it would for direct `resources/read` calls. + Example: ```python from fastmcp import FastMCP @@ -24,23 +28,26 @@ Example: ## Classes -### `ResourcesAsTools` +### `ResourcesAsTools` Transform that adds tools for listing and reading resources. Generates two tools: -- `list_resources`: Lists all resources and templates from the provider +- `list_resources`: Lists all resources and templates - `read_resource`: Reads a resource by URI -The transform captures a provider reference at construction and queries it -for resources when the generated tools are called. When used with FastMCP, -the provider's auth and visibility filtering is automatically applied. +The generated tools route through the server at runtime, so auth, +middleware, and visibility apply automatically. + +This transform should be applied to a FastMCP server instance, not +a raw Provider, because the generated tools need the server's +middleware chain for auth and visibility filtering. **Methods:** -#### `list_tools` +#### `list_tools` ```python list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool] @@ -49,7 +56,7 @@ list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool] Add resource tools to the tool list. -#### `get_tool` +#### `get_tool` ```python get_tool(self, name: str, call_next: GetToolNext) -> Tool | None diff --git a/docs/python-sdk/fastmcp-settings.mdx b/docs/python-sdk/fastmcp-settings.mdx index eeb1156f8..f9b0cf26a 100644 --- a/docs/python-sdk/fastmcp-settings.mdx +++ b/docs/python-sdk/fastmcp-settings.mdx @@ -7,13 +7,13 @@ sidebarTitle: settings ## Classes -### `DocketSettings` +### `DocketSettings` Docket worker configuration. -### `Settings` +### `Settings` FastMCP settings. @@ -21,7 +21,7 @@ FastMCP settings. **Methods:** -#### `get_setting` +#### `get_setting` ```python get_setting(self, attr: str) -> Any @@ -31,7 +31,7 @@ Get a setting. If the setting contains one or more `__`, it will be treated as a nested setting. -#### `set_setting` +#### `set_setting` ```python set_setting(self, attr: str, value: Any) -> None @@ -41,7 +41,7 @@ Set a setting. If the setting contains one or more `__`, it will be treated as a nested setting. -#### `normalize_log_level` +#### `normalize_log_level` ```python normalize_log_level(cls, v) diff --git a/docs/python-sdk/fastmcp-tools-tool.mdx b/docs/python-sdk/fastmcp-tools-tool.mdx index d3bb86176..8b7a0abd2 100644 --- a/docs/python-sdk/fastmcp-tools-tool.mdx +++ b/docs/python-sdk/fastmcp-tools-tool.mdx @@ -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 | Callable[..., Any]) -> TransformedTool ``` -#### `get_span_attributes` +#### `get_span_attributes` ```python get_span_attributes(self) -> dict[str, Any] diff --git a/docs/python-sdk/fastmcp-utilities-json_schema.mdx b/docs/python-sdk/fastmcp-utilities-json_schema.mdx index e08643cb9..a8b51f1d0 100644 --- a/docs/python-sdk/fastmcp-utilities-json_schema.mdx +++ b/docs/python-sdk/fastmcp-utilities-json_schema.mdx @@ -7,7 +7,7 @@ sidebarTitle: json_schema ## Functions -### `dereference_refs` +### `dereference_refs` ```python dereference_refs(schema: dict[str, Any]) -> dict[str, Any] @@ -27,6 +27,11 @@ For self-referencing/circular schemas where full dereferencing is not possible, this function falls back to resolving only the root-level $ref while preserving $defs for nested references. +Only local ``$ref`` values (those starting with ``#``) are resolved. +Remote URIs (``http://``, ``file://``, etc.) are stripped before +resolution to prevent SSRF / local-file-inclusion attacks when proxying +schemas from untrusted servers. + **Args:** - `schema`: JSON schema dict that may contain $ref references @@ -35,7 +40,7 @@ $defs for nested references. - when no longer needed -### `resolve_root_ref` +### `resolve_root_ref` ```python resolve_root_ref(schema: dict[str, Any]) -> dict[str, Any] @@ -57,7 +62,7 @@ the referenced definition while preserving $defs for nested references. - if no resolution is needed -### `compress_schema` +### `compress_schema` ```python compress_schema(schema: dict[str, Any], prune_params: list[str] | None = None, prune_additional_properties: bool = False, prune_titles: bool = False, dereference: bool = False) -> dict[str, Any] diff --git a/docs/python-sdk/fastmcp-utilities-skills.mdx b/docs/python-sdk/fastmcp-utilities-skills.mdx index ccb0c83b8..807d07782 100644 --- a/docs/python-sdk/fastmcp-utilities-skills.mdx +++ b/docs/python-sdk/fastmcp-utilities-skills.mdx @@ -75,7 +75,7 @@ Creates a subdirectory named after the skill containing all files. - `FileExistsError`: If skill directory exists and overwrite=False -### `sync_skills` +### `sync_skills` ```python sync_skills(client: Client, target_dir: str | Path) -> list[Path]