Generic Trello command-line interface in TypeScript — designed for autonomous-worker integrations, cron jobs, shell scripts, and humans alike.
- All HTTP requests rate-limited (token bucket: 25 req/s steady, 100 burst), with exponential backoff on
429and respect forRetry-After - Output is JSON by default for piping into
jq; pass--format tablefor a humans view - Auth lives at
~/.config/trello-cli/auth.json(chmod 600, atomic writes) with optionalXDG_CONFIG_HOMEandTRELLO_CLI_AUTH_PATHoverrides - Best-effort
cards claimprotocol with claim re-check rollback for autonomous-worker use cases - Idempotent
init,labels ensure, and board scaffolding — safe to re-run - ESM (Node 22+), zero
anyin the public API, validated with Zod
npm install -g @dr5hn/trello-cliFirst-time setup needs a Trello API key, user token, and board ID — see Auth setup for how to obtain them.
trello-cli init # interactive: API key, token, board, scaffolding
trello-cli cards list --label ww-ready --not-label intern-ok
trello-cli board summary| Command | Purpose |
|---|---|
trello-cli init [--board-id <id>] [--force] |
One-time setup: API key, token, board ID, status card. Refuses to overwrite existing auth without --force. |
trello-cli labels ensure |
Idempotently create the 8 ww-* workflow labels on the configured board. |
| Command | Purpose |
|---|---|
trello-cli cards list |
Filtered card listing. See "Filters" below. |
trello-cli cards get <id> |
Full card detail including custom fields. |
trello-cli cards create --title "..." [--list X] [--label Y...] [--field K=V...] |
Create a card. Defaults to first open list. |
trello-cli cards update <id> [--add-label X] [--remove-label Y] [--list Z] [--field K=V] |
Mutate labels, list, or custom fields. |
trello-cli cards comment <id> --body "..." (or --from-stdin) |
Add a comment. |
trello-cli cards claim <id> [--worker-id <id>] |
Best-effort 4-step claim protocol (worker use). Worker-id defaults to <hostname>:<pid>:<iso>. |
trello-cli cards release <id> --status <pr-opened|stuck|done> [--pr-url X] [--reason Y] |
Atomic state transition + clear claimed-at field + post status comment. |
| Command | Purpose |
|---|---|
trello-cli board summary |
Counts by list × label, excluding lists in internal_lists config. Useful for periodic summary jobs. |
| Command | Purpose |
|---|---|
trello-cli watch [--label X] [--interval 15m] |
Long-poll for new cards matching a filter; emit one NDJSON event per appearance. |
--label <name>... include cards with ALL listed labels (repeatable)
--not-label <name>... exclude cards bearing ANY of these labels (repeatable)
--list <name> restrict to one list
--repo <name>... filter by `repo` custom field exact match (repeatable)
--mine restrict to cards assigned to the authed user
--stale-days <n> only cards untouched for N+ days
--tier <tier> (reserved — not yet implemented in Phase 1; use --repo)
-f, --format <mode> json (default) or table
-v, --verbose verbose logging to stderr
# Cards ready for the worker, excluding intern-claimed cards
trello-cli cards list --label ww-ready --not-label intern-ok
# Mark a card as having an open PR
trello-cli cards release ABC123 --status pr-opened --pr-url https://github.com/x/y/pull/42
# Capture an idea from a script
echo "Add batch country export to csc-cli" \
| trello-cli cards create --title - --list "Ideas" --label tier-green
# Watch for new ww-ready cards every 5 minutes
trello-cli watch --label ww-ready --interval 5m | jq '.card.name'
# Compose a board snapshot for Slack
trello-cli board summary | jq '{cards: .totalCards, ready: (.labels[] | select(.name=="ww-ready") | .cardCount)}'You need three values: an API key, a user token, and a board ID. Trello's current flow requires creating a Power-Up first — the legacy trello.com/app-key page was retired by Atlassian.
- Sign in to Trello, then visit https://trello.com/power-ups/admin.
- Click "New" and create a Power-Up. The fields don't have to be meaningful for CLI use:
- Name:
trello-cli(or anything) - Workspace: pick any workspace you belong to
- Iframe connector URL: leave blank or use
https://example.com - Author / email / support contact: your own
- Name:
- After creation, open the Power-Up and go to the API Key tab.
- Click "Generate a new API Key" and accept the prompt. Copy the key.
On the same API Key page, click the hyperlinked "Token" next to your API key. This opens the OAuth-style authorization screen — approve it and Trello returns a token.
Or build the URL yourself (useful for scripts):
https://trello.com/1/authorize?expiration=never&name=trello-cli&scope=read,write&response_type=token&key=YOUR_API_KEY
Replace YOUR_API_KEY, open the URL, approve, and copy the token from the resulting page.
Heads up: the token is a user credential with the scope you just granted (
read,writeabove). Treat it like a password.expiration=neveris convenient for a worker; swap to1day/30daysif you'd rather rotate.
Open the board in Trello. The URL looks like:
https://trello.com/b/ABCD1234/my-board
^^^^^^^^^^^^^^^^^^^^^^^
this 8-char segment is the board ID
Alternatively, append .json to any board URL to see the full ID and metadata.
Interactive (recommended for first-time setup):
trello-cli init # prompts for key, token, board, plus scaffolding
# or, if you only want auth without scaffolding:
trello-cli authScripted (CI, provisioning, Dockerfiles):
trello-cli auth \
--api-key "$TRELLO_API_KEY" \
--token "$TRELLO_TOKEN" \
--board-id "$TRELLO_BOARD_ID"Either path writes ~/.config/trello-cli/auth.json (chmod 600, atomic):
{
"apiKey": "...",
"token": "...",
"boardId": "...",
"internal_lists": ["📊 Internal"]
}To override the path: export TRELLO_CLI_AUTH_PATH=/some/where/auth.json or export XDG_CONFIG_HOME=/elsewhere.
trello-cli board summary # smoke-tests auth + board accessIf you see a 401 / 403, the token is wrong or was revoked. A 404 on the board ID usually means the token's user can't access that board.
npm install
npm run dev -- cards list --label ww-ready # run from source via tsx
npm test # vitest, 100%+ coverage on lib/
npm run lint # tsc --noEmit
npm run build # emit dist/Tests use undici's MockAgent (not nock, which doesn't intercept undici's directly-imported fetch in v14).
The following are designed but deferred:
--tierfilter oncards list— reserved on the CLI but throws a clear error directing to--repo. Implementing tier resolution would require this generic CLI to read a downstream consumer's configuration, coupling it to a specific use case. Use--repoand let the consumer resolve tier→repo set on its own side.- Cross-process rate-limiter coordination via
proper-lockfile— included as a dependency, not yet wired. Single-process buckets are sufficient for typical single-worker setups.
MIT