chore: Update SDK documentation (#4569)

Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
This commit is contained in:
marvin-context-protocol[bot] 2026-07-20 18:44:54 -04:00 committed by GitHub
commit 4ec2757b6d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 261 additions and 34 deletions

View file

@ -42,7 +42,7 @@ infer_transport_type_from_url(url: str | AnyUrl) -> Literal['http', 'sse']
Infer the appropriate transport type from the given URL.
### `update_config_file` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L362" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `update_config_file` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L373" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
update_config_file(file_path: Path, server_name: str, server_config: CanonicalMCPServerTypes) -> None
@ -57,7 +57,7 @@ worry about transforming server objects here.
## Classes
### `StdioMCPServer` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L168" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `StdioMCPServer` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L179" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
MCP server configuration for stdio transport.
@ -67,19 +67,19 @@ This is the canonical configuration format for MCP servers using stdio transport
**Methods:**
#### `to_transport` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L201" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `to_transport` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L212" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
to_transport(self) -> StdioTransport
```
### `TransformingStdioMCPServer` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L213" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `TransformingStdioMCPServer` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L224" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
A Stdio server with tool transforms.
### `RemoteMCPServer` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L217" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `RemoteMCPServer` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L228" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
MCP server configuration for HTTP/SSE transport.
@ -89,19 +89,19 @@ This is the canonical configuration format for MCP servers using remote transpor
**Methods:**
#### `to_transport` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L253" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `to_transport` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L264" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
to_transport(self) -> StreamableHttpTransport | SSETransport
```
### `TransformingRemoteMCPServer` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L280" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `TransformingRemoteMCPServer` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L291" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
A Remote server with tool transforms.
### `MCPConfig` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L291" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `MCPConfig` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L302" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
A configuration object for MCP Servers that conforms to the canonical MCP configuration format
@ -113,7 +113,7 @@ For an MCPConfig that is strictly canonical, see the `CanonicalMCPConfig` class.
**Methods:**
#### `wrap_servers_at_root` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L305" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `wrap_servers_at_root` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L316" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
wrap_servers_at_root(cls, values: dict[str, Any]) -> dict[str, Any]
@ -122,7 +122,7 @@ wrap_servers_at_root(cls, values: dict[str, Any]) -> dict[str, Any]
If there's no mcpServers key but there are server configs at root, wrap them.
#### `add_server` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L318" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `add_server` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L329" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
add_server(self, name: str, server: MCPServerTypes) -> None
@ -131,7 +131,7 @@ add_server(self, name: str, server: MCPServerTypes) -> None
Add or update a server in the configuration.
#### `from_dict` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L323" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `from_dict` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L334" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
from_dict(cls, config: dict[str, Any]) -> Self
@ -140,7 +140,7 @@ from_dict(cls, config: dict[str, Any]) -> Self
Parse MCP configuration from dictionary format.
#### `to_dict` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L327" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `to_dict` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L338" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
to_dict(self) -> dict[str, Any]
@ -149,7 +149,7 @@ to_dict(self) -> dict[str, Any]
Convert MCPConfig to dictionary format, preserving all fields.
#### `write_to_file` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L331" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `write_to_file` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L342" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
write_to_file(self, file_path: Path) -> None
@ -158,7 +158,7 @@ write_to_file(self, file_path: Path) -> None
Write configuration to JSON file.
#### `from_file` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L337" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `from_file` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L348" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
from_file(cls, file_path: Path) -> Self
@ -167,7 +167,7 @@ from_file(cls, file_path: Path) -> Self
Load configuration from JSON file.
### `CanonicalMCPConfig` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L347" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `CanonicalMCPConfig` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L358" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Canonical MCP configuration format.
@ -178,7 +178,7 @@ The format is designed to be client-agnostic and extensible for future use cases
**Methods:**
#### `add_server` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L357" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `add_server` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/mcp_config.py#L368" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
add_server(self, name: str, server: CanonicalMCPServerTypes) -> None

View file

@ -0,0 +1,92 @@
---
title: asgi_transport
sidebarTitle: asgi_transport
---
# `fastmcp.utilities.asgi_transport`
An in-process, full-duplex HTTP transport for driving ASGI applications from httpx.
Ported from the MCP Python SDK's test suite (`tests/interaction/transports/_bridge.py`,
MIT licensed).
`httpx2.ASGITransport` runs the application to completion and only then hands the buffered
response to the caller, so a server that streams its response — as the streamable HTTP
transport's SSE responses do — can never converse with the client mid-request: a
server-initiated request nested inside a still-open call deadlocks.
`StreamingASGITransport` removes that limitation by running the application as a background
task and forwarding every `http.response.body` chunk to the client the moment it is sent.
Everything happens on the one event loop: no sockets, no threads, no sleeps.
The behavioural contract:
- The request body is buffered before the application is invoked (MCP requests are small
JSON documents); the response streams chunk by chunk.
- Closing the response — or the whole client — delivers `http.disconnect` to the
application, exactly as a real server sees when its peer goes away.
- An exception the application raises before sending `http.response.start` fails the
originating request with that same exception. After the response has started, a failure
is visible to the client only through the response itself (status code, truncated body) —
the same signal a real server over a real socket would give.
The transport owns an anyio task group for the application tasks; it is opened and closed by
`httpx2.AsyncClient`'s own context manager, so the client must be used as a context manager.
Closing the transport cancels every running application task by default; set
`cancel_on_close=False` to wait for the application's own disconnect handling instead, which
is what the legacy SSE transport relies on for resource cleanup.
## Functions
### `run_asgi_lifespan` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/asgi_transport.py#L224" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
run_asgi_lifespan(app: ASGIApp) -> AsyncIterator[None]
```
Run an ASGI application's lifespan, driving the protocol as a real server does.
The application's lifespan runs inside a dedicated task for the whole duration of
the context. This matters because a lifespan typically owns cancel scopes and task
groups — anyio requires those to be exited by the task that entered them, which
rules out entering the lifespan on one task and leaving it on another (as a pytest
fixture's setup and teardown phases may do).
**Args:**
- `app`: The ASGI application whose lifespan should run.
**Raises:**
- `RuntimeError`: If the application reports `lifespan.startup.failed`, or reports
`lifespan.shutdown.failed` (or crashes during shutdown) while the context
body itself completed successfully. A failure inside the body takes
precedence and propagates unchanged.
## Classes
### `StreamingASGITransport` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/asgi_transport.py#L71" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Drive an ASGI application in-process, streaming each response as it is produced.
This is an `httpx2` transport, so it plugs into anything that accepts an
`httpx2.AsyncClient` — including FastMCP's client transports via their
`httpx_client_factory` argument.
**Args:**
- `app`: The ASGI application to drive (e.g. `FastMCP.http_app()`).
- `cancel_on_close`: When True (the default), closing the transport cancels every
application task still running, so harness teardown can never hang. Set to
False to wait for the application's own disconnect handling to complete
instead, which the legacy SSE server transport relies on for cleanup.
**Methods:**
#### `handle_async_request` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/asgi_transport.py#L128" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
handle_async_request(self, request: httpx2.Request) -> httpx2.Response
```

View file

@ -37,10 +37,10 @@ Uses anyio.to_thread.run_sync which properly propagates contextvars,
making this safe for functions that depend on context (like dependency injection).
### `gather` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/async_utils.py#L51" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `gather` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/async_utils.py#L53" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
gather(*awaitables: Awaitable[T]) -> list[T] | list[T | BaseException]
gather(awaitables: Iterable[Awaitable[T]]) -> list[T] | list[T | BaseException]
```
@ -48,8 +48,25 @@ Run awaitables concurrently and return results in order.
Uses anyio TaskGroup for structured concurrency.
``awaitables`` is consumed lazily, one item at a time, right before each
is handed to the task group. Callers with a dynamic number of awaitables
should pass a generator expression (e.g. ``gather(f(x) for x in xs)``)
rather than a list or list comprehension: a list comprehension calls
every ``f(x)`` up front, creating a batch of coroutine objects before
this function even starts, whereas a generator expression creates each
coroutine only as this function's own scheduling loop asks for it. That
matters because coroutine creation and scheduling can be interrupted
between any two bytecode instructions by a synchronous signal handler
(for example pytest-timeout's SIGALRM-based per-test timeout). If that
happens while a whole batch of coroutines is sitting unscheduled, they
are silently abandoned and eventually trigger a "coroutine was never
awaited" warning attributed to whatever unrelated code happens to be
running when the garbage collector gets to them. Lazy consumption keeps
the window in which a created-but-unscheduled coroutine can exist as
small as possible.
**Args:**
- `*awaitables`: Awaitables to run concurrently
- `awaitables`: Iterable of awaitables to run concurrently.
- `return_exceptions`: If True, exceptions are returned in results.
If False, first exception cancels all and raises.

View file

@ -42,7 +42,7 @@ Extract information from a FastMCP v1.x instance using a Client.
- FastMCPInfo dataclass containing the extracted information
### `inspect_fastmcp` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L410" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `inspect_fastmcp` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L411" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
inspect_fastmcp(mcp: FastMCP[Any] | SDKServer) -> FastMCPInfo
@ -61,7 +61,7 @@ and uses the appropriate extraction method.
- FastMCPInfo dataclass containing the extracted information
### `format_fastmcp_info` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L435" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `format_fastmcp_info` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L436" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
format_fastmcp_info(info: FastMCPInfo) -> bytes
@ -73,7 +73,7 @@ Format FastMCPInfo as FastMCP-specific JSON.
This includes FastMCP-specific fields like tags, enabled, annotations, etc.
### `format_mcp_info` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L464" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `format_mcp_info` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L465" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
format_mcp_info(mcp: FastMCP[Any] | SDKServer) -> bytes
@ -86,7 +86,7 @@ Uses Client to get the standard MCP protocol format with camelCase fields.
Includes version metadata at the top level.
### `format_info` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L497" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `format_info` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L500" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
format_info(mcp: FastMCP[Any] | SDKServer, format: InspectFormat | Literal['fastmcp', 'mcp'], info: FastMCPInfo | None = None) -> bytes
@ -136,7 +136,7 @@ Information about a resource template.
Information extracted from a FastMCP instance.
### `InspectFormat` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L428" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `InspectFormat` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/inspect.py#L429" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
Output format for inspect command.

View file

@ -7,7 +7,7 @@ sidebarTitle: tests
## Functions
### `temporary_settings` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L25" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `temporary_settings` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L36" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
temporary_settings(**kwargs: Any)
@ -20,7 +20,7 @@ Temporarily override FastMCP setting values.
- `**kwargs`: The settings to override, including nested settings.
### `run_server_in_process` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L76" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `run_server_in_process` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L87" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
run_server_in_process(server_fn: Callable[..., None], *args: Any, **kwargs: Any) -> Generator[str, None, None]
@ -43,18 +43,20 @@ not pickleable, so we need a function that creates and runs one.
- The server URL.
### `run_server_async` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L144" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `run_server_async` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L175" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```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.
Start a FastMCP server on a real port as an asyncio task.
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.
This runs a real uvicorn server in the current process, bound to a real TCP port,
and yields its URL. Use it when the behaviour under test is genuinely about the
network — real sockets, TLS, or a server that must be reachable by something other
than an in-process client. Otherwise prefer `asgi_client` or `asgi_server`, which
exercise the same HTTP stack without binding a port.
**Args:**
- `server`: FastMCP server instance
@ -64,9 +66,124 @@ sleeps, and cleanup issues.
- `host`: Host to bind to (default\: "127.0.0.1")
### `asgi_server` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L335" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
asgi_server(server: FastMCP, transport: Literal['http', 'streamable-http', 'sse'] = 'http', path: str | None = None, **http_app_kwargs: Any) -> AsyncGenerator[ASGIServer, None]
```
Serve a FastMCP server's HTTP app in-process, with no socket and no uvicorn.
This is the fastest way to test a FastMCP server over HTTP. The server's real
Starlette app is built with `http_app()` and its lifespan is started, then every
request is dispatched directly into the app on the current event loop. That skips
port binding, uvicorn startup and connection setup entirely, while still exercising
the full HTTP stack: middleware, authentication, session management and SSE
streaming all run exactly as they do in production.
Use this as a fixture when several tests share one server but each needs its own
client. For a single test, `asgi_client` hands you a connected client in one step.
**Args:**
- `server`: FastMCP server instance.
- `transport`: Transport type ("http", "streamable-http", or "sse").
- `path`: URL path for the server (defaults to "/mcp", or "/sse" for SSE).
- `**http_app_kwargs`: Additional arguments forwarded to `server.http_app()`.
### `asgi_client` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L409" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
asgi_client(server: FastMCP, transport: Literal['http', 'streamable-http', 'sse'] = 'http', path: str | None = None, **client_kwargs: Any) -> AsyncGenerator[Client, None]
```
Serve a FastMCP server over HTTP in-process and yield a connected `Client`.
This is the shortest path to testing a server over a real HTTP stack. The server's
Starlette app is built and started, and requests are dispatched straight into it on
the current event loop — no port, no uvicorn, no subprocess — but middleware,
authentication, session management and SSE streaming all behave as in production.
Reach for `asgi_server` instead when a fixture must serve several tests that each
build their own client, or when a test needs raw HTTP access to the app.
**Args:**
- `server`: FastMCP server instance.
- `transport`: Transport type ("http", "streamable-http", or "sse").
- `path`: URL path for the server (defaults to "/mcp", or "/sse" for SSE).
- `headers`: HTTP headers to send with every request.
- `auth`: Client authentication, as accepted by the HTTP transports.
- `**client_kwargs`: Additional arguments forwarded to `Client`.
## Classes
### `HeadlessOAuth` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L226" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
### `ASGIServer` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L256" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
A FastMCP server's real HTTP app, reachable in-process with no sockets.
Yielded by `asgi_server`. The `url` looks like an ordinary server URL and the app
behind it is the genuine article — auth middleware, session manager, SSE framing and
redirects all run — but every request is dispatched straight into the ASGI
application on the current event loop.
Because nothing is listening on the network, a plain `httpx2.AsyncClient()` cannot
reach this server. Use `client()` for a FastMCP client, `http_client()` for raw HTTP
assertions, and `transport()` when you need to build the client transport yourself.
**Methods:**
#### `http_client` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L273" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
http_client(self, headers: dict[str, str] | None = None, timeout: httpx2.Timeout | None = None, auth: httpx2.Auth | None = None, **kwargs: Any) -> httpx2.AsyncClient
```
An `httpx2.AsyncClient` bound to the in-process app, for raw HTTP assertions.
Relative URLs resolve against the server's base URL, and absolute URLs on the
same origin work too, so `client.get(f"{server.url}/health")` reads the same as
it would against a real server.
The signature matches `McpHttpClientFactory`, so this method can also be handed
to anything that takes an `httpx_client_factory`.
#### `transport` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L302" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
transport(self, **kwargs: Any) -> StreamableHttpTransport | SSETransport
```
A FastMCP client transport wired to the in-process app.
Accepts the same keyword arguments as the underlying transport (`headers`,
`auth`, ...); `httpx_client_factory` is supplied automatically.
#### `client` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L313" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
client(self, **client_kwargs: Any) -> Client
```
An unconnected FastMCP `Client` pointed at the in-process app.
`headers` and `auth` configure the underlying HTTP transport; every other
keyword argument is passed to `Client` (`timeout`, `elicitation_handler`, ...).
Use it as a context manager, exactly like any other client.
**Args:**
- `headers`: HTTP headers to send with every request.
- `auth`: Client authentication, as accepted by the HTTP transports.
- `**client_kwargs`: Additional arguments forwarded to `Client`.
### `HeadlessOAuth` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L464" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
OAuth provider that bypasses browser interaction for testing.
@ -77,7 +194,7 @@ instead of opening a browser and running a callback server. Useful for automated
**Methods:**
#### `redirect_handler` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L239" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `redirect_handler` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L477" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
redirect_handler(self, authorization_url: str) -> None
@ -86,7 +203,7 @@ redirect_handler(self, authorization_url: str) -> None
Make HTTP request to authorization URL and store response for callback handler.
#### `callback_handler` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L245" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
#### `callback_handler` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/tests.py#L483" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
```python
callback_handler(self) -> AuthorizationCodeResult