---
sidebar_position: 6
title: Jira
---

# Jira skill

Read/write Jira Cloud — search issues, manage sprints, transition tickets, manage comments. Backed by a custom Zibby MCP server (`@zibby/mcp-jira`).

- **ID:** `jira`
- **MCP server:** `jira` (tools exposed as `mcp__jira__*`)

## Tools provided

| Tool | What it does |
|---|---|
| `jira_list_projects` | List all accessible Jira projects |
| `jira_list_statuses` | Status catalog. Pass `projectKey` for the project workflow's statuses; omit for the global catalog |
| `jira_list_issue_types` | Issue types allowed for issue creation in a `projectKey` |
| `jira_search` | JQL search. Auto-bounds queries with `created >= -365d` if no `ORDER BY` is given |
| `jira_get_issue` | Full details for an `issueKey` |
| `jira_create_issue` | Create an issue. Supports `moveToSprint` + `sprintId`/`sprintName`/`target` for atomic "create and place in sprint" |
| `jira_list_sprints` | Sprints for a project, optionally filtered by `state` (`active`/`closed`/`future`) |
| `jira_get_sprint_issues` | Issues in a sprint, optionally filtered by status — returns status breakdown |
| `jira_move_issue_to_sprint` | Move an issue to a sprint by id, name, or target (`current`/`active`/`latest`) with membership verification |
| `jira_get_comments` | Comments on an issue (newest first), ADF flattened to markdown |
| `jira_add_comment` | Add a plain-text comment |
| `jira_edit_issue` | PUT arbitrary fields (summary, labels, priority, story points, custom fields) |
| `jira_transition_issue` | Move to another status by `transitionId` or `toStatus`; lists available transitions when neither is provided |

## Setup

Jira uses Atlassian OAuth 2.0 (3LO).

1. In the Zibby dashboard, **Settings → Integrations → Connect Jira**.
2. Authorize Zibby for your Atlassian site.
3. In **Settings → Jira Configuration**, pick the project/space to use as the default.

See the [Jira Integration page](../integrations/jira.md) for the user-facing setup. Tokens auto-refresh; reconnect from the same panel if refresh fails.

Under the hood the bin reads `ATLASSIAN_ACCESS_TOKEN` + `ATLASSIAN_CLOUD_ID` (and optional `ATLASSIAN_INSTANCE_URL`), which the backend supplies through `resolveIntegrationToken('jira')`.

## Use in an agent

```js
import { WorkflowAgent, WorkflowGraph } from '@zibby/core';
import { SKILLS } from '@zibby/skills';

export class StandupBot extends WorkflowAgent {
  buildGraph() {
    const graph = new WorkflowGraph();
    graph.addNode('standup', {
      agent: 'claude',
      skills: [SKILLS.JIRA],
      prompt: (state) => `List active sprints for project ${state.projectKey}.
      For the current sprint, call jira_get_sprint_issues to get a status breakdown,
      then produce a standup-style summary grouped by assignee.`,
    });
    return graph;
  }
}
```

### Transitioning issues

The prompt fragment instructs the model to call `jira_transition_issue({ issueKey, toStatus })` directly when the user gives an explicit target; only when ambiguous should it call without `transitionId`/`toStatus` to list options. Status matching is normalized (whitespace, punctuation, case), then alias-matched, then dice-coefficient fuzzy-matched at a 0.45 threshold with a 0.12 gap.

### Sprint membership

To move an issue to a sprint, use `jira_move_issue_to_sprint` — it picks the right sprint (id/name/target), writes `customfield_10020`, then verifies membership via JQL and a second issue read before reporting success.

## Output example

`jira_get_sprint_issues`:

```json
{
  "count": 12,
  "total": 12,
  "statusCounts": { "To Do": 4, "In Progress": 5, "Done": 3 },
  "issues": [
    {
      "key": "SCRUM-123",
      "project": "SCRUM",
      "summary": "Refresh token on 401",
      "status": "In Progress",
      "assignee": "Alice",
      "priority": "High",
      "type": "Story"
    }
  ]
}
```

## Implementation notes

`resolve()` spawns `@zibby/mcp-jira` (`node @zibby/mcp-jira/index.js`) with the OAuth bearer token and cloud id in env. If the bin can't be resolved, `resolve()` returns `null` and the strategy falls back to in-process tool dispatch via `handleToolCall` (used by the `assistant` agent strategy).

`jiraFetch` clears the integration-token cache and retries once on auth-looking errors — the token endpoint can return a malformed payload mid-rotation. ADF (Atlassian Document Format) bodies are flattened to markdown in `jira_get_comments` so the model sees readable text instead of nested JSON.
