MCP & Claude Code
The hub exposes a Model Context Protocol endpoint at /mcp. Claude Code can list your clusters, find unhealthy Flux resources across the fleet, read events and leave review threads that show up in the Eddy UI. Everything runs as you, so the tools see only what your RBAC allows.
Full reference: docs/mcp.md in the repository.
Connect Claude Code
- Create a personal access token (PAT). In Eddy open Access tokens (press g then k). Choose the smallest scope you need:
read: the read tools, plus creating and replying to threads.operate: also reconcile, suspend and resume.
eddy_pat_…, is shown once, so copy it now. - Add the server, keeping the token in an environment variable so it stays out of your shell history:
$ export EDDY_PAT=eddy_pat_...$ claude mcp add --transport http eddy https://eddy.internal.example.com/mcp \--header "Authorization: Bearer $EDDY_PAT"
claude mcp addstores the expanded token in your Claude Code config. Add--scope userto make it available in every project. For a shared.mcp.json, write the file yourself and reference the variable, not the token:{"mcpServers": {"eddy": {"type": "http","url": "https://eddy.internal.example.com/mcp","headers": {"Authorization": "Bearer ${EDDY_PAT}"}}}}
- Verify. Run
claude mcp list(or/mcpinside Claude Code) and check thateddyis connected:$ claude mcp list
The hub address must be reachable from your machine, usually over VPN. /mcp does not go through your sign-in proxy: the token is the credential. Check claude mcp add --help if your version differs.
Tools
| Scope | Tools |
|---|---|
read | list_clusters, list_resources, list_unhealthy, get_resource, get_events, list_threads, get_thread, and get_logs when the operator enables it (mcp.allowLogs, and pods/log RBAC) |
| threads | create_thread, reply_thread, resolve_thread. They need read, or operate if the operator set auth.tokens.threadWriteScope: operate |
operate | reconcile, suspend, resume, when MCP writes are enabled (mcp.writes) |
get_resource returns a summary plus redacted YAML. Secrets and ConfigMaps are never available. Arguments and exact contracts are in docs/mcp.md and docs/api.md.
Threads
Threads are plain text or Markdown (at most 8 KiB) on a resource or a cluster. Those written over MCP carry a via mcp badge in the UI, so teammates can see what an assistant wrote, and reply or resolve them. See Using Eddy.
Example
With a read token, ask:
Use the eddy tools to review every failing HelmRelease across the fleet. For each one, read its events and summary, work out the likely cause, and leave a thread on the resource with the cause and the next step. Don't change anything.
Claude Code calls list_unhealthy, then get_resource and get_events for each HelmRelease, then create_thread with a short diagnosis. To act on a finding, use an operate token and expect approval prompts.
Protected clusters and confirm_cluster
On a cluster marked protected: true, every write tool needs confirm_cluster equal to the cluster name. Without it the tool returns an error that tells the assistant to ask you. Claude Code also asks for approval before it runs suspend, which is marked destructive. Treat the typed name as a speed bump: the real controls are your approval, your RBAC and the audit log. Operators can set config.mcp.protectedClusters: deny to block MCP writes there entirely.
Guardrails
- Your RBAC, always. Calls are impersonated as the token's owner, and group membership can only shrink after a token is issued.
- Bearer only,
/mcponly. Tokens are refused everywhere else, and/mcpignores cookies. The hub rejects a foreignOriginorHostand sends no CORS headers. - Redaction and untrusted data. YAML and logs are redacted and marked as data, not instructions. That limits prompt injection but does not remove it, so review write actions before approving.
- Limits. 256 KiB requests, 64 KiB results, 60 calls a minute per token and 10 writes a minute.
- Audit. Every call is logged with
via: mcp, the user, the token id, the tool and the target. - Expiry. Tokens expire (30 days by default, at most 90 for local users and 30 for proxy, GitHub and OIDC users) and you can revoke them in the UI. Never commit a token: the
eddy_pat_prefix lets secret scanners catch leaks. - Kill switch. Operators can turn off
/mcp, its writes orget_logswithout a restart. See Operations.
Troubleshooting
- 401 Unauthorized. The token expired, was revoked, or is sent to another path than
/mcp. It only works asAuthorization: Beareron/mcp. After a hub restart withstore.driver: memory, all tokens are gone. - The server does not connect. The hub is not reachable from your machine (VPN), or your sign-in proxy sits in front of
/mcp. Exempt it: MCP clients cannot do a browser login. - A tool is refused. The token scope is too small, or the operator switched off
mcpEnabled,mcpWritesormcpAllowLogs. - A tool says the cluster needs confirmation. Pass
confirm_clusterwith the cluster name.