Use jira CLI for Jira operations including issue management, project queries, transitions, and JQL search
jira config init # interactive setup → ~/.config/jira-cli/config.toml
jira config validate # test connection
No env vars. JIRA_URL / JIRA_EMAIL / JIRA_API_TOKEN are intentionally ignored. Use CLI flags --url/--email/--token for one-off overrides.
--format table # default
--format json # array
--format jsonl # one object per line, auto-paginates all results
JSONL is preferred for scripting — pipe directly to jq.
All resources follow: jira <resource> <verb> [args] [flags]
Resources: issues, projects, comments, attachments, worklogs, versions, components, filters, dashboards, issuetypes, statuses, issuelinks, remotelinks, development, plans, users, boards, sprints, fields, goals, screens, automations, auditlog
Read references/commands.md whenever you need exact flags or syntax for any resource.
204 empty response ≠ error. Mutating operations (assign, transition, delete) return HTTP 204. The MCP layer may surface this as an error. Always verify with a GET:
mcp__jira__jira_issues_assign(issue_key, account_id)
issue = mcp__jira__jira_issues_get(issue_key) # verify assignee
Users require account_id. Display names don't work for assignment. Lookup pattern:
1. mcp__jira__jira_users_search(query="Name")
2. extract account_id
3. mcp__jira__jira_issues_assign(issue_key, account_id)
Development API needs numeric ID. jira development * and mcp__jira__jira_development_summary require the internal numeric issue ID, not the key:
ISSUE_ID=$(jira issues get PROJ-123 --format json | jq -r '.id')
jira development pull-requests $ISSUE_ID --application-type github
MCP returns minimal fields by default (~70% token reduction). Use fields param to request additional data.
Goals field cannot be set via REST API. customfield_10025 returns 204 No Content but the field is never updated — /editmeta exposes allowedValues: []. Known bug: JRACLOUD-97866. Link issues to goals through the Jira UI only.
Always use remote links, never file attachments. File attachments do not render correctly in Jira — they appear as raw downloads. Remote links render as clickable chips with the correct application icon.
Google Drive URLs are auto-detected: Docs, Sheets, and Folders each get the correct icon. Non-Google URLs are linked as generic web links.
Never use jira attachments upload for documents — use jira remotelinks add instead. See references/commands.md for syntax.
# Search + stream to jq
jira issues search "project = PROJ AND status = Open" --format jsonl | jq '.fields.status.name'
# Count by status
jira issues search "project = PROJ" --format jsonl \
| jq -r '.fields.status.name' | sort | uniq -c | sort -rn
# Extract issue link edges (for dependency graphs)
jira issues search "issuelinktype is not EMPTY" --fields issuelinks --format jsonl \
| jq -r '.key as $k | .fields.issuelinks[]? |
if .outwardIssue then "\($k),\(.type.outward),\(.outwardIssue.key)"
else "\(.inwardIssue.key),\(.type.inward),\($k)" end'
# List active sprint issues on a board
BOARD_ID=$(jira boards list --format jsonl | jq -r 'select(.name=="My Board") | .id')
jira sprints list --board $BOARD_ID --state active --format jsonl \
| jq -r '.id' \
| xargs -I{} jira issues search "sprint = {}" --format jsonl
assignee = currentUser() AND status != Done
updated >= -7d ORDER BY updated DESC
type = Bug AND priority in (Highest, High)
sprint in openSprints() AND project = PROJ
issuelinktype is not EMPTY AND project = PROJ
Goals use a separate jira goals command group backed by the Atlassian GraphQL API — not Jira REST. Goal type ARIs are workspace-specific; run jira goals list-types to get them.
Hierarchy: Two levels only: GOAL → SUCCESS_MEASURE. A SUCCESS_MEASURE cannot have children.
See references/commands.md for full goal command syntax.
jira api GET "/rest/api/3/issue/PROJ-123?fields=summary,status"
jira api POST "/rest/api/3/search/jql" --data '{"jql":"project=PROJ","fields":["summary"]}'
jira api PUT "/rest/api/3/issue/PROJ-123" --data '{"fields":{"summary":"New title"}}'
Gotcha: /rest/api/3/search is removed — use POST /rest/api/3/search/jql with body {"jql":"...","fields":[...],"maxResults":50}.