Jira Enterprise MCP
# 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
Scored across 17 tools
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.
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.
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.
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.