From 9529fadd15f22dcd1329b07e11aee4fda0e10843 Mon Sep 17 00:00:00 2001 From: "marvin-context-protocol[bot]" <225465937+marvin-context-protocol[bot]@users.noreply.github.com> Date: Sun, 19 Oct 2025 20:33:47 -0400 Subject: [PATCH] chore: Update SDK documentation (#2141) Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com> --- docs/python-sdk/fastmcp-client-auth-oauth.mdx | 24 ++++---- .../fastmcp-client-oauth_callback.mdx | 13 ++++- docs/python-sdk/fastmcp-server-context.mdx | 56 +++++++++---------- ...stmcp-server-middleware-error_handling.mdx | 10 ++-- docs/python-sdk/fastmcp-utilities-tests.mdx | 29 ++++++++-- 5 files changed, 80 insertions(+), 52 deletions(-) diff --git a/docs/python-sdk/fastmcp-client-auth-oauth.mdx b/docs/python-sdk/fastmcp-client-auth-oauth.mdx index 7574d7a29..cb1f6ba77 100644 --- a/docs/python-sdk/fastmcp-client-auth-oauth.mdx +++ b/docs/python-sdk/fastmcp-client-auth-oauth.mdx @@ -7,7 +7,7 @@ sidebarTitle: oauth ## Functions -### `check_if_auth_required` +### `check_if_auth_required` ```python check_if_auth_required(mcp_url: str, httpx_kwargs: dict[str, Any] | None = None) -> bool @@ -22,47 +22,47 @@ Check if the MCP endpoint requires authentication by making a test request. ## Classes -### `ClientNotFoundError` +### `ClientNotFoundError` Raised when OAuth client credentials are not found on the server. -### `TokenStorageAdapter` +### `TokenStorageAdapter` **Methods:** -#### `clear` +#### `clear` ```python clear(self) -> None ``` -#### `get_tokens` +#### `get_tokens` ```python get_tokens(self) -> OAuthToken | None ``` -#### `set_tokens` +#### `set_tokens` ```python set_tokens(self, tokens: OAuthToken) -> None ``` -#### `get_client_info` +#### `get_client_info` ```python get_client_info(self) -> OAuthClientInformationFull | None ``` -#### `set_client_info` +#### `set_client_info` ```python set_client_info(self, client_info: OAuthClientInformationFull) -> None ``` -### `OAuth` +### `OAuth` OAuth client provider for MCP servers with browser-based authentication. @@ -73,7 +73,7 @@ a browser for user authorization and running a local callback server. **Methods:** -#### `redirect_handler` +#### `redirect_handler` ```python redirect_handler(self, authorization_url: str) -> None @@ -82,7 +82,7 @@ redirect_handler(self, authorization_url: str) -> None Open browser for authorization, with pre-flight check for invalid client. -#### `callback_handler` +#### `callback_handler` ```python callback_handler(self) -> tuple[str, str | None] @@ -91,7 +91,7 @@ callback_handler(self) -> tuple[str, str | None] Handle OAuth callback and return (auth_code, state). -#### `async_auth_flow` +#### `async_auth_flow` ```python async_auth_flow(self, request: httpx.Request) -> AsyncGenerator[httpx.Request, httpx.Response] diff --git a/docs/python-sdk/fastmcp-client-oauth_callback.mdx b/docs/python-sdk/fastmcp-client-oauth_callback.mdx index 87e667b76..cc8097559 100644 --- a/docs/python-sdk/fastmcp-client-oauth_callback.mdx +++ b/docs/python-sdk/fastmcp-client-oauth_callback.mdx @@ -25,10 +25,10 @@ create_callback_html(message: str, is_success: bool = True, title: str = 'FastMC Create a styled HTML response for OAuth callbacks. -### `create_oauth_callback_server` +### `create_oauth_callback_server` ```python -create_oauth_callback_server(port: int, callback_path: str = '/callback', server_url: str | None = None, response_future: asyncio.Future | None = None) -> Server +create_oauth_callback_server(port: int, callback_path: str = '/callback', server_url: str | None = None, result_container: OAuthCallbackResult | None = None, result_ready: anyio.Event | None = None) -> Server ``` @@ -38,7 +38,8 @@ Create an OAuth callback server. - `port`: The port to run the server on - `callback_path`: The path to listen for OAuth redirects on - `server_url`: Optional server URL to display in success messages -- `response_future`: Optional future to resolve when OAuth callback is received +- `result_container`: Optional container to store callback results +- `result_ready`: Optional event to signal when callback is received **Returns:** - Configured uvicorn Server instance (not yet running) @@ -61,3 +62,9 @@ from_dict(cls, data: dict[str, str]) -> CallbackResponse ```python to_dict(self) -> dict[str, str] ``` + +### `OAuthCallbackResult` + + +Container for OAuth callback results, used with anyio.Event for async coordination. + diff --git a/docs/python-sdk/fastmcp-server-context.mdx b/docs/python-sdk/fastmcp-server-context.mdx index 13b6e18ca..f5826ace0 100644 --- a/docs/python-sdk/fastmcp-server-context.mdx +++ b/docs/python-sdk/fastmcp-server-context.mdx @@ -7,7 +7,7 @@ sidebarTitle: context ## Functions -### `set_context` +### `set_context` ```python set_context(context: Context) -> Generator[Context, None, None] @@ -15,7 +15,7 @@ set_context(context: Context) -> Generator[Context, None, None] ## Classes -### `LogData` +### `LogData` Data object for passing log arguments to client-side handlers. @@ -24,7 +24,7 @@ This provides an interface to match the Python standard library logging, for compatibility with structured logging. -### `Context` +### `Context` Context object providing access to MCP capabilities. @@ -72,7 +72,7 @@ The context is optional - tools that don't need it can omit the parameter. **Methods:** -#### `fastmcp` +#### `fastmcp` ```python fastmcp(self) -> FastMCP @@ -81,7 +81,7 @@ fastmcp(self) -> FastMCP Get the FastMCP instance. -#### `request_context` +#### `request_context` ```python request_context(self) -> RequestContext[ServerSession, Any, Request] @@ -92,7 +92,7 @@ Access to the underlying request context. If called outside of a request context, this will raise a ValueError. -#### `report_progress` +#### `report_progress` ```python report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None @@ -105,7 +105,7 @@ Report progress for the current operation. - `total`: Optional total value e.g. 100 -#### `read_resource` +#### `read_resource` ```python read_resource(self, uri: str | AnyUrl) -> list[ReadResourceContents] @@ -120,7 +120,7 @@ Read a resource by URI. - The resource content as either text or bytes -#### `log` +#### `log` ```python log(self, message: str, level: LoggingLevel | None = None, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -138,7 +138,7 @@ Messages sent to Clients are also logged to the `fastmcp.server.context.to_clien - `extra`: Optional mapping for additional arguments -#### `client_id` +#### `client_id` ```python client_id(self) -> str | None @@ -147,7 +147,7 @@ client_id(self) -> str | None Get the client ID if available. -#### `request_id` +#### `request_id` ```python request_id(self) -> str @@ -156,7 +156,7 @@ request_id(self) -> str Get the unique ID for this request. -#### `session_id` +#### `session_id` ```python session_id(self) -> str @@ -173,7 +173,7 @@ the same client session. - for other transports. -#### `session` +#### `session` ```python session(self) -> ServerSession @@ -182,7 +182,7 @@ session(self) -> ServerSession Access to the underlying session for advanced usage. -#### `debug` +#### `debug` ```python debug(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -193,7 +193,7 @@ Send a `DEBUG`-level message to the connected MCP Client. Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`. -#### `info` +#### `info` ```python info(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -204,7 +204,7 @@ Send a `INFO`-level message to the connected MCP Client. Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`. -#### `warning` +#### `warning` ```python warning(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -215,7 +215,7 @@ Send a `WARNING`-level message to the connected MCP Client. Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`. -#### `error` +#### `error` ```python error(self, message: str, logger_name: str | None = None, extra: Mapping[str, Any] | None = None) -> None @@ -226,7 +226,7 @@ Send a `ERROR`-level message to the connected MCP Client. Messages sent to Clients are also logged to the `fastmcp.server.context.to_client` logger with a level of `DEBUG`. -#### `list_roots` +#### `list_roots` ```python list_roots(self) -> list[Root] @@ -235,7 +235,7 @@ list_roots(self) -> list[Root] List the roots available to the server, as indicated by the client. -#### `send_tool_list_changed` +#### `send_tool_list_changed` ```python send_tool_list_changed(self) -> None @@ -244,7 +244,7 @@ send_tool_list_changed(self) -> None Send a tool list changed notification to the client. -#### `send_resource_list_changed` +#### `send_resource_list_changed` ```python send_resource_list_changed(self) -> None @@ -253,7 +253,7 @@ send_resource_list_changed(self) -> None Send a resource list changed notification to the client. -#### `send_prompt_list_changed` +#### `send_prompt_list_changed` ```python send_prompt_list_changed(self) -> None @@ -262,7 +262,7 @@ send_prompt_list_changed(self) -> None Send a prompt list changed notification to the client. -#### `sample` +#### `sample` ```python sample(self, messages: str | Sequence[str | SamplingMessage], system_prompt: str | None = None, include_context: IncludeContext | None = None, temperature: float | None = None, max_tokens: int | None = None, model_preferences: ModelPreferences | str | list[str] | None = None) -> TextContent | ImageContent | AudioContent @@ -275,25 +275,25 @@ completion from the client. The client must be appropriately configured, or the request will error. -#### `elicit` +#### `elicit` ```python elicit(self, message: str, response_type: None) -> AcceptedElicitation[dict[str, Any]] | DeclinedElicitation | CancelledElicitation ``` -#### `elicit` +#### `elicit` ```python elicit(self, message: str, response_type: type[T]) -> AcceptedElicitation[T] | DeclinedElicitation | CancelledElicitation ``` -#### `elicit` +#### `elicit` ```python elicit(self, message: str, response_type: list[str]) -> AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation ``` -#### `elicit` +#### `elicit` ```python elicit(self, message: str, response_type: type[T] | list[str] | None = None) -> AcceptedElicitation[T] | AcceptedElicitation[dict[str, Any]] | AcceptedElicitation[str] | DeclinedElicitation | CancelledElicitation @@ -322,7 +322,7 @@ type or dataclass or BaseModel. If it is a primitive type, an object schema with a single "value" field will be generated. -#### `get_http_request` +#### `get_http_request` ```python get_http_request(self) -> Request @@ -331,7 +331,7 @@ get_http_request(self) -> Request Get the active starlette request. -#### `set_state` +#### `set_state` ```python set_state(self, key: str, value: Any) -> None @@ -340,7 +340,7 @@ set_state(self, key: str, value: Any) -> None Set a value in the context state. -#### `get_state` +#### `get_state` ```python get_state(self, key: str) -> Any diff --git a/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx b/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx index f6204b815..5339b4a8c 100644 --- a/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx +++ b/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx @@ -10,7 +10,7 @@ Error handling middleware for consistent error responses and tracking. ## Classes -### `ErrorHandlingMiddleware` +### `ErrorHandlingMiddleware` Middleware that provides consistent error handling and logging. @@ -21,7 +21,7 @@ proper MCP error responses. Also tracks error patterns for monitoring. **Methods:** -#### `on_message` +#### `on_message` ```python on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any @@ -30,7 +30,7 @@ on_message(self, context: MiddlewareContext, call_next: CallNext) -> Any Handle errors for all messages. -#### `get_error_stats` +#### `get_error_stats` ```python get_error_stats(self) -> dict[str, int] @@ -39,7 +39,7 @@ get_error_stats(self) -> dict[str, int] Get error statistics for monitoring. -### `RetryMiddleware` +### `RetryMiddleware` Middleware that implements automatic retry logic for failed requests. @@ -50,7 +50,7 @@ backoff to avoid overwhelming the server or external dependencies. **Methods:** -#### `on_request` +#### `on_request` ```python on_request(self, context: MiddlewareContext, call_next: CallNext) -> Any diff --git a/docs/python-sdk/fastmcp-utilities-tests.mdx b/docs/python-sdk/fastmcp-utilities-tests.mdx index dbe05bde5..37784a90d 100644 --- a/docs/python-sdk/fastmcp-utilities-tests.mdx +++ b/docs/python-sdk/fastmcp-utilities-tests.mdx @@ -43,7 +43,28 @@ not pickleable, so we need a function that creates and runs one. - The server URL. -### `caplog_for_fastmcp` +### `run_server_async` + +```python +run_server_async(server: FastMCP, port: int | None = None, transport: Literal['http', 'streamable-http', 'sse'] = 'http', path: str = '/mcp', host: str = '127.0.0.1') -> AsyncGenerator[str, None] +``` + + +Start a FastMCP server as an asyncio task for in-process async testing. + +This is the recommended way to test FastMCP servers. It runs the server +as an async task in the same process, eliminating subprocess coordination, +sleeps, and cleanup issues. + +**Args:** +- `server`: FastMCP server instance +- `port`: Port to bind to (default\: find available port) +- `transport`: Transport type ("http", "streamable-http", or "sse") +- `path`: URL path for the server (default\: "/mcp") +- `host`: Host to bind to (default\: "127.0.0.1") + + +### `caplog_for_fastmcp` ```python caplog_for_fastmcp(caplog) @@ -55,7 +76,7 @@ Context manager to capture logs from FastMCP loggers even when propagation is di ## Classes -### `HeadlessOAuth` +### `HeadlessOAuth` OAuth provider that bypasses browser interaction for testing. @@ -66,7 +87,7 @@ instead of opening a browser and running a callback server. Useful for automated **Methods:** -#### `redirect_handler` +#### `redirect_handler` ```python redirect_handler(self, authorization_url: str) -> None @@ -75,7 +96,7 @@ redirect_handler(self, authorization_url: str) -> None Make HTTP request to authorization URL and store response for callback handler. -#### `callback_handler` +#### `callback_handler` ```python callback_handler(self) -> tuple[str, str | None]