Claude-skill-registry jira-agile
Manage Jira Agile boards and sprints. Use when listing boards, creating sprints, or moving issues to/from sprints.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/jira-agile" ~/.claude/skills/majiayu000-claude-skill-registry-jira-agile && rm -rf "$T"
manifest:
skills/data/jira-agile/SKILL.mdsource content
Jira Agile Skill
Purpose
Manage Jira Agile boards and sprints - list boards, manage sprints, move issues to sprints.
When to Use
- Listing Scrum/Kanban boards
- Managing sprints (create, start, end)
- Moving issues to/from sprints
- Getting sprint issues
Prerequisites
- Authenticated JiraClient (see jira-auth skill)
- Board/sprint management permissions
- Note: Uses
NOT/rest/agile/1.0//rest/api/3/
Implementation Pattern
Step 1: Create Agile Client Extension
class JiraAgileClient extends JiraClient { async agileRequest<T>(path: string, options: RequestInit = {}): Promise<T> { const url = `${this.baseUrl}/rest/agile/1.0${path}`; const response = await fetch(url, { ...options, headers: { ...this.headers, ...options.headers }, }); if (!response.ok) { const error = await response.json().catch(() => ({})); throw new Error(`Jira Agile API error: ${response.status} - ${JSON.stringify(error)}`); } return response.json(); } }
Step 2: List Boards
interface Board { id: number; self: string; name: string; type: 'scrum' | 'kanban'; projectKey?: string; } interface BoardsResponse { values: Board[]; startAt: number; maxResults: number; total: number; isLast: boolean; } async function listBoards( client: JiraAgileClient, options: { type?: 'scrum' | 'kanban'; projectKeyOrId?: string; maxResults?: number; } = {} ): Promise<Board[]> { const params = new URLSearchParams(); if (options.type) params.set('type', options.type); if (options.projectKeyOrId) params.set('projectKeyOrId', options.projectKeyOrId); if (options.maxResults) params.set('maxResults', String(options.maxResults)); const response = await client.agileRequest<BoardsResponse>( `/board?${params.toString()}` ); return response.values; }
Step 3: Get Board Sprints
interface Sprint { id: number; self: string; state: 'future' | 'active' | 'closed'; name: string; startDate?: string; endDate?: string; goal?: string; } async function getBoardSprints( client: JiraAgileClient, boardId: number, state?: 'future' | 'active' | 'closed' | string ): Promise<Sprint[]> { const params = state ? `?state=${state}` : ''; const response = await client.agileRequest<{ values: Sprint[] }>( `/board/${boardId}/sprint${params}` ); return response.values; }
Step 4: Get Sprint Issues
interface SprintIssue { id: string; key: string; self: string; fields: { summary: string; status: { name: string }; assignee?: { displayName: string }; }; } async function getSprintIssues( client: JiraAgileClient, sprintId: number, options: { maxResults?: number; startAt?: number; } = {} ): Promise<SprintIssue[]> { const params = new URLSearchParams(); if (options.maxResults) params.set('maxResults', String(options.maxResults)); if (options.startAt) params.set('startAt', String(options.startAt)); const response = await client.agileRequest<{ issues: SprintIssue[] }>( `/sprint/${sprintId}/issue?${params.toString()}` ); return response.issues; }
Step 5: Move Issues to Sprint
async function moveIssuesToSprint( client: JiraAgileClient, sprintId: number, issueKeys: string[], options: { rankBeforeIssue?: string; rankAfterIssue?: string; } = {} ): Promise<void> { await client.agileRequest(`/sprint/${sprintId}/issue`, { method: 'POST', body: JSON.stringify({ issues: issueKeys, ...options, }), }); }
Step 6: Create Sprint
interface CreateSprintInput { name: string; boardId: number; startDate?: string; endDate?: string; goal?: string; } async function createSprint( client: JiraAgileClient, input: CreateSprintInput ): Promise<Sprint> { return client.agileRequest<Sprint>('/sprint', { method: 'POST', body: JSON.stringify({ name: input.name, originBoardId: input.boardId, startDate: input.startDate, endDate: input.endDate, goal: input.goal, }), }); }
Step 7: Start/End Sprint
async function startSprint( client: JiraAgileClient, sprintId: number, startDate: string, endDate: string ): Promise<void> { await client.agileRequest(`/sprint/${sprintId}`, { method: 'POST', body: JSON.stringify({ state: 'active', startDate, endDate, }), }); } async function endSprint( client: JiraAgileClient, sprintId: number ): Promise<void> { await client.agileRequest(`/sprint/${sprintId}`, { method: 'POST', body: JSON.stringify({ state: 'closed', }), }); }
curl Examples
List Boards
curl -X GET "https://mycompany.atlassian.net/rest/agile/1.0/board?type=scrum" \ -H "Authorization: Basic $(echo -n 'email:token' | base64)" \ -H "Accept: application/json"
Get Board Sprints
curl -X GET "https://mycompany.atlassian.net/rest/agile/1.0/board/1/sprint?state=active,future" \ -H "Authorization: Basic $(echo -n 'email:token' | base64)" \ -H "Accept: application/json"
Move Issues to Sprint
curl -X POST "https://mycompany.atlassian.net/rest/agile/1.0/sprint/1/issue" \ -H "Authorization: Basic $(echo -n 'email:token' | base64)" \ -H "Content-Type: application/json" \ -d '{"issues": ["PROJ-123", "PROJ-124"]}'
Create Sprint
curl -X POST "https://mycompany.atlassian.net/rest/agile/1.0/sprint" \ -H "Authorization: Basic $(echo -n 'email:token' | base64)" \ -H "Content-Type: application/json" \ -d '{"name": "Sprint 1", "originBoardId": 1, "goal": "Complete MVP"}'
API Endpoints Summary
| Operation | Method | Path |
|---|---|---|
| List boards | GET | |
| Get board | GET | |
| Get board sprints | GET | |
| Get sprint | GET | |
| Create sprint | POST | |
| Update sprint | PUT | |
| Delete sprint | DELETE | |
| Get sprint issues | GET | |
| Move issues to sprint | POST | |
Common Mistakes
- Using
instead of/rest/api/3//rest/agile/1.0/ - Trying to add issues to closed sprints
- Kanban boards don't have sprints
- Sprint IDs are board-specific
References
Version History
- 2025-12-10: Created