# 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