npm package: @gongrzhe/server-jira
Description: Stateless multi-tenant MCP server for Atlassian JIRA with OAuth 2.0 and automatic URL discovery
Author: Gong Rzhe
Latest version: 0.1.1

# JIRA MCP Server

A stateless, multi-tenant Model Context Protocol (MCP) server for Atlassian JIRA, providing comprehensive access to JIRA's REST API through standardized tools.

## Features

- **🎯 Zero Configuration**: Just provide your token - Jira URL is auto-discovered!
- **🔐 Dual Authentication**: Support for both OAuth 2.0 and API tokens
- **🌐 Multi-Tenant Architecture**: Each user connects to their own Jira instance
- **⚡ Stateless Design**: Complete request isolation with no session management
- **🔑 Smart Routing**: OAuth tokens → API Gateway, API tokens → Direct URL
- **📦 Fresh Instance Per Request**: Each request gets a new server instance
- **🛠️ Comprehensive API Coverage**: 30+ tools covering all major JIRA operations
- **📈 Horizontal Scaling**: Stateless design enables easy load balancing
- **💾 Smart Caching**: Token-to-URL mappings cached for performance (5-min TTL)
- **🚀 OAuth Helper**: Included script for easy OAuth token generation

## Tools Overview

### Issue Management (7 tools)
- `jira_get_issue` - Get issue details by key
- `jira_search_issues` - Search using JQL queries
- `jira_create_issue` - Create new issues
- `jira_update_issue` - Update issue fields
- `jira_delete_issue` - Delete issues
- `jira_assign_issue` - Assign issues to users
- `jira_link_issues` - Create issue relationships

### Comments (4 tools)
- `jira_get_comments` - Retrieve all comments
- `jira_add_comment` - Add new comments
- `jira_update_comment` - Modify comments
- `jira_delete_comment` - Remove comments

### Projects (6 tools)
- `jira_list_projects` - List accessible projects
- `jira_get_project` - Get project details
- `jira_get_project_issues` - Get issues in project
- `jira_get_project_versions` - Get project versions
- `jira_get_project_components` - Get project components
- `jira_search_projects` - Search projects

### Workflow (3 tools)
- `jira_get_transitions` - Get available transitions
- `jira_transition_issue` - Move issues through workflow
- `jira_get_workflows` - List workflows

### Users & Watchers (5 tools)
- `jira_get_current_user` - Current user info
- `jira_search_users` - Find users
- `jira_get_watchers` - Get issue watchers
- `jira_add_watcher` - Add watchers
- `jira_remove_watcher` - Remove watchers

### Metadata (5 tools)
- `jira_get_issue_types` - Available issue types
- `jira_get_priorities` - Available priorities
- `jira_get_statuses` - Available statuses
- `jira_get_fields` - System/custom fields
- `jira_get_resolutions` - Available resolutions

### Time Tracking (4 tools)
- `jira_get_worklogs` - Get time entries
- `jira_add_worklog` - Log work time
- `jira_update_worklog` - Update time entries
- `jira_delete_worklog` - Remove time entries

## Authentication

The server supports **two authentication methods** with **automatic Jira URL discovery**:

1. **API Tokens** - For personal/service account access
2. **OAuth 2.0** - For delegated user access (recommended for production)

Both methods automatically discover your Jira instance URL - no manual configuration needed!

### Option 1: API Token Authentication (Quick Start)

#### Getting Your API Token

1. Go to https://id.atlassian.com/manage-profile/security/api-tokens
2. Click "Create API token"
3. Give it a label (e.g., "MCP Server")
4. Copy the generated token

#### Using API Tokens

```bash
curl -X POST http://localhost:30000/mcp \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": "1",
    "method": "tools/call",
    "params": {
      "name": "jira_get_current_user",
      "arguments": {}
    }
  }'
```

### Option 2: OAuth 2.0 Authentication (Recommended)

OAuth 2.0 provides better security and user experience for production deployments.

#### Setting Up OAuth 2.0

1. **Create OAuth 2.0 App** at https://developer.atlassian.com/console/myapps/
   - Click "Create" → "OAuth 2.0 integration"
   - Set Authorization callback URL (e.g., `https://your-app.com/callback`)
   - Add permissions: `read:jira-work`, `write:jira-work`, `read:jira-user`, `offline_access`
   - Save your Client ID and Client Secret

2. **Generate Access Token** using the included helper:
   ```bash
   JIRA_CLIENT_ID=your_client_id \
   JIRA_CLIENT_SECRET=your_client_secret \
   node get-oauth-token.js
   ```

3. **Use OAuth Token** (same as API token):
   ```bash
   curl -X POST http://localhost:30000/mcp \
     -H "Authorization: Bearer YOUR_OAUTH_ACCESS_TOKEN" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json, text/event-stream" \
     -d '{"jsonrpc":"2.0","id":"1","method":"tools/call","params":{"name":"jira_get_current_user","arguments":{}}}'
   ```

## Quick Start

### Development Mode

```bash
# Install dependencies
npm install

# Run in development mode
npm run dev
```

### Production Mode

```bash
# Build the project
npm run build

# Start the server
npm start
```

The server will start on port 30000 by default (configurable via `PORT` environment variable).

**No environment variables required!** Each request provides its own JIRA URL.

## Usage Examples

**Important**: Only provide your API token - the Jira URL is auto-discovered!

### Search Issues
```bash
curl -X POST http://localhost:30000/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": "1",
    "method": "tools/call",
    "params": {
      "name": "jira_search_issues",
      "arguments": {
        "jql": "project = PROJ AND status = \"In Progress\"",
        "maxResults": 10
      }
    }
  }'
```

### Create Issue
```bash
curl -X POST http://localhost:30000/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": "2",
    "method": "tools/call",
    "params": {
      "name": "jira_create_issue",
      "arguments": {
        "project": "PROJ",
        "issueType": "Task",
        "summary": "New task from MCP server",
        "description": "Created via MCP JIRA server"
      }
    }
  }'
```

### Add Comment
```bash
curl -X POST http://localhost:30000/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": "3",
    "method": "tools/call",
    "params": {
      "name": "jira_add_comment",
      "arguments": {
        "issueKey": "PROJ-123",
        "body": "This is a comment from the MCP server"
      }
    }
  }'
```

### Transition Issue
```bash
curl -X POST http://localhost:30000/mcp \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": "4",
    "method": "tools/call",
    "params": {
      "name": "jira_transition_issue",
      "arguments": {
        "issueKey": "PROJ-123",
        "transitionId": "41",
        "comment": "Transitioning via MCP server"
      }
    }
  }'
```

## Configuration

### Environment Variables

The server requires **zero configuration**:

- `PORT` - Server port (default: 30000) - **Optional**

**That's it!** Users only provide:
- API token - Via `Authorization: Bearer <token>` header
- Jira URL - **Automatically discovered from the token**

### JQL (JIRA Query Language)

Many tools support JQL for powerful querying:

```sql
-- Basic searches
project = "PROJ"
status = "In Progress"
assignee = currentUser()

-- Advanced searches
project = "PROJ" AND status WAS "In Progress" DURING ("2024-01-01", "2024-12-31")
worklogAuthor = currentUser() AND worklogDate >= startOfWeek()
issueType = Bug AND priority = High AND created >= -7d
```

## Error Handling

The server provides structured error responses:

```json
{
  "error": true,
  "tool": "jira_get_issue",
  "message": "Error in jira_get_issue: [404] Issue not found: PROJ-999",
  "timestamp": "2024-01-15T10:30:00.000Z"
}
```

Common error codes:
- `401` - Authentication required/invalid
- `403` - Permission denied
- `404` - Resource not found
- `400` - Validation error
- `429` - Rate limit exceeded

## Health Check

```bash
curl http://localhost:30000/health
```

Returns:
```json
{
  "status": "healthy",
  "version": "0.1.0",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "mode": "stateless"
}
```

## Architecture

### Smart Token Discovery
- Calls Atlassian's `oauth/token/accessible-resources` API
- Discovers all Jira instances accessible to the token
- Uses the primary/first site automatically
- Caches URL mappings for 5 minutes (configurable)
- Automatic cache cleanup for memory efficiency

### Multi-Tenant Support
- Each user's token maps to their own Jira instance
- No shared configuration between users
- Perfect for SaaS deployments
- Supports JIRA Cloud, Server, and Data Center
- Handles multi-site tokens gracefully

### Stateless Design
- Fresh server instance per request
- No session management
- Complete request isolation
- Automatic cleanup prevents memory leaks

### Security
- No token storage (except in-memory cache)
- Request-level authentication and discovery
- Standard Bearer token support
- Fresh token validation per request
- Zero cross-tenant contamination

### Performance
- Horizontal scaling ready
- Intelligent caching (5-min TTL)
- Minimal memory footprint
- Fast startup time
- Zero configuration overhead
- Automatic cache eviction

## API Compatibility

This server is compatible with:
- JIRA Cloud
- JIRA Server/Data Center (7.0+)
- JIRA REST API v2

## License

MIT