Skip to content

MCP

Zilean exposes a Model Context Protocol endpoint so an AI agent can read your job registry, check on activity and metrics, and enable, disable or run a job — without you building a custom integration on top of the admin API.

  1. Turn the endpoint on: Settings → MCP → Enabled.
  2. Click Create token, pick the least-privileged role that covers what the agent needs, and copy the token — it is shown only once.
  3. Paste the snippet for your client from Connecting a client, replacing <your-host> and <token>.

Then ask the agent something like “list my Zilean jobs” to confirm it works.

The endpoint is off by default. Turn it on under Settings → MCP, or with the API:

Terminal window
curl -X PUT https://<your-host>/api/settings/mcp \
-H 'Content-Type: application/json' \
-d '{"enabled": true}'

While disabled, every request to the endpoint gets a 503 — a signal that the surface exists but is turned off, rather than a 404 that would send you hunting for a typo.

cmd/mcp — the process that actually serves this endpoint — is deployed separately from the admin API/UI (see Architecture), so turning the toggle on doesn’t guarantee it’s running. The Settings page live-probes it (an internal health check against cmd/mcp, not the metrics dashboard) on every load and warns — without blocking the toggle or token creation — when it isn’t reachable; if you see that warning, check that binary is actually up before assuming a client-side problem.

Tokens are issued and managed under Settings → MCP, alongside the enabled toggle, or:

Terminal window
curl -X POST https://<your-host>/api/mcp-tokens \
-H 'Content-Type: application/json' \
-d '{"name": "claude-desktop", "role_id": "<uuid>", "expires_in": "90d"}'

role_id picks the role the token acts as — this is what decides which tools the token can see, so choose the least-privileged role that covers what the agent needs to do (see Permissions). expires_in is one of 30d, 90d, 365d, or never.

The response’s token field is the plaintext bearer credential, returned exactly once. Copy it before closing the panel — only its hash is stored, and there is no way to recover it afterward. Losing it means issuing a new token.

Each token is backed by its own hidden service account, so calls made with it are attributable to that exact token in the audit log rather than to a shared identity.

The endpoint is https://<your-host>/mcp, and it authenticates with a bearer token sent as Authorization: Bearer <token>. Every client below is configured with those two values.

Terminal window
claude mcp add --transport http zilean https://<your-host>/mcp \
--header "Authorization: Bearer <token>"
Symptom Cause
503 The endpoint is disabled — enable it under Settings → MCP.
401 The token is missing, mistyped, revoked, or expired. There is no session-cookie fallback; issue a new token.
Connects, but a tool is missing The token’s role lacks that tool’s permission. tools/list only shows what the role allows — see Tools.
Certificate or connection errors The client must reach https://<your-host>/mcp directly; check your reverse proxy passes /mcp through.

A token only ever sees the tools its role’s permissions allow — tools/list reflects exactly what that token can call, nothing more.

Tool Permission Does
zilean_list_jobs jobs:read List jobs, with filters. Each entry includes capabilities.
zilean_get_job jobs:read Read one job’s full configuration, including its capabilities (declared script volumes)
zilean_job_activity jobs:read Windowed call volume, latency, and lifetime invocation counters for one job
zilean_recent_calls jobs:read Recent attempts for one job, from River’s own job rows
zilean_worker_metrics metrics:read CPU/memory history for a Zilean service
zilean_audit_log audit:read Query the audit log
zilean_enable_job jobs:write Enable one job
zilean_disable_job jobs:write Disable one job
zilean_run_job jobs:write Trigger one job to run immediately, bypassing its schedule
  • No job authoring. There is no create, edit, or delete tool. A token can look at jobs and flip them on or off, but shaping a job’s request, auth, loop, or retry behavior stays an admin-API/UI operation.
  • No volume surface. A token can read which volumes a job declares, but nothing here creates a volume or changes a declaration.
  • No jobs:script surface. Nothing here can create or edit a script job, regardless of the token’s role.
  • No bulk operations. Every write tool acts on exactly one job by id — there’s no enable-all, disable-all, or group enable/disable. One malformed or over-eager agent call should never be able to touch every job at once.

These are intentional boundaries, not gaps waiting to be filled in.