Drive enclavia from a local AI agent (CLI skill)
There are two ways to let an AI agent manage your enclaves, and they trade off in opposite directions:
- The hosted MCP server at
mcp.beta.enclavia.io. Zero local setup, OAuth in the client, a per-request bearer token. Best for agents that run in someone else's runtime (Claude on the web, ChatGPT) and have no shell of their own. - The
enclaviaCLI with--jsonplus the agent skill (this page). The agent runs theenclaviabinary locally and reads a short skill file that teaches it the command surface. It needs a shell and a seeded credentials file, but it is more token-efficient than the MCP server for the same operations (one CLI call returns one JSON value, instead of an MCP tool round-trip), and it exposes the local-tool commands the hosted MCP server cannot offer:push(needs local Docker),reproduce(needs the local builder and Nix), andsecretmanagement. Both cover the enclave lifecycle,logs, andupgrade.
If your agent already has a terminal, prefer this path. If it does not, use the MCP server.
Agents should not use enclavia deploy
enclavia deploy is a human convenience that wraps create + push + a long-lived watch (spinner, streamed build log) in one process. Agents should run the individual commands instead: enclave create, push, then poll enclave status. That keeps each step's JSON output and exit code separately actionable and avoids holding a process open for the many minutes a build can take. The skill file already steers agents this way.
The --json contract
--json is a global flag: it works on every subcommand and in either position (enclavia --json enclave list or enclavia enclave list --json). It turns the CLI into a clean, scriptable surface. The contract an agent relies on:
- Success: a single JSON value (object or array) is printed to stdout and the process exits
0. - Failure: a single
{"error": "<message>", "kind": "<kind>"}object is printed to stdout and the process exits non-zero.kindis one ofnot_logged_in,unauthorized, orerror. - Progress and prompts (including the OAuth login URL) and any diagnostics go to stderr, never stdout. So stdout is always exactly one parseable JSON value.
The agent therefore parses stdout once and branches on the exit code, not on prose:
out=$(enclavia enclave list --json) # capture stdout
if [ $? -eq 0 ]; then
# $out is the success array of enclave objects
else
# $out is {"error": ..., "kind": ...}; inspect .kind
fiThe reproduce exception
enclavia reproduce is a verification command, so its PCR verdict maps onto the exit code the way diff or test do:
| Exit code | Meaning |
|---|---|
0 | Reproducible: the local rebuild's PCRs match the recorded build. |
2 | Diverged: the build ran but the PCRs do not match. |
1 | Operational error (the usual {"error", "kind"} shape). |
On both 0 and 2 the full reproduce payload (including reproducible and the mismatches array) is printed to stdout, so a field-reading agent gets the detail while an exit-code-only caller still fails closed. Gate on exit 0 (or reproducible == true).
The agent skill
The skill is a Claude Code skill: a single SKILL.md file with YAML frontmatter that an agent loads when a task matches its description. It teaches the agent the enclavia command surface, the --json rule above, and the per-command output shapes, so the agent does not have to rediscover them.
It lives in the public workspace at skills/enclavia/SKILL.md in the EnclaviaIO/enclavia repo, next to the CLI source it documents.
Install it for your agent
Copy the file into your agent's skills directory. For Claude Code that is ~/.claude/skills/enclavia/:
mkdir -p ~/.claude/skills/enclavia
curl -fsSL https://raw.githubusercontent.com/EnclaviaIO/enclavia/master/skills/enclavia/SKILL.md \
-o ~/.claude/skills/enclavia/SKILL.mdIf you already have the repo checked out, copy it from there instead:
mkdir -p ~/.claude/skills/enclavia
cp path/to/enclavia/skills/enclavia/SKILL.md ~/.claude/skills/enclavia/SKILL.mdThe agent picks the skill up on its next run. From then on, asking it to "deploy", "list", or "inspect" an Enclavia enclave routes through the skill and the --json CLI.
Authentication for headless agents
The CLI reads credentials from ~/.config/enclavia/credentials.json (honouring $XDG_CONFIG_HOME). That file holds an OAuth access token plus a refresh token; the CLI auto-refreshes on expiry and rewrites the file, so once it exists an agent keeps working with no further interaction.
The catch is how the file gets created. enclavia auth login is interactive: it opens a browser (OAuth 2.1 + PKCE) and prints the approval URL to stderr. A headless agent cannot complete it. The flow is therefore:
- A human runs
enclavia auth loginonce on a machine with a browser (see Authenticate). - Copy the resulting
~/.config/enclavia/credentials.jsonto the agent's~/.config/enclavia/if the agent runs somewhere else. - Run the agent with that file present.
If no credentials exist, every command fails with {"kind": "not_logged_in"}.
To target a non-production backend, set ENCLAVIA_BACKEND_URL (default https://api.beta.enclavia.io), for example http://localhost:3000. Note that the credentials file also records the backend it was minted against and uses it as the base URL, so keep the two consistent: a credentials file from one backend will not authenticate against another.
Which should I use?
| MCP server | CLI + --json + skill | |
|---|---|---|
| Setup | None local; paste a URL, OAuth in the client | Install the enclavia binary, seed credentials, drop in the skill |
| Auth | Per-request bearer token, OAuth in the client | Human-seeded credentials.json, auto-refreshed |
| Best for | Hosted agents with no shell (Claude web, ChatGPT) | Local agents that already have a terminal |
| Token overhead | Higher (MCP tool round-trips) | Lower (one CLI call, one JSON value) |
| Surface | Enclave lifecycle (create/list/status/start/stop/destroy), logs, and upgrade | Enclave lifecycle (plus restart), logs, and upgrade, plus push, secret, and reproduce |
In short: reach for the MCP server when you want a hosted connector with no local setup, and for the CLI + skill when your agent already has a shell and you want the lower token overhead plus the local-tool commands (push, reproduce, secret).
See also
- Connect an AI agent with the MCP server — the hosted alternative to this page.
- Authenticate — the interactive login that seeds the credentials file.
- Reproduce a build — the verification command whose exit codes the skill special-cases.