From atlassian
Search Jira, manage issues, add comments, transition work, and inspect sprints.
npx claudepluginhub pgoell/pgoell-claude-tools --plugin atlassianThis skill uses the workspace's default tool permissions.
Interact with Jira Cloud: search issues, create and update tickets, transition workflows, add comments, manage sprints, and perform bulk operations.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
Interact with Jira Cloud: search issues, create and update tickets, transition workflows, add comments, manage sprints, and perform bulk operations.
Do NOT check authentication upfront. Just run the command. If it fails with an auth error, see the Self-Healing section for diagnostics.
NEVER print, echo, or log the values of ATLASSIAN_API_TOKEN, ATLASSIAN_EMAIL, or any credentials. Only check whether they are set (e.g., test -n), never display their contents.
Prefer raw curl for all operations. It has the fewest dependencies and the clearest behavior. Only fall back to acli for the handful of things curl can't do ergonomically — bulk transitions (--jql + --yes) and some sprint operations.
Pattern for all curl requests:
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
"https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/..."
For write operations, add:
-H "Content-Type: application/json" -X POST -d '...'
curl:
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/search/jql" \
-d '{"jql": "assignee = currentUser() AND resolution = Unresolved", "maxResults": 50}'
acli (fallback):
acli jira workitem search --jql "assignee = currentUser() AND resolution = Unresolved" --json
curl:
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
"https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issue/KEY-123"
acli (fallback):
acli jira workitem view KEY-123 --json
acli:
acli jira project list
curl:
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
"https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/project/search"
acli:
acli jira workitem comment list --key KEY-123
curl:
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
"https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issue/KEY-123/comment"
List sprints for a board:
acli jira board list-sprints --board-id {id}
List work items in a sprint:
acli jira sprint list-workitems --sprint-id {id}
For sprint operations without acli, use the Jira Agile REST API (/rest/agile/1.0/...).
Before creating a user story, task, or research/design ticket, ask the user:
Do you have a ticket template or writing guide you'd like me to follow (e.g., a team standard for Description + Acceptance Criteria)?
If not, I can use the default template in
ticket-template.md— it structures Context, Deliverable, Scope, Stakeholders, Timebox, References, and Acceptance Criteria checkboxes.
If the user has their own template, follow it. If they opt into the default (or don't have one), read ticket-template.md and structure the --summary, --description, and acceptance criteria fields according to it. For trivial bug reports or quick one-line tasks, skip the prompt unless the user explicitly asks for a structured ticket.
curl (requires ADF body for description — see adf-format.md):
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issue" \
-d '{
"fields": {
"project": {"key": "PROJ"},
"summary": "Implement rate limiting",
"issuetype": {"name": "Task"},
"description": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [{"type": "text", "text": "Add rate limiting to auth endpoints to prevent brute-force attacks."}]
}
]
}
}
}'
acli (fallback, plain text — no ADF needed):
acli jira workitem create \
--project PROJ \
--type Task \
--summary "Implement rate limiting" \
--description "Add rate limiting to auth endpoints to prevent brute-force attacks."
curl (requires ADF body):
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issue/KEY-123/comment" \
-d '{
"body": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [{"type": "text", "text": "Investigated the issue. Root cause identified. Fix incoming."}]
}
]
}
}'
acli (fallback, plain text):
acli jira workitem comment create --key KEY-123 --body "Investigated the issue. Root cause identified. Fix incoming."
curl:
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-X PUT "https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issue/KEY-123" \
-d '{
"fields": {
"summary": "Updated summary",
"labels": ["backend", "urgent"]
}
}'
acli (fallback):
acli jira workitem edit --key KEY-123 --summary "Updated summary" --description "New description" --labels "backend,urgent"
curl (must fetch transition IDs first, then POST):
# Step 1: Get available transitions
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
"https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issue/KEY-123/transitions"
# Step 2: POST with the transition ID from step 1
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issue/KEY-123/transitions" \
-d '{"transition": {"id": "31"}}'
acli (fallback, uses status name directly):
acli jira workitem transition --key KEY-123 --status "Done"
curl:
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-X PUT "https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issue/KEY-123/assignee" \
-d '{"accountId": "5b10ac8d82e05b22cc7d4ef5"}'
Note: with curl, you must know the user's accountId. Use GET /rest/api/3/myself to get the current user's account ID for self-assignment.
acli (fallback):
acli jira workitem assign --key KEY-123 --assignee "@me"
curl:
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issueLink" \
-d '{
"type": {"name": "Blocks"},
"inwardIssue": {"key": "KEY-123"},
"outwardIssue": {"key": "KEY-456"}
}'
acli (fallback):
acli jira workitem link create --inward-key KEY-123 --outward-key KEY-456 --type "Blocks"
acli (transition all matching issues at once):
acli jira workitem transition \
--jql "project = PROJ AND status = 'To Do'" \
--status "In Progress" \
--yes
Bulk operations are an acli-only feature. With curl, loop over search results and POST transitions individually.
See jql-recipes.md for common JQL patterns including:
See ticket-template.md for the default structure to use when creating user stories, research tickets, or design tickets (Description + Acceptance Criteria). Always ask the user first whether they have their own template before falling back to this one.
See adf-format.md for the Atlassian Document Format reference.
ADF is required for curl write operations (create issue descriptions, add comments, update descriptions). When falling back to acli, pass plain text directly — no ADF required.
When an API call or acli command fails:
Check which auth paths are available — never print token or credential values:
# Check if acli is available and authenticated
command -v acli && acli auth status
# Check if env vars are set (NOT their values)
test -n "${ATLASSIAN_DOMAIN:-}" && echo "ATLASSIAN_DOMAIN is set" || echo "ATLASSIAN_DOMAIN is NOT set"
test -n "${ATLASSIAN_EMAIL:-}" && echo "ATLASSIAN_EMAIL is set" || echo "ATLASSIAN_EMAIL is NOT set"
test -n "${ATLASSIAN_API_TOKEN:-}" && echo "ATLASSIAN_API_TOKEN is set" || echo "ATLASSIAN_API_TOKEN is NOT set"
If neither auth path is available, tell the user:
I cannot connect to Jira. You need one of these:
Option A (recommended): Install and authenticate the Atlassian CLI:
acli auth loginOption B: Set these environment variables:
ATLASSIAN_DOMAIN— your subdomain (e.g.,mycompanyformycompany.atlassian.net)ATLASSIAN_EMAIL— your Atlassian account emailATLASSIAN_API_TOKEN— generate one at https://id.atlassian.com/manage/api-tokens
acli [command] --help for current flags and syntaxhttps://developer.atlassian.com/cloud/jira/platform/rest/v3/https://developer.atlassian.com/cloud/acli/reference/commands/When you need to find available fields or issue types:
# Available issue types and fields for a project
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
"https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/issue/createmeta/PROJ/issuetypes"
# All available fields in the instance
curl -s -u "$ATLASSIAN_EMAIL:$ATLASSIAN_API_TOKEN" \
-H "Accept: application/json" \
"https://$ATLASSIAN_DOMAIN.atlassian.net/rest/api/3/field"
assignee = currentUser() AND resolution = Unresolved. "What's in the current sprint?" becomes sprint in openSprints().acli only for bulk operations (--jql + --yes) and sprint management.--json with acli when you need to parse structured output programmatically./issue/PROJ-123/transitions, then POST the matching transition ID/myself for accountId, then PUT /issue/PROJ-123/assignee/search/jql with assignee = currentUser() AND statusCategory = 'In Progress'/issue with ADF descriptionticket-template.md and structure the description + acceptance criteria accordingly. Skip this prompt for trivial bugs or one-line tasks.