CLI
The deliverd command-line tool: ask a person from a build step, push actions and policy, connect your AI tools, and publish from a terminal or CI.
deliverd is Deliverd's command-line tool, published on npm. It puts a person in the loop of a shell script or a CI job, pushes the actions and policy your organisation's gate reads, sets up your AI tools, and publishes reports from a terminal or a build.
Install
npm install -g deliverd
Or run any command without installing, with npx deliverd ….
Set up your AI tools
npx deliverd setup
setup finds Claude Code, Codex, Claude Desktop, Cursor and Muse Code on this machine and adds the Deliverd MCP server to each one it finds. It writes no credential — each tool asks you to approve the connection in a browser the first time — merges into existing configuration rather than replacing it, keeps a backup of anything it changes, and refuses a file it cannot parse. --print shows the configuration without writing it, --agent <id> limits it to one tool, and --url points it at your own Deliverd address.
Sign in
deliverd login deliverd login --url https://your-deliverd-address
login opens your browser at /cli/authorize; you approve, and the CLI receives an API token for you and keeps it in ~/.config/deliverd/config.json. --token takes a token from Settings → API tokens instead, with no browser.
In CI there is no browser and nothing keeps that file between steps, so set DELIVERD_URL and DELIVERD_TOKEN instead. They take precedence over the configuration file.
export DELIVERD_URL=https://your-deliverd-address export DELIVERD_TOKEN=dlv_… # from Settings → API tokens, stored as a CI secret npx deliverd ask "Deploy to production?" --approver release@firm.com --wait npx deliverd publish ./dist/report --slug finance/weekly --living --json
Commands
| Command | What it does |
|---|---|
deliverd ask "Ship v4?" --wait | Block a build until a person decides. |
deliverd approvals get <id> --wait | Wait on a request somebody else opened. |
deliverd reviews ask "Check the pack" --reviewer … | Put work in front of named readers. |
deliverd collect ask "Renewal details" --question … | Typed questions to the people who know. |
deliverd flows start "Q3 close" | Group one job's requests into one evidence timeline. |
deliverd policy simulate --action … | What your gate policy would say, recording nothing. |
deliverd actions push --file deliverd.actions.json | Register the actions your policy is written against. |
deliverd setup | Find the AI tools on this machine and connect them to the MCP server. |
deliverd login | Approve once in a browser; keeps a token for you. |
deliverd publish ./report.html | Publish an HTML file, a ZIP or a folder as a report. |
deliverd update <report> ./report.html | A new version at the same URL. |
…and the rest: reviews, requests for information, flows and evidence packs, schedules, renaming, archiving, versions, copies and templates, datasets, comments and analytics. deliverd --help lists them all, and deliverd <command> --help explains one.
Putting a person in the loop
A build step that opens an approval, exits zero and carries on has done worse than not asking. --wait blocks — for an hour, or the number of seconds you give it — and exits non-zero on anything but an approval, so set -e is the whole integration.
# Blocks until somebody decides, then exits 0 only if they approved.
deliverd ask "Ship the Q3 pack to Acme?" \
--why "Final numbers, partner-reviewed" \
--approver partner@firm.com --wait
# With arguments the approver may correct, and the decision as JSON
deliverd ask "Refund Acme for invoice 4821" \
--input '{"customer": "acme", "amount": 1240}' --editable amount \
--risk high --approver finance@firm.com --wait --json > decision.json
deliverd approvals get <id> --wait
deliverd approvals answer <id> --question <question-id> --answer "Yes, signed off Friday"
deliverd reviews ask "Check the Q3 commentary" --reviewer "Finance team" --report finance/weekly
deliverd collect ask "Renewal details" --question "Which quarter?" --respondent ops@firm.com
deliverd flows start "Q3 close" # then pass --flow <id> to the above--inputtakes inline JSON,@file.json, or@-for standard input, and must be an object.--editablemust name fields--inputhas. Both are checked before anything is sent.- Run with
approvedInputfrom the JSON, never with what you proposed. - A wait stops when the approver asks an unanswered question, rather than timing out silently: the request is waiting on you.
--callback <url>has the outcome posted to you instead; the signing secret is printed once. See Callbacks.
Actions and policy
deliverd actions push --file deliverd.actions.json
deliverd policy push --file deliverd.policy.json --activate
deliverd policy simulate --action finance.refund \
--input '{"amount":1240}'actions push registers every action in deliverd.actions.json and is meant to run on deploy. policy push stores deliverd.policy.json as a new version and puts it in force only with --activate. Both need a key belonging to an owner or administrator: an action's schema and default risk are what policy is written against. The key deliverd login stores cannot do either, because any coding agent on the machine can read it; create a key under Settings → API tokens and set it as DELIVERD_TOKEN (with DELIVERD_URL) for these commands. See Agent policy for the file formats.
Publishing
deliverd publish ./report.html --audience "Finance team" --title "Q3 Review" deliverd publish ./report-folder --slug finance/weekly --living # A new version at the same URL, refused if somebody else published first deliverd update finance/weekly ./report-folder \ --change-summary "October figures" --expected-version 4 deliverd who "Finance team" sarah@acme.com # check a name before you share deliverd share finance/weekly --audience "Finance team" deliverd unshare finance/weekly --audience sarah@acme.com deliverd send finance/weekly --to sarah@client.com -m "Final numbers." deliverd rollback finance/weekly --version 3 deliverd archive finance/weekly # stops the URL serving; nothing is deleted
deliverd versions <report> prints latestVersion, which is what --expected-version compares against. A living report's numbers can change with no new version: deliverd data set <report> <name> <file>, or - to read standard input. See Publishing reports.
Conventions
- Errors
- Every failure prints
Error (code): messageon standard error and exits 1. The code is the API's own — branch on it in a script, not on the message. See Errors and limits. --json- Every command that returns something takes
--jsonand prints exactly what the API said. The human output is meant to be read, and will be reworded. - Lists
- No
--limitmeans all of them: a list follows the cursor to the end.--limit Ngives one page and prints the cursor to continue from. - Agent tokens
- If
DELIVERD_TOKENbelongs to an agent that has been deleted, every command fails withagent_not_found. The token still authenticates; the identity it acts as is gone.
Try it on your own agent.
Free to start, no card. Sign up with Google, Microsoft or GitHub, and the first page after hands you an API key.