Stdio Bridge#
Use the bridge when an MCP client only supports local stdio servers and your Litestar app exposes MCP over Streamable HTTP.
Run the bridge through Litestar's app-bound CLI:
litestar --app my_app:app mcp bridge
The command loads the same app object as the rest of the Litestar CLI, finds
the installed LitestarMCP plugin, and proxies local
stdio JSON-RPC to that app's MCP endpoint.
The bridge is a thin transport adapter:
it reads JSON-RPC messages from local stdin;
adds MCP 2026-07-28 request metadata and standard/custom routing headers;
forwards independent messages concurrently to the target
POSTendpoint;multiplexes
subscriptions/listenPOST-response streams;writes remote JSON-RPC messages back to local stdout;
maps stdio cancellation to closure of the matching HTTP response stream;
lazily caches tool schemas used for
Mcp-Param-*headers.
It does not depend on the official mcp Python SDK. The base package
already depends on httpx; installing the bridge extra adds only
httpx-sse.
Install#
Install the bridge extra in the same environment as your Litestar app:
pip install "litestar-mcp[bridge]"
or:
uv add "litestar-mcp[bridge]"
Default Endpoint#
By default, litestar --app my_app:app mcp bridge targets:
http://127.0.0.1:8000{MCPConfig.base_path}
If LITESTAR_HOST or LITESTAR_PORT are set, the command uses those
values for the origin. The path always comes from the loaded app's
LitestarMCP plugin configuration:
docs/examples/snippets/bridge_custom_base_path.py#app = Litestar(
plugins=[LitestarMCP(MCPConfig(base_path="/api/mcp"))],
)
With that app, the default bridge endpoint is
http://127.0.0.1:8000/api/mcp.
Use --base-url to change the origin while preserving the configured MCP
base path:
litestar --app my_app:app mcp bridge \
--base-url https://app.example.com
Use --endpoint only when you need a full URL override:
litestar --app my_app:app mcp bridge \
--endpoint https://app.example.com/custom/mcp
--endpoint wins over --base-url and MCPConfig.base_path.
Client Configuration#
For stdio-only clients, configure the Litestar CLI command as the MCP server.
Run it from an environment where your application package and
litestar-mcp[bridge] are installed:
{
"mcpServers": {
"my-litestar-app": {
"command": "litestar",
"args": [
"--app",
"my_app:app",
"mcp",
"bridge",
"--base-url",
"http://127.0.0.1:8000"
]
}
}
}
If the client supports Streamable HTTP directly, prefer the app's HTTP MCP URL instead of the bridge.
Headers and Bearer Tokens#
The bridge does not infer credentials from application auth metadata. Pass headers and token sources explicitly.
Static headers can be passed more than once:
litestar --app my_app:app mcp bridge \
--header "X-Tenant: acme" \
--header "X-Trace-Source: mcp-client"
For bearer tokens stored in an environment variable:
litestar --app my_app:app mcp bridge \
--bearer-env MCP_TOKEN
For platforms that expect the token in a non-Authorization header,
override the header name and prefix:
litestar --app my_app:app mcp bridge \
--bearer-env IAP_JWT \
--header-name X-Goog-IAP-JWT-Assertion \
--token-prefix ""
--bearer-cmd runs a local command before each HTTP request and uses
stdout as the token. Prefer --bearer-env on Windows when possible:
command strings are split with POSIX-style shell parsing. For complex
Windows commands, wrap token lookup in a small script and pass that script
path as --bearer-cmd.
Timeouts#
--timeout bounds ordinary HTTP connection setup, writes, and pool
acquisition. Long-lived SSE streams use --sse-read-timeout instead;
the default allows 300 seconds between server events. Set
--sse-read-timeout 0 to disable quiet-period timeouts for idle streams.
Memory Bounds#
The bridge does not retain message history. It reads stdin one newline-delimited JSON-RPC message at a time and streams server responses as JSON or SSE events.
To prevent a malformed client from growing memory indefinitely by sending a message without a newline, the bridge caps each stdin JSON-RPC message at 16 MiB by default:
litestar --app my_app:app mcp bridge \
--max-message-size 16777216
Set --max-message-size -1 to disable this per-message cap.
Identity Boundary#
The target Litestar app remains the authorization boundary. The bridge can attach headers and bearer tokens, but it cannot prove domain ownership or enforce object-level permissions locally. Put those checks in ordinary Litestar guards, authentication middleware, or dependencies as described in Security.
Windows Support#
On Windows, the bridge uses inherited stdin/stdout pipes. For token lookup,
prefer --bearer-env or wrap platform-specific logic in a small script and
pass it with --bearer-cmd.
Troubleshooting#
MissingDependencyErrorat startupInstall
litestar-mcp[bridge]sohttpx-sseis available.Unexpected Streamable HTTP content typeThe server returned neither JSON nor
text/event-stream. Check the endpoint URL and make sure the target app is serving the MCP Streamable HTTP route.401 UnauthorizedThe bridge retries once with a fresh token. If the second request still fails, check the bearer source and target auth middleware.