Observed since 20 Oct, 23:34 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Agent-ready command-line interface for Drone CI (builds, logs, repos, secrets, crons, usage reporting). Installs the `drone-cli` command.
A fast, scriptable Drone CI CLI for builds, pipeline logs, repositories, promotions and deployments — and the first Drone command-line tool designed to be driven by AI agents (Claude, Cursor, LLM tool-loops) as well as humans.
Install: pipx install agent-tool-drone-cli — then run drone-cli guide.
agent-tool-drone-cli (the
installed command is drone-cli) is a Python command-line interface for the
Drone CI REST API. It covers the day-to-day pipeline
workflow — waiting on a commit's build, reading just the failing step's
logs, listing and triggering builds, restart/cancel/approve,
promotions and rollbacks, repositories, and "what is actually live on prod" —
all with first-class JSON output so it slots straight into automation and AI
agents.
drone-cli wait --commit HEAD
answers "did the thing I just pushed pass?" Build numbers are racy — if a
colleague pushes while you do, "the latest build" is a coin flip and you'd
report their failure as yours. You already know your SHA. --commit HEAD reads
it from the local checkout. Nothing else in the ecosystem works this way.drone-cli log failed — the failing step, and nothing else. Doing this by
hand means: GET the build, walk stages[], find the failed step, know that
stage/step are 1-based ordinals (not names, not ids), GET
logs/{stage}/{step}, then strip the {pos,out,time} envelope. One command
instead, --tail-bounded — so an agent spends its context on the fix rather
than on apt-get noise.drone-cli guide playbook so an agent can
learn the tool from the tool itself. See AGENTS.md.drone-cli promote --commit HEAD,
drone-cli deploy status --to prod (which commit is on prod right now?),
drone-cli deploy of --commit HEAD (has my commit shipped?). The API exposes
the data; nothing surfaces the answer.finished: 0 for 1970).json (default), table, markdown, csv; pick
per command with -o, trim to exact --fields, or --stream NDJSON.--dry-run previews any write at the transport layer,
the client retries genuinely transient failures (and pointedly not Drone's
500s), and drone-cli context gives sticky per-session defaults.0600 file fallback.
DRONE_SERVER/DRONE_TOKEN work for CI.drone-cli raw calls any endpoint the typed commands don't
wrap. Drone's API is thinly and sometimes wrongly documented; this is how you
check.Docs: Full command reference · Agent guide · built-in: drone-cli guide
Keywords: Drone CI CLI, Drone command line, Drone API client, drone.io, pipeline automation, CI/CD CLI, build logs, continuous integration tooling, promote deployment, AI agent tool, LLM tooling, Claude, DevOps automation.
Everything is discoverable from the binary — drone-cli --help, then
drone-cli guide for the playbook and drone-cli <group> --help for any group.
The top level:
Usage: drone-cli [OPTIONS] COMMAND [ARGS]...
Agent-friendly CLI for Drone CI (builds, logs, repos, secrets, crons,
deployments).
Output is JSON on stdout by default (errors are JSON on stderr with a non-zero
exit code); add `-o table` or trim with `--fields number,status`. Address builds
by COMMIT, not by number: `drone-cli wait --commit HEAD`.
New here / no context? Run `drone-cli guide` for the full playbook.
╭─ Commands ───────────────────────────────────────────────────────────────────────╮
│ guide Built-in operating guide — how to use this CLI without external docs. │
│ report Report a bug / missing feature — repo + pre-filled issue link. │
│ wait Wait for a commit's build to finish. `--commit HEAD` after a push. │
│ promote Promote a commit/build to a target (default: prod). │
│ auth Log in, log out, inspect credentials. │
│ repo Repositories: list, enable, sync, inspect. │
│ build Builds: list, inspect, run, restart, cancel, wait. │
│ log Build logs — including just the failing step. │
│ deploy Deployments: what is on prod, and what got it there. │
│ secret Repository secrets (values are write-only). │
│ orgsecret Organisation secrets, shared across a namespace's repos. │
│ cron Scheduled builds — with a guard for Drone's seconds-first cron. │
│ template Pipeline templates (namespaced). │
│ server Server version, health, queue — and `server doctor`. │
│ user Your build feed, and user administration (admin only). │
│ raw Escape hatch: call any API endpoint directly. │
│ settings View & change CLI settings. │
│ context Sticky session defaults (repo, etc.) reused across commands. │
│ install Integrate with other tools (e.g. `install claude`). │
╰──────────────────────────────────────────────────────────────────────────────────╯
Global options — -o/--output json|table|markdown|csv, --fields, --dry-run,
--stream, --no-context — are stripped from argv before parsing, so they work
anywhere on the line. Full reference: docs/COMMANDS.md.
drone-cli, not droneThe installed command is drone-cli. The name drone belongs to the
official Go client that most Drone users already have on their PATH, and this
project deliberately does not claim it — the two are designed to coexist on
the same machine, and clobbering the binary everyone's muscle memory and existing
scripts point at would be a hostile way to install software.
drone-agent is refused for the same reason: in Drone's own vocabulary an
"agent" is the runner. Alias it yourself if you want it shorter:
alias dc=drone-cli.
<server>/api. Verified
live against drone/drone:2 (2.28.x) with a Docker runner; Drone is in
maintenance, so there is no version matrix to chase.drone-cli settings set-scm) — see the limitations below for why it can't be
auto-detected.Anything not wrapped is reachable with drone-cli raw <method> <path>.
a) pipx (recommended — isolated, puts drone-cli on your PATH)
pipx install agent-tool-drone-cli
b) pip
pip install agent-tool-drone-cli
# or, from a clone:
python3 -m venv .venv && . .venv/bin/activate && pip install -e .
c) Single self-contained binary (no Python on the target)
Download the prebuilt binary for your OS from the GitHub Releases page:
chmod +x drone-cli-linux-x86_64 && mv drone-cli-linux-x86_64 /usr/local/bin/drone-cli
drone-cli --help
Or build one yourself — a single file that bundles the interpreter, the deps and the OS keyring backends:
pip install -e '.[build]'
python scripts/build_binary.py # -> dist/drone-cli (.exe on Windows)
.github/workflows/release.yml builds Linux/macOS/Windows binaries on every v*
tag and attaches them to the release.
drone-cli auth login # asks for the server, then shows you
# exactly where to get a token
drone-cli auth whoami
login verifies the token before persisting anything, saves the connection
profile to ~/.config/drone-cli/config.json, and stores the token in your
keyring. Get a token at <your-drone-server>/account.
For headless/CI use, skip the keyring entirely — the ecosystem's own env vars are read as-is:
export DRONE_SERVER=https://drone.example.com
export DRONE_TOKEN=xxxxxxxx
drone-cli build ls --repo octocat/hello-world
Precedence hazard, stated plainly: env beats keyring. That is what makes the tool work in CI — but
DRONE_*is also the namespace the Drone runner injects into every build step, so an exportedDRONE_TOKENsilently overrides your keyring login.drone-cli auth statusalways names the token actually in use. Don't guess.
drone-cli install claude # writes ~/.claude/skills/drone-ci/SKILL.md
drone-cli install claude --print # preview it first
The skill points Claude at drone-cli guide, so it learns the tool from the
tool. On the first interactive run, if Claude Code is detected, the CLI offers to
install it — once. Decline and nothing changes.
Run drone-cli <group> --help for full options, or drone-cli guide <topic>.
waitdrone-cli wait --commit HEAD # did my push pass?
drone-cli wait --commit HEAD --timeout 20m
drone-cli wait --commit HEAD --exit-code && ./deploy.sh
Three outcomes an agent must distinguish, and this command keeps them apart: finished (the outcome is in the JSON), blocked (a human must approve — the approve command is included in the output), and never appeared (exit 10: the webhook may be broken or the repo not enabled — that is not "the tests failed").
drone-cli logdrone-cli log failed --commit HEAD --tail 80 # just the failing step
drone-cli log failed 42 --all # every failing step, not just the first
drone-cli log view 42 --stage 1 --step 2 # 1-based ordinals, not names
drone-cli log view 42 --grep "error"
drone-cli builddrone-cli build ls --repo octocat/hello-world --status failure
drone-cli build info --commit HEAD --links # stages[].steps[] + a real commit URL
drone-cli build run --branch main # NOTE: event = "custom", not "push"
drone-cli build restart 42 # -> creates a NEW build number
drone-cli build cancel 42
drone-cli build approve 42 --stage 2 # blocked builds
drone-cli promote / drone-cli deploydrone-cli promote --commit HEAD # --to defaults to `prod`
drone-cli promote --commit HEAD --to staging
drone-cli deploy status --to prod # which commit is live on prod?
drone-cli deploy of --commit HEAD # has my commit been promoted?
drone-cli settings set-promote-target staging # change the default target
drone-cli build ls -o table
drone-cli build ls --fields number,status,after # trim the payload
drone-cli build ls --stream # NDJSON
drone-cli build restart 42 --dry-run # prints the request, sends nothing
drone-cli context set --repo octocat/hello-world # stop repeating --repo
drone-cli context show # incl. where each value came from
drone-cli --no-context build ls # ignore it for one command
drone-cli raw get repos/octocat/hello-world/builds
{"error": "...", "status": 404}).log view / log failed print raw log text. Logs are prose,
not records — don't json.loads them.0 ok · 1 generic · 3 config · 4 auth · 5 not-found ·
7 validation · 8 not-implemented-on-this-server · 9 wait timed out ·
10 no build for that commit · 130 interrupted. (6 is reserved
family-wide for conflicts; Drone has no optimistic locking and never conflicts.)wait --exit-code opts into a separate 20–29 band so "the build failed"
can never be confused with "the CLI failed".Full contract: AGENTS.md.
You do not need Drone, Docker, a server, or a token to contribute. Clone it and run:
pip install -e '.[test]'
pytest # green on a clean checkout, ~2s, no server needed
That is the whole setup. The suite is green on a fresh clone with nothing
running: the tests that need a live instance detect there isn't one and skip with
a message telling you exactly what to set. make test-unit runs the same
hermetic set explicitly (pytest -m "not integration" — the marker is the source
of truth, never a file list).
Please add a test with your change; the hermetic suite is fast enough to run on every save.
A live Drone needs an SCM behind it (repos only enter Drone by syncing from
Gitea/Forgejo/GitHub), a runner to execute anything, and a token injected into
the DB. spike/docker-compose.spike.yml and spike/VERIFIED_FINDINGS.md document
a stack that was proven end-to-end. Point the suite at any live server with:
export DRONE_SERVER=http://localhost:8080
export DRONE_TOKEN=<your token>
pytest # the integration tests light up automatically
Unset those and they skip again. spike/VERIFIED_FINDINGS.md is the authoritative
record of what this API actually does — it is worth more than the official docs,
which are wrong in several documented places.
drone-cli auth status shows which backend is in use.0600 file
under ~/.config/drone-cli/ and the CLI says so.DRONE_TOKEN / DRONECLI_TOKEN in the environment always win (nothing is
written to disk in that mode).These are properties of Drone itself, verified live during a spike against a real server. The CLI works around what it can and is loud about what it can't.
created/started/finished epochs. Every duration you see
here is derived client-side. (Also why finished: 0 means still running, not
1970.)GET .../secrets/{name} yields
{id, repo_id, name}. There is no --show-value that could ever exist, and no
export, copy-between-repos, or value drift-check. That a read-back returns no
value is not a failure.branch/tag are
server-side. Anything else is a client-side scan under a page budget — which is
why a search can honestly report "I stopped looking", never "nothing found".Second Minute Hour Dom Month Dow). A normal 5-field crontab "0 3 * * *"
parses fine and means every hour at :03 — not 03:00 daily. Silent, 24×
wrong, no error. The API also can't preview a schedule: next is only computed
after the cron is persisted.build.link is not a commit link. For a push it's a compare URL
(/compare/before...after); for an API-triggered build it's an API URL that
renders as JSON. Drone passes through whatever the SCM handed it and never
normalises. --links derives a real one from {repo.link}/commit/{sha} —
and since repo.scm is an empty string even on a synced repo, the provider
is not discoverable, so the pattern is a setting (settings set-scm) rather
than a guess.Unauthorized is not about your token. It means the server's
link to the git provider is broken. The CLI maps it to a real auth error that
says so, and never retries it.POST .../lint and POST .../verify
are 404s, and GET /api/version is a 404 (the real one is GET /version on the
web root). Others are documented with the wrong ACL. See
spike/VERIFIED_FINDINGS.md.Built on agent-tool-shared-cli —
the chassis every tool in this family shares: JSON on stdout, JSON errors on
stderr, a stable cross-tool exit-code contract, --dry-run, four output formats,
and a built-in guide so an agent can learn each tool from the tool itself.
| Tool | Install | For |
|---|---|---|
| drone-cli | pipx install agent-tool-drone-cli | Drone CI — builds, failing-step logs, promotions |
| grafana-cli | pipx install agent-tool-grafana-cli | Grafana — log discovery, health scan, alert routing |
| openproject | pipx install agent-tool-openproject-cli | OpenProject — work packages, time, invoicing |
| lexware-office | pipx install agent-tool-lexware-office-cli | Lexware Office — invoices, contacts, AR-aging |
They compose over the shared contract:
drone-cli wait --commit HEAD && grafana-cli scan --since 10m answers "my commit
built — is it healthy in production?"
MIT — see LICENSE.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.3 | 20 Jul 2026 | 8 |
This describes our collected data; it is not a security assessment.
Shared repository data · GitHub
Observed since 20 Oct, 23:34 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:7a53fb967bb13ab85b82295fe4abf2ccd52601297c2b88ebedb39a5539978f10