Skip to main content

stdio

The agent launches the MCP server as a subprocess and exchanges MCP JSON-RPC messages over stdin/stdout. No network, no authentication (the agent already owns the process), one agent per process. This is the default transport: voicegw mcp with no flags uses it. Use it for local development with Claude Code, Cursor, or Codex.

HTTP/SSE

Runs a Starlette/uvicorn server. Agents open a long-lived GET /sse connection for the server-to-client stream and POST /messages/ to send tool calls. Multiple agents can connect at once; the server runs until you stop it. Use it for a shared team gateway, or a remote agent that can’t launch a local subprocess.
voicegw serve (the main API, 0.0.0.0:8080 by default) mounts this same MCP surface too, at /mcp/sse and /mcp/messages/, gated by the same VOICEGW_MCP_TOKEN. If voicegw serve is already running, you don’t need a second voicegw mcp process for HTTP/SSE access.

Authentication

Controlled by VOICEGW_MCP_TOKEN. Unset (the default): every request is accepted. Set: every request needs a matching Authorization: Bearer <token> header, checked with hmac.compare_digest for constant-time comparison. A missing or malformed header gets 401 with body Missing bearer token; a wrong token gets 401 Invalid token. Only the Bearer scheme is accepted. stdio ignores this variable entirely: there’s no network boundary to protect.
Set VOICEGW_MCP_TOKEN and put the HTTP transport behind a reverse proxy with TLS before exposing it beyond localhost. Leaving it unset is appropriate for local development, an internal network already behind a VPN, or when a reverse proxy handles auth upstream.
Example proxy config (buffering off, so SSE actually streams):

Comparison

Next steps