Skip to main content
Glama
README.md
# Jira MCP

Production [FastMCP](https://gofastmcp.com) server for **Jira Cloud** (REST v3 / ADF) and **Data Center** (often REST v2 / plain text). This is a self-hosted adapter you run against your site. It is not Atlassian's hosted Rovo endpoint; it uses the same MCP ideas (Streamable HTTP, inbound auth, annotated tools, structured output).

Auth follows the same split used by Azure MCP and Atlassian Rovo:

1. **Inbound** — the MCP client authenticates to this server (HTTP only).
2. **Outbound** — this server authenticates to Jira with email + API token (Cloud Basic auth).

HTTP is fail-closed without `MCP_JWKS_URI` or `MCP_JWT_SECRET`.

Author: **Clinton Follette**.

## Tools

| Tool | Access | Notes |
|---|---|---|
| `get_issue` | read | Key, status, summary, Source Ticket #, Customer Order #. |
| `create_issue` | write | Project, issue type, summary, description. Hidden when `MCP_READ_ONLY=true`. |

Look up custom field ids with `GET /rest/api/3/field` after you create **Source Ticket #** and **Customer Order #** and put them on the create screen.

## Install (local STDIO)

```json
{
  "mcpServers": {
    "jira": {
      "command": "mcp-jira",
      "env": {
        "JIRA_BASE_URL": "https://your-site.atlassian.net",
        "JIRA_EMAIL": "you@example.com",
        "JIRA_API_TOKEN": "<api-token>",
        "JIRA_SOURCE_TICKET_FIELD": "customfield_10001",
        "JIRA_CUSTOMER_ORDER_FIELD": "customfield_10002"
      }
    }
  }
}
```

Create a Cloud token at [id.atlassian.com](https://id.atlassian.com/manage-profile/security/api-tokens).

```bash
pip install .
mcp-jira
```

## Remote HTTP

```bash
export MCP_TRANSPORT=http
export MCP_HOST=127.0.0.1
export MCP_PORT=8003
export MCP_JWKS_URI=https://login.example.com/.well-known/jwks.json
export MCP_JWT_ISSUER=https://login.example.com
export MCP_JWT_AUDIENCE=mcp-jira
mcp-jira
```

Endpoint: `http://127.0.0.1:8003/mcp`. Health: `GET /health`.

## Outbound Jira configuration

| Variable | Required | Purpose |
|---|---|---|
| `JIRA_BASE_URL` | yes | Site origin |
| `JIRA_EMAIL` | yes | Cloud account |
| `JIRA_API_TOKEN` | yes | API token |
| `JIRA_API_PATH` | no | Default `/rest/api/3` |
| `JIRA_DESCRIPTION_FORMAT` | no | `adf` (Cloud v3) or `plain` (often DC v2) |
| `JIRA_ISSUE_TYPE` | no | Default `Task` |
| `JIRA_SOURCE_TICKET_FIELD` | for close-loop | `customfield_XXXXX` |
| `JIRA_CUSTOMER_ORDER_FIELD` | for T2 | `customfield_YYYYY` |
| `MCP_READ_ONLY` | no | Hide `create_issue` |

## Security

- HTTP without inbound JWT configuration refuses to boot.
- Issue and project keys are validated before they are placed in URLs.
- Custom field ids must start with `customfield_` or they are ignored.
- `mask_error_details` is on.

See [SECURITY.md](SECURITY.md).

## License

MIT. Copyright (c) 2026 Clinton Follette.

TDQS

B3.4/5.0

Scored across 2 tools

Disambiguation5/5

get_issue and create_issue have unambiguous, non-overlapping purposes — one reads, one writes. An agent can select correctly without hesitation.

Naming Consistency5/5

Both tools follow a clean, predictable verb_noun snake_case pattern (get_issue, create_issue), consistent with common MCP conventions.

Tool Count2/5

Only 2 tools for a server branded as a general 'Jira MCP' is thin; it covers just a narrow read/create slice of the Jira domain and leaves the set feeling minimally scoped.

Completeness3/5

Create and get are present but there is no update, delete, search, transition, or comment operation, so agents hit dead ends for common Jira workflows. The narrow customfield focus partially excuses the gap but not fully.

Maintenance

ActivityMaintained
ResponsivenessNo issues