Skip to main content
Glama
README.md
# JIRA MCP Server

[![CI](https://github.com/Rajendar-Muddasani-2/jira-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/Rajendar-Muddasani-2/jira-mcp-server/actions/workflows/ci.yml)
![Tests](https://img.shields.io/badge/tests-13%20passed-brightgreen)
[![Evidence](https://img.shields.io/badge/evidence-verified-blue)](evidence/claims.json)

A production-ready Model Context Protocol (MCP) server for JIRA integration. This server enables AI assistants to query JIRA issues and perform searches using natural language.

## ๐ŸŽฏ What This Demonstrates

### MCP Concepts
- **Tool Registration**: Using `@mcp.tool` decorator
- **Async Operations**: Asynchronous tool functions
- **Tool Documentation**: Proper descriptions and type hints
- **Server Lifecycle**: Managing MCP sessions with FastAPI
- **HTTP Streaming**: Stateless HTTP-based MCP communication

### Integration Patterns
- **API Wrapper Design**: Clean separation between MCP layer and API layer
- **Error Handling**: Robust error handling for API failures
- **Configuration**: Environment-based configuration
- **Formatting**: LLM-friendly Markdown output
- **Authentication**: Bearer token authentication

## ๐Ÿš€ Quick Start

### Prerequisites

- Python 3.11 or higher
- JIRA instance (Atlassian Cloud or self-hosted)
- JIRA API token with appropriate permissions

### Installation

1. **Navigate to this directory**:
   ```bash
   cd 20_mcp/04-implementations/02-jira-server
   ```

2. **Install dependencies**:
   ```bash
   # Using uv (recommended)
   uv venv
   uv sync
   
   # Or using pip
   python -m venv venv
   source venv/bin/activate  # On Windows: venv\Scripts\activate
   pip install -r requirements.txt
   ```

3. **Configure environment**:
   ```bash
   cp .env.example .env
   nano .env
   ```

### Configuration

Create a `.env` file with your JIRA details:

```env
# JIRA Configuration
JIRA_API_TOKEN=your_api_token_here
JIRA_BASE_URL=https://your-company.atlassian.net

# Optional: Custom SSL Certificate Path
# JIRA_CERT_PATH=/path/to/ca-bundle.crt

# Optional: Server Port
PORT=8000
```

### Getting Your JIRA API Token

#### For Atlassian Cloud:
1. Log in to https://id.atlassian.com
2. Go to **Security** โ†’ **API tokens**
3. Click **Create API token**
4. Copy the token and add to `.env`

#### For Self-Hosted JIRA:
1. Log in to your JIRA instance
2. Go to **Profile** โ†’ **Personal Access Tokens**
3. Create a new token with appropriate scopes
4. Copy the token and add to `.env`

### Running the Server

```bash
# Method 1: Using Python
python server.py

# Method 2: Using uvicorn directly
uvicorn server:app --host 0.0.0.0 --port 8000

# Method 3: Using uv
uv run server.py
```

Server will be available at:
- **MCP Endpoint**: http://localhost:8000/jira
- **API Docs**: http://localhost:8000/docs

## ๐Ÿ“– Usage

### Available Tools

#### 1. Get JIRA Issue
Fetch detailed information about a specific JIRA issue.

**Example**:
```python
# Single issue
get_jira_issue("PROJECT-123")

# Multiple issues (comma-separated)
get_jira_issue("PROJECT-123,PROJECT-456")
```

**Returns**:
```markdown
### Issue PROJECT-123: Fix login bug
**Status:** Open
#### Description:
Users cannot log in after password reset. Error occurs on login page...
```

#### 2. Search JIRA Issues
Search for issues using JQL (JIRA Query Language).

**Example JQL Queries**:
```jql
# Open issues in a project
project = MYPROJECT AND status = Open

# High priority bugs assigned to you
assignee = currentUser() AND priority = High AND type = Bug

# Recently created issues
created >= -7d

# Search by text
summary ~ "performance" OR description ~ "performance"

# Complex query
project = MYPROJECT AND status IN (Open, "In Progress") AND assignee = currentUser() ORDER BY priority DESC
```

**Example**:
```python
search_jira_issue("project = MYPROJECT AND status = Open")
```

**Returns**:
```markdown
### Issue PROJECT-123: Fix login bug
**Status:** Open
#### Description:
Users cannot log in...

### Issue PROJECT-456: Update API documentation
**Status:** Open
#### Description:
API docs need updating...
```

## ๐Ÿ”Œ Integration with AI Assistants

### VS Code with GitHub Copilot

Add to your VS Code `settings.json`:

```json
{
  "mcp.servers": {
    "jira": {
      "command": "python",
      "args": ["/path/to/20_mcp/04-implementations/02-jira-server/server.py"],
      "env": {
        "JIRA_API_TOKEN": "${env:JIRA_API_TOKEN}",
        "JIRA_BASE_URL": "https://your-company.atlassian.net"
      }
    }
  }
}
```

### Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "jira": {
      "command": "python",
      "args": ["/path/to/20_mcp/04-implementations/02-jira-server/server.py"],
      "env": {
        "JIRA_API_TOKEN": "your_token_here",
        "JIRA_BASE_URL": "https://your-company.atlassian.net"
      }
    }
  }
}
```

### Using with MCP Client

```python
from mcp.client import Client

async with Client("http://localhost:8000/jira") as client:
    # Get issue details
    result = await client.call_tool("get_jira_issue", {"issue_key": "PROJECT-123"})
    print(result)
    
    # Search issues
    result = await client.call_tool(
        "search_jira_issue", 
        {"query": "project = MYPROJECT AND status = Open"}
    )
    print(result)
```

## ๐Ÿณ Docker Deployment

```dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY pyproject.toml ./
RUN pip install uv && uv sync

COPY . .

CMD ["python", "server.py"]
```

Build and run:
```bash
docker build -t jira-mcp .
docker run -p 8000:8000 --env-file .env jira-mcp
```

## ๐Ÿ”’ Security Considerations

### Authentication
- โœ… Uses Bearer token authentication (secure)
- โœ… Tokens stored in environment variables (not in code)
- โœ… Supports custom SSL certificates for enterprise
- โš ๏ธ Ensure `.env` is in `.gitignore`

### Best Practices
- Use read-only JIRA tokens when possible
- Implement rate limiting for production
- Add request validation and sanitization
- Use HTTPS in production
- Implement proper logging (avoid logging tokens)

## ๐Ÿ“š JQL Reference

### Common Operators
- `=` : Equals
- `!=` : Not equals
- `~` : Contains text
- `>`, `<`, `>=`, `<=` : Comparison
- `IN` : Match any of a list
- `AND`, `OR` : Logical operators

### Common Fields
- `project` : Project key
- `status` : Issue status
- `assignee` : Assigned user
- `priority` : Issue priority
- `type` : Issue type (Bug, Story, etc.)
- `created`, `updated` : Dates
- `summary`, `description` : Text fields

### Special Functions
- `currentUser()` : Current logged-in user
- `-7d` : Relative dates (7 days ago)
- `ORDER BY` : Sort results

**Full JQL Documentation**:
- https://support.atlassian.com/jira-service-management-cloud/docs/use-advanced-search-with-jira-query-language-jql/

## ๐Ÿงช Testing

```bash
# Run tests
pytest

# With coverage
pytest --cov=. --cov-report=html

# Test individual tool
python -c "
from jiraAPI import JIRA
print(JIRA.get_jira_issue('PROJECT-123'))
"
```

## ๐Ÿ”ง Customization

### Adding More Tools

```python
@mcp.tool(description="Create a new JIRA issue")
async def create_jira_issue(
    project: str, 
    summary: str, 
    description: str,
    issue_type: str = "Task"
) -> str:
    """Create a new JIRA issue"""
    # Implementation here
    pass
```

### Adding Resources

```python
@mcp.resource("jira://projects")
async def list_projects() -> str:
    """List all available JIRA projects"""
    # Implementation here
    pass
```

### Adding Prompts

```python
@mcp.prompt()
async def analyze_sprint() -> str:
    """Generate a sprint analysis prompt"""
    return "Analyze the current sprint and provide insights..."
```

## ๐Ÿ“Š Architecture

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   AI Assistant  โ”‚ (Claude, GPT, Copilot)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚ MCP Protocol
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  FastAPI Server โ”‚ (server.py)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   jiraMCP.py    โ”‚ (MCP Tools)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   jiraAPI.py    โ”‚ (JIRA API Wrapper)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚ HTTPS
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   JIRA Server   โ”‚ (Atlassian Cloud / Self-Hosted)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

## ๐Ÿ› Troubleshooting

### "Authentication failed"
- Verify JIRA_API_TOKEN is correct
- Check token hasn't expired
- Ensure token has appropriate permissions

### "SSL Certificate verify failed"
- For self-hosted JIRA with custom certs, set JIRA_CERT_PATH
- For Atlassian Cloud, ensure JIRA_CERT_PATH is not set or set to `None`

### "Issue not found"
- Verify issue key format (e.g., "PROJECT-123")
- Check you have permission to view the issue
- Ensure project key is correct

### "JQL query failed"
- Validate JQL syntax at: https://your-jira-instance/secure/IssueNavigator.jspa
- Check field names are correct
- Ensure you have permission for the queried projects

## ๐Ÿ“ License

MIT License - Feel free to use in your projects

## ๐Ÿค Contributing

This is an educational example. Feel free to:
- Extend with more JIRA operations
- Add better error handling
- Implement caching
- Add rate limiting
- Improve documentation

## ๐Ÿ“š Related Documentation

- [MCP Protocol Documentation](https://modelcontextprotocol.io/)
- [JIRA REST API Reference](https://developer.atlassian.com/cloud/jira/platform/rest/v2/)
- [JQL Documentation](https://support.atlassian.com/jira-software-cloud/docs/what-is-advanced-search-in-jira-cloud/)
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
- [FastMCP Documentation](https://github.com/jlowin/fastmcp)

---

**Part of the MCP Learning Guide**: [Main Repository](../../README.md)