mcpField
A
ado-axi

ado-axi

github.com/jeffreyhaenDevelopment1950 installsUpdated 1w ago
Repository

About ado-axi

ado-axi is an agent-oriented CLI for Azure DevOps, with profiles for organization, project, and authentication settings. It covers work items, pull requests, pipelines, tests, repositories, and a raw REST API bridge.

Key features

  1. 01Multiple organization profiles
  2. 02Work item and pull request management
  3. 03Pipeline runs, logs, and monitoring
  4. 04Test results and repository operations
  5. 05Raw Azure DevOps REST API bridge

Use cases

  1. 01Review and update work items safely
  2. 02Inspect PR discussions and checks
  3. 03Run or diagnose build pipelines
  4. 04Access Azure DevOps REST endpoints without a dedicated command

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/jeffreyhaen/ado-axi --skill ado-axi

After installing, type/ado-axiin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

.nvmrc
.gitignore
LICENSE
BENCHMARK.md
README.md
CHANGELOG.md
pnpm-workspace.yaml
package.json
pnpm-lock.yaml
.github/workflows/
ci.yml
release.yml
benchmark/
scenarios.mjs
targets.example.json
tool-surface.json
scripts/
release-notes.mjs
scripts/benchmark/
tokens.mjs
capture.mjs
bench.mjs
capture-surface.mjs
fetch-hook.mjs
scrub.mjs
src/bin/
ado-axi.ts
src/commands/
doctor.ts
home.ts
config.ts
api.ts
repo.ts
ref.ts
pipeline.ts
pr.ts

Details

From the project README

ado-axi

Agent-ergonomic CLI over the Azure DevOps REST API. Multiple organizations are handled with profiles; each profile carries its own org, project, and authentication (Azure CLI login or a personal access token).

Install globally for normal use with npm install -g @jeffreyhaen/ado-axi. If ado-axi is not on PATH, prefix commands with npx -y @jeffreyhaen/ado-axi.

Orientation

Run ado-axi with no arguments first. It prints the active profile plus your open work items, project-active pull requests (active-pull-requests), and recent pipeline runs.

ado-axi                      # dashboard
ado-axi config list          # configured profiles
ado-axi doctor               # authentication check per profile
ado-axi project list         # projects (30 most recently updated; --name <filter>, --limit N)

Selecting org, project, and profile

Every command accepts these, and they never count as unknown flags:

  • --profile <name> — a configured profile (ado-axi config list); may also be written before the command (ado-axi --profile acme pr list), including on the bare dashboard
  • --org <org> / --project <project> — one-off overrides; an --org that matches a configured profile inherits that profile's authentication. Organization-root URLs (https://dev.azure.com/<org> or https://<org>.visualstudio.com) also work; no project/API path
  • $ADO_AXI_ORG / $ADO_AXI_PROJECT — environment overrides

For pasted PR web URLs, extract org, project, repo, and id and pass them explicitly. Establish org/project from the task or a project-specific profile and reuse them for the session. If project context is missing, use ado-axi project list --org <org>; ask the user if the intended project remains unclear. Never select a project arbitrarily, especially for mutations.

Work items

ado-axi work-item list [--state open|all|<State>] [--type <type>] [--assigned-to @me|<name>]
                       [--iteration @current|<path>] [--area <path>] [--tag <tag>] [--search <text>]
                       [--query "<raw WIQL>"] [--limit 30]
ado-axi work-item get <id> [--comments] [--full]       # includes `rev` for compare-and-swap
ado-axi work-item create --type Task --title "..." [--description "..."] [--description-format markdown|html]
                         [--assigned-to <user>] [--parent <id>] [--area <path>] [--iteration <path>] [--tags "a; b"]
ado-axi work-item update <id> [--state <state>] [--title "..."] [--assigned-to <user>]
                              [--description "..."] [--description-format markdown|html]
                              [--add-tags a,b] [--remove-tags c] [--if-rev <n>]
                              [--set '{"Microsoft.VSTS.Common.Priority": 1}']
ado-axi work-item comment <id> [--body "..."] [--format markdown|html]
ado-axi work-item link list <id> [--limit 50]
ado-axi work-item link add <id> (--parent <id> | --child <id> | --related <id> | --pr <id>
                                 | --commit <40-hex> --repo <name> | --branch <name> --repo <name>)
                                [--comment "..."] [--if-rev <n>]

link list resolves hierarchy links to work item ids and artifact links to pull request ids, short commit SHAs, and branch names. link add builds the vstfs:// artifact URI for you — pass the pull request id, not a URL — and treats an already-present link as a no-op.

list builds WIQL for you; drop to --query for anything the flags do not express. --description-format markdown renders a Markdown description; use html only when supplying HTML. The format is only applied when a description is supplied. work-item comment stores comments as Markdown by default; use --format html only when supplying raw HTML. The comments API requires 7.1-preview.4 or later for this format selection. update is idempotent — setting a field to its current value reports a no-op and exits 0.

Safe concurrent updates

--if-rev <n> turns an update into a compare-and-swap: the patch carries a JSON-Patch {"op":"test","path":"/rev"}, so the write either applies to exactly that revision or fails with PRECONDITION_FAILED — never a silent double-claim. Read rev from work-item get. --if-rev also disables the idempotent no-op skip, so the intended fields are always written.

--add-tags / --remove-tags mutate the tag list in place (case-insensitive, deduplicated) instead of replacing System.Tags, so unrelated tags survive. They cannot be combined with --tags, which replaces the whole string.

ado-axi work-item get 4211                  # read `rev` from the output
ado-axi work-item update 4211 --assigned-to [email protected] --add-tags agent-claimed --if-rev 7

Pull requests

ado-axi pr list [--repo <repo>] [--status active|draft|completed|abandoned|all] [--creator @me]
                [--reviewer @me] [--target <branch>] [--limit 30]
ado-axi pr get <id> [--threads] [--full]   # --full = complete description AND comment text
ado-axi pr comments <id> [--full]          # alias for `pr get <id> --threads`
ado-axi pr create --repo <repo> --source <branch> [--target main] --title "..." [--description "..."]
                  [--reviewers a,b] [--draft] [--work-items 1,2]
ado-axi pr update <id> [--title "..."] [--description "..."] [--draft true|false]
                       [--auto-complete true|false]
ado-axi pr complete <id> [--squash true|false] [--delete-source-branch true|false]
ado-axi pr abandon <id>
ado-axi pr checks <id> [--limit 10] [--full]
ado-axi pr diff <id> [--limit 20] [--full]
ado-axi pr reviewer list <id>
ado-axi pr reviewer add|remove <id> --reviewer <identity> [--required]
ado-axi pr approve <id> [--vote approve|approve-with-suggestions|wait-for-author|reject|reset]
ado-axi pr comment <id> [--body "..."] [--file <path> --line <n>] [--thread <id>]
ado-axi pr thread list <id> [--limit 20] [--full]
ado-axi pr thread reply <id> --thread <n> [--body "..."] [--resolve]
ado-axi pr thread resolve|reopen <id> --thread <n> [--status active|fixed|wont-fix|closed|by-design|pending]

Finish review feedback with pr thread: list gives thread ids plus an unresolved count, reply --resolve answers and closes a thread in one call, and resolve/reopen report an already-set status as a no-op.

Safe shell input

For Markdown or multiline comment content, pipe a quoted heredoc to stdin for work-item comment, pr comment, and pr thread reply; omit --body:

ado-axi pr thread reply 812 --thread 5 --resolve <<'EOF'
Fixed in `3f2a1c9`: `$value` is now validated.
EOF

Never double-quote a flag value containing backticks, $, !, or quotes. Git Bash expands these before ado-axi starts, so the CLI receives valid but mangled input and cannot detect it. The same applies to --title, --description, --set, --variables, --parameters, and --query: use stdin where the command supports it, or pipe a complete JSON payload to ado-axi api.

pr list shows a review tally (2/3 approved) so no follow-up call is needed to judge status. Work-item and PR descriptions may be piped when --description is omitted. pr update and reviewer mutations report safely detected retries as no-ops. pr complete uses the current source commit, never bypasses policy, and treats an already completed PR as a no-op. pr abandon treats an already abandoned PR as a no-op. Run pr checks before completion to see concise policy/status counts; use --full only when the bounded actionable list is insufficient.

Git Bash repository paths

On Windows, Git Bash converts repository paths beginning with / even when quoted. Prefix inline comment commands with MSYS_NO_PATHCONV=1 so --file reaches Azure DevOps unchanged.

Example:

MSYS_NO_PATHCONV=1 ado-axi pr comment 812 --file '/src/Project/File.cs' --line 10 --body '...'

Without the prefix, the CLI restores paths converted by Git for Windows. It rejects other Windows paths, and paths under /bin or /usr/bin, before creating a thread.

Pipelines

ado-axi pipeline list [--name <filter>]
ado-axi pipeline runs [--pipeline <id>] [--branch <branch>] [--result failed] [--limit 20]
ado-axi pipeline run --pipeline <id> [--branch <branch>] [--variables '{"k":"v"}']
ado-axi pipeline logs <run-id> [--log <log-id>] [--tail 120] [--full] [--failed-only]
ado-axi pipeline timeline <run-id> [--limit 20] [--full]
ado-axi pipeline watch <run-id> [--interval 10] [--timeout 1800]

watch uses seconds, refuses intervals below 2 seconds, and enforces its deadline across authentication, HTTP requests, and response bodies (30 minutes by default). Failed, cancelled, timed-out, and unexpected outcomes exit non-zero with TOON output.

logs returns the tail of the last log by default — pass --log <id> for a specific step.

When a run failed, start with timeline: it names the failing stage/job/step, includes the first error issue, and gives the log id to read. logs --failed-only goes straight to that step's log.

Tests

ado-axi test results <run-id> [--outcome failed|passed|aborted|not-executed|all] [--limit 20] [--full]
ado-axi test results --run <test-run-id>

<run-id> is the pipeline run id. All pages of published test runs contribute to totals; result counts match --outcome. --limit bounds displayed results, not totals. --full expands error messages without increasing that limit. When a build is red, test results usually answers what broke and pipeline logs --failed-only why.

Repositories

ado-axi repo list [--name <filter>]
ado-axi repo branches --repo <name> [--name <filter>]
ado-axi repo file <path> --repo <name> [--ref <branch> | --commit <40-hex>] [--limit <lines>] [--full]
ado-axi ref list --repo <name> [--name <prefix>] [--limit 50] [--full]
ado-axi ref create --repo <name> --name <branch> (--source <branch> | --source-object-id <40-hex>)
ado-axi ref delete --repo <name> --name <branch> [--old-object-id <40-hex>]

repo file reads a single file straight from Azure DevOps: the default branch, a branch tip (--ref), or an exact revision (--commit). Use it for files outside the working copy — another repository, or the target-branch version of a file under review. Folders and binaries are refused, and paths follow the same /src/Project/File.cs form as pr comment --file.

Ref creation never overwrites an existing branch. Deletion resolves the exact branch and uses its current object ID as the Azure DevOps concurrency guard; --old-object-id additionally asserts a previously observed version. Existing-at-the-intended-object and already-absent requests are no-ops.

Escape hatch

Anything without a dedicated command — wikis, test plans, code search, artifacts, security — goes through the raw REST bridge:

ado-axi api _apis/wiki/wikis
ado-axi api _apis/testplan/plans --query 'filterActivePlans=true'
ado-axi api POST _apis/search/codesearchresults --host almsearch --body '{"searchText":"TODO"}'
cat payload.bin | ado-axi api POST _apis/wit/attachments --query 'fileName=payload.bin' --content-type application/octet-stream
ado-axi api _apis/projects --no-project           # organization-level path
ado-axi api 'https://vsrm.dev.azure.com/acme/Platform/_apis/release/releases?api-version=7.1'
ado-axi api PATCH _apis/wit/workitems/4211 --content-type json-patch \
  --body '[{"op":"test","path":"/rev","value":7},{"op":"add","path":"/fields/System.State","value":"Active"}]'

Relative paths use https://dev.azure.com/<org>/<project>/; --host selects dev (default), vsrm, vssps, or almsearch. Full HTTPS REST URLs on those four hosts also work: URL org/project/host/query replace default context and use matching profile authentication. Conflicting flags or a --profile from another org are rejected; do not override URL context. Quote URLs with query parameters. When --body is omitted and stdin is piped, stdin is sent unchanged as the request body. --content-type accepts the shorthands json (default), json-patch, merge-patch, text, or any media type — work item writes require json-patch.

Conventions

  • In ADO descriptions/comments, #123 references a work item, !123 an Azure DevOps PR; for GitHub PRs use the full URL, never bare #123 or !123, even when Boards/pipelines run in ADO.
  • Output is TOON on stdout; errors are TOON too, with a help list of next steps.
  • Exit codes: 0 success (including no-ops), 1 runtime error, 2 usage error.
  • Unknown flags are rejected by name — read the help line and retry once.
  • Lists take --limit and --fields a,b; detail views truncate and take --full.
  • On Windows/Git Bash, never pass large or multiline content through a .cmd shim as an interpolated CLI argument such as --description "$(cat file)"; cmd.exe can truncate it. Pipe it instead: cat file | ado-axi work-item update <id> or cat file | ado-axi api POST <path> --content-type <media-type>.
  • Mutating commands (create, update, complete, reviewer add/remove, ref create/delete, comment, approve, pipeline run) change real state — only run them when the user asked.
  • Never use PR completion to bypass policy and never delete a ref whose exact target is ambiguous.

Comments

Markdown supported