Skip to content

HTTP transport & auth

By default ray-mcp speaks MCP over stdio — your agent launches it as a subprocess (see Install). It can also serve over a streamable HTTP transport, so a remote or shared client can connect to a long-running listener. The same tool set is served over either transport; only how the client connects differs.

Enabling HTTP

Flag Env Default What it does
--transport http RAY_MCP_TRANSPORT stdio serve over streamable HTTP instead of stdio
--http-addr <host:port> RAY_MCP_HTTP_ADDR 127.0.0.1:8765 address the listener binds
--auth-mode <mode> RAY_MCP_AUTH_MODE static static (bearer token) or tokenreview (Kubernetes SA tokens)
--auth-token <token> RAY_MCP_AUTH_TOKEN (none) the accepted bearer token in static mode
ray-mcp --transport http --http-addr 127.0.0.1:8765 \
  --default-namespace ray-system

The bind/auth boot invariant

A non-loopback bind requires auth — there is no --insecure escape hatch.

ray-mcp refuses to expose an unauthenticated listener on a routable address. The rule is enforced twice: once at config load (refuse to boot) and again at the transport edge (refuse to serve), so the code that binds the socket is itself the thing that refuses to serve insecurely.

  • Loopback (127.0.0.1 / localhost) with no token → allowed. Access is gated by the OS to processes on the same host.
  • Non-loopback (0.0.0.0, a LAN/pod IP, ::) with no auth → the process refuses to boot:
refusing to boot: --http-addr "0.0.0.0:8765" binds a non-loopback address
without auth; set --auth-token (static mode) or --auth-mode tokenreview
(no --insecure escape hatch)
  • --auth-mode tokenreview with no reachable cluster → refuses to serve (it cannot validate tokens, and advertising a mode it can't enforce would be an unauthenticated bind):
refusing to serve: --auth-mode tokenreview requires a live cluster connection
to validate tokens (none available)

TLS is expected to be terminated in front of ray-mcp (an ingress or service mesh), not by the binary itself.

Auth modes

static — a shared bearer token

The server accepts exactly the token given in --auth-token. Clients send it as a standard Authorization: Bearer <token> header. In the audit log the caller is recorded as a fingerprint of the token (not the token itself).

ray-mcp --transport http --http-addr 0.0.0.0:8765 \
  --auth-mode static --auth-token "$RAY_MCP_TOKEN"

tokenreview — Kubernetes ServiceAccount tokens

The server validates each caller's bearer token against the cluster's TokenReview API, and records the resolved ServiceAccount username in the audit log. This requires a live cluster connection.

ray-mcp --transport http --http-addr 0.0.0.0:8765 --auth-mode tokenreview

v1 caveat: any valid in-cluster token is accepted

tokenreview mode validates tokens without an explicit audience, so the API server checks them against its own default audience — meaning any valid in-cluster ServiceAccount token is accepted (and audited under that SA's name), not only tokens minted for ray-mcp. The HTTP token gates reach, not privilege — the server's own ServiceAccount RBAC is the real authorization boundary — but until audience binding lands, restrict who can reach the listener with a NetworkPolicy. This mode also requires the server's ServiceAccount to hold create on tokenreviews (bind the built-in system:auth-delegator ClusterRole).

Connecting a client

The listener speaks the MCP streamable HTTP protocol at the root path. You can sanity-check it with curl by POSTing a JSON-RPC frame.

Loopback, no token (default --http-addr):

curl -sS http://127.0.0.1:8765 \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

With a bearer token (static or tokenreview mode):

curl -sS http://your-host:8765 \
  -H "Authorization: Bearer $RAY_MCP_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

A request with a missing or invalid token is rejected with 401 Unauthorized before it reaches any tool.

For MCP clients that support HTTP transports, point the client at the listener URL (http://<host>:<port>) and configure the bearer token per that client's docs.

See Configuration for the complete flag and environment-variable reference, and Safety tiers for how tool permissions are gated independently of the transport.