Skip to main content
Glama
w-10-m

Jira Enterprise MCP

by w-10-m
README.md
# Jira Enterprise MCP

Small MCP server for Codex that connects to enterprise Jira with a Jira personal access token.

## What it does

- Tests connectivity to Jira
- Lists accessible Jira projects
- Looks up a Jira issue by key
- Looks up a Jira issue by key, including derived acceptance criteria when present in a custom field
- Looks up a Jira issue by key and can return screenshot/image attachments as MCP image content, including derived acceptance criteria when present in a custom field
- Fetches individual attachments and can return raw attachment bytes as base64, with image attachments also exposed as MCP image content
- Inspects issue creation metadata for a project and issue type, with a fallback for tenants that do not expose `createmeta`
- Runs JQL searches
- Creates a Jira issue
- Updates an existing issue
- Lists issue comments
- Lists or performs issue transitions
- Uploads attachments to an issue
- Uploads an attachment and posts a comment that references it, with optional inline image markup
- Lists linked issues
- Fetches and creates worklog entries
- Adds a comment to an existing issue

## Requirements

- Node.js 18+
- A Jira PAT that works against your Jira instance
- Network access to your Jira base URL

## Setup

1. Install dependencies:

```bash
npm install
```

2. Copy `.env.example` to `.env` and fill in your values if you want a local template file:

```bash
cp .env.example .env
```

3. Export the variables before launching the MCP server, or let your MCP host pass them in:

```bash
export JIRA_BASE_URL=https://your-jira.example.com
export JIRA_PAT=your-token
export JIRA_DEFAULT_PROJECT=YOURPROJECT
export JIRA_REQUEST_TIMEOUT_MS=30000
export JIRA_MAX_ATTACHMENT_BYTES=26214400
```

## Run locally

```bash
npm start
```

Note: this server reads `JIRA_BASE_URL`, `JIRA_PAT`, and `JIRA_DEFAULT_PROJECT` from `process.env`. It does not load `.env` automatically, so `.env.example` is a template, not a runtime loader.

## Project structure

- `src/index.js` starts the stdio transport only.
- `src/server.js` builds the MCP server and wires tool listing/call handlers.
- `src/jira-client.js` owns Jira HTTP requests, auth headers, timeouts, attachment downloads, and uploads.
- `src/tools/*-tools.js` co-locates each feature area's MCP tool schemas with its handlers.
- `src/tools/registry.js` combines feature modules into the MCP tool list and dispatch table.
- `src/config.js`, `src/validation.js`, `src/jira-formatters.js`, and `src/mcp-content.js` keep shared config, validation, serialization, and MCP response helpers isolated.

## Recommended validation flow

Use this order when validating a new PAT against your Jira instance:

1. `jira_test_connection`
2. `jira_list_projects`
3. `jira_get_create_meta`
4. `jira_get_issue`
5. `jira_get_issue_with_images`
6. `jira_get_attachment`
7. `jira_list_issue_comments`
8. `jira_transition_issue`
9. `jira_update_issue`
10. `jira_search`
11. `jira_create_issue`
12. `jira_add_attachment`
13. `jira_add_comment_with_attachment`
14. `jira_get_issue_links`
15. `jira_get_worklog`
16. `jira_add_worklog`
17. `jira_add_comment`

This matters because enterprise Jira tenants often allow reads before creates, and issue creation may require project-specific issue types or custom fields.

## MCP host wiring

### Codex

If you are using Codex locally, point an MCP entry at this server command:

```json
{
  "mcpServers": {
    "jira-enterprise": {
      "command": "node",
      "args": ["/absolute/path/to/src/index.js"],
      "env": {
        "JIRA_BASE_URL": "https://your-jira.example.com",
        "JIRA_PAT": "YOUR_PAT",
        "JIRA_DEFAULT_PROJECT": "YOURPROJECT"
      }
    }
  }
}
```

If you prefer the Codex CLI helper, the shape should be equivalent to:

```bash
codex mcp add jira-enterprise --env JIRA_BASE_URL=https://your-jira.example.com --env JIRA_PAT=YOUR_PAT --env JIRA_DEFAULT_PROJECT=YOURPROJECT -- node /absolute/path/to/src/index.js
```

The exact config location can vary by Codex app version, so use whichever local MCP configuration flow your Codex build exposes.

### Claude

For Claude clients that support local MCP servers, use the equivalent `mcpServers` entry and pass the same environment variables:

```json
{
  "mcpServers": {
    "jira-enterprise": {
      "command": "node",
      "args": ["/absolute/path/to/src/index.js"],
      "env": {
        "JIRA_BASE_URL": "https://your-jira.example.com",
        "JIRA_PAT": "YOUR_PAT",
        "JIRA_DEFAULT_PROJECT": "YOURPROJECT"
      }
    }
  }
}
```

If your Claude app exposes an MCP configuration file or settings UI, add the server there. The important part is that Claude launches `node /absolute/path/to/src/index.js` with those three env vars present.

## Notes

- This server uses `Authorization: Bearer <PAT>`.
- `JIRA_REQUEST_TIMEOUT_MS` and `JIRA_MAX_ATTACHMENT_BYTES` are optional safety limits. Defaults are 30 seconds and 25 MiB.
- If your Jira instance accepts UI logins but rejects API calls, the PAT may not be enabled for your tenant or may require a different auth scheme.
- If your Jira admins require custom CA certificates, you may need to trust that certificate at the OS or Node runtime level before this server can connect cleanly.
- On some Jira tenants, `createmeta` may return `404 "Issue Does Not Exist"`. The MCP falls back to project issue types and workflow statuses so you can still discover valid issue types even when field-level create metadata is unavailable.

## Tools

- `jira_test_connection`
- `jira_list_projects`
- `jira_get_issue`
- `jira_get_issue_with_images`
- `jira_get_attachment`
- `jira_list_issue_comments`
- `jira_transition_issue`
- `jira_update_issue`
- `jira_get_create_meta`
- `jira_search`
- `jira_create_issue`
- `jira_add_attachment`
- `jira_add_comment_with_attachment`
- `jira_get_issue_links`
- `jira_get_worklog`
- `jira_add_worklog`
- `jira_add_comment`

## Attachment content behavior

- `jira_get_attachment` with `includeContent: false` returns attachment metadata only.
- `jira_get_attachment` with `includeContent: true` returns raw file bytes in `contentBase64` with `contentEncoding: "base64"`.
- For image attachments such as PNGs, the tool also includes MCP image preview content, but the downloadable bytes are always in `contentBase64`.

TDQS

B3.4/5.0

Scored across 17 tools

Disambiguation4/5

Most tools have distinct purposes, but `jira_add_attachment` and `jira_add_comment_with_attachment` overlap in attachment functionality, potentially causing misselection. Descriptions help clarify, so ambiguity is minimal.

Naming Consistency5/5

All tools follow the `jira_verb_noun` pattern consistently. Naming is predictable and clear, with only minor exceptions like `search` (no noun) which is still unambiguous.

Tool Count4/5

17 tools is slightly above the typical well-scoped range but reasonable for a complex system like Jira. The set covers many aspects without being excessive.

Completeness3/5

Core issue operations (create, read, update, transition) are covered, but a delete issue tool is missing. Other gaps like project management and user operations are acceptable for a focused MCP server.

Maintenance

ActivityInactive
ResponsivenessNo issues