jira-mcp
by vaspap1790
README.md
# Jira MCP Server
A Model Context Protocol (MCP) server that provides tools for interacting with Jira. Enables Cursor and other MCP clients to fetch tickets, manage linked tickets, and update ticket status.
## Quick Start
### 1. Install Dependencies
```bash
# Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install project dependencies
uv sync
```
### 2. Configure Jira Credentials
**Recommended: Personal Access Token (PAT)**
1. Log into Jira: https://jira.telekom.de
2. Go to your profile > **Personal Access Tokens**
3. Click "Create token"
4. Give it a name (e.g., "Cursor MCP") and set expiration
5. **Important:** Ensure the token has **"Read"** or **"Browse Projects"** permissions
6. Copy the token immediately (you won't see it again)
Create `.env` file:
```bash
cp .env.example .env
```
Edit `.env` with your credentials:
```env
JIRA_URL=https://jira.telekom.de
JIRA_USERNAME=your.username@telekom.de
JIRA_API_TOKEN=your_personal_access_token_here
JIRA_AUTH_TYPE=bearer
```
**Note:** Kantega SSO API tokens may have IP restrictions or require admin-configured permissions. Personal Access Tokens are recommended for most users.
### 3. Configure in Cursor
1. Open Cursor
2. Go to **Settings > Tools and MCP**
3. Add this configuration:
```json
{
"mcpServers": {
"jira": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/jira-mcp",
"run",
"-m",
"src"
]
}
}
}
```
**Important:** Replace the path and credentials with your actual values!
4. Restart Cursor completely
### 4. Try It Out
In Cursor chat, try:
- "Get details for Jira ticket PROJ-123"
- "Show me all linked tickets for PROJ-456"
- "Update PROJ-789 status to In Progress"
## Features
### Available Tools
| Tool | Description | Example |
|------|-------------|---------|
| `get_ticket` | Fetch full ticket details | "Get PROJ-123" |
| `get_linked_tickets` | Get related tickets & subtasks | "Show linked tickets for PROJ-123" |
| `update_ticket_status` | Update ticket status | "Move PROJ-123 to In Progress" |
### Authentication Support
- **Bearer Token**: Personal Access Tokens (PAT) - **Recommended**
- **Basic Auth**: Username + API token (Atlassian Cloud)
- **Cookie Auth**: Session-based authentication (fallback option)
## Tool Details
### get_ticket
Fetches complete ticket information.
**Parameters:**
- `ticket_id` (string, required): Ticket ID or key (e.g., "PROJ-123")
**Returns:**
```json
{
"key": "PROJ-123",
"summary": "Ticket summary",
"description": "Detailed description",
"status": "In Progress",
"issue_type": "Story",
"priority": "High",
"assignee": "John Doe",
"reporter": "Jane Smith",
"created": "2024-01-15T10:30:00.000+0000",
"updated": "2024-01-20T14:45:00.000+0000",
"comments_count": 3,
"comments": [...],
"custom_fields": {...}
}
```
### get_linked_tickets
Fetches all related tickets and subtasks.
**Parameters:**
- `ticket_id` (string, required): Ticket ID or key
**Returns:**
```json
{
"ticket": "PROJ-123",
"linked_tickets": [
{
"link_type": "Blocks",
"direction": "blocks",
"key": "PROJ-124",
"summary": "Related ticket",
"status": "To Do"
}
],
"linked_tickets_count": 1,
"subtasks": [...],
"subtasks_count": 2
}
```
### update_ticket_status
Updates ticket status with workflow validation.
**Parameters:**
- `ticket_id` (string, required): Ticket ID or key
- `status` (string, required): Target status (e.g., "In Progress", "Done")
**Returns:**
```
Successfully updated ticket PROJ-123 status from 'To Do' to 'In Progress'
```
**Note:** The tool validates transitions. If invalid, it returns available transitions.
## Testing
### Run Tests
```bash
# Run all tests
.venv/bin/pytest tests/ -v
# Run with coverage
.venv/bin/pytest tests/ --cov=src -v
# Run specific test file
.venv/bin/pytest tests/test_integration/test_real_tickets.py -v
```
### Manual Testing
Test the server directly:
```bash
uv run --env-file .env -m src
```
Press Ctrl+C to stop.
## Troubleshooting
### Authentication Errors
**Symptoms:** "401 Unauthorized" or "403 Forbidden"
**Solutions:**
- **Most common:** Personal Access Token is expired - generate a new one
- Verify your PAT has "Read" or "Browse Projects" permissions
- Check your username matches your Jira account email
- Ensure `JIRA_URL` includes `https://`
- Confirm `JIRA_AUTH_TYPE=bearer` for Personal Access Tokens
### Ticket Not Found
**Symptoms:** "404 Not Found"
**Solutions:**
- Verify the ticket key is correct (e.g., "PROJ-123")
- Check you have permission to view the ticket
- Ensure you're using the correct Jira instance
### Server Not Appearing in Cursor
**Solutions:**
- Verify the absolute path in your MCP settings
- Check Python 3.12+ is installed: `python3 --version`
- Restart Cursor completely (quit and reopen)
- Check Cursor's developer console for errors
### Cannot Transition Ticket
**Symptoms:** "Invalid status transition"
**Solutions:**
- The error message lists available transitions
- Status names must match exactly (case-insensitive)
- Check your Jira workflow permissions
- Verify the transition is valid for your workflow
## Architecture
This project follows SOLID principles and clean architecture:
```
src/
├── __init__.py
├── __main__.py # Entry point
├── server.py # MCP server setup
├── config/ # Configuration management
├── client/ # Jira API client
├── tools/ # 3 MCP tools
├── models/ # Domain models
├── mappers/ # Data transformation
└── utils/ # Error handling, JSON utils
```
**Key Principles:**
- **SOLID**: Single responsibility, dependency inversion
- **DRY**: No duplication, reusable components
- **Type Safety**: Full type hints throughout
- **Testable**: Clean separation of concerns
See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed technical documentation.
## Development
### Project Structure
```
jira-mcp/
├── src/ # Source code (22 Python files)
├── tests/ # Test suite
├── pyproject.toml # Project config (includes pytest config)
├── .env.example # Config template
├── .gitignore
├── README.md # This file
└── ARCHITECTURE.md # Technical docs
```
### Adding Dependencies
```bash
uv add package-name
```
### Running with Different Config
```bash
uv run --env-file .env.production -m src
```
### Code Quality
- **Linting errors:** 0
- **Type coverage:** 100%
- **Test coverage:** Integration tests for all 3 tools
- **Architecture:** SOLID + DRY compliant
## Requirements
- Python 3.12+
- Jira account with API access
- Jira API token (Kantega SSO Enterprise or Atlassian Cloud)
## License
This project is provided as-is for use with Cursor and Jira.
---
**Built with best practices following SOLID and DRY principles** 🚀
TDQS
A3.8/5.0
Scored across 3 tools
Disambiguation5/5
Each tool targets a distinct operation: retrieving a ticket, fetching linked tickets, and updating status. No overlap in functionality.
Naming Consistency5/5
All tool names follow a consistent 'verb_noun' pattern in snake_case (get_ticket, get_linked_tickets, update_ticket_status), making them predictable.
Tool Count4/5
Three tools is on the lower end of the ideal range but still reasonable for a focused Jira server. Each tool serves a clear purpose without feeling sparse.
Completeness2/5
Missing essential CRUD operations such as create_ticket, search_tickets, or add_comment. Agents cannot create new tickets or perform most lifecycle actions.
Maintenance
ActivityInactive
ResponsivenessNo issues