Jira Utilities MCP Server
by celigo
README.md
# JIRA Utilities - MCP Server v2.6
> **Complete JIRA automation via Cursor AI + Optimized standalone utilities**
[](https://modelcontextprotocol.io/)
[](https://www.docker.com/)
[](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
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessSyncing