Sign inSign up

n8500x/mcp-jira

By n8500x

•Updated 29 days ago

Jira Cloud MCP server: every REST operation as a tool, from Atlassian OpenAPI specs

Image
0

210

n8500x/mcp-jira repository overview

⁠mcp-jira — the whole Jira Cloud REST API as MCP tools

A Model Context Protocol⁠ server that exposes every operation of the Jira Cloud platform REST API v3, the Jira Software (agile) API and the Jira Service Management API as a tool — 809 operations, generated at start-up from Atlassian's own OpenAPI specifications, so there is no hand-maintained tool list to fall behind. TypeScript, stdio and Streamable HTTP transports, API-token or OAuth 2.0 authentication, operator policy (read-only, method deny-list, tool filters), and a self-contained Docker image with the docs, examples, test harness, mock Jira and test-suite baked in for air-gapped sites.

docker run --rm -i -e JIRA_BASE_URL=https://acme.atlassian.net -e [email protected] -e JIRA_API_TOKEN=... n8500x/mcp-jira
Operations → tools629 platform + 105 software + 75 service management = 809, plus 4 discovery tools
Tool namesjira_get_issue, jira_agile_get_all_sprints, jira_jsm_create_customer_request (snake_case operationId, prefixed per API)
Modesfull (everything, ~1.5 MB tools/list), compact (~70 essentials + discovery), meta (discovery only) — every operation stays reachable through jira_call_operation
PolicyJIRA_READ_ONLY, JIRA_DENY_METHODS, include/exclude globs, tag and API-set filters
Authemail + API token (basic), or OAuth 2.0 bearer via api.atlassian.com
Transportsstdio (desktop hosts) and stateless Streamable HTTP (/mcp, /healthz, /docs)
Imagen8500x/mcp-jira — node:22-alpine, non-root uid 1001/gid 0 (OpenShift-ready), tini, ~self-contained

⁠Quick start

1. Credentials. Create an API token at https://id.atlassian.com/manage-profile/security/api-tokens⁠ (ideally for a dedicated service account) — see docs/AUTH.md⁠ for OAuth 2.0 and the Atlassian Enterprise / Guard policy notes.

2. Check it works.

docker run --rm -e JIRA_BASE_URL=https://acme.atlassian.net -e [email protected] -e JIRA_API_TOKEN=atatt_... \
  n8500x/mcp-jira doctor

doctor reports the configuration, the spec/tool counts, Jira reachability, who you are, your effective permissions, and whether Jira Software / Service Management exist on the site.

3. Plug into an MCP host (stdio). Claude Desktop / Claude Code / Cursor / any stdio host:

{
  "mcpServers": {
    "jira": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "-e",
        "JIRA_BASE_URL",
        "-e",
        "JIRA_EMAIL",
        "-e",
        "JIRA_API_TOKEN",
        "n8500x/mcp-jira"
      ],
      "env": {
        "JIRA_BASE_URL": "https://acme.atlassian.net",
        "JIRA_EMAIL": "[email protected]",
        "JIRA_API_TOKEN": "atatt_..."
      }
    }
  }
}

Ready-made files: examples/claude_desktop_config.json⁠, examples/claude-code.mcp.json⁠. Hosts that struggle with 800+ tools: add -e JIRA_TOOL_MODE=compact.

4. Or run it as a shared service (HTTP).

cp examples/env.example .env   # fill in the site + credentials, set MCP_HTTP_BEARER_TOKEN
docker compose up -d           # Streamable HTTP on :3000 — /mcp, /healthz, /docs
MCP_URL=http://localhost:3000 MCP_TOKEN=... examples/curl-http.sh

Kubernetes/OpenShift manifests: examples/k8s⁠.

⁠How tools look

Tool names are the spec operationId in snake_case with a prefix per API set; arguments use Jira's own parameter names, the JSON request body goes under body, uploads under files:

jira_get_issue            { "issueIdOrKey": "PLAT-123", "fields": ["summary","status"] }
jira_create_issue         { "body": { "fields": { "project": {"key":"PLAT"}, "issuetype": {"name":"Task"}, "summary": "…" } } }
jira_do_transition        { "issueIdOrKey": "PLAT-123", "body": { "transition": { "id": "31" } } }
jira_add_attachment       { "issueIdOrKey": "PLAT-123", "files": [ { "filename": "a.csv", "contentBase64": "…" } ] }
jira_agile_get_issues_for_sprint { "sprintId": 345, "fields": ["summary"] }
jira_jsm_get_customer_requests   { "serviceDeskId": "3", "requestStatus": "OPEN_REQUESTS" }

Each tool description carries the HTTP method and path, Atlassian's summary, the OAuth scopes it needs, [DEPRECATED]/experimental flags and a link to the Atlassian docs page. Results are the raw Jira JSON (also as structuredContent.data), truncated above a size cap with a visible notice; errors return the HTTP status, Jira's own messages and a hint (401 → token expired?, 403 → missing scope X, 404 → no permission, 410 → endpoint removed, …).

Full catalogue: docs/TOOLS.md⁠. Worked examples (JQL, ADF comments, transitions, sprints, JSM, pagination): docs/RECIPES.md⁠.

⁠Discovery tools (always on)
ToolDoes
jira_list_operationsSearch all 809 operations by keyword / tag / method / API; shows which are registered
jira_describe_operationEvery parameter and the deep request-body schema, scopes, docs link — for one operation
jira_call_operationRun any operation by tool name or operationId, registered or not
jira_requestRaw request to any /rest/ path (endpoints newer than the specs)

So a server configured with 12 tools can still do everything; the model finds and reads the schema of what it needs, then calls it. Hard policy applies to every route.

⁠Choosing the surface and the policy

VariableDefaultEffect
JIRA_API_SETSplatform,software,servicedeskWhich specs to load (drop servicedesk on sites without JSM)
JIRA_TOOL_MODEfullfull = all operations; compact = ~70 everyday operations; meta = discovery tools only
JIRA_TOOL_INCLUDE / JIRA_TOOL_EXCLUDE—Comma-separated globs on tool names, e.g. jira_get_*,jira_agile_*
JIRA_TOOL_TAGS—Only operations in these spec groups, e.g. Issues,Issue search,Projects
JIRA_INCLUDE_DEPRECATED / JIRA_INCLUDE_EXPERIMENTALtrueHide what Atlassian flags as deprecated / experimental
JIRA_READ_ONLYfalseHard policy: only GET operations run, by any route
JIRA_DENY_METHODS—Hard policy: e.g. DELETE or DELETE,PUT
JIRA_RAW_TOOL / JIRA_META_TOOLStrueTurn off jira_request / the discovery tools

Filters decide what is advertised; JIRA_READ_ONLY and JIRA_DENY_METHODS decide what may run — including through jira_call_operation and jira_request. Full reference and every other setting (timeouts, retries, result cap, TLS/proxy, HTTP options, logging): docs/OPERATIONS.md⁠.

⁠Image commands

docker run --rm [-i] <env> n8500x/mcp-jira                 serve (stdio)        | ... serve --http  (Streamable HTTP)
docker run --rm        n8500x/mcp-jira tools [filter] [--all] list registered tools / every operation   (no Jira needed)
docker run --rm        n8500x/mcp-jira describe jira_edit_issue  parameters, body schema, scopes, docs   (no Jira needed)
docker run --rm <env>  n8500x/mcp-jira call jira_get_issue issueIdOrKey=PLAT-1 'fields=["summary"]'
docker run --rm <env>  n8500x/mcp-jira doctor                connectivity + auth + permissions report
docker run --rm <env>  n8500x/mcp-jira harness scenario /usr/share/mcp-jira/examples/scenarios/smoke.json
docker run --rm        n8500x/mcp-jira mock                  bundled fake Jira for tests  (MOCK_HOST/MOCK_PORT)
docker run --rm        n8500x/mcp-jira selftest              the vitest suite, offline
docker run --rm        n8500x/mcp-jira docs [file] | examples | export [dir] | readme | compose | spec

GET /docs on a running HTTP instance serves the same README, docs/ and examples/.

⁠About Jira Cloud "versions"

Jira Cloud is evergreen — every tenant runs the same build — so there is nothing to pin. What matters is the REST API version (platform v3; v2 is legacy) and Atlassian's deprecations: the vendored specs flag 37 operations, notably the classic GET/POST /rest/api/3/search (replaced by /search/jql with token pagination) and GET /rest/api/3/project. They are exposed as [DEPRECATED] tools until JIRA_INCLUDE_DEPRECATED=false. Spec provenance and refresh procedure: spec/README.md⁠; JIRA_SPEC_DIR can point at newer spec files at run time without a rebuild.

⁠Development

npm ci && npm run build && npm test          # ~70 tests, offline, against the bundled mock Jira
npm run lint && npm run docs:check           # eslint (type-aware) + generated TOOLS.md is current
npm run mock                                 # fake Jira on :18080, then: JIRA_BASE_URL=http://127.0.0.1:18080 ... npm run doctor
npm run harness -- tools issue               # generic MCP harness: tools | describe | call | scenario | doctor | repl
.\build.ps1          # docker build (tests run in the builder stage) + smoke;  .\build.ps1 -Push -Overview to publish
.\test.ps1           # end-to-end against the image: doctor, call, scenarios, HTTP mode, /docs, selftest

Design and layout: docs/ARCHITECTURE.md⁠. Contributing and spec refresh: docs/DEVELOPMENT.md⁠. Layout:

packages/jira      @n8500x/mcp-jira      server, CLI, mock Jira        packages/harness   @n8500x/mcp-harness   generic MCP client CLI
spec/              vendored Atlassian OpenAPI documents              docs/ examples/     baked into the image under /usr/share/mcp-jira

MIT licence for this code; the OpenAPI documents remain Atlassian's and are redistributed unmodified for build reproducibility.

Tag summary

Content type

Image

Digest

sha256:dac9c6fbd…

Size

111.7 MB

Last updated

29 days ago

docker pull n8500x/mcp-jira