Documentation

Operator runbook

Install, least-privilege credentials, the write-approval workflow, the audit log, and what to do when something refuses to start.


Install

uv tool install janus-mcp-server        # or: pipx install janus-mcp-server

# from a checkout:
uv sync

Full client recipes live in the quick start.


Set up least-privilege credentials

Strongly recommended. Run the server against a dedicated ServiceAccount, never cluster-admin.

kubectl create namespace janus-mcp
kubectl apply -f rbac/janus-mcp-rbac.yaml          # edit namespaces first
# then create a kubeconfig context bound to the janus-mcp ServiceAccount token,
# e.g. named limited-sa@prod-cluster

What the manifests grant, and what they deliberately omit, is broken down in least-privilege RBAC.


Configure

mkdir -p ~/.config/janus-mcp
cp examples/config.yaml ~/.config/janus-mcp/config.yaml
$EDITOR ~/.config/janus-mcp/config.yaml   # context, namespaces, write_tools

The server refuses to start if the pinned context is missing from the kubeconfig, if required read permissions are absent, or, with --strict, if the credentials are over-privileged enough to read Secrets.


Register with an MCP client

Example: Claude Desktop, ~/Library/Application Support/Claude/claude_desktop_config.json.

{
  "mcpServers": {
    "kubernetes": {
      "command": "uvx",
      "args": ["janus-mcp", "serve", "--config", "/Users/me/.config/janus-mcp/config.yaml"]
    }
  }
}

VS Code, Codex CLI and Cursor recipes are in the quick start.


Approving writes

With an elicitation-capable client, approval cards render natively. Read the live state line before clicking Approve.

With other clients the write returns status=pending approval_id=<id>:

janus-mcp approvals            # list pending requests
janus-mcp approve <id>         # approve one

Then tell the assistant to re-issue the call with the same arguments. Approvals expire (write_tools.oob_approval_ttl_seconds, default 10 minutes) and are burned on first use.

Scale approvals are additionally bound to the resourceVersion observed when the request was created. If the object changed while the approval waited, whether an HPA scaled it or a colleague did, the write aborts with a conflict instead of applying to state you never saw. Re-request and re-approve.


Audit

Every call is one JSONL record in ~/.local/state/janus-mcp/audit.jsonl, rotated at 10 MiB: timestamp, tool, identifier args, scope and approval decisions, redaction counts. Bodies are never logged.

jq 'select(.event=="write_approved")' ~/.local/state/janus-mcp/audit.jsonl

Troubleshooting

SymptomCause and fix
cannot load kubeconfig context at startThe pinned context does not exist. Check kubectl config get-contexts.
missing permissions: list pods in …Apply or extend the RBAC manifests for that namespace.
Over-privilege warning at startYou pointed it at an admin kubeconfig. Create the dedicated ServiceAccount.
rate limit exceeded tool errorsExpected back-pressure. Raise limits.rate_per_minute deliberately if needed.
truncated=true in resultsNarrow with label_selector, tail_lines or since_minutes. Raise result_max_bytes only with the token budget in mind.
Writes missing from the client's tool listread_only: true, or the tool is not listed in write_tools.enabled.
Works in the terminal, fails from a GUI clientGUI hosts spawn the server with a minimal PATH, so the kubeconfig's exec: auth plugin is not found. Use the plugin's absolute path in users[].user.exec.command.
[REDACTED:high-entropy] over-firing on legitimate idsRaise redaction.entropy_threshold slightly, for example to 4.8. Never disable the pass.

Development

uv sync
uv run pytest                          # unit + security suites (no cluster needed)
uv run pytest tests/security           # probing + frame-capture leak tests
UPDATE_GOLDENS=1 uv run pytest tests/unit/test_goldens.py   # regen, then REVIEW the diff
uv run ruff check . && uv run ruff format --check . && uv run mypy

Integration tests against a real cluster:

kind create cluster --name janus-test
JANUS_KIND_TEST=1 uv run pytest tests/integration -m integration