Choosing a transport
tai serve takes --transport. HTTP is the default; the MCP endpoint is then
served under /mcp.
- HTTP — the default network transport, for MCP clients over the network.
- SSE — a streaming HTTP transport.
- STDIO — for a client that launches the server as a subprocess and talks over its standard streams.
The UDS path
For same-machine communication,--uds <path> binds the server to a
Unix-domain socket instead of a host and port — a fast local path that avoids the
network stack. tai42-kit supplies the client-side UDS transports and a selector,
get_mcp_transport, that picks the right transport for a target: a UDS transport
for a socket, or a plain config for a networked server. A mounted external MCP
server can be reached over any of these — the manifest’s mcp entry sets url,
uds, or command per server.
Statefulness and workers
The HTTP transports are stateful per process: each MCP session is pinned to the worker that created it. Under multiple workers a session opened on one worker breaks when another worker handles its next request, sotai serve refuses
--workers greater than one on any stateful transport (http, streamable-http,
sse) with an error that names the fix.
The fix is --stateless-http, which turns on the underlying stateless HTTP mode and
lifts the refusal — for the HTTP transports only. It has no meaning for sse or
stdio (SSE has no stateless mode and STDIO has no HTTP sessions), so combining it
with either is itself refused.
tai serve also refuses --workers greater than one without the
worker bus: sibling workers would serve stale config after a
reload with no channel to converge on. So a multi-worker HTTP server needs both
--stateless-http and TAI_BUS_REDIS_URL.
Embedding the runtime in your own process applies the session-pinning rule the same
way: pass
create_app(manifest_path="manifest.yml", stateless_http=True) to run
several workers. The bus, though, is a documented limitation when you embed — the
workers-count rule lives in the tai serve CLI, and in-process code cannot count
sibling processes, so a create_app(..., stateless_http=True) factory run under an
external --workers passes no rule yet runs busless-stale. Set TAI_BUS_REDIS_URL
yourself in any multi-process embed. See
Multi-worker and fleet sync.
Before binding a UDS path,
tai serve cleans up a stale socket left by an unclean
shutdown, but refuses to unlink a socket that answers a connect probe (a live
server) or a path that is not a socket. This keeps one command from clobbering
another server’s socket.tai serve options.
