# Jira Issue Manager

> Use when the user mentions Jira issues (e.g., "PROJ-123"), asks about tickets, wants to create/view/update issues, check sprint status, or manage their Jira workflow. Triggers on keywords like "jira", "issue", "ticket", "sprint", "backlog", or issue key patterns.

- Skill: `shalomb/jira-issue-manager` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add shalomb/jira-issue-manager`
- Raw SKILL.md: https://api.skillmd.com/api/skills/shalomb/jira-issue-manager/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: shalomb (https://skillmd.com/u/shalomb)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/shalomb/jira-issue-manager

---


# Jira

Natural language interaction with Jira. Supports multiple backends.

## Backend Detection

**Run this check first** to determine which backend to use:

```
1. Check if jira CLI is available:
   → Run: which jira
   → If found: USE CLI BACKEND

2. If no CLI, check for Atlassian MCP:
   → Look for mcp__atlassian__* tools
   → If available: USE MCP BACKEND

3. If neither available:
   → GUIDE USER TO SETUP
```

| Backend | When to Use | Reference |
|---------|-------------|-----------|
| **CLI** | `jira` command available | `references/commands.md` |
| **MCP** | Atlassian MCP tools available | `references/mcp.md` |
| **None** | Neither available | Guide to install CLI |

---

## Quick Reference (CLI)

> Skip this section if using MCP backend.

| Intent | Command |
|--------|---------|
| View issue | `jira issue view ISSUE-KEY` |
| List my issues | `jira issue list -a$(jira me)` |
| My in-progress | `jira issue list -a$(jira me) -s"In Progress"` |
| Create issue | `jira issue create -tType -s"Summary" -b"Description"` |
| Move/transition | `jira issue move ISSUE-KEY "State"` |
| Assign to me | `jira issue assign ISSUE-KEY $(jira me)` |
| Unassign | `jira issue assign ISSUE-KEY x` |
| Add comment | `jira issue comment add ISSUE-KEY -b"Comment text"` |
| Open in browser | `jira open ISSUE-KEY` |
| Current sprint | `jira sprint list --state active` |
| Who am I | `jira me` |

---

## Quick Reference (MCP)

> Skip this section if using MCP backend.

| Intent | MCP Tool |
|--------|----------|
| Search issues | `mcp__atlassian__searchJiraIssuesUsingJql` |
| View issue | `mcp__atlassian__getJiraIssue` |
| Create issue | `mcp__atlassian__createJiraIssue` |
| Update issue | `mcp__atlassian__editJiraIssue` |
| Get transitions | `mcp__atlassian__getTransitionsForJiraIssue` |
| Transition | `mcp__atlassian__transitionJiraIssue` |
| Add comment | `mcp__atlassian__addCommentToJiraIssue` |
| User lookup | `mcp__atlassian__lookupJiraAccountId` |
| List projects | `mcp__atlassian__getVisibleJiraProjects` |

See `references/mcp.md` for full MCP patterns.

---

## Triggers

- "create a jira ticket"
- "show me PROJ-123"
- "list my tickets"
- "move ticket to done"
- "what's in the current sprint"

---

## Issue Key Detection

Issue keys follow the pattern: `[A-Z]+-[0-9]+` (e.g., PROJ-123, ABC-1).

When a user mentions an issue key in conversation:
- **CLI:** `jira issue view KEY` or `jira open KEY`
- **MCP:** `mcp__atlassian__jira_get_issue` with the key

---

## Workflow

**Creating tickets:**
1. Research context if user references code/tickets/PRs
2. Draft ticket content
3. Review with user
4. Create using appropriate backend

**Updating tickets:**
1. Fetch issue details first
2. Check status (careful with in-progress tickets)
3. Show current vs proposed changes
4. Get approval before updating
5. Add comment explaining changes

---

## Before Any Operation

Ask yourself:

1. **What's the current state?** — Always fetch the issue first. Don't assume status, assignee, or fields are what user thinks they are.

2. **Who else is affected?** — Check watchers, linked issues, parent epics. A "simple edit" might notify 10 people.

3. **Is this reversible?** — Transitions may have one-way gates. Some workflows require intermediate states. Description edits have no undo.

4. **Do I have the right identifiers?** — Issue keys, transition IDs, account IDs. Display names don't work for assignment (MCP).

---

## NEVER

- **NEVER transition without fetching current status** — Workflows may require intermediate states. "To Do" → "Done" might fail silently if "In Progress" is required first.

- **NEVER assign using display name (MCP)** — Only account IDs work. Always call `lookupJiraAccountId` first, or assignment silently fails.

- **NEVER edit description without showing original** — Jira has no undo. User must see what they're replacing.

- **NEVER use `--no-input` without all required fields (CLI)** — Fails silently with cryptic errors. Check project's required fields first.

- **NEVER assume transition names are universal** — "Done", "Closed", "Complete" vary by project. Always get available transitions first.

- **NEVER bulk-modify without explicit approval** — Each ticket change notifies watchers. 10 edits = 10 notification storms.

---

## Safety

- Always show the command/tool call before running it
- Always get approval before modifying tickets
- Preserve original information when editing
- Verify updates after applying
- Always surface authentication issues clearly so the user can resolve them

---

## No Backend Available

If neither CLI nor MCP is available, guide the user:

```
To use Jira, you need one of:

1. **jira CLI** (recommended):
   https://github.com/ankitpokhrel/jira-cli

   Install: brew install ankitpokhrel/jira-cli/jira-cli
   Setup:   jira init

2. **Atlassian MCP**:
   Configure in your MCP settings with Atlassian credentials.
```

---

## Deep Dive

**LOAD reference when:**
- Creating issues with complex fields or multi-line content
- Building JQL queries beyond simple filters
- Troubleshooting errors or authentication issues
- Working with transitions, linking, or sprints

**Do NOT load reference for:**
- Simple view/list operations (Quick Reference above is sufficient)
- Basic status checks (`jira issue view KEY`)
- Opening issues in browser

| Task | Load Reference? |
|------|-----------------|
| View single issue | No |
| List my tickets | No |
| Create with description (no links) | **Yes** — CLI needs `/tmp` pattern |
| Edit description with hyperlinks | **Yes** — `references/jira-cloud-adf.md` — CLI breaks links; use REST API v3 + ADF JSON |
| Write a PI epic description | **Yes** — `references/epic-template.md` + `references/jira-cloud-adf.md` |
| Transition issue | **Yes** — need transition ID workflow |
| Transition with required fields (project validators) | **Yes** — `references/workflow-transition.md` — CLI shows success but may silently roll back |
| JQL search | **Yes** — for complex queries |
| Link issues | **Yes** — MCP limitation, need script |
| Post rich comment (ADF with hyperlinks) | **Yes** — CLI strips links; use REST API v3 + ADF JSON via `~/.netrc` |
| Read a Jira board (kanban/scrum) | **Yes** — board UI URLs are not readable; use Agile REST API |
| Bulk close multiple epics | **Yes** — comment + transition pattern; see below |

References:
- CLI patterns + gotchas: `references/commands.md`
- MCP patterns: `references/mcp.md`
- PI epic template: `references/epic-template.md`
- Jira Cloud ADF (description rendering, hyperlinks): `references/jira-cloud-adf.md`

---

## REST API Fallback (when CLI is insufficient)

Use the Jira REST API v3 directly for operations the CLI cannot handle well.
Credentials from `~/.netrc` (machine `<your-jira-host>`):

```python
import netrc, base64, urllib.request, json

n = netrc.netrc()
login, _, password = n.authenticators('<your-jira-host>')
creds = base64.b64encode(f'{login}:{password}'.encode()).decode()
headers = {'Authorization': f'Basic {creds}', 'Content-Type': 'application/json', 'Accept': 'application/json'}
```

### Post ADF comment with hyperlinks

```python
body = {
  'body': {
    'type': 'doc', 'version': 1,
    'content': [
      {'type': 'paragraph', 'content': [
        {'type': 'text', 'text': 'See ', 'marks': []},
        {'type': 'text', 'text': 'issue #42', 'marks': [{'type': 'link', 'attrs': {'href': 'https://github.com/org/repo/issues/42'}}]},
      ]}
    ]
  }
}
# POST to /rest/api/3/issue/PROJ-123/comment
```

### Transition an issue

```python
# 1. Get available transitions
GET /rest/api/3/issue/PROJ-123/transitions

# 2. Apply by ID
POST /rest/api/3/issue/PROJ-123/transitions
{"transition": {"id": "61"}}
```

### Link issues

```python
# Get link types first
GET /rest/api/3/issueLinkType

# Create link
POST /rest/api/3/issueLink
{
  "type": {"id": "10003"},           # "Relates" — check your instance for IDs
  "inwardIssue": {"key": "PROJ-1"},
  "outwardIssue": {"key": "PROJ-2"}
}
```

### Read a Jira board

Board UI URLs (`/jira/software/c/projects/X/boards/Y`) are not readable by web fetch.
Use the Agile REST API instead:

```python
GET /rest/agile/1.0/board/{board-id}/issue?maxResults=50
```

Returns issues on the board with `key`, `status`, `summary`, `assignee`.
Paginate with `startAt=N`.

---

## Bulk Epic Closure Pattern

When closing multiple epics at end of a PI:

1. **Draft a closure comment** for each — include carry-forward destination, GitHub issue links, and continuation epic references
2. **Post comment** via REST API (ADF for hyperlinks) or CLI for plain text
3. **Fetch available transitions**: `GET /rest/api/3/issue/KEY/transitions` — confirm "Done" transition ID
4. **Transition to Done**: `POST /rest/api/3/issue/KEY/transitions` with the transition ID
5. **Verify** with `jira issue view KEY` — check status is Done

Do all four steps per epic before moving to the next. Do not batch transitions without confirming each comment posted first.

