pnd-jira-mcp 1.0.0
Standalone Jira MCP (Model Context Protocol) connector for Claude Desktop integration
License: MIT
Requires Python: >=3.10
Keywords: mcp, jira, claude, atlassian, connector

# pnd-jira-mcp

A standalone Jira MCP (Model Context Protocol) connector for Claude Desktop integration.

## Installation

```bash
pip install pnd-jira-mcp
```

## Quick Start

1. Set environment variables:

```bash
export JIRA_BASE_URL="https://your-instance.atlassian.net"
export JIRA_EMAIL="your-email@example.com"
export JIRA_API_TOKEN="your-api-token"
```

2. Run the MCP server:

```bash
pnd-jira-mcp
```

Or via Python:

```bash
python -m pnd_jira_mcp
```

## Claude Desktop Integration

Add to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):

```json
{
  "mcpServers": {
    "jira": {
      "command": "pnd-jira-mcp",
      "env": {
        "JIRA_BASE_URL": "https://your-instance.atlassian.net",
        "JIRA_EMAIL": "your-email@example.com",
        "JIRA_API_TOKEN": "your-api-token"
      }
    }
  }
}
```

## Available Tools

### Issue Operations

#### get_issue
Get details of a Jira issue by key.
```json
{"issue_key": "PROJ-123"}
```

#### search_issues
Search for Jira issues using JQL.
```json
{"jql": "project = PROJ AND status = Open", "max_results": 50}
```

#### add_comment
Add a comment to a Jira issue (supports markdown).
```json
{"issue_key": "PROJ-123", "body": "This is a **markdown** comment"}
```

#### add_label
Add a label to a Jira issue.
```json
{"issue_key": "PROJ-123", "label": "reviewed"}
```

#### update_fields
Update fields on a Jira issue.
```json
{"issue_key": "PROJ-123", "fields": {"summary": "New summary"}}
```

#### update_ai_fields
Update AI-related custom fields.
```json
{"issue_key": "PROJ-123", "ai_used": true, "agent_name": "Claude"}
```

### Transition Operations

#### get_transitions
Get available transitions for an issue.
```json
{"issue_key": "PROJ-123"}
```

#### transition_issue
Transition an issue to a new status.
```json
{"issue_key": "PROJ-123", "transition_id": "31"}
```

### Sprint Operations

#### get_boards
Get all Jira boards, optionally filtered by project or type.
```json
{"project_key": "PROJ", "board_type": "scrum"}
```

#### get_sprints
Get sprints for a board.
```json
{"board_id": 123, "state": "active"}
```

#### get_sprint
Get details of a specific sprint.
```json
{"sprint_id": 456}
```

#### get_active_sprint
Get the currently active sprint for a board.
```json
{"board_id": 123}
```

#### get_sprint_issues
Get all issues in a sprint.
```json
{"sprint_id": 456, "max_results": 200}
```

### Utility

#### test_connection
Test the Jira connection and verify credentials.
```json
{}
```

## Environment Variables

| Variable | Description | Required |
|----------|-------------|----------|
| `JIRA_BASE_URL` | Jira instance URL | Yes |
| `JIRA_EMAIL` | Jira account email | Yes |
| `JIRA_API_TOKEN` | Jira API token | Yes |
| `JIRA_FIELD_AI_USED` | Custom field ID for AI used flag | No |
| `JIRA_FIELD_AGENT_NAME` | Custom field ID for agent name | No |
| `JIRA_FIELD_EFFICIENCY_SCORE` | Custom field ID for efficiency score | No |
| `JIRA_FIELD_DURATION` | Custom field ID for duration | No |

## Getting a Jira API Token

1. Go to https://id.atlassian.com/manage-profile/security/api-tokens
2. Click "Create API token"
3. Give it a descriptive name
4. Copy the token and store it securely

## Example Usage in Claude

Once configured, you can ask Claude to interact with Jira:

- "Add a comment to PROJ-123 saying the code review is complete"
- "What's the status of PROJ-456?"
- "Move PROJ-789 to In Progress"
- "Find all open bugs in the PROJ project"
- "Show me the active sprint for board 123"
- "List all issues in the current sprint"

## Programmatic Usage

```python
from pnd_jira_mcp import JiraClient, JiraConfig

config = JiraConfig(
    base_url="https://your-instance.atlassian.net",
    email="your-email@example.com",
    api_token="your-api-token"
)

with JiraClient(config=config) as client:
    issue = client.get_issue("PROJ-123")
    print(f"Issue: {issue.summary}")
    
    # Get active sprint
    boards = client.get_boards(project_key="PROJ")
    if boards:
        sprint = client.get_active_sprint(boards[0]["id"])
        print(f"Active sprint: {sprint['name']}")
```

## License

MIT