jira-mcp-server
README.md
# JIRA MCP Server
A production-grade [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that exposes JIRA sprint data as MCP **Tools** and **Prompts**.
Ships with rich in-memory mock data (30 issues, 8 assignees) and a pluggable `JiraClient` abstraction that makes connecting to a real Atlassian JIRA instance a drop-in upgrade.
---
## Features
| Category | Detail |
|----------|--------|
| Transport | SSE (HTTP) — compatible with Cursor, Claude.ai Web, and any SSE-capable MCP client |
| Tools | `get_active_sprint_issues`, `get_issue_details` |
| Prompts | `format_sprint_progress`, `format_issue_details` |
| Data layer | Abstract `JiraClient` — swap mock ↔ real API via env var |
| Models | Pydantic v2 with full type safety |
---
## Project Structure
```
jira-mcp-server/
├── main.py # Entry point (SSE server)
├── pyproject.toml
└── src/
├── data/
│ ├── models.py # Pydantic v2 models (JiraIssue, Assignee, SprintMeta)
│ └── mock_issues.py # 30 mock issues + SPRINT_META
├── jira/
│ ├── __init__.py # get_jira_client() factory
│ ├── base.py # Abstract JiraClient (ABC)
│ ├── mock_client.py # MockJiraClient — in-memory fixture data
│ └── api_client.py # ApiJiraClient — real JIRA REST stub
├── server/
│ ├── app.py # FastMCP instance + client initialisation
│ └── tools.py # @mcp.tool registrations
└── prompts/
├── sprint_progress.py # @mcp.prompt: format_sprint_progress
└── issue_details.py # @mcp.prompt: format_issue_details
```
---
## Quick Start
### Prerequisites
- Python 3.12+
- [uv](https://docs.astral.sh/uv/) (recommended) or pip
### Install dependencies
```bash
uv sync
```
### Run the server
```bash
# Using the installed script:
uv run jira-mcp-server
# Or directly:
uv run python main.py
```
The SSE server starts at **`http://localhost:8000/sse`** by default.
Override host/port via environment variables:
```bash
MCP_HOST=127.0.0.1 MCP_PORT=9000 uv run jira-mcp-server
```
---
## MCP Client Configuration
### Cursor
Add to `.cursor/mcp.json` (project-level) or `~/.cursor/mcp.json` (global):
```json
{
"mcpServers": {
"jira": {
"url": "http://localhost:8000/sse"
}
}
}
```
### Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"jira": {
"url": "http://localhost:8000/sse"
}
}
}
```
---
## Tools
### `get_active_sprint_issues`
Returns all issues in the active sprint for the provided Scrum board name as a JSON array.
```json
{ "scrum_board_name": "Platform Engineering Scrum Board" }
```
### `get_issue_details`
Returns the full details of a single issue.
```json
{ "issue_id": "PROJ-1" }
```
Raises an error if the issue key does not exist.
---
## Prompts
### `format_sprint_progress`
Generates a comprehensive **scrum master report** in Markdown:
- Sprint Overview table (totals, velocity, completion %)
- Blockers section (table + impact analysis per blocker)
- Risk Analysis (Critical + High items not Done)
- Resource Utilisation table (per-assignee: issues, SP, completion %)
- Bandwidth Analysis (overloaded / under-utilised members + rebalancing suggestions)
- Key Insights (patterns, anomalies)
- Recommended Next Steps (prioritised action list)
```json
{
"sprint_data_json": "{\"sprint_meta\":{...},\"issues\":[...]}"
}
```
`sprint_data_json` should be the JSON payload returned by tools (metadata + issues),
or an issues-only JSON array.
### `format_issue_details`
Renders a single issue as a structured Markdown document with:
- Header (ID + Summary + Type + Status + Priority)
- Metadata table (all fields)
- Description section
- Acceptance Criteria checklist (auto-checked if status = Done)
- Labels
```json
{
"issue_json": "{\"id\":\"PROJ-5\",...}"
}
```
`issue_json` should be the JSON object returned by `get_issue_details`.
---
## Connecting to Real JIRA
The `JiraClient` abstraction makes this a configuration-only change:
1. Set the following environment variables:
```bash
JIRA_BASE_URL=https://your-org.atlassian.net
JIRA_EMAIL=service-account@your-org.com
JIRA_API_TOKEN=your-atlassian-api-token
JIRA_BOARD_ID=3
JIRA_PROJECT_KEY=PROJ
```
2. Fill in the `TODO` sections in [src/jira/api_client.py](src/jira/api_client.py):
- Uncomment the `httpx` import and install `httpx` (`uv add httpx`)
- Implement `get_sprint_issues`, `get_issue`, and `get_sprint_meta` using the JIRA Agile REST API v1 and REST API v3 endpoints documented inline
3. Restart the server — the factory auto-selects `ApiJiraClient` when `JIRA_API_TOKEN` is present.
No changes to tools, prompts, or server code are required.
---
## Development
### Inspect with MCP Inspector
```bash
uv run mcp dev main.py
```
Opens the interactive MCP Inspector in your browser with all tools and prompts available for testing.
### Static analysis
```bash
uv run mypy src/ main.py
uv run ruff check src/ main.py
```
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues