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 POST endpoint;

  • multiplexes subscriptions/listen POST-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#

MissingDependencyError at startup

Install litestar-mcp[bridge] so httpx-sse is available.

Unexpected Streamable HTTP content type

The 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 Unauthorized

The bridge retries once with a fresh token. If the second request still fails, check the bearer source and target auth middleware.