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 tokenreviewwith 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.