jira-pm-mcp
Wraps JIRA Cloud REST API for AI-driven agile project management, enabling sprint health monitoring, label syncing, risk flagging, and audit receipt writing.
README
jira-pm-mcp
An MCP server that wraps the JIRA Cloud REST API for AI-driven agile project management. Designed to be run as a daily batch by an AI agent (e.g. via OpenClaw) to monitor sprint health, sync labels, flag risks, and write audit receipts.
Requirements
- Node.js 20+
- JIRA Cloud instance
- API token with edit-issues and add-comments permissions on the target projects
Setup
npm install
npm run build
Environment variables
| Variable | Required | Description |
|---|---|---|
JIRA_BASE_URL |
yes | Base URL of your JIRA instance (e.g. https://yourcompany.atlassian.net) |
JIRA_EMAIL |
yes | Email address tied to the API token |
JIRA_API_TOKEN |
yes | JIRA Cloud API token |
PORT |
no | When set, starts an HTTP/SSE server on this port instead of stdio |
Transport modes
The server supports two transport modes selected at startup.
stdio (default)
The server process is spawned and managed by the MCP client. Env vars are passed through the client config. Best for local single-user setups.
{
"mcpServers": {
"jira-pm": {
"command": "node",
"args": ["/path/to/jira-pm-mcp/dist/index.js"],
"env": {
"JIRA_BASE_URL": "https://yourcompany.atlassian.net",
"JIRA_EMAIL": "you@company.com",
"JIRA_API_TOKEN": "your-token"
}
}
}
}
HTTP/SSE
The server runs as a persistent HTTP process. The MCP client connects to it via SSE. Best for running the server as a system service or Docker container shared across multiple clients.
Start the server:
export JIRA_BASE_URL=https://yourcompany.atlassian.net
export JIRA_EMAIL=you@company.com
export JIRA_API_TOKEN=your-token
export PORT=3000
node dist/index.js
Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"jira-pm": {
"url": "http://localhost:3000/sse"
}
}
}
Endpoints:
| Endpoint | Method | Description |
|---|---|---|
/sse |
GET | SSE stream — MCP client connects here |
/message?sessionId=<id> |
POST | MCP message delivery (used internally by client) |
/health |
GET | Liveness probe — returns {"status":"ok","sessions":<n>} |
Tools
setup_project
Configure a project for PM Agent monitoring. Must be run before any other tools. Validates connectivity and write permissions, then stores configuration as a YAML comment on the Root Epic and registers the project locally.
| Parameter | Type | Required | Description |
|---|---|---|---|
project_key |
string | yes | JIRA project key (e.g. PROJ) |
root_epic_key |
string | yes | Key of the root epic that parents all cross-project tasks (e.g. PROJ-1) |
board_id |
number | no | JIRA board ID (optional, for validation only) |
epic_link_field |
string | no | JQL field for child tasks. "Epic Link" (default, classic projects) or "parent" (next-gen/team-managed) |
active_statuses |
string[] | no | Status names that count as in-progress. Default: In Progress, In Review, Code Review, In Testing |
committed_date |
string | no | Project delivery deadline YYYY-MM-DD. Enables delivery risk and velocity tracking. |
story_points_field |
string | no | Custom field key for story points. Default: customfield_10016 |
Returns: A checklist of validation results (root_epic, fix_versions, write_permissions, config_written) plus the config comment ID.
list_projects
List all projects registered with the PM Agent, with their configuration summary.
No parameters.
Returns: Array of projects with project_key, root_epic_key, committed_date, epic_link_field, active_statuses, and config_available.
list_fix_versions
List all fixVersions (sprints) for a project. Identifies the currently active sprint and how far through it we are.
| Parameter | Type | Required | Description |
|---|---|---|---|
project_key |
string | yes | JIRA project key |
Returns: Array of versions with name, label_equivalent (spaces replaced with hyphens), start_date, release_date, is_active, is_released, and elapsed_pct.
get_sprint_health
Read-only full sprint health snapshot. Builds the full dependency graph — stories → blocking tasks → dates and status — without making any changes to JIRA. Safe to call at any time.
| Parameter | Type | Required | Description |
|---|---|---|---|
project_key |
string | yes | JIRA project key |
fix_version |
string | yes | fixVersion name identifying the sprint |
Returns:
- Sprint metadata (dates,
elapsed_pct,committed_date) - Summary counts (
total_stories,stories_with_no_tasks,stories_past_sprint_end,tasks_missing_dates,orphaned_tasks) - Per-story breakdown:
effective_completion_date(max end date across blocking tasks),past_sprint_end,past_committed_date,has_date_gap, and the full list of blocking tasks with their dates, assignees, and currentpm-*labels orphaned_tasks: tasks under the root epic that don't block any story in this sprint
run_sprint_audit
Run the daily PM audit for a sprint. This is the main write tool — it applies all label and date changes to JIRA and writes an audit receipt to the Root Epic.
| Parameter | Type | Required | Description |
|---|---|---|---|
project_key |
string | yes | JIRA project key |
fix_version |
string | yes | fixVersion name identifying the sprint |
dry_run |
boolean | no | If true, compute all changes but do not write to JIRA (default: false) |
What it does (in order):
- Sync sprint labels — adds the sprint label (fixVersion with spaces → hyphens) to all blocking tasks in the sprint
- Compute task flags — evaluates each blocking task and applies
pm-flag-*labels:- Date slip: end date past sprint boundary (
pm-flag-critical-date-slip,pm-flag-warn-date-approaching) - Commitment risk: end date past
committed_date(pm-flag-task-beyond-commitment) - Not started: task in Backlog/Todo at mid-sprint (
pm-flag-critical-not-started,pm-flag-warn-not-started) - Stalled: no status change for more than
stalled_threshold_days(pm-flag-warn-stalled)
- Date slip: end date past sprint boundary (
- Compute story flags — evaluates each story:
- Stories whose
effective_completion_dateslips past the sprint end orcommitted_date(pm-flag-story-at-risk,pm-flag-story-beyond-commitment) - Stories with missing blocking tasks (
pm-flag-missing-tasks) - Stories with date gaps between blocking tasks (
pm-flag-date-gap) - Stories recommended for deferral (
pm-flag-recommend-defer)
- Stories whose
- Update story due dates — sets each story's
duedateto itseffective_completion_date(max end date of blocking tasks) - Velocity calculation — if
committed_dateis set, samples up to 5 past released sprints, computes average velocity, and projects expected completion date - Write audit receipt — posts a YAML receipt comment to the Root Epic
Tasks with pm-acknowledged are skipped entirely (human override).
Returns: Summary of changes made, label_changes, story_date_changes, tasks_needing_dates, defer_recommendations, velocity result, and receipt_comment_id.
rollback_audit
Reverse the label and story date changes made by a previous run_sprint_audit. Reads the audit receipt from the Root Epic and applies the inverse diff. Never removes pm-acknowledged labels.
| Parameter | Type | Required | Description |
|---|---|---|---|
project_key |
string | yes | JIRA project key |
audit_timestamp |
string | no | Timestamp from the receipt to roll back (e.g. 2026-02-22T06-00-00-000Z). Defaults to the most recent audit. |
Returns: rolled_back_audit, changes_reversed, errors, and rollback_receipt_comment_id.
search_issues
Escape hatch for ad-hoc JQL queries. Returns a page of matching issues with key, summary, status, assignee, labels, fixVersions, and due date. Use the high-level tools (get_sprint_health, run_sprint_audit) for routine PM operations.
| Parameter | Type | Required | Description |
|---|---|---|---|
jql |
string | yes | JQL query string |
start_at |
number | no | Pagination offset (default: 0) |
max_results |
number | no | Results per page, max 100 (default: 50) |
fields |
string[] | no | Specific field keys to return |
Returns: total, start_at, max_results, returned, and issues array.
pm-* label taxonomy
The agent owns the full pm-* label namespace. All managed labels are cleared and recomputed on each audit run. The one exception is pm-acknowledged — set by a human to suppress all agent flags on that issue; the agent never removes it.
| Label | Applied to | Meaning |
|---|---|---|
pm-acknowledged |
Task or Story | Human override — agent skips this issue entirely |
pm-flag-critical-date-slip |
Task | End date is past the sprint boundary |
pm-flag-warn-date-approaching |
Task | End date is within the last 20% of the sprint |
pm-flag-task-beyond-commitment |
Task | End date is past committed_date |
pm-flag-critical-not-started |
Task | Still in Backlog/Todo past the 50% sprint mark |
pm-flag-warn-not-started |
Task | Still in Backlog/Todo past the 25% sprint mark |
pm-flag-warn-stalled |
Task | No status change for more than stalled_threshold_days |
pm-flag-shared-task |
Task | Task blocks stories in multiple projects |
pm-flag-story-at-risk |
Story | effective_completion_date is past sprint end |
pm-flag-story-beyond-commitment |
Story | effective_completion_date is past committed_date |
pm-flag-delivery-at-risk |
Story | Velocity projection shows project won't meet committed_date |
pm-flag-missing-tasks |
Story | Story has no blocking tasks linked |
pm-flag-date-gap |
Story | Gap exists between consecutive blocking task date windows |
pm-flag-recommend-defer |
Story | Story is unlikely to complete in time; defer recommended |
Sprint labels (e.g. SIT-27-02-2026) are also applied to blocking tasks by the audit — these are derived from fixVersion names with spaces replaced by hyphens.
Authority model
| Action | Who |
|---|---|
| Set task start/end dates | Human only |
| Set story due date | PM Agent (auto-set to effective_completion_date) |
Add/remove pm-flag-* labels |
PM Agent |
| Add sprint label to tasks | PM Agent |
Add pm-acknowledged |
Human only |
Remove pm-acknowledged |
Human only |
| Create fixVersions | Human only |
| Sprint planning (assign stories to fixVersion) | Human only |
Architecture
src/
server.ts — MCP server entry point, registers all tools
tools/ — One file per MCP tool
jira/ — JIRA REST API client wrappers (client, search, issues, versions, comments)
audit/ — Core audit logic (graph, flags, velocity, receipt)
config/ — Project config schema, JIRA-backed storage, local registry
utils/ — Labels, dates, JQL builder
Configuration is stored as a YAML comment on the Root Epic in JIRA (prefixed with ## pm-agent-config), making it portable and version-controlled alongside the project. A local .jira-pm-registry.json maps project_key → root_epic_key to bootstrap config reads without a prior JIRA call.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.