Jira Issue Management
Create and manage Jira issues using the Jira REST API or MCP.
Setup
Option 1: Jira MCP Server
Install the Jira MCP server for seamless integration:
bash1npx @anthropic/create-mcp-server jira
Option 2: Direct API
Set environment variables:
bash1export JIRA_BASE_URL="https://yourcompany.atlassian.net" 2export JIRA_EMAIL="your-email@company.com" 3export JIRA_API_TOKEN="your-api-token"
Get your API token: https://id.atlassian.com/manage-profile/security/api-tokens
Creating Issues
Basic Issue
python1import requests 2from requests.auth import HTTPBasicAuth 3import os 4 5def create_issue(project_key, summary, description, issue_type="Task"): 6 url = f"{os.environ['JIRA_BASE_URL']}/rest/api/3/issue" 7 8 auth = HTTPBasicAuth( 9 os.environ['JIRA_EMAIL'], 10 os.environ['JIRA_API_TOKEN'] 11 ) 12 13 payload = { 14 "fields": { 15 "project": {"key": project_key}, 16 "summary": summary, 17 "description": { 18 "type": "doc", 19 "version": 1, 20 "content": [{ 21 "type": "paragraph", 22 "content": [{"type": "text", "text": description}] 23 }] 24 }, 25 "issuetype": {"name": issue_type} 26 } 27 } 28 29 response = requests.post(url, json=payload, auth=auth) 30 return response.json() 31 32# Example 33issue = create_issue("PROJ", "Fix login bug", "Users can't login with SSO", "Bug") 34print(f"Created: {issue['key']}")
With Labels and Priority
python1def create_detailed_issue(project_key, summary, description, 2 issue_type="Task", priority="Medium", 3 labels=None, assignee=None): 4 payload = { 5 "fields": { 6 "project": {"key": project_key}, 7 "summary": summary, 8 "description": { 9 "type": "doc", 10 "version": 1, 11 "content": [{ 12 "type": "paragraph", 13 "content": [{"type": "text", "text": description}] 14 }] 15 }, 16 "issuetype": {"name": issue_type}, 17 "priority": {"name": priority}, 18 } 19 } 20 21 if labels: 22 payload["fields"]["labels"] = labels 23 if assignee: 24 payload["fields"]["assignee"] = {"accountId": assignee} 25 26 # ... make request
Common Issue Types
| Type | Use For |
|---|---|
| Bug | Something broken |
| Task | Work item |
| Story | User-facing feature |
| Epic | Large initiative |
| Sub-task | Part of larger task |
Updating Issues
Change Status
python1def transition_issue(issue_key, transition_name): 2 # Get available transitions 3 url = f"{JIRA_BASE_URL}/rest/api/3/issue/{issue_key}/transitions" 4 transitions = requests.get(url, auth=auth).json() 5 6 # Find matching transition 7 transition_id = None 8 for t in transitions['transitions']: 9 if t['name'].lower() == transition_name.lower(): 10 transition_id = t['id'] 11 break 12 13 # Execute transition 14 requests.post(url, json={"transition": {"id": transition_id}}, auth=auth)
Add Comment
python1def add_comment(issue_key, comment_text): 2 url = f"{JIRA_BASE_URL}/rest/api/3/issue/{issue_key}/comment" 3 4 payload = { 5 "body": { 6 "type": "doc", 7 "version": 1, 8 "content": [{ 9 "type": "paragraph", 10 "content": [{"type": "text", "text": comment_text}] 11 }] 12 } 13 } 14 15 requests.post(url, json=payload, auth=auth)
Searching Issues
JQL Queries
python1def search_issues(jql): 2 url = f"{JIRA_BASE_URL}/rest/api/3/search" 3 params = {"jql": jql, "maxResults": 50} 4 response = requests.get(url, params=params, auth=auth) 5 return response.json()['issues'] 6 7# Examples 8my_bugs = search_issues("project = PROJ AND type = Bug AND assignee = currentUser()") 9open_items = search_issues("project = PROJ AND status != Done") 10recent = search_issues("project = PROJ AND created >= -7d")
Quick Commands
When user says... create this:
| Command | Action |
|---|---|
| "log bug about X" | Bug issue with description |
| "create task for X" | Task issue |
| "what's on my plate" | JQL: assignee = currentUser() AND status != Done |
| "move X to done" | Transition issue to Done |
| "add comment to X" | Add comment to issue |
Best Practices
- Summary: Keep under 80 chars, start with verb (Fix, Add, Update)
- Description: Include steps to reproduce for bugs
- Labels: Use for categorization (frontend, backend, urgent)
- Links: Reference related issues when relevant