Skip to content

Use the Hydrant CLI

The Hydrant CLI calls the same tools your agent does, from a terminal or a CI job. Use it to read the board without opening a browser, or to have a pipeline move an issue when the work it describes lands. It’s the @hydrantdev/cli (opens in a new tab) package on npm: no dependencies, and it never stores the key.

  • An agent key. Create one under Settings › Agents › Access; Agent keys covers the details. A Read only key can run list, view, tools and every read tool. Anything that writes needs Read and write.
  • Node 20.12 or later. node --version tells you.
  • The right package name. Bare npx hydrant runs someone else’s package. Always ask for @hydrantdev/cli.
  1. Put the key in the environment. read -s HYDRANT_KEY (paste, then Return) keeps it out of your shell history; then export HYDRANT_KEY.
  2. Run npx @hydrantdev/cli tools. That lists every tool the key can call, one line each.
  3. If you’ll use it often, npm i -g @hydrantdev/cli installs the hydrant command. The examples below use that name; npx @hydrantdev/cli works anywhere hydrant does.

HYDRANT_URL defaults to https://hydrant.dev. --key and --url override the environment for one run.

Terminal window
hydrant list # open issues, newest first
hydrant list --status "in progress" --assignee ada
hydrant list --view all --all --q export # include Done and Canceled
hydrant view 12 # one issue and its latest activity

Names match case-insensitively. An unknown status, person, label, project or milestone lists the valid ones instead of guessing.

Terminal window
hydrant tools get_issue # one tool's input schema
hydrant call get_workspace
hydrant call list_issues '{"limit":5}'
echo '{"limit":5}' | hydrant call list_issues -

Arguments are one JSON object. Only - reads them from stdin, so a script with an open pipe never hangs waiting.

Write tools need a request id. Leave it out and the CLI makes one and prints it to stderr. If a write fails partway, retry with --request-id and that id, and it lands once. Writes that don’t bite explains why.

list, view and call print compact JSON when piped or with --json; tools needs --json. hydrant list --json | jq '.issues[].title' does what it looks like.

In GitHub Actions, keep the key in a repository secret. This step moves an issue to Done; update_issue needs the issue’s current version, so it reads that first:

- name: Mark the Hydrant issue done
env:
HYDRANT_KEY: ${{ secrets.HYDRANT_KEY }}
ISSUE_ID: 00000000-0000-4000-8000-000000000000 # the issue's id
run: |
version=$(npx --yes @hydrantdev/cli call get_issue "{\"issueId\":\"$ISSUE_ID\"}" | jq '.data.issue.version')
npx --yes @hydrantdev/cli call update_issue "{\"issueId\":\"$ISSUE_ID\",\"version\":$version,\"patch\":{\"status\":\"done\"}}"

Pin a version, like @hydrantdev/cli@0.2.0, if you’d rather upgrade on purpose.

hydrant list in a terminal prints a table, in colour unless NO_COLOR is set:

# Status Priority Assignee Title
#12 In Progress High Ada Lovelace Rename the export button
#3 Backlog Urgent — Fix the login copy

hydrant view 12 prints the issue’s fields, its description and the five latest activity entries.

call prints what the tool returned. Piped, it’s one line of JSON; in a terminal, indented. The tool’s answer sits under data:

{"workspace":{"id":"…","name":"Acme","role":"member"},"kind":"receipt","data":{"issue":{"number":12,"status":"done","version":3}}}

A write without --request-id also prints one line to stderr, which you keep in case you need to retry:

request id: 980d643b-1d14-4ff4-8f77-1c1a79dfe093

hydrant alone prints the overview. hydrant <command> --help gives an example for every flag that command takes.

Every failure prints one line to stderr: what happened, then what to do. Nothing goes to stdout. Piped or with --json, that line is a JSON object with code, message and hint. The exit code says which kind of failure it was:

Code Means The hint says
0 It worked.
1 The tool refused: not found, invalid arguments, not allowed for your role, or too large. What to fix, such as checking the arguments against hydrant tools <name>.
2 Usage: unknown command, flag or name, invalid JSON, or no key. Run hydrant <command> --help, or set HYDRANT_KEY.
3 Key refused, read-only key on a write, origin refused, or the key’s owner lost access. Check the key, use a read-and-write key, or fix HYDRANT_URL.
4 Conflict: someone changed it first. Reread it and send the current version.
5 Rate limited, after one automatic retry. Try again in the number of seconds it gives.
6 Hydrant is unavailable or unreachable. Try again. For a write, reuse its --request-id.
  • Exit 2 and “must be an origin”. HYDRANT_URL takes an origin only: https://hydrant.dev, with no path, no query and no trailing /api/mcp. Plain http works only for a local server.
  • Exit 3 and “HYDRANT_URL must be the exact origin the key was issued for.” The shape is fine but Hydrant refused it: use the exact origin the key came from, usually https://hydrant.dev.
  • Exit 3 on a write with a read-only key. Create a Read and write key under Settings › Agents › Access and revoke the old one if nothing else uses it.
  • Exit 5. A rate-limited request never runs, so the CLI waits and sends it once more when the wait is 30 seconds or less. If that fails too, or the wait is longer, it stops and tells you how long to wait. A command that makes several requests, like list across pages, can wait more than once.
  • Exit 6 after a write. The write may have gone through. Retry with the --request-id from stderr; Hydrant applies it once either way.
  • The key leaked. Keys live in Settings › Agents › Access, nowhere else. Revoke it there, now. The CLI never writes the key to disk, but your shell history or CI logs might have it.
  • Something else. When an agent gets stuck covers the errors the CLI passes through from Hydrant.