Skip to main content
Glama
celigo

Jira Utilities MCP Server

by celigo
README.md
# JIRA Utilities - MCP Server v2.6

> **Complete JIRA automation via Cursor AI + Optimized standalone utilities**

[![MCP Ready](https://img.shields.io/badge/MCP-Ready-brightgreen)](https://modelcontextprotocol.io/)
[![Docker](https://img.shields.io/badge/docker-enabled-blue)](https://www.docker.com/)
[![Version](https://img.shields.io/badge/version-2.6.0-blue)](https://github.com)

---

## Quick Decision: MCP or Standalone?

| Your Task | Issue/Subtask Count | Use This | Time |
|-----------|---------------------|----------|------|
| Quick query | 1-20 | **MCP Prompts** | ~30-60 sec |
| Medium batch | 21-50 | **MCP Prompts** (auto-batched) | ~2-4 min |
| Large batch | 51-100 | **MCP Prompts** (may timeout) | ~5-10 min |
| Very large | 100+ | **npm scripts** (recommended) | ~10-20 min |

**Example**: 35 issues -> MCP auto-batches (2 batches) -> ~70 sec  
**Example**: 196 issues -> Use `npm run pr-reporter` (~15 min)

> **Auto-Batching**: MCP automatically splits requests >20 into manageable chunks with rate limiting. For very large batches (100+), use npm scripts for better performance.

---

## Quick Start

### For Small Batches (1-20 items) - Use MCP

```bash
# 1. Build Docker image
./build-docker.sh

# 2. Configure Cursor MCP (~/.cursor/mcp.json)
{
  "mcpServers": {
    "jira-utilities": {
      "command": "sh",
      "args": [
        "-c",
        "docker run -i --rm -v $HOME/Downloads:/output -e JIRA_EMAIL -e JIRA_API_TOKEN -e OUTPUT_DIR=/output -e TZ -e OPENAI_API_KEY public.ecr.aws/c4g3p9t9/jira-utilities-mcp"
      ],
      "env": {
        "JIRA_EMAIL": "your-email@celigo.com",
        "JIRA_API_TOKEN": "your-jira-api-token",
        "TZ": "Asia/Kolkata",
        "OPENAI_API_KEY": "your-openai-key"
      }
    }
  }
}

# Note: OPENAI_API_KEY is optional — image OCR uses Cursor's model by default (no key needed)

# 3. Restart Cursor and use prompts
"List all subtasks of IOAUT-23008"
"Get comments on IO-106827"
"Extract text from the image in IO-106827"
```

### For Large Batches (20+ items) - Use Standalone

```bash
# Set environment variables and run the scripts directly
export JIRA_EMAIL="your-email@celigo.com"
export JIRA_API_TOKEN="your-api-token"

npm run pr-reporter        # For CSV reports (by issue keys)
npm run jql-reporter       # For CSV reports (by JQL query)
npm run subtask-manager    # For closing subtasks
```

---

## 15 MCP Tools Available

### Issue Reading & Search

| # | Tool | Best For | Example Prompt |
|---|------|----------|----------------|
| 1 | `get_issue_details` | Summary, **Bug description** (Celigo custom field), effectiveDescription, splunkLinks, attachments, comments | "Get details of IO-166270" |
| 2 | `get_issue_comments` | Full comment history with body text | "Show all comments on IO-106827" |
| 3 | `get_issue_changelog` | Activity/field change history | "Show changelog for IO-177818" |
| 4 | `search_issues` | Lightweight JQL search | "Find my in-progress tickets" |
| 5 | `get_issue_attachments` | List attachments + resolve inline images | "List attachments on IO-106827" |
| 6 | `get_attachment_content` | Read text, PDF (page-limited), or zip inner text files | "Read attachment 5002 on IO-106827" |
| 7 | `download_attachment` | Save file to OUTPUT_DIR (large binaries) | "Download attachment 5001 to disk" |
| 8 | `get_attachment_text` | OCR images (OpenAI) or PDF text (pdf-parse) | "Extract text from attachment 145341" |

### Issue Analysis & Reporting

| # | Tool | Best For | Example Prompt |
|---|------|----------|----------------|
| 9 | `analyze_jira_issue` | PR + Zephyr extraction | "Analyze IOAUT-23009 for PRs and test cases" |
| 10 | `generate_csv_report` | CSV by issue keys (auto-batched) | "Generate CSV for 35 critical issues" |
| 11 | `generate_csv_report_jql` | CSV by JQL query | "CSV for fixVersion = '2026.1.1'" |
| 12 | `list_subtasks` | List subtasks with status | "List all subtasks of IOAUT-23008" |

### Issue Modification

| # | Tool | Best For | Example Prompt |
|---|------|----------|----------------|
| 13 | `add_comment` | Post a comment | "Add comment 'all tests passed' on IO-191317" |
| 14 | `close_subtasks` | Bulk close (auto-batched) | "Close all subtasks except IOAUT-23009" |
| 15 | `transition_issue` | Change status | "Close IOAUT-76461 with resolution 'Fixed'" |

---

## New in v2.6: Celigo Bug description field

IO/QA bugs store Splunk logs in **`Bug description`** (`customfield_15129`), not the standard Jira `description` field.

`get_issue_details` now returns:

- `description` — standard Jira description (often null on IO bugs)
- `bugDescription` — Celigo custom field (Splunk stack traces, errors)
- `effectiveDescription` — merged text for agents (uses bug description when standard is empty)
- `splunkLinks` — URLs extracted from bug text
- `environment` — Jira environment field when set

Override field IDs via env:

- `MCP_CELIGO_BUG_DESCRIPTION_FIELD` (default: `customfield_15129`)
- `MCP_CELIGO_STEPS_FIELD`, `MCP_CELIGO_ACCEPTANCE_FIELD`

Set `includeCustomFields=true` to include other long ADF custom fields.

---

## New in v2.5: Attachments (PDF, zip, download, media API)

### List attachments + resolve inline media

```
"List all attachments on IO-106827"
```

Resolves inline images via media id, filename, Jira attachment API lookup, and content-URL match. Set `includeCommentMedia=true` for comment inline images.

### Read text, PDF, or zip (no OpenAI)

```
"Read the content of attachment 5002 on IO-106827"
```

- Text: `.txt`, `.log`, `.json`, `.csv`, `.xml`, `.md`, etc. (up to 512KB)
- PDF: text extraction via `pdf-parse` (`maxPdfPages`: use `1` for first page only)
- Zip: lists entries and extracts small inner text files

### Download large files to disk

```
"Download attachment 5001 on IO-106827"
```

Saves to `OUTPUT_DIR` (mount `$HOME/Downloads:/output`). Returns `savedPath` for the agent or user.

### Description OCR

```
"Get issue IO-106827 with extractDescriptionImageText true"
```

OCRs screenshots pasted in the issue description (not only comments). Requires `OPENAI_API_KEY`.

### Image OCR / PDF text

```
"Extract text from attachment 145341 on IO-106827"
```

Images use OpenAI Vision (`OPENAI_API_KEY`). PDFs use `pdf-parse` without OpenAI.

---

## New in v2.3: Comments, Changelog, Search & Image OCR

### Read Summary & Description

`get_issue_details` returns:
- **summary** — plain text (as stored in Jira)
- **description** — converted from ADF to readable plain text (tables, lists, code blocks, inline images as `[IMAGE: ...]` placeholders)

`search_issues` includes description when you add `description` to the `fields` parameter, e.g. `fields: "key,summary,description,status"`.

### Read Comments (full body text)

```
"Show all comments on IO-106827"
"Get the latest 5 comments on IOAUT-23008"
```

The tool converts Jira's Atlassian Document Format (ADF) to **plain readable text** (formatting marks like bold are not preserved), including mentions, links, code blocks, and lists.

**Pagination:** Use `startAt` / `nextStartAt` for the next page, or `fetchAll=true` to auto-fetch (capped at `MCP_MAX_COMMENTS_TOTAL`, default 200).

### Read Activity/Changelog

```
"Show the changelog for IO-177818"
"What status changes happened on IOAUT-23008?"
```

Returns field transitions, assignee changes, sprint changes, and all other modifications. Supports `startAt` / `fetchAll` pagination (capped at `MCP_MAX_CHANGELOG_TOTAL`, default 200).

### Lightweight JQL Search

```
"Search for my in-progress tickets"
"Find all bugs in project IO assigned to me"
```

Returns structured summaries without the overhead of full CSV generation. Use `nextPageToken` from the response for the next page, or `fetchAll=true` (capped at `MCP_MAX_SEARCH_ISSUES_TOTAL`, default 200).

### Image Text Extraction (OCR)

```
"Extract text from the screenshot in IO-106827"
"Read the image attachment 145341 on IO-106827"
```

Downloads image attachments and uses OpenAI Vision API (`gpt-4o-mini`) to extract all visible text. Works with screenshots, diagrams, tables, and scanned documents.

**With auto-OCR on comments:**
```
"Get comments on IO-106827 with image text extraction enabled"
```

When `extractImageText=true` is passed to `get_issue_comments`, inline images are automatically OCR'd and the extracted text is appended to the comment body.

### Add Comments

```
"Add a comment to IO-191317: deployment completed successfully"
```

Plain text is automatically converted to Atlassian Document Format for posting.

---

## What's Included

1. **`jira-mcp-server.js`** - MCP protocol server with 15 tools, auto-batching, ADF handling, and attachments/OCR
2. **`scripts/jira_pr_zephyr_reporter.js`** - PR and Zephyr extraction by issue keys, optimized for large batches
3. **`scripts/jira_jql_reporter.js`** - PR and Zephyr extraction by JQL query with automatic pagination
4. **`scripts/jira_subtask_manager.js`** - Bulk subtask closure with exclusions

---

## Environment Variables

| Variable | Required | Purpose |
|----------|----------|---------|
| `JIRA_EMAIL` | Yes | Your Celigo email for Jira API auth |
| `JIRA_API_TOKEN` | Yes | Jira API token ([generate here](https://id.atlassian.com/manage-profile/security/api-tokens)) |
| `TZ` | No | Timezone for timestamps (default: UTC) |
| `OPENAI_API_KEY` | No | Optional — only for `ocrMode: "openai"` server-side OCR (headless/CI). Default uses Cursor's vision. |
| `MCP_OCR_MODE` | No | Set to `openai` to default server-side OCR when `OPENAI_API_KEY` is set |
| `MCP_MAX_COMMENTS_TOTAL` | No | Max comments when `fetchAll=true` (default: 200) |
| `MCP_MAX_CHANGELOG_TOTAL` | No | Max changelog entries when `fetchAll=true` (default: 200) |
| `MCP_MAX_SEARCH_ISSUES_TOTAL` | No | Max issues when `fetchAll=true` on search (default: 200) |
| `MCP_MAX_OCR_IMAGES` | No | Max images OCR'd per request (default: 5) |
| `OUTPUT_DIR` | No | CSV output directory (default: `/tmp`; use `/output` with Docker volume) |
| `MCP_CELIGO_BUG_DESCRIPTION_FIELD` | No | Celigo Bug description field id (default: `customfield_15129`) |
| `MCP_CELIGO_STEPS_FIELD` | No | Steps to reproduce custom field id |
| `MCP_CELIGO_ACCEPTANCE_FIELD` | No | Acceptance criteria custom field id |

---

## When to Use What

### Via Cursor MCP (1-20 items)
- Natural language prompts
- No terminal needed
- Quick for small batches
- Full comment/changelog/search capabilities
- Image OCR for screenshots

**Use For**: "Show comments on IO-106827", "List subtasks", "Search my tickets", "Extract text from image"

### Via npm scripts (20+ items)
- Much faster for large batches
- No timeout issues
- Direct CSV file output
- Progress indicators

**Use For**: Sprint reports (30+ issues), Epic cleanup (50+ subtasks)

---

## Example Prompts

### Reading & Searching

```
"Get details of IO-177818"
"Show all comments on IO-106827"
"Show changelog for IO-177818"
"Search for project = IO AND status = 'In Progress' AND assignee = currentUser()"
"Extract text from attachment 145341 on IO-106827"
"Get comments on IO-106827 with extractImageText enabled"
```

### Analysis & Reporting

```
"Analyze IOAUT-23009 for PRs and Zephyr test cases"
"Generate CSV for IOAUT-23008, IOAUT-23009, IOAUT-23010"
"Generate CSV for fixVersion = '2026.1.1' AND project = IO"
"List all subtasks of IOAUT-23008"
```

### Modification

```
"Add comment 'tests passed' to IO-191317"
"Close all subtasks of IOAUT-23008 except IOAUT-23009"
"Transition IO-76461 to Done with resolution Fixed"
```

### For Large Batches (npm scripts)

```bash
export JIRA_EMAIL="your-email@celigo.com"
export JIRA_API_TOKEN="your-api-token"

npm run pr-reporter        # Paste issue IDs when prompted
npm run jql-reporter       # Enter JQL query when prompted
npm run subtask-manager    # For bulk closures
```

---

## Automatic Batch Processing

The MCP server **automatically handles** requests with >20 issues:

```
LARGE BATCH DETECTED: 35 issues requested

Automatically splitting into 2 batches of 20 to avoid timeouts...
Processing 2 batch(es) with rate limiting
Estimated time: ~70 seconds

======================================================================

BATCH 1/2: Processing 20 issues
============================================================
Batch 1/2 complete (20 issues processed)
Waiting 3 seconds before next batch...

BATCH 2/2: Processing 15 issues
============================================================
Batch 2/2 complete (15 issues processed)

======================================================================
All 2 batches processed successfully!
Total issues analyzed: 35
======================================================================
```

---

## Docker/ECR Deployment

```bash
# Build locally
./build-docker.sh

# Deploy to ECR - See docs/ECR_DEPLOYMENT_GUIDE.md
```

---

## Project Structure

```
jira-utilities-mcp-server/
├── README.md                      # This file
├── jira-mcp-server.js             # MCP server entry (15 tools)
├── lib/                           # Shared modules
│   ├── jira-adf-utils.js          # ADF flatten / textToADF helpers
│   ├── jira-validation.js         # Issue key & input validation
│   ├── jira-celigo-fields.js      # Bug description, Splunk links
│   └── jira-attachment-utils.js   # Attachments, PDF, OCR helpers
├── scripts/                       # Standalone CLIs (also used by MCP)
│   ├── jira_pr_zephyr_reporter.js
│   ├── jira_jql_reporter.js
│   └── jira_subtask_manager.js
├── docs/                          # All documentation
│   ├── README.md                  # Doc index
│   ├── PROMPTS.md                 # Scenario prompt playbooks
│   ├── END_TO_END_PROMPTS.md      # Multi-MCP end-to-end workflow
│   └── ECR_DEPLOYMENT_GUIDE.md    # Docker / ECR deployment
├── __tests__/                     # Unit + regression tests
├── Dockerfile
├── build-docker.sh
└── package.json
```

---

## Documentation

| File | Purpose |
|------|---------|
| **README.md** | Overview & quick start |
| **[docs/README.md](docs/README.md)** | Documentation index |
| **[docs/PROMPTS.md](docs/PROMPTS.md)** | Scenario prompt playbooks (triage, RCA, QA, sprint CSV, etc.) |
| **[docs/END_TO_END_PROMPTS.md](docs/END_TO_END_PROMPTS.md)** | End-to-end: Jira + Splunk + Zephyr + GitHub in one Cursor chat |
| **[docs/ECR_DEPLOYMENT_GUIDE.md](docs/ECR_DEPLOYMENT_GUIDE.md)** | Docker / ECR deployment |

---

## Changelog

### v2.6.0 (May 2026)

Shipped in one release cycle (same day); supersedes interim v2.3.1–v2.5.0 notes.

**Celigo IO fields**
- `get_issue_details` reads **Bug description** custom field (`customfield_15129`)
- `bugDescription`, `effectiveDescription`, `splunkLinks`, `environment` in response
- `includeCustomFields` for other long ADF custom fields

**`get_issue_details` & subtasks**
- Issue links, priority, labels, components, fix versions, resolution
- `attachments` array; `extractDescriptionImageText` for description screenshots
- `list_subtasks` — parent + subtask descriptions (plain text), optional `includeDescriptions`
- CSV batch path uses `flattenADF` for PR/Zephyr extraction (same as `analyze_jira_issue`)

**Attachments & media**
- `get_issue_attachments` — list attachments + inline media resolution
- `get_attachment_content` — text files without OpenAI; PDF extraction (page-limited, size-capped)
- `get_attachment_text` — image OCR (host vision by default; optional OpenAI)
- Zip: list entries + extract small inner text files
- `download_attachment` — save binaries to `OUTPUT_DIR`
- Reliable `media_id` resolution via Jira attachment API + content-URL fallback
- Improved OCR media matching (id, filename, partial filename)

### v2.3.0 (May 2026)
- Added `get_issue_comments` - full comment body text with ADF-to-text conversion + pagination
- Added `get_issue_changelog` - activity/field change history + pagination
- Added `add_comment` - post comments to issues (empty body rejected)
- Added `search_issues` - lightweight JQL search with `nextPageToken` pagination
- Added `get_attachment_text` - image OCR via OpenAI Vision API
- Enhanced `get_issue_details` - description as plain text + last 5 comments via comment API
- `analyze_jira_issue` now includes `description` field (plain text)
- Extracted `jira-adf-utils.js`, `jira-validation.js`, `jira-attachment-utils.js`
- `analyze_jira_issue` uses `flattenADF` for description/comments
- See [docs/FUTURE_OPTIMIZATIONS.md](docs/FUTURE_OPTIMIZATIONS.md) for planned attachment improvements

### v2.2.0 (November 2025)
- Added `generate_csv_report_jql` for JQL-based reporting
- Auto-batching for large requests (>20 issues)
- Rate limiting between API calls

### v2.1.0
- Added `transition_issue` tool
- Added `close_subtasks` with exclusion support

---

## Support

- **Prompts & Examples**: [docs/PROMPTS.md](docs/PROMPTS.md) · **End-to-end multi-MCP**: [docs/END_TO_END_PROMPTS.md](docs/END_TO_END_PROMPTS.md)
- **ECR Deployment**: [docs/ECR_DEPLOYMENT_GUIDE.md](docs/ECR_DEPLOYMENT_GUIDE.md)
- **JIRA API**: https://developer.atlassian.com/cloud/jira/platform/rest/v3/
- **MCP Protocol**: https://modelcontextprotocol.io/

---

**Status**: Production Ready | ECR Deployable | 15 Tools | Attachments + PDF + OCR

**Version**: 2.6.0 | **Last Updated**: May 26, 2026