Jira cli
Claude Code plugin marketplace — 58 installable reference skills across vLLM/SGLang inference, Kubernetes & Harvester, GPU host bring-up, observability, security, and agent workflows.
npx -y skills add air-gapped/skills --skill jira-cliAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Drive Atlassian Jira from the terminal with the `jira` CLI (jira-cli, v1.7.0) against ANY Jira — Cloud or on-premise/Data Center. Covers the full command surface (issue / epic / sprint / board / project / release), the non-interactive automation contract (`--no-input` + `--plain`/`--raw`/`--csv` for agent-safe, parseable output), JQL filtering, GitHub/Jira markdown → Atlassian Document Format (ADF) conversion, authentication for every backend (Cloud API token, on-prem basic, PAT/bearer, mTLS), and live-discovery of instance-specific values (project keys, issue types, statuses, priorities, link types, custom fields) instead of guessing them.
SKILL.md
16.9 KB, as published. Nobody here has run it
jira-cli — Atlassian Jira from the terminal
Target audience: an operator or agent driving Jira non-interactively — creating and transitioning tickets, running JQL, exporting issues, and scripting bulk changes — against any Jira deployment (Cloud, Server, or Data Center). This skill is instance-agnostic: it never assumes the target's project keys, workflows, or field schemes — it shows how to discover them and then act safely.
jira is ankitpokhrel/jira-cli, a single static Go binary inspired by GitHub's gh. It is not an official Atlassian tool.
Why this matters
Three things make jira-cli easy to get wrong, and all three are what this skill exists to prevent:
-
It is interactive by default.
create,edit,assign,move,comment add, andworklog addopen a TUI or prompt for missing fields. A script (or an agent) that forgets--no-input— or omits a required flag — hangs forever waiting on a prompt that no one will answer. Reads (list,view,epic list,sprint list) default to an interactive pager/table UI; without--plain/--raw/--csvthe output is terminal-control gibberish, not parseable data. The automation contract is non-negotiable: writes get--no-input+ every required flag; reads get a plain/raw/csv format flag. -
Almost every value is instance-defined and case-sensitive. Issue types, statuses, priorities, resolutions, link types, components, and custom fields are configured per-project on the Jira side — the CLI invents none of them.
-tBugfails on a project that calls itDefect;move ISSUE-1 "Done"fails if the workflow's state isClosedordone(lowercase). Discover before acting (see below). Hardcoding values from memory is the most common cause of confusing failures. -
Descriptions/comments are converted to Atlassian Document Format (ADF). Markdown is not stored verbatim — it's translated. Some constructs (Jira
{code}blocks, strikethrough,@mentions, emoji shortcodes, raw HTML) translate imperfectly or are dropped. Seereferences/markdown-adf.md.
Version & source of truth
- Pinned at v1.7.0 (released 2025-08-31, the current latest). Verify locally:
jira version. --helpis the authoritative flag reference, always.jira <cmd> <subcmd> --helpprints flags, arguments, aliases, and examples. If this skill ever disagrees with--helpon a flag, trust--help(and update the skill). Generate full man pages withjira man --generate --output <dir>.- This skill's exhaustive flag/argument tables live in
references/commands.md, captured from the v1.7.0 binary.
Cloud vs Server / Data Center — know which backend you're on
The CLI talks to two different Jira APIs and the behavior diverges in ways that change real commands. Check with jira serverinfo (Deployment Type: Cloud vs Server). The command surface is identical; these semantics are not:
| Aspect | Jira Cloud | Jira Server / Data Center |
|---|---|---|
| REST API | v3 | v2 |
| Description/comment format | GFM/Jira markdown → ADF (auto-converted) | Jira wiki markup — create/comment convert GFM→wiki, but edit sends it verbatim (#935); prefer h2., *bold*, {code} |
| Auth | email + API token | password (basic), or PAT (JIRA_AUTH_TYPE=bearer), or mTLS |
User identity for -a/-r | accountId (GDPR strict mode, #342) — email/display name may not resolve | username (or display name) |
--paginate <from>: offset | ignored — can't page past the first 100 (#898) | works — old search API still honors startAt |
| SSO in front of the instance | rare | API must be reachable directly with a PAT; basic-auth/email hits the SSO HTML login → 401 / invalid character '<' (#477, #822) |
| Releases/Versions, sprints | feature-gated | same, plus older Agile API quirks |
When a recipe below assumes Cloud (ADF markdown, accountId, the pagination cap), the Server/DC equivalent is in the right-hand column. Auth/SSO specifics: references/config-auth.md. Markdown specifics: references/markdown-adf.md.
Step 0 — ALWAYS discover the instance before acting
A skill that hardcodes project keys or status names is wrong on the next Jira. Before any create/edit/move/assign, learn what the target instance actually offers. These are read-only and safe:
jira me # confirm auth + identity (prints the account/email)
jira project list # KEY NAME TYPE LEAD — tab-separated table, takes no output flags
jira board list # ID NAME TYPE — board IDs for sprints (also takes no output flags)
# Discover the field VALUES a project accepts — read them off existing issues:
jira issue list -p PROJ --plain --no-truncate --paginate 5 # see real types/statuses/priorities in use
jira issue view PROJ-123 --raw | jq '.fields | {type:.issuetype.name, status:.status.name, priority:.priority.name, resolution:.resolution.name}'
jira issue view PROJ-123 --raw | jq '.fields | keys' # custom field IDs (customfield_XXXXX)
For transitions specifically, the valid target states depend on the issue's current status and the project workflow — there is no global list. The reliable move is: read the issue, see its status, and use the exact target-state string the workflow allows (often surfaced in the Jira UI's transition buttons). When unsure, run jira issue move <KEY> interactively once to see the offered states, then script the exact string with --no-input-style full args. Full discovery recipes: references/config-auth.md.
Command map
| Goal | Command | Notes |
|---|---|---|
| Who am I / is auth working | jira me, jira serverinfo | $(jira me) is the self-reference idiom |
| List/search issues | jira issue list (aliases ls, search) | Filters + JQL; see references/jql-and-filters.md |
| View one issue | jira issue view KEY | --comments N, --raw for JSON |
| Create issue | jira issue create -t<Type> -s"..." --no-input | -P parent (epic link / required for sub-task) |
| Edit issue | jira issue edit KEY ... --no-input | --label appends, --component replaces (asymmetric!) |
| Transition | jira issue move KEY "State" (aliases transition, mv) | --comment/-a/-R inline; state is workflow-defined |
| Assign | `jira issue assign KEY <user | $(jira me) |
| Comment | jira issue comment add KEY "body" | --internal for service-desk-internal; markdown→ADF |
| Worklog | jira issue worklog add KEY "2d 1h 30m" --no-input | --started, --timezone, --new-estimate |
| Link / unlink | jira issue link IN OUT <Type> / unlink / link remote | <Type> is instance-defined (Blocks, Duplicates, …) |
| Clone | jira issue clone KEY -H"find:replace" | copy + tweak fields |
| Delete (permanent) | jira issue delete KEY [--cascade] | irreversible; --cascade also deletes subtasks |
| Epics | jira epic list [KEY] / create -n"Name" / add / remove | create needs -n/--name; add/remove ≤50 at once |
| Sprints | jira sprint list [ID] / add / close | --current/--prev/--next/--state; get IDs from --table |
| Releases (versions) | jira release list [-p PROJ] | requires Releases/Versions enabled on the instance |
| Open in browser | jira open [KEY] | --no-browser prints the URL instead |
| Projects / boards | jira project list, jira board list | discovery |
Full flag tables, arguments, and aliases for every command: references/commands.md.
The automation contract (read this before scripting)
Output flags (reads) — bare list/view open an interactive UI, so any piping needs one of:
--plain(+--no-headers,--no-truncate,--columns key,summary,status,--delimiter "|") — tabular text; column names come from--help.--raw— Jira REST JSON (parse withjq; shape.[].fields.*).--csv— CSV with headers.--paginate <limit>— cap result count (max 100). Jira Cloud, v1.7.0: the<from>:offset is silently ignored — Atlassian's new JQL search API droppedstartAt, so there is no way to page past the first 100 issues (#898). Narrow with JQL/filters instead. Server/Data Center (older API) still honors<from>:<limit>.
Write flags:
--no-input— the load-bearing flag. Disables prompting for non-required fields. Pair with every required flag so the command runs unattended.--web— open the result in a browser after the write (skip in headless/CI).
Idioms:
# Self-reference
ME=$(jira me)
# Create → capture key → act on it
KEY=$(jira issue create -tTask -s"Automated task" --no-input --raw | jq -r '.key')
jira issue assign "$KEY" "$ME"
jira issue move "$KEY" "In Progress"
# Bulk: list keys, then loop
for k in $(jira issue list -q'assignee = currentUser() AND status = "To Do"' --plain --columns key --no-headers); do
jira issue move "$k" "In Progress" --comment "Picking up"
done
More patterns (CSV/JSON pipelines, dashboards, safe bulk edits): references/scripting.md.
Critical pitfalls
-
Forgetting
--no-inputon a write hangs the process. In a non-interactive context (CI, agent,&&chain) this looks like the command "froze". Everycreate/edit/assign/move/comment add/worklog addin a script needs--no-inputplus all required positional/flag values. Known bug: even with--no-input, the body-reading writes (create,edit,comment add,epic create) can still block on stdin when it's a socket/subprocess pipe — jira-cli treats "stdin is not a TTY" as "read the body from stdin" and waits for EOF (#948/#984). Append</dev/nullwhen shelling out from an agent. -
Guessing field values.
-tBug,-sDone,-yHigh,link ... Blocksall reference instance-defined, case-sensitive strings. Run Step-0 discovery first. A failed write with "specify a valid issue type" / "field cannot be set" almost always means the value doesn't exist on that project. -
editappend-vs-replace asymmetry.--labeland--fix-versionappend/add;--componentreplaces. Remove an existing value by prefixing minus:jira issue edit KEY --label -stale --label fresh --component -OldComp --component NewComp --no-input. Expecting--label newto replace the label set is a classic mistake — it only adds. -
-b/--bodyand the positional comment body beat--template. If both are passed, the flag/positional wins and the template is silently ignored. Use one or the other. -
Epic creation quirks.
jira epic create -n"Epic name" -s"Summary" [-b"body"] --no-inputworks non-interactively on both classic and next-gen. Two gotchas:-n/--nameis required even on next-gen (where its value is then ignored — the mandatory check still demands it), andepic createhas no--rawflag (it printsEpic created\n<url>). To capture the new key as JSON, usejira issue create -tEpic -s"…" --no-input --rawinstead (Epic is an issue type), then attach children with-P/--parent EPIC-KEY(the flag is "parent" because next-gen reuses the parent relationship). The? Epic Keyprompt comes fromepic addwhen itsEPIC-KEYarg is missing — not from create. -
Sub-tasks require
-P/--parent, and the parent must be a type that allows sub-tasks. "Given parent work item does not belong to appropriate hierarchy" means-Ppoints at something (e.g. an epic, or another sub-task) that can't hold sub-tasks. -
deleteis irreversible and--cascadedeletes subtasks too. Never run it speculatively on someone's behalf — confirm the key and intent first. There is no undo. -
Markdown → ADF is lossy. Prefer GitHub fenced code blocks (
```) over Jira{code}(which can leak escape characters).~~strike~~renders as-text-;@usermentions need Jira's[~accountid]form; emoji shortcodes (:rocket:) and raw HTML are dropped. For anything structured, use--template file.mdand test on one issue first. Details:references/markdown-adf.md. -
Assignee/watcher must match exactly. Pass an exact email or display name. On many Jira Cloud instances, GDPR strict mode means assignment resolves by accountId — if
assign KEY "Jane Doe"fails, try the email, or look up the accountId viajira issue view ... --raw.xunassigns;defaultuses the project's default assignee. -
-q/--jqlruns within the configured project's context. To query across all projects, add a project clause yourself:-q'project IS NOT EMPTY'or name projects in the JQL. Plain filter flags (-s,-y,-l, …) and a-qJQL can combine. -
Auth is via the
JIRA_API_TOKENenvironment variable, not the config file. The token never lives in.config.yml. Cloud wants an API token (not the account password); on-prem basic wants the password; PAT wants the token plusJIRA_AUTH_TYPE=bearer. A 401 is nearly always a missing/wrongJIRA_API_TOKENor the wrong auth type. Seereferences/config-auth.md. -
Cloud vs Server/Data Center differ. Some features and
--rawJSON fields vary by backend; non-English on-prem instances may need manualepic.name/epic.link/issue.types.*.handleentries in the config. Don't assume Cloud behavior on Server.
What to read next
| File | Read when… |
|---|---|
references/commands.md | Looking up exact flags, arguments, aliases for any command. Full v1.7.0 surface. |
references/jql-and-filters.md | Building a list/epic list/sprint list query — filter flags, the date syntax (week, -7d, 2025-09-15), ~ negation, x unassigned, JQL examples. |
references/markdown-adf.md | Writing a description/comment with formatting — GFM vs Jira markup, ADF conversion limits, templates, here-docs, $'...' newlines. |
references/scripting.md | Automating — non-interactive recipes, --raw+jq and --csv pipelines, safe bulk edits, capturing created keys, dashboards. |
references/config-auth.md | First-time setup, multi-instance configs, every auth type (Cloud/basic/PAT/mTLS), env vars, and the full instance-discovery recipes. |
references/troubleshooting.md | A specific error or symptom — hangs, 401s, "valid issue type", parent-hierarchy errors, empty output, pager weirdness. |
references/known-issues.md | Tracking an upstream bug the skill works around — (#NNN) tags in the body map to this table (status, what it affects). |
references/sources.md | Verifying or freshening external claims; per-row Last verified dates. |
Quick recipes
# Smoke test: am I connected and what can I see?
jira me && jira project list
# List my open issues, parseable
jira issue list -q'assignee = currentUser() AND statusCategory != Done' \
--plain --no-headers --columns key,status,summary
# Create a bug, non-interactively, and print its key
jira issue create -tBug -s"Login 500 on submit" -yHigh -lregression \
-b$'## Steps\n1. ...\n\n## Expected\n...' --no-input --raw | jq -r '.key'
# Transition with a comment and resolution
jira issue move PROJ-42 "Done" -RFixed --comment "Shipped in 1.2.3"
# Export everything in a project to CSV
jira issue list -p PROJ --csv --paginate 0:100 > issues.csv
# Add a sub-task under a story
jira issue create -t"Sub-task" -P PROJ-100 -s"Write tests" --no-input
For anything beyond these, drill into the references/ files — they carry the exhaustive flag tables, JQL grammar, ADF rules, and auth matrix.