# Jira REST MCP Server A Model Context Protocol (MCP) server that provides Jira integration for Claude Code and other MCP-compatible clients. Interact with Jira issues, projects, and workflows directly from your AI assistant. ## Why This Server? This server was created as an alternative to the official Atlassian MCP endpoint (`https://mcp.atlassian.com/v1/sse`). Some MCP clients, including Claude Code, experience authentication issues with the SSE-based endpoint where the connection can lose authentication state without the client detecting it, causing subsequent requests to fail silently or with confusing errors. This REST-based implementation provides: - **Reliable authentication** - Uses standard API token auth that doesn't lose state - **Bidirectional markdown/ADF conversion** - Write in markdown, get responses in markdown - Automatically converts markdown to Jira's ADF format when creating/updating issues - Converts ADF responses back to markdown for easy reading (configurable) - Supports headings, lists, bold, code blocks, tables, and more - **Predictable behavior** - Each request is independent, avoiding stateful connection issues ## Quick Start ### 1. Get 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 label (e.g., "MCP Server") and copy the token ### 2. Configure Your MCP Client Choose your client below:
Claude Code (CLI) #### Option A: Project-level (Recommended) This keeps secrets out of your committed codebase. Add to `.claude/settings.json` in your project: ```json { "mcpServers": { "jira": { "command": "npx", "args": ["-y", "jira-rest-mcp-server"], "env": { "JIRA_BASE_URL": "${JIRA_BASE_URL}", "JIRA_EMAIL": "${JIRA_EMAIL}", "JIRA_API_TOKEN": "${JIRA_API_TOKEN}" } } } } ``` Add your credentials to `.claude/settings.local.json` (add this file to `.gitignore`): ```json { "env": { "JIRA_BASE_URL": "https://your-domain.atlassian.net", "JIRA_EMAIL": "your-email@example.com", "JIRA_API_TOKEN": "your-api-token" } } ``` #### Option B: User-level Add to `~/.claude/settings.json`: ```json { "mcpServers": { "jira": { "command": "npx", "args": ["-y", "jira-rest-mcp-server"], "env": { "JIRA_BASE_URL": "https://your-domain.atlassian.net", "JIRA_EMAIL": "your-email@example.com", "JIRA_API_TOKEN": "your-api-token" } } } } ```
Claude Desktop Add to your Claude Desktop config file: - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` ```json { "mcpServers": { "jira": { "command": "npx", "args": ["-y", "jira-rest-mcp-server"], "env": { "JIRA_BASE_URL": "https://your-domain.atlassian.net", "JIRA_EMAIL": "your-email@example.com", "JIRA_API_TOKEN": "your-api-token" } } } } ```
Cursor Add to your Cursor settings (`.cursor/mcp.json` in your project or global config): ```json { "mcpServers": { "jira": { "command": "npx", "args": ["-y", "jira-rest-mcp-server"], "env": { "JIRA_BASE_URL": "https://your-domain.atlassian.net", "JIRA_EMAIL": "your-email@example.com", "JIRA_API_TOKEN": "your-api-token" } } } } ```
Windsurf Add to your Windsurf MCP config (`~/.codeium/windsurf/mcp_config.json`): ```json { "mcpServers": { "jira": { "command": "npx", "args": ["-y", "jira-rest-mcp-server"], "env": { "JIRA_BASE_URL": "https://your-domain.atlassian.net", "JIRA_EMAIL": "your-email@example.com", "JIRA_API_TOKEN": "your-api-token" } } } } ```
VS Code with Continue Add to your Continue config (`~/.continue/config.json`): ```json { "experimental": { "modelContextProtocolServers": [ { "transport": { "type": "stdio", "command": "npx", "args": ["-y", "jira-rest-mcp-server"], "env": { "JIRA_BASE_URL": "https://your-domain.atlassian.net", "JIRA_EMAIL": "your-email@example.com", "JIRA_API_TOKEN": "your-api-token" } } } ] } } ```
### 3. Restart Your Client Restart your MCP client to load the Jira tools. ## Configuration | Variable | Required | Default | Description | |----------|----------|---------|-------------| | `JIRA_BASE_URL` | Yes | - | Your Jira instance URL (e.g., `https://your-domain.atlassian.net`) | | `JIRA_EMAIL` | Yes | - | Email address associated with your Jira account | | `JIRA_API_TOKEN` | Yes | - | API token from step 1 | | `CONVERT_ADF_TO_MARKDOWN` | No | `true` | Convert ADF responses to markdown. Set to `false` to receive raw ADF format | ## Markdown Support This server provides seamless bidirectional conversion between Markdown and Jira's Atlassian Document Format (ADF): **When sending to Jira** (automatic): - Issue descriptions and comments written in markdown are automatically converted to ADF - Supports headings (`#`, `##`, `###`), lists (ordered and unordered), **bold**, *italic*, `code`, code blocks, tables, and more **When receiving from Jira** (configurable): - By default, ADF content in responses is converted back to markdown for easy reading - Disable with `CONVERT_ADF_TO_MARKDOWN=false` if you need raw ADF format **Example:** ```markdown ## Bug Description The API endpoint fails with 500 error. **Steps to reproduce:** 1. Send POST request 2. Check response **Expected:** 200 OK **Actual:** 500 Internal Server Error ``` This markdown is automatically converted to proper ADF when creating issues, and responses are converted back to markdown for readability. ## Available Tools ### Issue Management | Tool | Description | |------|-------------| | `jira_get_issue` | Get details of a Jira issue by key | | `jira_create_issue` | Create a new Jira issue (supports markdown in descriptions) | | `jira_edit_issue` | Update fields on an existing issue (markdown supported) | | `jira_get_transitions` | Get available workflow transitions | | `jira_transition_issue` | Transition an issue to a new status | | `jira_add_comment` | Add a comment to an issue (supports markdown formatting) | | `jira_add_worklog` | Log work time on an issue | | `jira_get_remote_links` | Get remote links for an issue | ### Search | Tool | Description | |------|-------------| | `jira_search_jql` | Search issues using JQL (Jira Query Language) | ### Projects | Tool | Description | |------|-------------| | `jira_get_projects` | List visible projects | | `jira_get_project_issue_types` | Get issue types for a project | | `jira_get_issue_type_fields` | Get fields for an issue type | ### Users | Tool | Description | |------|-------------| | `jira_get_user_info` | Get current authenticated user info | | `jira_lookup_account_id` | Look up users by name or email | | `jira_get_accessible_resources` | Get accessible Jira instances | ### Boards & Sprints | Tool | Description | |------|-------------| | `jira_get_boards` | List boards, optionally filtered by project | | `jira_get_sprints` | Get sprints for a board (filter by state: active/future/closed) | | `jira_move_issues_to_sprint` | Move issues to a sprint | ## Example Prompts Once configured, you can ask Claude things like: **Issue Management:** - "Get the details of PROJ-123" - "Create a new task in PROJ with summary 'Update documentation'" - "Create a bug with this description: ## Problem\n\nThe login fails with:\n```\nError 500\n```\n\n**Steps to reproduce:**\n1. Navigate to login\n2. Enter credentials" - "What are the available transitions for PROJ-456?" - "Move PROJ-456 to In Progress" **Comments & Updates:** - "Add a comment to PROJ-789: 'Fixed in latest release'" - "Add a comment with **bold** text and a numbered list of next steps" - "Update the description of PROJ-123 to include a table of test results" **Search & Tracking:** - "Search for all open bugs in the BACKEND project assigned to me" - "Find all issues in sprint 42" - "Log 2 hours of work on PROJ-101" **Sprint Management:** - "What sprint is PROJ-123 assigned to?" - "Show me all active sprints for the PROJ board" - "Move PROJ-456 and PROJ-457 to the current sprint" ## Alternative Installation Methods ### Global Install ```bash npm install -g jira-rest-mcp-server ``` Then use in your MCP config: ```json { "mcpServers": { "jira": { "command": "jira-rest-mcp-server", "env": { "JIRA_BASE_URL": "https://your-domain.atlassian.net", "JIRA_EMAIL": "your-email@example.com", "JIRA_API_TOKEN": "your-api-token" } } } } ``` ### From Source ```bash git clone https://github.com/jklz/jira-rest-mcp-server.git cd jira-rest-mcp-server npm install npm run build ``` Then use the full path in your MCP config: ```json { "mcpServers": { "jira": { "command": "node", "args": ["/path/to/jira-rest-mcp-server/dist/index.js"], "env": { "JIRA_BASE_URL": "https://your-domain.atlassian.net", "JIRA_EMAIL": "your-email@example.com", "JIRA_API_TOKEN": "your-api-token" } } } } ``` ## Security - API tokens are passed via environment variables only - Tokens are never logged or included in error messages - All inputs are validated before being sent to Jira - Error messages are sanitized to prevent credential exposure ## Troubleshooting ### "Tool not found" errors - Restart Claude Code after adding the MCP configuration - Check that the server name matches in your config ### Authentication failures - Verify your API token is valid and not expired - Ensure the email matches your Jira account - Check the base URL includes `https://` ### Connection issues - Verify your Jira instance is accessible - Check for any firewall or proxy restrictions ## License MIT