diff --git a/.github/workflows/run-static.yml b/.github/workflows/run-static.yml index 4ef8d2430..422c6d136 100644 --- a/.github/workflows/run-static.yml +++ b/.github/workflows/run-static.yml @@ -42,7 +42,29 @@ jobs: python-version: "3.12" - name: Install dependencies run: uv sync --dev + - name: Install just + uses: extractions/setup-just@v3 + - name: Check lockfile is up to date + run: | + if ! uv lock --check; then + echo "❌ Lockfile is out of date!" + echo "To update the lockfile, run 'uv lock'." + exit 1 + fi + echo "✅ Lockfile is up to date" - name: Run pre-commit uses: pre-commit/action@v3.0.1 env: SKIP: no-commit-to-branch + - name: Check SDK documentation is up to date + run: | + just api-ref-all > /dev/null 2>&1 + if ! git diff --quiet docs/python-sdk/ docs/docs.json; then + echo "❌ SDK documentation is out of date!" + echo "Files that were updated:" + git diff --name-only docs/python-sdk/ docs/docs.json + echo "" + echo "Run 'just api-ref-all' and commit the changes." + exit 1 + fi + echo "✅ SDK documentation is up to date" diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index fce0326f5..119d24e38 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -44,7 +44,8 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install FastMCP - run: uv sync --locked + # run with frozen to use the current lockfile; static checks will determine if it needs updating + run: uv sync --frozen - name: Run tests (excluding integration and client_process) run: uv run pytest tests -m "not integration and not client_process" @@ -68,7 +69,8 @@ jobs: python-version: "3.10" - name: Install FastMCP - run: uv sync --locked + # run with frozen to use the current lockfile; static checks will determine if it needs updating + run: uv sync --frozen - name: Run integration tests run: uv run pytest tests -m "integration" diff --git a/docs/docs.json b/docs/docs.json index 157ff9b3f..df3e54c26 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -65,7 +65,10 @@ { "group": "Essentials", "icon": "cube", - "pages": ["servers/server", "deployment/running-server"] + "pages": [ + "servers/server", + "deployment/running-server" + ] }, { "group": "Core Components", @@ -108,7 +111,10 @@ { "group": "Essentials", "icon": "cube", - "pages": ["clients/client", "clients/transports"] + "pages": [ + "clients/client", + "clients/transports" + ] }, { "group": "Core Operations", @@ -134,7 +140,10 @@ { "group": "Authentication", "icon": "user-shield", - "pages": ["clients/auth/oauth", "clients/auth/bearer"] + "pages": [ + "clients/auth/oauth", + "clients/auth/bearer" + ] } ] }, @@ -180,12 +189,17 @@ }, { "anchor": "What's New", - "pages": ["updates", "changelog"] + "pages": [ + "updates", + "changelog" + ] }, { "anchor": "Community", "icon": "users", - "pages": ["community/showcase"] + "pages": [ + "community/showcase" + ] } ] }, diff --git a/docs/python-sdk/fastmcp-cli-run.mdx b/docs/python-sdk/fastmcp-cli-run.mdx index 00f8383d8..4aaf9995d 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. -### `parse_file_path` +### `parse_file_path` ```python parse_file_path(server_spec: str) -> tuple[Path, str | None] @@ -36,10 +36,10 @@ Parse a file path that may include a server object specification. - Tuple of (file_path, server_object) -### `import_server` +### `import_server` ```python -import_server(file: Path, server_object: str | None = None) -> Any +import_server(file: Path, server_or_factory: str | None = None) -> Any ``` @@ -47,13 +47,13 @@ Import a MCP server from a file. **Args:** - `file`: Path to the file -- `server_object`: Optional object name in format "module\:object" or just "object" +- `server_or_factory`: Optional object name in format "module\:object" or just "object" **Returns:** -- The server object +- The server object (or result of calling a factory function) -### `run_with_uv` +### `run_with_uv` ```python run_with_uv(server_spec: str, python_version: str | None = None, with_packages: list[str] | None = None, with_requirements: Path | None = None, project: Path | None = None, transport: TransportType | None = None, host: str | None = None, port: int | None = None, path: str | None = None, log_level: LogLevelType | None = None, show_banner: bool = True) -> None @@ -76,7 +76,7 @@ Run a MCP server using uv run subprocess. - `show_banner`: Whether to show the server banner -### `create_client_server` +### `create_client_server` ```python create_client_server(url: str) -> Any @@ -92,7 +92,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] @@ -102,10 +102,10 @@ create_mcp_config_server(mcp_config_path: Path) -> FastMCP[None] Create a FastMCP server from a MCPConfig. -### `import_server_with_args` +### `import_server_with_args` ```python -import_server_with_args(file: Path, server_object: str | None = None, server_args: list[str] | None = None) -> Any +import_server_with_args(file: Path, server_or_factory: str | None = None, server_args: list[str] | None = None) -> Any ``` @@ -113,14 +113,14 @@ Import a server with optional command line arguments. **Args:** - `file`: Path to the server file -- `server_object`: Optional server object name +- `server_or_factory`: Optional server object or factory function name - `server_args`: Optional command line arguments to inject **Returns:** - The imported server 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) -> None @@ -141,7 +141,7 @@ Run a MCP server or connect to a remote one. - `use_direct_import`: Whether to use direct import instead of subprocess -### `run_v1_server` +### `run_v1_server` ```python run_v1_server(server: FastMCP1x, host: str | None = None, port: int | None = None, transport: TransportType | None = None) -> None diff --git a/docs/python-sdk/fastmcp-client-logging.mdx b/docs/python-sdk/fastmcp-client-logging.mdx index e4a36db09..8d9176ea8 100644 --- a/docs/python-sdk/fastmcp-client-logging.mdx +++ b/docs/python-sdk/fastmcp-client-logging.mdx @@ -13,7 +13,11 @@ sidebarTitle: logging default_log_handler(message: LogMessage) -> None ``` -### `create_log_callback` + +Default handler that properly routes server log messages to appropriate log levels. + + +### `create_log_callback` ```python create_log_callback(handler: LogHandler | None = None) -> LoggingFnT diff --git a/docs/python-sdk/fastmcp-client-transports.mdx b/docs/python-sdk/fastmcp-client-transports.mdx index 3650b7f93..13d6a3818 100644 --- a/docs/python-sdk/fastmcp-client-transports.mdx +++ b/docs/python-sdk/fastmcp-client-transports.mdx @@ -7,7 +7,7 @@ sidebarTitle: transports ## Functions -### `infer_transport` +### `infer_transport` ```python infer_transport(transport: ClientTransport | FastMCP | FastMCP1Server | AnyUrl | Path | MCPConfig | dict[str, Any] | str) -> ClientTransport @@ -57,13 +57,13 @@ transport = infer_transport(config) ## Classes -### `SessionKwargs` +### `SessionKwargs` Keyword arguments for the MCP ClientSession constructor. -### `ClientTransport` +### `ClientTransport` Abstract base class for different MCP client transport mechanisms. @@ -74,7 +74,7 @@ to an MCP server, and providing a ClientSession within an async context. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] @@ -93,7 +93,7 @@ within this context. constructor (e.g., callbacks, timeouts). -#### `close` +#### `close` ```python close(self) @@ -102,7 +102,7 @@ close(self) Close the transport. -### `WSTransport` +### `WSTransport` Transport implementation that connects to an MCP server via WebSockets. @@ -110,13 +110,13 @@ Transport implementation that connects to an MCP server via WebSockets. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] ``` -### `SSETransport` +### `SSETransport` Transport implementation that connects to an MCP server via Server-Sent Events. @@ -124,13 +124,13 @@ Transport implementation that connects to an MCP server via Server-Sent Events. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] ``` -### `StreamableHttpTransport` +### `StreamableHttpTransport` Transport implementation that connects to an MCP server via Streamable HTTP Requests. @@ -138,13 +138,13 @@ 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] ``` -### `StdioTransport` +### `StdioTransport` Base transport for connecting to an MCP server via subprocess with stdio. @@ -155,67 +155,67 @@ transports like Python, Node, Uvx, etc. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] ``` -#### `connect` +#### `connect` ```python connect(self, **session_kwargs: Unpack[SessionKwargs]) -> ClientSession | None ``` -#### `disconnect` +#### `disconnect` ```python disconnect(self) ``` -#### `close` +#### `close` ```python close(self) ``` -### `PythonStdioTransport` +### `PythonStdioTransport` Transport for running Python scripts. -### `FastMCPStdioTransport` +### `FastMCPStdioTransport` Transport for running FastMCP servers using the FastMCP CLI. -### `NodeStdioTransport` +### `NodeStdioTransport` Transport for running Node.js scripts. -### `UvStdioTransport` +### `UvStdioTransport` Transport for running commands via the uv tool. -### `UvxStdioTransport` +### `UvxStdioTransport` Transport for running commands via the uvx tool. -### `NpxStdioTransport` +### `NpxStdioTransport` Transport for running commands via the npx tool. -### `FastMCPTransport` +### `FastMCPTransport` In-memory transport for FastMCP servers. @@ -228,13 +228,13 @@ tests or scenarios where client and server run in the same runtime. **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] ``` -### `MCPConfigTransport` +### `MCPConfigTransport` Transport for connecting to one or more MCP servers defined in an MCPConfig. @@ -287,7 +287,7 @@ async with client: **Methods:** -#### `connect_session` +#### `connect_session` ```python connect_session(self, **session_kwargs: Unpack[SessionKwargs]) -> AsyncIterator[ClientSession] diff --git a/docs/python-sdk/fastmcp-resources-resource_manager.mdx b/docs/python-sdk/fastmcp-resources-resource_manager.mdx index 52a8c766f..38ac4a5c0 100644 --- a/docs/python-sdk/fastmcp-resources-resource_manager.mdx +++ b/docs/python-sdk/fastmcp-resources-resource_manager.mdx @@ -45,7 +45,7 @@ get_resource_templates(self) -> dict[str, ResourceTemplate] Get all registered templates, keyed by URI template. -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> list[Resource] @@ -54,7 +54,7 @@ list_resources(self) -> list[Resource] Lists all resources, applying protocol filtering. -#### `list_resource_templates` +#### `list_resource_templates` ```python list_resource_templates(self) -> list[ResourceTemplate] @@ -63,7 +63,7 @@ list_resource_templates(self) -> list[ResourceTemplate] Lists all templates, applying protocol filtering. -#### `add_resource_or_template_from_fn` +#### `add_resource_or_template_from_fn` ```python add_resource_or_template_from_fn(self, fn: Callable[..., Any], uri: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> Resource | ResourceTemplate @@ -84,7 +84,7 @@ Add a resource or template to the manager from a function. - returns the existing resource or template. -#### `add_resource_from_fn` +#### `add_resource_from_fn` ```python add_resource_from_fn(self, fn: Callable[..., Any], uri: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> Resource @@ -105,7 +105,7 @@ Add a resource to the manager from a function. - returns the existing resource. -#### `add_resource` +#### `add_resource` ```python add_resource(self, resource: Resource) -> Resource @@ -116,10 +116,10 @@ Add a resource to the manager. **Args:** - `resource`: A Resource instance to add. The resource's .key attribute will be used as the storage key. To overwrite it, call -Resource.with_key() before calling this method. +Resource.model_copy(key=new_key) before calling this method. -#### `add_template_from_fn` +#### `add_template_from_fn` ```python add_template_from_fn(self, fn: Callable[..., Any], uri_template: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> ResourceTemplate @@ -128,7 +128,7 @@ add_template_from_fn(self, fn: Callable[..., Any], uri_template: str, name: str Create a template from a function. -#### `add_template` +#### `add_template` ```python add_template(self, template: ResourceTemplate) -> ResourceTemplate @@ -139,14 +139,14 @@ Add a template to the manager. **Args:** - `template`: A ResourceTemplate instance to add. The template's .key attribute will be used as the storage key. To overwrite it, call -ResourceTemplate.with_key() before calling this method. +ResourceTemplate.model_copy(key=new_key) before calling this method. **Returns:** - The added template. If a template with the same URI already exists, - returns the existing template. -#### `has_resource` +#### `has_resource` ```python has_resource(self, uri: AnyUrl | str) -> bool @@ -155,7 +155,7 @@ has_resource(self, uri: AnyUrl | str) -> bool Check if a resource exists. -#### `get_resource` +#### `get_resource` ```python get_resource(self, uri: AnyUrl | str) -> Resource @@ -170,7 +170,7 @@ Get resource by URI, checking concrete resources first, then templates. - `NotFoundError`: If no resource or template matching the URI is found. -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: AnyUrl | str) -> str | bytes diff --git a/docs/python-sdk/fastmcp-server-auth-auth.mdx b/docs/python-sdk/fastmcp-server-auth-auth.mdx index 7f17f1c43..fcc2a5667 100644 --- a/docs/python-sdk/fastmcp-server-auth-auth.mdx +++ b/docs/python-sdk/fastmcp-server-auth-auth.mdx @@ -7,7 +7,13 @@ sidebarTitle: auth ## Classes -### `AuthProvider` +### `AccessToken` + + +AccessToken that includes all JWT claims. + + +### `AuthProvider` Base class for all FastMCP authentication providers. @@ -20,7 +26,7 @@ custom authentication routes. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -37,25 +43,34 @@ All auth providers must implement token verification. - AccessToken object if valid, None if invalid or expired -#### `customize_auth_routes` +#### `get_routes` ```python -customize_auth_routes(self, routes: list[Route]) -> list[Route] +get_routes(self) -> list[Route] ``` -Customize authentication routes after standard creation. +Get the routes for this authentication provider. -This method allows providers to modify or add to the standard OAuth routes. -The default implementation returns the routes unchanged. - -**Args:** -- `routes`: List of standard routes (may be empty for token-only providers) +Each provider is responsible for creating whatever routes it needs: +- TokenVerifier: typically no routes (default implementation) +- RemoteAuthProvider: protected resource metadata routes +- OAuthProvider: full OAuth authorization server routes +- Custom providers: whatever routes they need **Returns:** -- List of routes (potentially modified or extended) +- List of routes for this provider -### `TokenVerifier` +#### `get_resource_metadata_url` + +```python +get_resource_metadata_url(self) -> AnyHttpUrl | None +``` + +Get the resource metadata URL for RFC 9728 compliance. + + +### `TokenVerifier` Base class for token verifiers (Resource Servers). @@ -66,7 +81,7 @@ Token verifiers typically don't provide authentication routes by default. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -75,7 +90,46 @@ verify_token(self, token: str) -> AccessToken | None Verify a bearer token and return access info if valid. -### `OAuthProvider` +### `RemoteAuthProvider` + + +Authentication provider for resource servers that verify tokens from known authorization servers. + +This provider composes a TokenVerifier with authorization server metadata to create +standardized OAuth 2.0 Protected Resource endpoints (RFC 9728). Perfect for: +- JWT verification with known issuers +- Remote token introspection services +- Any resource server that knows where its tokens come from + +Use this when you have token verification logic and want to advertise +the authorization servers that issue valid tokens. + + +**Methods:** + +#### `verify_token` + +```python +verify_token(self, token: str) -> AccessToken | None +``` + +Verify token using the configured token verifier. + + +#### `get_routes` + +```python +get_routes(self) -> list[Route] +``` + +Get OAuth routes for this provider. + +By default, returns only the standardized OAuth 2.0 Protected Resource routes. +Subclasses can override this method to add additional routes by calling +super().get_routes() and extending the returned list. + + +### `OAuthProvider` OAuth Authorization Server provider. @@ -86,7 +140,7 @@ authorization flows, token issuance, and token verification. **Methods:** -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -104,21 +158,18 @@ to our existing load_access_token method. - AccessToken object if valid, None if invalid or expired -#### `customize_auth_routes` +#### `get_routes` ```python -customize_auth_routes(self, routes: list[Route]) -> list[Route] +get_routes(self) -> list[Route] ``` -Customize OAuth authentication routes after standard creation. +Get OAuth authorization server routes and optional protected resource routes. -This method allows providers to modify the standard OAuth routes -returned by create_auth_routes. The default implementation returns -the routes unchanged. - -**Args:** -- `routes`: List of standard OAuth routes from create_auth_routes +This method creates the full set of OAuth routes including: +- Standard OAuth authorization server routes (/.well-known/oauth-authorization-server, /authorize, /token, etc.) +- Optional protected resource routes if resource_server_url is configured **Returns:** -- List of routes (potentially modified) +- List of OAuth routes diff --git a/docs/python-sdk/fastmcp-server-auth-providers-bearer_env.mdx b/docs/python-sdk/fastmcp-server-auth-providers-bearer_env.mdx deleted file mode 100644 index 10bc8637b..000000000 --- a/docs/python-sdk/fastmcp-server-auth-providers-bearer_env.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: bearer_env -sidebarTitle: bearer_env ---- - -# `fastmcp.server.auth.providers.bearer_env` - -## Classes - -### `EnvBearerAuthProviderSettings` - - -Settings for the BearerAuthProvider. - - -### `EnvBearerAuthProvider` - - -A BearerAuthProvider that loads settings from environment variables. Any -providing setting will always take precedence over the environment -variables. - diff --git a/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx b/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx index c40254b10..9f83a21ab 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx @@ -10,19 +10,19 @@ TokenVerifier implementations for FastMCP. ## Classes -### `JWKData` +### `JWKData` JSON Web Key data structure. -### `JWKSData` +### `JWKSData` JSON Web Key Set data structure. -### `RSAKeyPair` +### `RSAKeyPair` RSA key pair for JWT testing. @@ -30,7 +30,7 @@ RSA key pair for JWT testing. **Methods:** -#### `generate` +#### `generate` ```python generate(cls) -> RSAKeyPair @@ -42,7 +42,7 @@ Generate an RSA key pair for testing. - Generated key pair -#### `create_token` +#### `create_token` ```python create_token(self, subject: str = 'fastmcp-user', issuer: str = 'https://fastmcp.example.com', audience: str | list[str] | None = None, scopes: list[str] | None = None, expires_in_seconds: int = 3600, additional_claims: dict[str, Any] | None = None, kid: str | None = None) -> str @@ -60,13 +60,13 @@ Generate a test JWT token for testing purposes. - `kid`: Key ID to include in header -### `JWTVerifierSettings` +### `JWTVerifierSettings` Settings for JWT token verification. -### `JWTVerifier` +### `JWTVerifier` JWT token verifier using public key or JWKS. @@ -85,7 +85,7 @@ Use this when: **Methods:** -#### `load_access_token` +#### `load_access_token` ```python load_access_token(self, token: str) -> AccessToken | None @@ -100,7 +100,7 @@ Validates the provided JWT bearer token. - AccessToken object if valid, None if invalid or expired -#### `verify_token` +#### `verify_token` ```python verify_token(self, token: str) -> AccessToken | None @@ -118,7 +118,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. @@ -139,7 +139,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-auth-providers-workos.mdx b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx index 6732b97ff..48e965b49 100644 --- a/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx +++ b/docs/python-sdk/fastmcp-server-auth-providers-workos.mdx @@ -7,14 +7,14 @@ sidebarTitle: workos ## Classes -### `AuthKitProviderSettings` +### `AuthKitProviderSettings` -### `AuthKitProvider` +### `AuthKitProvider` -WorkOS AuthKit metadata provider for DCR (Dynamic Client Registration). +AuthKit metadata provider for DCR (Dynamic Client Registration). -This provider implements WorkOS AuthKit integration using metadata forwarding +This provider implements AuthKit integration using metadata forwarding instead of OAuth proxying. This is the recommended approach for WorkOS DCR as it allows WorkOS to handle the OAuth flow directly while FastMCP acts as a resource server. @@ -35,24 +35,14 @@ https://workos.com/docs/authkit/mcp/integrating/token-verification **Methods:** -#### `verify_token` +#### `get_routes` ```python -verify_token(self, token: str) -> AccessToken | None +get_routes(self) -> list[Route] ``` -Verify a WorkOS token using the configured token verifier. +Get OAuth routes including AuthKit authorization server metadata forwarding. - -#### `customize_auth_routes` - -```python -customize_auth_routes(self, routes: list[BaseRoute]) -> list[BaseRoute] -``` - -Add AuthKit metadata endpoints. - -This adds: -- /.well-known/oauth-authorization-server (forwards AuthKit metadata) -- /.well-known/oauth-protected-resource (returns FastMCP resource info) +This returns the standard protected resource routes plus an authorization server +metadata endpoint that forwards AuthKit's OAuth metadata to clients. diff --git a/docs/python-sdk/fastmcp-server-dependencies.mdx b/docs/python-sdk/fastmcp-server-dependencies.mdx index 5c84be69a..d9a6d6bed 100644 --- a/docs/python-sdk/fastmcp-server-dependencies.mdx +++ b/docs/python-sdk/fastmcp-server-dependencies.mdx @@ -7,19 +7,19 @@ sidebarTitle: dependencies ## Functions -### `get_context` +### `get_context` ```python get_context() -> Context ``` -### `get_http_request` +### `get_http_request` ```python get_http_request() -> Request ``` -### `get_http_headers` +### `get_http_headers` ```python get_http_headers(include_all: bool = False) -> dict[str, str] @@ -34,3 +34,16 @@ an empty dict is returned). By default, strips problematic headers like `content-length` that cause issues if forwarded to downstream clients. If `include_all` is True, all headers are returned. + +### `get_access_token` + +```python +get_access_token() -> AccessToken | None +``` + + +Get the FastMCP access token from the current context. + +**Returns:** +- The access token if an authenticated user is available, None otherwise. + diff --git a/docs/python-sdk/fastmcp-server-http.mdx b/docs/python-sdk/fastmcp-server-http.mdx index 335710343..1dd86b49f 100644 --- a/docs/python-sdk/fastmcp-server-http.mdx +++ b/docs/python-sdk/fastmcp-server-http.mdx @@ -7,29 +7,13 @@ sidebarTitle: http ## Functions -### `set_http_request` +### `set_http_request` ```python set_http_request(request: Request) -> Generator[Request, None, None] ``` -### `setup_auth_middleware_and_routes` - -```python -setup_auth_middleware_and_routes(auth: AuthProvider) -> tuple[list[Middleware], list[Route], list[str]] -``` - - -Set up authentication middleware and routes if auth is enabled. - -**Args:** -- `auth`: An AuthProvider for authentication (TokenVerifier or OAuthProvider) - -**Returns:** -- Tuple of (middleware, auth_routes, required_scopes) - - -### `create_base_app` +### `create_base_app` ```python create_base_app(routes: list[BaseRoute], middleware: list[Middleware], debug: bool = False, lifespan: Callable | None = None) -> StarletteWithLifespan @@ -48,7 +32,7 @@ Create a base Starlette app with common middleware and routes. - A Starlette application -### `create_sse_app` +### `create_sse_app` ```python create_sse_app(server: FastMCP[LifespanResultT], message_path: str, sse_path: str, auth: AuthProvider | None = None, debug: bool = False, routes: list[BaseRoute] | None = None, middleware: list[Middleware] | None = None) -> StarletteWithLifespan @@ -70,7 +54,7 @@ Returns: A Starlette application with RequestContextMiddleware -### `create_streamable_http_app` +### `create_streamable_http_app` ```python create_streamable_http_app(server: FastMCP[LifespanResultT], streamable_http_path: str, event_store: EventStore | None = None, auth: AuthProvider | None = None, json_response: bool = False, stateless_http: bool = False, debug: bool = False, routes: list[BaseRoute] | None = None, middleware: list[Middleware] | None = None) -> StarletteWithLifespan @@ -96,17 +80,23 @@ Return an instance of the StreamableHTTP server app. ## Classes -### `StarletteWithLifespan` +### `StreamableHTTPASGIApp` + + +ASGI application wrapper for Streamable HTTP server transport. + + +### `StarletteWithLifespan` **Methods:** -#### `lifespan` +#### `lifespan` ```python -lifespan(self) -> Lifespan +lifespan(self) -> Lifespan[Starlette] ``` -### `RequestContextMiddleware` +### `RequestContextMiddleware` Middleware that stores each request in a ContextVar diff --git a/docs/python-sdk/fastmcp-server-proxy.mdx b/docs/python-sdk/fastmcp-server-proxy.mdx index 5ad50f8d4..db13c1378 100644 --- a/docs/python-sdk/fastmcp-server-proxy.mdx +++ b/docs/python-sdk/fastmcp-server-proxy.mdx @@ -7,7 +7,7 @@ sidebarTitle: proxy ## Functions -### `default_proxy_roots_handler` +### `default_proxy_roots_handler` ```python default_proxy_roots_handler(context: RequestContext[ClientSession, LifespanContextT]) -> RootsList @@ -19,7 +19,13 @@ A handler that forwards the list roots request from the remote server to the pro ## Classes -### `ProxyToolManager` +### `ProxyManagerMixin` + + +A mixin for proxy managers to provide a unified client retrieval method. + + +### `ProxyToolManager` A ToolManager that sources its tools from a remote client in addition to local and mounted tools. @@ -27,7 +33,7 @@ A ToolManager that sources its tools from a remote client in addition to local a **Methods:** -#### `get_tools` +#### `get_tools` ```python get_tools(self) -> dict[str, Tool] @@ -36,7 +42,7 @@ get_tools(self) -> dict[str, Tool] Gets the unfiltered tool inventory including local, mounted, and proxy tools. -#### `list_tools` +#### `list_tools` ```python list_tools(self) -> list[Tool] @@ -45,7 +51,7 @@ list_tools(self) -> list[Tool] Gets the filtered list of tools including local, mounted, and proxy tools. -#### `call_tool` +#### `call_tool` ```python call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult @@ -54,7 +60,7 @@ call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult Calls a tool, trying local/mounted first, then proxy if not found. -### `ProxyResourceManager` +### `ProxyResourceManager` A ResourceManager that sources its resources from a remote client in addition to local and mounted resources. @@ -62,7 +68,7 @@ A ResourceManager that sources its resources from a remote client in addition to **Methods:** -#### `get_resources` +#### `get_resources` ```python get_resources(self) -> dict[str, Resource] @@ -71,7 +77,7 @@ get_resources(self) -> dict[str, Resource] Gets the unfiltered resource inventory including local, mounted, and proxy resources. -#### `get_resource_templates` +#### `get_resource_templates` ```python get_resource_templates(self) -> dict[str, ResourceTemplate] @@ -80,7 +86,7 @@ get_resource_templates(self) -> dict[str, ResourceTemplate] Gets the unfiltered template inventory including local, mounted, and proxy templates. -#### `list_resources` +#### `list_resources` ```python list_resources(self) -> list[Resource] @@ -89,7 +95,7 @@ list_resources(self) -> list[Resource] Gets the filtered list of resources including local, mounted, and proxy resources. -#### `list_resource_templates` +#### `list_resource_templates` ```python list_resource_templates(self) -> list[ResourceTemplate] @@ -98,7 +104,7 @@ list_resource_templates(self) -> list[ResourceTemplate] Gets the filtered list of templates including local, mounted, and proxy templates. -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: AnyUrl | str) -> str | bytes @@ -107,7 +113,7 @@ read_resource(self, uri: AnyUrl | str) -> str | bytes Reads a resource, trying local/mounted first, then proxy if not found. -### `ProxyPromptManager` +### `ProxyPromptManager` A PromptManager that sources its prompts from a remote client in addition to local and mounted prompts. @@ -115,7 +121,7 @@ A PromptManager that sources its prompts from a remote client in addition to loc **Methods:** -#### `get_prompts` +#### `get_prompts` ```python get_prompts(self) -> dict[str, Prompt] @@ -124,7 +130,7 @@ get_prompts(self) -> dict[str, Prompt] Gets the unfiltered prompt inventory including local, mounted, and proxy prompts. -#### `list_prompts` +#### `list_prompts` ```python list_prompts(self) -> list[Prompt] @@ -133,7 +139,7 @@ list_prompts(self) -> list[Prompt] Gets the filtered list of prompts including local, mounted, and proxy prompts. -#### `render_prompt` +#### `render_prompt` ```python render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPromptResult @@ -142,7 +148,7 @@ render_prompt(self, name: str, arguments: dict[str, Any] | None = None) -> GetPr Renders a prompt, trying local/mounted first, then proxy if not found. -### `ProxyTool` +### `ProxyTool` A Tool that represents and executes a tool on a remote server. @@ -150,7 +156,7 @@ A Tool that represents and executes a tool on a remote server. **Methods:** -#### `from_mcp_tool` +#### `from_mcp_tool` ```python from_mcp_tool(cls, client: Client, mcp_tool: mcp.types.Tool) -> ProxyTool @@ -159,7 +165,7 @@ from_mcp_tool(cls, client: Client, mcp_tool: mcp.types.Tool) -> ProxyTool Factory method to create a ProxyTool from a raw MCP tool schema. -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResult @@ -168,7 +174,7 @@ run(self, arguments: dict[str, Any], context: Context | None = None) -> ToolResu Executes the tool by making a call through the client. -### `ProxyResource` +### `ProxyResource` A Resource that represents and reads a resource from a remote server. @@ -176,7 +182,7 @@ A Resource that represents and reads a resource from a remote server. **Methods:** -#### `from_mcp_resource` +#### `from_mcp_resource` ```python from_mcp_resource(cls, client: Client, mcp_resource: mcp.types.Resource) -> ProxyResource @@ -185,7 +191,7 @@ from_mcp_resource(cls, client: Client, mcp_resource: mcp.types.Resource) -> Prox Factory method to create a ProxyResource from a raw MCP resource schema. -#### `read` +#### `read` ```python read(self) -> str | bytes @@ -194,7 +200,7 @@ read(self) -> str | bytes Read the resource content from the remote server. -### `ProxyTemplate` +### `ProxyTemplate` A ResourceTemplate that represents and creates resources from a remote server template. @@ -202,7 +208,7 @@ A ResourceTemplate that represents and creates resources from a remote server te **Methods:** -#### `from_mcp_template` +#### `from_mcp_template` ```python from_mcp_template(cls, client: Client, mcp_template: mcp.types.ResourceTemplate) -> ProxyTemplate @@ -211,7 +217,7 @@ from_mcp_template(cls, client: Client, mcp_template: mcp.types.ResourceTemplate) 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 @@ -220,7 +226,7 @@ create_resource(self, uri: str, params: dict[str, Any], context: Context | None Create a resource from the template by calling the remote server. -### `ProxyPrompt` +### `ProxyPrompt` A Prompt that represents and renders a prompt from a remote server. @@ -228,7 +234,7 @@ A Prompt that represents and renders a prompt from a remote server. **Methods:** -#### `from_mcp_prompt` +#### `from_mcp_prompt` ```python from_mcp_prompt(cls, client: Client, mcp_prompt: mcp.types.Prompt) -> ProxyPrompt @@ -237,7 +243,7 @@ from_mcp_prompt(cls, client: Client, mcp_prompt: mcp.types.Prompt) -> ProxyPromp Factory method to create a ProxyPrompt from a raw MCP prompt schema. -#### `render` +#### `render` ```python render(self, arguments: dict[str, Any]) -> list[PromptMessage] @@ -246,14 +252,14 @@ render(self, arguments: dict[str, Any]) -> list[PromptMessage] Render the prompt by making a call through the client. -### `FastMCPProxy` +### `FastMCPProxy` A FastMCP server that acts as a proxy to a remote MCP-compliant server. It uses specialized managers that fulfill requests via a client factory. -### `ProxyClient` +### `ProxyClient` A proxy client that forwards advanced interactions between a remote MCP server and the proxy's connected clients. @@ -262,7 +268,7 @@ Supports forwarding roots, sampling, elicitation, logging, and progress. **Methods:** -#### `default_sampling_handler` +#### `default_sampling_handler` ```python default_sampling_handler(cls, messages: list[mcp.types.SamplingMessage], params: mcp.types.CreateMessageRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> mcp.types.CreateMessageResult @@ -271,7 +277,7 @@ default_sampling_handler(cls, messages: list[mcp.types.SamplingMessage], params: A handler that forwards the sampling request from the remote server to the proxy's connected clients and relays the response back to the remote server. -#### `default_elicitation_handler` +#### `default_elicitation_handler` ```python default_elicitation_handler(cls, message: str, response_type: type, params: mcp.types.ElicitRequestParams, context: RequestContext[ClientSession, LifespanContextT]) -> ElicitResult @@ -280,7 +286,7 @@ default_elicitation_handler(cls, message: str, response_type: type, params: mcp. A handler that forwards the elicitation request from the remote server to the proxy's connected clients and relays the response back to the remote server. -#### `default_log_handler` +#### `default_log_handler` ```python default_log_handler(cls, message: LogMessage) -> None @@ -289,7 +295,7 @@ default_log_handler(cls, message: LogMessage) -> None A handler that forwards the log notification from the remote server to the proxy's connected clients. -#### `default_progress_handler` +#### `default_progress_handler` ```python default_progress_handler(cls, progress: float, total: float | None, message: str | None) -> None @@ -298,7 +304,7 @@ default_progress_handler(cls, progress: float, total: float | None, message: str A handler that forwards the progress notification from the remote server to the proxy's connected clients. -### `StatefulProxyClient` +### `StatefulProxyClient` A proxy client that provides a stateful client factory for the proxy server. @@ -312,7 +318,7 @@ Note that it is essential to ensure that the proxy server itself is also statefu **Methods:** -#### `clear` +#### `clear` ```python clear(self) @@ -321,7 +327,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-server.mdx b/docs/python-sdk/fastmcp-server-server.mdx index 09f3341d7..ae1052a68 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 context object -### `add_resource_prefix` +### `add_resource_prefix` ```python add_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> str @@ -64,7 +64,7 @@ add_resource_prefix("resource:///absolute/path", "prefix") - `ValueError`: If the URI doesn't match the expected protocol\://path format -### `remove_resource_prefix` +### `remove_resource_prefix` ```python remove_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> str @@ -103,7 +103,7 @@ remove_resource_prefix("resource://prefix//absolute/path", "prefix") - `ValueError`: If the URI doesn't match the expected protocol\://path format -### `has_resource_prefix` +### `has_resource_prefix` ```python has_resource_prefix(uri: str, prefix: str, prefix_format: Literal['protocol', 'path'] | None = None) -> bool @@ -147,25 +147,31 @@ False **Methods:** -#### `settings` +#### `settings` ```python settings(self) -> Settings ``` -#### `name` +#### `name` ```python name(self) -> str ``` -#### `instructions` +#### `instructions` ```python instructions(self) -> str | None ``` -#### `run_async` +#### `version` + +```python +version(self) -> str | None +``` + +#### `run_async` ```python run_async(self, transport: Transport | None = None, show_banner: bool = True, **transport_kwargs: Any) -> None @@ -177,7 +183,7 @@ Run the FastMCP server asynchronously. - `transport`: Transport protocol to use ("stdio", "sse", or "streamable-http") -#### `run` +#### `run` ```python run(self, transport: Transport | None = None, show_banner: bool = True, **transport_kwargs: Any) -> None @@ -189,13 +195,13 @@ Run the FastMCP server. Note this is a synchronous function. - `transport`: Transport protocol to use ("stdio", "sse", or "streamable-http") -#### `add_middleware` +#### `add_middleware` ```python add_middleware(self, middleware: Middleware) -> None ``` -#### `get_tools` +#### `get_tools` ```python get_tools(self) -> dict[str, Tool] @@ -204,13 +210,13 @@ get_tools(self) -> dict[str, Tool] Get all registered tools, indexed by registered key. -#### `get_tool` +#### `get_tool` ```python get_tool(self, key: str) -> Tool ``` -#### `get_resources` +#### `get_resources` ```python get_resources(self) -> dict[str, Resource] @@ -219,13 +225,13 @@ get_resources(self) -> dict[str, Resource] Get all registered resources, indexed by registered key. -#### `get_resource` +#### `get_resource` ```python get_resource(self, key: str) -> Resource ``` -#### `get_resource_templates` +#### `get_resource_templates` ```python get_resource_templates(self) -> dict[str, ResourceTemplate] @@ -234,7 +240,7 @@ get_resource_templates(self) -> dict[str, ResourceTemplate] Get all registered resource templates, indexed by registered key. -#### `get_resource_template` +#### `get_resource_template` ```python get_resource_template(self, key: str) -> ResourceTemplate @@ -243,7 +249,7 @@ get_resource_template(self, key: str) -> ResourceTemplate Get a registered resource template by key. -#### `get_prompts` +#### `get_prompts` ```python get_prompts(self) -> dict[str, Prompt] @@ -252,13 +258,13 @@ get_prompts(self) -> dict[str, Prompt] List all available prompts. -#### `get_prompt` +#### `get_prompt` ```python get_prompt(self, key: str) -> Prompt ``` -#### `custom_route` +#### `custom_route` ```python custom_route(self, path: str, methods: list[str], name: str | None = None, include_in_schema: bool = True) -> Callable[[Callable[[Request], Awaitable[Response]]], Callable[[Request], Awaitable[Response]]] @@ -279,7 +285,7 @@ Starlette's reverse URL lookup feature) - `include_in_schema`: Whether to include in OpenAPI schema, defaults to True -#### `add_tool` +#### `add_tool` ```python add_tool(self, tool: Tool) -> Tool @@ -297,7 +303,7 @@ with the Context type annotation. See the @tool decorator for examples. - The tool instance that was added to the server. -#### `remove_tool` +#### `remove_tool` ```python remove_tool(self, name: str) -> None @@ -312,7 +318,7 @@ Remove a tool from the server. - `NotFoundError`: If the tool is not found -#### `add_tool_transformation` +#### `add_tool_transformation` ```python add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None @@ -321,7 +327,7 @@ add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfi Add a tool transformation. -#### `remove_tool_transformation` +#### `remove_tool_transformation` ```python remove_tool_transformation(self, tool_name: str) -> None @@ -330,19 +336,19 @@ remove_tool_transformation(self, tool_name: str) -> None Remove a tool transformation. -#### `tool` +#### `tool` ```python tool(self, name_or_fn: AnyFunction) -> FunctionTool ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | None = None) -> Callable[[AnyFunction], FunctionTool] ``` -#### `tool` +#### `tool` ```python tool(self, name_or_fn: str | AnyFunction | None = None) -> Callable[[AnyFunction], FunctionTool] | FunctionTool @@ -398,7 +404,7 @@ server.tool(my_function, name="custom_name") ``` -#### `add_resource` +#### `add_resource` ```python add_resource(self, resource: Resource) -> Resource @@ -413,7 +419,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 @@ -428,7 +434,7 @@ Add a resource template to the server. - The template instance that was added to the server. -#### `add_resource_fn` +#### `add_resource_fn` ```python add_resource_fn(self, fn: AnyFunction, uri: str, name: str | None = None, description: str | None = None, mime_type: str | None = None, tags: set[str] | None = None) -> None @@ -448,7 +454,7 @@ has parameters, it will be registered as a template resource. - `tags`: Optional set of tags for categorizing the resource -#### `resource` +#### `resource` ```python resource(self, uri: str) -> Callable[[AnyFunction], Resource | ResourceTemplate] @@ -508,7 +514,7 @@ async def get_weather(city: str) -> str: ``` -#### `add_prompt` +#### `add_prompt` ```python add_prompt(self, prompt: Prompt) -> Prompt @@ -523,19 +529,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 @@ -613,7 +619,7 @@ Decorator to register a prompt. ``` -#### `run_stdio_async` +#### `run_stdio_async` ```python run_stdio_async(self, show_banner: bool = True) -> None @@ -622,7 +628,7 @@ run_stdio_async(self, show_banner: bool = True) -> None Run the server using stdio transport. -#### `run_http_async` +#### `run_http_async` ```python run_http_async(self, show_banner: bool = True, transport: Literal['http', 'streamable-http', 'sse'] = 'http', host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None, middleware: list[ASGIMiddleware] | None = None, stateless_http: bool | None = None) -> None @@ -641,7 +647,7 @@ Run the server using HTTP transport. - `stateless_http`: Whether to use stateless HTTP (defaults to settings.stateless_http) -#### `run_sse_async` +#### `run_sse_async` ```python run_sse_async(self, host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None) -> None @@ -650,7 +656,7 @@ run_sse_async(self, host: str | None = None, port: int | None = None, log_level: Run the server using SSE transport. -#### `sse_app` +#### `sse_app` ```python sse_app(self, path: str | None = None, message_path: str | None = None, middleware: list[ASGIMiddleware] | None = None) -> StarletteWithLifespan @@ -664,7 +670,7 @@ Create a Starlette app for the SSE server. - `middleware`: A list of middleware to apply to the app -#### `streamable_http_app` +#### `streamable_http_app` ```python streamable_http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None) -> StarletteWithLifespan @@ -677,7 +683,7 @@ Create a Starlette app for the StreamableHTTP server. - `middleware`: A list of middleware to apply to the app -#### `http_app` +#### `http_app` ```python http_app(self, path: str | None = None, middleware: list[ASGIMiddleware] | None = None, json_response: bool | None = None, stateless_http: bool | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http') -> StarletteWithLifespan @@ -694,13 +700,13 @@ Create a Starlette app using the specified HTTP transport. - A Starlette application configured with the specified transport -#### `run_streamable_http_async` +#### `run_streamable_http_async` ```python run_streamable_http_async(self, host: str | None = None, port: int | None = None, log_level: str | None = None, path: str | None = None, uvicorn_config: dict[str, Any] | None = None) -> None ``` -#### `mount` +#### `mount` ```python mount(self, server: FastMCP[LifespanResultT], prefix: str | None = None, as_proxy: bool | None = None) -> None @@ -754,7 +760,7 @@ automatically determined based on whether the server has a custom lifespan - `prompt_separator`: Deprecated. Separator character for prompt names. -#### `import_server` +#### `import_server` ```python import_server(self, server: FastMCP[LifespanResultT], prefix: str | None = None, tool_separator: str | None = None, resource_separator: str | None = None, prompt_separator: str | None = None) -> None @@ -795,7 +801,7 @@ applied using the protocol\://prefix/path format - `prompt_separator`: Deprecated. Separator for prompt names. -#### `from_openapi` +#### `from_openapi` ```python from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, route_maps: list[RouteMap] | list[RouteMapNew] | None = None, route_map_fn: OpenAPIRouteMapFn | OpenAPIRouteMapFnNew | None = None, mcp_component_fn: OpenAPIComponentFn | OpenAPIComponentFnNew | None = None, mcp_names: dict[str, str] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI | FastMCPOpenAPINew @@ -804,7 +810,7 @@ from_openapi(cls, openapi_spec: dict[str, Any], client: httpx.AsyncClient, route Create a FastMCP server from an OpenAPI specification. -#### `from_fastapi` +#### `from_fastapi` ```python from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] | list[RouteMapNew] | None = None, route_map_fn: OpenAPIRouteMapFn | OpenAPIRouteMapFnNew | None = None, mcp_component_fn: OpenAPIComponentFn | OpenAPIComponentFnNew | None = None, mcp_names: dict[str, str] | None = None, httpx_client_kwargs: dict[str, Any] | None = None, tags: set[str] | None = None, **settings: Any) -> FastMCPOpenAPI | FastMCPOpenAPINew @@ -813,7 +819,7 @@ from_fastapi(cls, app: Any, name: str | None = None, route_maps: list[RouteMap] Create a FastMCP server from a FastAPI application. -#### `as_proxy` +#### `as_proxy` ```python as_proxy(cls, backend: Client[ClientTransportT] | ClientTransport | FastMCP[Any] | AnyUrl | Path | MCPConfig | dict[str, Any] | str, **settings: Any) -> FastMCPProxy @@ -827,7 +833,7 @@ instance or any value accepted as the `transport` argument of `fastmcp.client.Client` constructor. -#### `from_client` +#### `from_client` ```python from_client(cls, client: Client[ClientTransportT], **settings: Any) -> FastMCPProxy @@ -836,4 +842,4 @@ from_client(cls, client: Client[ClientTransportT], **settings: Any) -> FastMCPPr Create a FastMCP proxy server from a FastMCP client. -### `MountedServer` +### `MountedServer` diff --git a/docs/python-sdk/fastmcp-tools-tool.mdx b/docs/python-sdk/fastmcp-tools-tool.mdx index aaa3cbf53..2aaf97cc3 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]] ``` -### `Tool` +### `Tool` Internal tool registration info. @@ -33,34 +33,34 @@ Internal tool registration info. **Methods:** -#### `enable` +#### `enable` ```python enable(self) -> None ``` -#### `disable` +#### `disable` ```python disable(self) -> None ``` -#### `to_mcp_tool` +#### `to_mcp_tool` ```python to_mcp_tool(self, **overrides: Any) -> MCPTool ``` -#### `from_function` +#### `from_function` ```python -from_function(fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | None | NotSetT | Literal[False] = NotSet, serializer: Callable[[Any], str] | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None) -> FunctionTool +from_function(fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | None | NotSetT = NotSet, serializer: Callable[[Any], str] | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None) -> FunctionTool ``` Create a Tool from a function. -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any]) -> ToolResult @@ -75,10 +75,10 @@ implemented by subclasses. (list of ContentBlocks, dict of structured output). -#### `from_tool` +#### `from_tool` ```python -from_tool(cls, tool: Tool, transform_fn: Callable[..., Any] | None = None, name: str | None = None, title: str | None | NotSetT = NotSet, transform_args: dict[str, ArgTransform] | None = None, description: str | None | NotSetT = NotSet, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, output_schema: dict[str, Any] | None | Literal[False] = None, serializer: Callable[[Any], str] | None = None, meta: dict[str, Any] | None | NotSetT = NotSet, enabled: bool | None = None) -> TransformedTool +from_tool(cls, tool: Tool) -> TransformedTool ``` ### `FunctionTool` @@ -88,7 +88,7 @@ from_tool(cls, tool: Tool, transform_fn: Callable[..., Any] | None = None, name: #### `from_function` ```python -from_function(cls, fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | None | NotSetT | Literal[False] = NotSet, serializer: Callable[[Any], str] | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None) -> FunctionTool +from_function(cls, fn: Callable[..., Any], name: str | None = None, title: str | None = None, description: str | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, exclude_args: list[str] | None = None, output_schema: dict[str, Any] | None | NotSetT = NotSet, serializer: Callable[[Any], str] | None = None, meta: dict[str, Any] | None = None, enabled: bool | None = None) -> FunctionTool ``` Create a Tool from a function. diff --git a/docs/python-sdk/fastmcp-tools-tool_manager.mdx b/docs/python-sdk/fastmcp-tools-tool_manager.mdx index 3b94ee85e..99a6d9774 100644 --- a/docs/python-sdk/fastmcp-tools-tool_manager.mdx +++ b/docs/python-sdk/fastmcp-tools-tool_manager.mdx @@ -24,7 +24,7 @@ mount(self, server: MountedServer) -> None Adds a mounted server as a source for tools. -#### `has_tool` +#### `has_tool` ```python has_tool(self, key: str) -> bool @@ -33,7 +33,7 @@ has_tool(self, key: str) -> bool Check if a tool exists. -#### `get_tool` +#### `get_tool` ```python get_tool(self, key: str) -> Tool @@ -42,7 +42,7 @@ get_tool(self, key: str) -> Tool Get tool by key. -#### `get_tools` +#### `get_tools` ```python get_tools(self) -> dict[str, Tool] @@ -51,7 +51,7 @@ get_tools(self) -> dict[str, Tool] Gets the complete, unfiltered inventory of all tools. -#### `list_tools` +#### `list_tools` ```python list_tools(self) -> list[Tool] @@ -60,7 +60,7 @@ list_tools(self) -> list[Tool] Lists all tools, applying protocol filtering. -#### `add_tool_from_fn` +#### `add_tool_from_fn` ```python add_tool_from_fn(self, fn: Callable[..., Any], name: str | None = None, description: str | None = None, tags: set[str] | None = None, annotations: ToolAnnotations | None = None, serializer: Callable[[Any], str] | None = None, exclude_args: list[str] | None = None) -> Tool @@ -69,7 +69,7 @@ add_tool_from_fn(self, fn: Callable[..., Any], name: str | None = None, descript Add a tool to the server. -#### `add_tool` +#### `add_tool` ```python add_tool(self, tool: Tool) -> Tool @@ -78,7 +78,7 @@ add_tool(self, tool: Tool) -> Tool Register a tool with the server. -#### `add_tool_transformation` +#### `add_tool_transformation` ```python add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfig) -> None @@ -87,7 +87,7 @@ add_tool_transformation(self, tool_name: str, transformation: ToolTransformConfi Add a tool transformation. -#### `get_tool_transformation` +#### `get_tool_transformation` ```python get_tool_transformation(self, tool_name: str) -> ToolTransformConfig | None @@ -96,7 +96,7 @@ get_tool_transformation(self, tool_name: str) -> ToolTransformConfig | None Get a tool transformation. -#### `remove_tool_transformation` +#### `remove_tool_transformation` ```python remove_tool_transformation(self, tool_name: str) -> None @@ -105,7 +105,7 @@ remove_tool_transformation(self, tool_name: str) -> None Remove a tool transformation. -#### `remove_tool` +#### `remove_tool` ```python remove_tool(self, key: str) -> None @@ -120,7 +120,7 @@ Remove a tool from the server. - `NotFoundError`: If the tool is not found -#### `call_tool` +#### `call_tool` ```python call_tool(self, key: str, arguments: dict[str, Any]) -> ToolResult diff --git a/docs/python-sdk/fastmcp-tools-tool_transform.mdx b/docs/python-sdk/fastmcp-tools-tool_transform.mdx index 51bce981f..b0a891fc2 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) -> 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) -> 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] @@ -75,7 +75,7 @@ are left unchanged. ## Classes -### `ArgTransform` +### `ArgTransform` Configuration for transforming a parent tool's argument. @@ -137,7 +137,7 @@ ArgTransform(name="new_name", description="New desc", default=None, type=int) ``` -### `ArgTransformConfig` +### `ArgTransformConfig` A model for requesting a single argument transform. @@ -145,7 +145,7 @@ A model for requesting a single argument transform. **Methods:** -#### `to_arg_transform` +#### `to_arg_transform` ```python to_arg_transform(self) -> ArgTransform @@ -154,7 +154,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. @@ -171,7 +171,7 @@ inherited from the parent tool but can be overridden or disabled. **Methods:** -#### `run` +#### `run` ```python run(self, arguments: dict[str, Any]) -> ToolResult @@ -190,10 +190,10 @@ functions. - ToolResult object containing content and optional structured output. -#### `from_tool` +#### `from_tool` ```python -from_tool(cls, tool: Tool, name: str | None = None, title: str | None | NotSetT = NotSet, description: str | None | NotSetT = NotSet, tags: set[str] | None = None, transform_fn: Callable[..., Any] | None = None, transform_args: dict[str, ArgTransform] | None = None, annotations: ToolAnnotations | None = None, output_schema: dict[str, Any] | None | Literal[False] = None, serializer: Callable[[Any], str] | None = None, meta: dict[str, Any] | None | NotSetT = NotSet, enabled: bool | None = None) -> TransformedTool +from_tool(cls, tool: Tool, name: str | None = None, title: str | None | NotSetT = NotSet, description: str | None | NotSetT = NotSet, tags: set[str] | None = None, transform_fn: Callable[..., Any] | None = None, transform_args: dict[str, ArgTransform] | None = None, annotations: ToolAnnotations | None | NotSetT = NotSet, output_schema: dict[str, Any] | None | NotSetT = NotSet, serializer: Callable[[Any], str] | None | NotSetT = NotSet, meta: dict[str, Any] | None | NotSetT = NotSet, enabled: bool | None = None) -> TransformedTool ``` Create a transformed tool from a parent tool. @@ -272,7 +272,7 @@ async def custom_output(**kwargs) -> ToolResult: ``` -### `ToolTransformConfig` +### `ToolTransformConfig` Provides a way to transform a tool. @@ -280,7 +280,7 @@ Provides a way to transform a tool. **Methods:** -#### `apply` +#### `apply` ```python apply(self, tool: Tool) -> TransformedTool diff --git a/docs/python-sdk/fastmcp-utilities-components.mdx b/docs/python-sdk/fastmcp-utilities-components.mdx index 01cbdfda8..e18484bec 100644 --- a/docs/python-sdk/fastmcp-utilities-components.mdx +++ b/docs/python-sdk/fastmcp-utilities-components.mdx @@ -41,13 +41,21 @@ If include_fastmcp_meta is True, a `_fastmcp` key will be added to the meta, containing a `tags` field with the tags of the component. -#### `with_key` +#### `model_copy` ```python -with_key(self, key: str) -> Self +model_copy(self) -> Self ``` -#### `enable` +Create a copy of the component. + +**Args:** +- `update`: A dictionary of fields to update. +- `deep`: Whether to deep copy the component. +- `key`: The key to use for the copy. + + +#### `enable` ```python enable(self) -> None @@ -56,7 +64,7 @@ enable(self) -> None Enable the component. -#### `disable` +#### `disable` ```python disable(self) -> None @@ -65,7 +73,7 @@ disable(self) -> None Disable the component. -#### `copy` +#### `copy` ```python copy(self) -> Self @@ -74,7 +82,7 @@ copy(self) -> Self Create a copy of the component. -### `MirroredComponent` +### `MirroredComponent` Base class for components that are mirrored from a remote server. @@ -85,7 +93,7 @@ to create a local version you can modify. **Methods:** -#### `enable` +#### `enable` ```python enable(self) -> None @@ -94,7 +102,7 @@ enable(self) -> None Enable the component. -#### `disable` +#### `disable` ```python disable(self) -> None @@ -103,7 +111,7 @@ disable(self) -> None Disable the component. -#### `copy` +#### `copy` ```python copy(self) -> Self diff --git a/docs/python-sdk/fastmcp-utilities-inspect.mdx b/docs/python-sdk/fastmcp-utilities-inspect.mdx index 850983f9d..d05ddcff5 100644 --- a/docs/python-sdk/fastmcp-utilities-inspect.mdx +++ b/docs/python-sdk/fastmcp-utilities-inspect.mdx @@ -10,7 +10,7 @@ Utilities for inspecting FastMCP instances. ## Functions -### `inspect_fastmcp_v2` +### `inspect_fastmcp_v2` ```python inspect_fastmcp_v2(mcp: FastMCP[Any]) -> FastMCPInfo @@ -26,10 +26,10 @@ Extract information from a FastMCP v2.x instance. - FastMCPInfo dataclass containing the extracted information -### `inspect_fastmcp_v1` +### `inspect_fastmcp_v1` ```python -inspect_fastmcp_v1(mcp: Any) -> FastMCPInfo +inspect_fastmcp_v1(mcp: FastMCP1x) -> FastMCPInfo ``` @@ -42,10 +42,10 @@ Extract information from a FastMCP v1.x instance using a Client. - FastMCPInfo dataclass containing the extracted information -### `inspect_fastmcp` +### `inspect_fastmcp` ```python -inspect_fastmcp(mcp: FastMCP[Any] | Any) -> FastMCPInfo +inspect_fastmcp(mcp: FastMCP[Any] | FastMCP1x) -> FastMCPInfo ``` @@ -63,31 +63,31 @@ and uses the appropriate extraction method. ## Classes -### `ToolInfo` +### `ToolInfo` Information about a tool. -### `PromptInfo` +### `PromptInfo` Information about a prompt. -### `ResourceInfo` +### `ResourceInfo` Information about a resource. -### `TemplateInfo` +### `TemplateInfo` Information about a resource template. -### `FastMCPInfo` +### `FastMCPInfo` Information extracted from a FastMCP instance. diff --git a/docs/python-sdk/fastmcp-utilities-openapi.mdx b/docs/python-sdk/fastmcp-utilities-openapi.mdx index a9c7ffa37..745f6fd18 100644 --- a/docs/python-sdk/fastmcp-utilities-openapi.mdx +++ b/docs/python-sdk/fastmcp-utilities-openapi.mdx @@ -25,7 +25,7 @@ Format an array parameter according to OpenAPI specifications. - String (comma-separated) or list (for query params with explode=True) -### `format_deep_object_parameter` +### `format_deep_object_parameter` ```python format_deep_object_parameter(param_value: dict, parameter_name: str) -> dict[str, str] @@ -47,7 +47,7 @@ For example: `{"id": "123", "type": "user"}` becomes `param[id]=123¶m[type]= - Dictionary with bracketed parameter names as keys -### `parse_openapi_to_http_routes` +### `parse_openapi_to_http_routes` ```python parse_openapi_to_http_routes(openapi_dict: dict[str, Any]) -> list[HTTPRoute] @@ -60,7 +60,7 @@ using the openapi-pydantic library. Supports both OpenAPI 3.0.x and 3.1.x versions. -### `clean_schema_for_display` +### `clean_schema_for_display` ```python clean_schema_for_display(schema: JsonSchema | None) -> JsonSchema | None @@ -70,7 +70,7 @@ clean_schema_for_display(schema: JsonSchema | None) -> JsonSchema | None Clean up a schema dictionary for display by removing internal/complex fields. -### `generate_example_from_schema` +### `generate_example_from_schema` ```python generate_example_from_schema(schema: JsonSchema | None) -> Any @@ -81,7 +81,7 @@ Generate a simple example value from a JSON schema dictionary. Very basic implementation focusing on types. -### `format_json_for_description` +### `format_json_for_description` ```python format_json_for_description(data: Any, indent: int = 2) -> str @@ -91,7 +91,7 @@ format_json_for_description(data: Any, indent: int = 2) -> str Formats Python data as a JSON string block for markdown. -### `format_description_with_responses` +### `format_description_with_responses` ```python format_description_with_responses(base_description: str, responses: dict[str, Any], parameters: list[ParameterInfo] | None = None, request_body: RequestBodyInfo | None = None) -> str @@ -114,7 +114,7 @@ including its description, whether it is required, and its content schema. - and the request body. -### `extract_output_schema_from_responses` +### `extract_output_schema_from_responses` ```python extract_output_schema_from_responses(responses: dict[str, ResponseInfo], schema_definitions: dict[str, Any] | None = None, openapi_version: str | None = None) -> dict[str, Any] | None @@ -138,31 +138,31 @@ object type, it wraps it to comply with MCP requirements. ## Classes -### `ParameterInfo` +### `ParameterInfo` Represents a single parameter for an HTTP operation in our IR. -### `RequestBodyInfo` +### `RequestBodyInfo` Represents the request body for an HTTP operation in our IR. -### `ResponseInfo` +### `ResponseInfo` Represents response information in our IR. -### `HTTPRoute` +### `HTTPRoute` Intermediate Representation for a single OpenAPI operation. -### `OpenAPIParser` +### `OpenAPIParser` Unified parser for OpenAPI schemas with generic type parameters to handle both 3.0 and 3.1. @@ -170,7 +170,7 @@ Unified parser for OpenAPI schemas with generic type parameters to handle both 3 **Methods:** -#### `parse` +#### `parse` ```python parse(self) -> list[HTTPRoute] diff --git a/docs/python-sdk/fastmcp-utilities-types.mdx b/docs/python-sdk/fastmcp-utilities-types.mdx index 52044dd68..adb5df0c2 100644 --- a/docs/python-sdk/fastmcp-utilities-types.mdx +++ b/docs/python-sdk/fastmcp-utilities-types.mdx @@ -23,7 +23,7 @@ However, this isn't feasible for user-generated functions. Instead, we use a cache to minimize the cost of creating them as much as possible. -### `issubclass_safe` +### `issubclass_safe` ```python issubclass_safe(cls: type, base: type) -> bool @@ -33,7 +33,7 @@ issubclass_safe(cls: type, base: type) -> bool Check if cls is a subclass of base, even if cls is a type variable. -### `is_class_member_of_type` +### `is_class_member_of_type` ```python is_class_member_of_type(cls: type, base: type) -> bool @@ -46,7 +46,7 @@ Base can be a type, a UnionType, or an Annotated type. Generic types are not considered members (e.g. T is not a member of list\[T]). -### `find_kwarg_by_type` +### `find_kwarg_by_type` ```python find_kwarg_by_type(fn: Callable, kwarg_type: type) -> str | None @@ -58,7 +58,7 @@ Find the name of the kwarg that is of type kwarg_type. Includes union types that contain the kwarg_type, as well as Annotated types. -### `replace_type` +### `replace_type` ```python replace_type(type_, type_map: dict[type, type]) @@ -93,7 +93,7 @@ list[list[str]] Base model for FastMCP models. -### `Image` +### `Image` Helper class for returning images from tools. @@ -101,7 +101,7 @@ Helper class for returning images from tools. **Methods:** -#### `to_image_content` +#### `to_image_content` ```python to_image_content(self, mime_type: str | None = None, annotations: Annotations | None = None) -> mcp.types.ImageContent @@ -110,7 +110,7 @@ to_image_content(self, mime_type: str | None = None, annotations: Annotations | Convert to MCP ImageContent. -### `Audio` +### `Audio` Helper class for returning audio from tools. @@ -118,13 +118,13 @@ Helper class for returning audio from tools. **Methods:** -#### `to_audio_content` +#### `to_audio_content` ```python to_audio_content(self, mime_type: str | None = None, annotations: Annotations | None = None) -> mcp.types.AudioContent ``` -### `File` +### `File` Helper class for returning audio from tools. @@ -132,7 +132,7 @@ Helper class for returning audio from tools. **Methods:** -#### `to_resource_content` +#### `to_resource_content` ```python to_resource_content(self, mime_type: str | None = None, annotations: Annotations | None = None) -> mcp.types.EmbeddedResource diff --git a/justfile b/justfile index 1cf298d05..cfb9f1a3e 100644 --- a/justfile +++ b/justfile @@ -17,7 +17,6 @@ docs: # Generate API reference documentation for all modules api-ref-all: uvx --with-editable . --refresh-package mdxify mdxify@latest --all --root-module fastmcp --anchor-name "Python SDK" --exclude fastmcp.contrib - # Generate API reference for specific modules (e.g., just api-ref prefect.flows prefect.tasks) api-ref *MODULES: uvx --with-editable . --refresh-package mdxify mdxify@latest {{MODULES}} --root-module fastmcp --anchor-name "Python SDK" diff --git a/src/fastmcp/server/auth/providers/jwt.py b/src/fastmcp/server/auth/providers/jwt.py index 0da7cdac1..d4968b76f 100644 --- a/src/fastmcp/server/auth/providers/jwt.py +++ b/src/fastmcp/server/auth/providers/jwt.py @@ -107,8 +107,6 @@ class RSAKeyPair: additional_claims: Any additional claims to include kid: Key ID to include in header """ - import time - # Create header header = {"alg": "RS256"} if kid: