Skip to main content
Glama

jira-mcp

npm version license: MIT node

An MCP (Model Context Protocol) server that exposes the Jira REST API to AI assistants — boards, sprints, epics, issues, JQL search, workflow transitions, comments, worklogs, projects, users, plus a generic passthrough tool for any Jira REST endpoint.

Works with both Jira Cloud (REST API v3) and Jira Data Center (REST API v2), auto-detected from the base URL.

Install (one-click)

Once published to npm, any MCP client can run it via npx — no local build needed.

Interactive installer (all agents at once)

npx -y @thammarongg/jira-mcp@latest install

Shows a menu — Select All or pick agents (Claude Code, OpenCode, Codex, Cursor, Claude Desktop, Gemini CLI) — then asks for the Jira base URL and credentials (token entry is masked on a TTY). If a selected agent already has a jira entry, the installer offers to reuse its base URL and account without asking for the credentials again. Existing config files are backed up to .bak before any modification, and re-running updates the jira entry in place instead of duplicating it.

With --yes and no credential flags, a selected existing entry's credentials are reused without prompting.

Non-interactive (CI / scripting):

# Jira Cloud
npx -y @thammarongg/jira-mcp@latest install --agents all \
  --base-url https://your-org.atlassian.net \
  --email you@example.com --token xxx --yes

# Jira Data Center (subset of agents)
npx -y @thammarongg/jira-mcp@latest install --agents claude-code,codex \
  --base-url https://jira.yourcompany.com \
  --username you --token xxx --yes

Flags: --agents all or comma-separated ids/numbers (claude-code, opencode, codex, cursor, claude-desktop, gemini-cli), --base-url, --email (Cloud) / --username (Data Center), --token (API token or PAT), --password (DC app password), --yes (skip the confirm prompt).

CLI commands

npx -y @thammarongg/jira-mcp@latest update                 # refresh configured agents
npx -y @thammarongg/jira-mcp@latest update --agents codex
npx -y @thammarongg/jira-mcp@latest uninstall              # choose configured agents interactively
npx -y @thammarongg/jira-mcp@latest uninstall --agents all --yes
npx -y @thammarongg/jira-mcp@latest --version
npx -y @thammarongg/jira-mcp@latest --help

update is non-interactive and repairs every existing jira entry from that agent's own credentials; agents without an entry are skipped. uninstall removes only the jira entry, preserving the rest of each agent configuration; it accepts the same --agents selection grammar as install and asks for confirmation unless --yes is supplied.

Running npx -y @thammarongg/jira-mcp@latest bare in a terminal prints a status card with the installed version, configured agents, and available commands. MCP clients pipe stdio, so the same bare command starts the MCP server for them; it expects JIRA_* environment variables, which is why running it bare without those variables reports a missing JIRA_BASE_URL.

Claude Code (manual one-liner)

claude mcp add jira --env JIRA_BASE_URL=https://your-org.atlassian.net \
  --env JIRA_EMAIL=you@example.com --env JIRA_API_TOKEN=xxx \
  -- npx -y @thammarongg/jira-mcp@latest
// Claude Desktop / any MCP client (mcpServers)
{
  "mcpServers": {
    "jira": {
      "command": "npx",
      "args": ["-y", "@thammarongg/jira-mcp@latest"],
      "env": {
        "JIRA_BASE_URL": "https://your-org.atlassian.net",
        "JIRA_EMAIL": "you@example.com",
        "JIRA_API_TOKEN": "xxx"
      }
    }
  }
}
// opencode (opencode.json)
{
  "mcp": {
    "jira": {
      "type": "local",
      "command": ["npx", "-y", "@thammarongg/jira-mcp@latest"],
      "environment": {
        "JIRA_BASE_URL": "https://your-org.atlassian.net",
        "JIRA_EMAIL": "you@example.com",
        "JIRA_API_TOKEN": "xxx"
      },
      "enabled": true
    }
  }
}

Publishing

npm login
npm publish          # prepublishOnly runs build + smoke test first

Local development (no publish)

npm install
npm run build
# run directly: node dist/index.js  (or `npm run dev` via tsx)

Configuration (environment variables)

Variable

Required

Description

JIRA_BASE_URL

yes

https://your-org.atlassian.net (Cloud) or https://jira.yourcompany.com (DC); a DC context path such as /jira is preserved

JIRA_EMAIL

Cloud

Your Atlassian account email

JIRA_API_TOKEN

yes

API token (Cloud: id.atlassian.com → Security → API tokens; DC: personal access token)

JIRA_USERNAME

DC

Username (alternative to JIRA_EMAIL)

JIRA_PASSWORD

DC

App password (alternative to JIRA_API_TOKEN)

JIRA_API_VERSION

no

Force 2 or 3. Default: auto (Cloud → 3, DC → 2)

JIRA_TIMEOUT_MS

no

Request timeout, default 30000

Quick auth check:

JIRA_BASE_URL=... JIRA_EMAIL=... JIRA_API_TOKEN=... node dist/index.js

Then call the get_current_user tool from your MCP client — it verifies credentials.

Related MCP server: Jira MCP Server

Using a local checkout

Prefer not to publish? Point the client at the built file instead of npx — same env vars as above:

claude mcp add jira --env JIRA_BASE_URL=https://your-org.atlassian.net \
  --env JIRA_EMAIL=you@example.com --env JIRA_API_TOKEN=xxx \
  -- node /absolute/path/to/jira-mcp/dist/index.js
// opencode (opencode.json)
{
  "mcp": {
    "jira": {
      "type": "local",
      "command": ["node", "/absolute/path/to/jira-mcp/dist/index.js"],
      "environment": {
        "JIRA_BASE_URL": "https://your-org.atlassian.net",
        "JIRA_EMAIL": "you@example.com",
        "JIRA_API_TOKEN": "xxx"
      },
      "enabled": true
    }
  }
}

Agent skill

A ready-made agent skill (setup + workflow guidance for the tools) ships in skill/SKILL.md. Install it by copying to your skills directory:

mkdir -p ~/.claude/skills/jira && cp skill/SKILL.md ~/.claude/skills/jira/
# or for opencode / shared agents:
mkdir -p ~/.agents/skills/jira && cp skill/SKILL.md ~/.agents/skills/jira/

Tools

Boards & sprints (Agile + Software APIs)

Tool

Description

list_boards

List boards (filter by type/name/project key or ID)

get_board

Board details incl. projects

list_sprints

Sprints on a board (state: active/closed/future)

get_sprint

Sprint details

create_sprint

New sprint on a board

update_sprint

Rename, reschedule, change goal/state

close_sprint

Close a sprint

get_sprint_issues

Issues in a sprint (Cloud cursor or DC offset paging)

get_sprint_view

Full UI-like sprint view (board + sprint + issues in one call)

get_backlog

Board backlog (Cloud Software enhanced or DC Agile, rank-ordered)

Epics

Tool

Description

list_epics

Epics on a board (optionally filtered by done)

get_epic / get_epic_issues

Read an epic and its children (works on team-managed projects)

create_epic

New epic in a project

move_issue_to_epic

Add issues to an epic (sets parent on team-managed)

get_epic_meta

Epic-level issue types available in a project

Issues

Tool

Description

get_issue

Issue by key

create_issue

Create (supports custom fields)

update_issue

Set fields and/or relative update ops

delete_issue

Delete

search_issues

JQL search — enhanced search (/search/jql) on Cloud, legacy /search on Data Center

get_issue_create_meta

Discover projects/types/required fields (current per-project metadata endpoints)

get_issue_transitions / transition_issue

Workflow transitions

assign_issue

Assign/unassign

add_comment / list_comments / delete_comment

Comments (plain text in, auto-converted to ADF on Cloud/v3)

get_issue_worklogs / add_worklog

Time tracking

Projects, users, meta

list_projects, get_project, get_project_components, create_project_component, get_project_issue_types, get_project_roles, get_project_versions, get_current_user, find_users, get_user, get_fields, get_issue_types

Escape hatch

Tool

Description

jira_api

Raw call to any /rest/... endpoint (method, path, query, body) — covers the full Jira REST API

Typical agent workflow

  1. list_boards → pick a board

  2. list_sprints (state: active) → pick a sprint

  3. get_sprint_issues or get_sprint_view → see the work

  4. search_issues with JQL for anything custom

  5. create_issue / transition_issue / add_comment to act

  6. Anything else → jira_api

Rich text and ADF

Jira Cloud REST v3 stores descriptions, comment bodies and worklog comments as Atlassian Document Format, not plain strings. Pass plain text to create_issue, create_epic, update_issue, transition_issue, add_comment and add_worklog — the server wraps it in ADF when JIRA_API_VERSION is 3, and leaves it alone on v2 (Data Center), where wiki markup applies. Blank lines start a new paragraph and single newlines become line breaks; Markdown is not rendered (**bold** shows literally). Already-built ADF objects are passed through untouched.

Development

npm run dev        # run from source via tsx
npm run build      # compile to dist/
npm run typecheck  # tsc --noEmit
node scripts/smoke.mjs   # stdio handshake + tools/list smoke test

Notes & limitations

  • Auth is HTTP Basic (email+token for Cloud, username+token/password for DC) — the standard for Jira REST.

  • JIRA_BASE_URL may include a Data Center context path (for example https://jira.example.com/jira); it is retained when resolving /rest/... endpoints.

  • Pagination: most list tools return Jira's native startAt/maxResults/total; pass startAt to page.

  • Platform routing: Cloud-only enhanced Software reads use /rest/software/1.0 for backlog, sprint issues, and epic issues (cursor nextPageToken); Data Center uses the corresponding Agile 1.0 endpoints with startAt/total. list_boards passes its project filter as the Agile API's singular projectKeyOrId parameter.

  • create_sprint uses the documented top-level Agile POST /rest/agile/1.0/sprint route and sends the selected board as originBoardId.

  • JQL search on Jira Cloud uses /rest/api/3/search/jql, since Atlassian removed GET /rest/api/{2,3}/search on 2025-05-01 (CHANGE-2046 — the old endpoint now returns HTTP 410). Consequences for search_issues on Cloud: the JQL must be bounded (include a restriction such as project, assignee, or key), the response carries no total, and paging is by cursor — pass the returned nextPageToken back and stop when isLast is true. startAt is rejected there rather than silently ignored, and includeApproximateTotal: true adds an approximate match count via /search/approximate-count.

  • Jira Data Center keeps the legacy /search endpoint with startAt/total; if a Cloud site on a custom domain is misdetected as DC, a 410 from /search transparently retries against /search/jql.

  • get_issue_create_meta composes the current per-project and per-issue-type metadata endpoints (/issue/createmeta/{project}/issuetypes and /issue/createmeta/{project}/issuetypes/{issueType}), because the old /issue/createmeta query form is deprecated on Cloud and removed from Jira Data Center 9.0+. Its output keeps the familiar projects[].issuetypes[].fields shape. Pass projectKeys when fields are expanded (the default); omitting it is allowed only with expand: "projects.issuetypes" for bounded issue-type summaries. Project metadata is fetched with a fixed concurrency of four, and issue-type field metadata is likewise limited to four concurrent requests.

  • get_backlog, get_sprint_issues, and get_epic_issues use Cloud's current Software enhanced endpoints with cursor paging; pass nextPageToken for the next page. Data Center keeps Agile 1.0 and startAt/total. The older Cloud Agile issue-list endpoints remain available but are deprecated.

  • Rapid view IDs are computed as boardId * 10^13 + sprintId (Jira's documented convention).

  • Comment bodies use the body field on both Cloud (v3) and Data Center (v2).

  • User references use accountId on API v3/Cloud and name on API v2/Data Center. get_user calls /user?accountId=... on v3; the v3 path form /user/{accountId} is not a current endpoint. create_issue's dueDate input is sent as Jira's duedate field; add_worklog accepts an optional started timestamp and Jira defaults it to now when omitted.

  • Epics: the Agile epic API (/rest/agile/1.0/epic/...) only understands company-managed epics and returns HTTP 400 on team-managed ("next-gen") projects. get_epic, get_epic_issues, and move_issue_to_epic detect that and fall back to the issue/search APIs, where an epic is an ordinary issue linked to its children by parent.

  • Jira Data Center exposes platform REST API v2/latest, not /rest/api/3. Leave JIRA_API_VERSION at its default (2) for DC; forcing 3 against a DC host is unsupported and causes the server to request unavailable /rest/api/3/... routes. Cloud-vs-DC endpoint routing is based on the detected deployment (*.atlassian.net is Cloud), while field representations are based on the selected API version.

  • jira_api paths must resolve under /rest/ — paths that would escape it (e.g. via .. segments) are rejected, and ?/# must be passed via query.

License

MIT © Thammarong G.

Available Tools

43 tools
add_commentAdd commentC

Add a comment to an issue.

Inputs: body (required), issueKey (required), visibility.

add_worklogAdd worklogA

Add a worklog (time spent) to an issue. started is optional and defaults to now when omitted; timeSpent uses Jira format, e.g. '2h 30m' or '1d'.

Inputs: issueKey (required), timeSpent (required), comment, started.

assign_issueAssign issueA

Assign (or unassign, with an empty value) an issue to a user. Uses PUT /issue/{key}/assignee with accountId on v3 and name on v2.

Inputs: issueKey (required), name, accountId.

close_sprintClose sprintA

Close a sprint (sets its state to closed).

Inputs: sprintId (required).

create_epicCreate epicA

Create an epic in a project. Company-managed projects usually also require the 'Epic Name' custom field — call get_epic_meta or get_issue_create_meta first and pass it via customFields.

Inputs: name (required), projectKey (required), assignee, issueType, +2 more.

create_issueCreate issueA

Create a new issue. Use get_issue_create_meta to discover valid projects, issue types, and required fields. Extra custom fields can be passed via customFields (e.g. { 'customfield_10010': 'value' }).

Inputs: summary (required), issueType (required), projectKey (required), labels, +8 more.

create_project_componentCreate project componentC

Create a component in a project.

Inputs: name (required), projectKey (required), description.

create_sprintCreate sprintB

Create a new sprint on a board. Dates are ISO-8601 strings, e.g. 2026-09-01T09:00:00.000+0000.

Inputs: name (required), boardId (required), goal, endDate, +1 more.

delete_commentDelete commentA

Delete a comment by its ID (from list_comments).

Inputs: issueKey (required), commentId (required).

delete_issueDelete issueA

Delete an issue. This is destructive.

Inputs: issueKey (required).

find_usersFind usersA

Search for users by name/email (Cloud) or username (Data Center). Returns account IDs / usernames usable for assignment.

Inputs: query (required), maxResults.

get_backlogGet board backlogA

List a board's backlog issues (in the board's filter, not in a sprint), ordered by rank. On Cloud this uses the current Software API enhanced backlog endpoint and cursor paging; on Data Center it uses Agile 1.0 with startAt/total.

Inputs: boardId (required), jql, fields, startAt, +2 more.

get_boardGet boardA

Get a single Jira board by ID, including its projects, location, and settings.

Inputs: boardId (required).

get_current_userGet current userA

Get the profile of the user whose credentials are configured (also verifies auth works).

Inputs: no named parameters.

get_epicGet epicA

Get a single epic by key (e.g. PROJ-1) or numeric issue ID. Falls back to the issue API for team-managed projects, where epics are ordinary issues.

Inputs: epicIdOrKey (required).

get_epic_issuesGet epic issuesA

List the issues belonging to an epic. Cloud uses the current Software API enhanced endpoint; Data Center uses Agile 1.0. Falls back to a JQL 'parent = ' search on team-managed projects, where the epic API does not apply.

Inputs: epicIdOrKey (required), fields, startAt, maxResults, +1 more.

get_epic_metaGet epic metaA

List the epic-level issue types available in a project (hierarchy level above Story/Task). Use get_issue_create_meta for the fields required to create one.

Inputs: projectKey (required).

get_fieldsGet all fieldsA

List all issue fields (including custom field IDs) in the Jira instance.

Inputs: no named parameters.

get_issueGet issueC

Get a single Jira issue by key (e.g. PROJ-123).

Inputs: issueKey (required), expand, fields.

get_issue_create_metaGet issue create metadataA

Discover valid projects, issue types, and their fields (with required flags) before creating an issue. Uses the current per-project metadata endpoints instead of the deprecated /issue/createmeta query form. Pass projectKeys when fields are expanded (the default) to bound requests; omit it only with expand=projects.issuetypes for issue-type summaries.

Inputs: expand, projectKeys, issuetypeIds.

get_issue_transitionsGet issue transitionsA

List the workflow transitions available for an issue.

Inputs: issueKey (required).

get_issue_typesGet issue typesA

List all issue types (Story, Task, Bug, Epic, ...) in the Jira instance.

Inputs: no named parameters.

get_issue_worklogsGet issue worklogsB

List time-tracking worklogs on an issue.

Inputs: issueKey (required), orderBy, startAt, maxResults.

get_projectGet projectA

Get a single project by key or ID.

Inputs: projectKeyOrId (required), expand.

get_project_componentsGet project componentsB

List components of a project.

Inputs: projectKey (required).

get_project_issue_typesGet project issue typesB

List the issue types available in a project, with their hierarchy levels (epic = 1, story/task = 0, sub-task = -1).

Inputs: projectKey (required), startAt, maxResults.

get_project_rolesGet project rolesB

List roles (and their actors) of a project.

Inputs: projectKey (required).

get_project_versionsGet project versionsB

List versions (releases) of a project.

Inputs: projectKey (required), startAt, maxResults.

get_sprintGet sprintA

Get a single sprint by ID (name, state, start/end dates, goal).

Inputs: sprintId (required).

get_sprint_issuesGet sprint issuesA

List the issues in a sprint. Cloud uses the current Software API enhanced endpoint with cursor paging; Data Center uses Agile 1.0 with startAt/total.

Inputs: sprintId (required), fields, startAt, maxResults, +1 more.

get_sprint_viewGet sprint viewA

Full sprint view like the Jira UI: board details, the sprint, and its issues, in one call. Cloud issue results use Software API cursor paging; Data Center uses Agile 1.0 offset paging.

Inputs: boardId (required), sprintId (required), fields, startAt, +2 more.

get_userGet userA

Get a user by account ID (Jira Cloud / API v3) or username (Data Center / API v2).

Inputs: username, accountId.

jira_apiRaw Jira REST API callA

Call any Jira REST API endpoint not covered by a dedicated tool. Path must start with /rest/ and stay under it (e.g. '/rest/api/3/issue/PROJ-1/names' or '/rest/agile/1.0/board/1'). Query params go in query, JSON payload in body. Returns the raw JSON response.

Inputs: path (required), method (required), body, query.

list_boardsList Jira boardsA

List Jira agile boards (scrum or kanban), optionally filtered by type, name, or one project key/ID.

Inputs: name, type, startAt, maxResults, +1 more.

list_commentsList issue commentsB

List comments on an issue.

Inputs: issueKey (required), orderBy, startAt, maxResults.

list_epicsList epicsA

List the epics on a board, including whether each one is done.

Inputs: boardId (required), done, startAt, maxResults.

list_projectsList projectsA

List all Jira projects visible to the current user. Cloud uses paginated /project/search; Data Center uses /project.

Inputs: startAt, maxResults.

list_sprintsList sprints for a boardA

List sprints on a board, optionally filtered by state (active, closed, future).

Inputs: boardId (required), state, startAt, maxResults.

move_issue_to_epicMove issue to epicA

Add issues to an epic. On team-managed projects this sets the issue's parent instead. To remove an issue from an epic, use update_issue with fields { "parent": null } (team-managed) or { "epic": null } (company-managed).

Inputs: issueKeys (required), epicIdOrKey (required).

search_issuesSearch issues (JQL)A

Search issues with JQL, e.g. 'project = PROJ AND sprint = 42 ORDER BY rank' or 'project = PROJ AND sprint IS NONE'. On Jira Cloud this uses enhanced search (/search/jql): the JQL must be bounded (include a restriction such as project, assignee, or key — a bare 'ORDER BY created DESC' is rejected), the response has no total, and paging is by cursor — pass the returned nextPageToken back in for the next page and stop when isLast is true. On Jira Data Center this uses the legacy /search endpoint, which pages with startAt and returns total.

Inputs: jql (required), expand, fields, startAt, +3 more.

transition_issueTransition issueA

Move an issue through its workflow. Use get_issue_transitions first to find the transition ID and required fields.

Inputs: issueKey (required), transitionId (required), fields.

update_issueUpdate issueA

Update an issue. Pass absolute values in fields (e.g. { summary: 'new' }) and/or relative changes in update (e.g. { labels: [{ add: 'x' }, { remove: 'y' }] }).

Inputs: issueKey (required), fields, update.

update_sprintUpdate sprintA

Update a sprint's name, goal, dates, or state (active/closed/future). Only provided fields are changed.

Inputs: sprintId (required), goal, name, state, +2 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 43 tools

    Disambiguation4/5

    Most tools target a distinct resource and action, and descriptions clarify likely variants like get_sprint, get_sprint_issues, and get_sprint_view. A few close pairs exist—get_issue_types vs get_project_issue_types and update_issue vs move_issue_to_epic—but the resource scopes and descriptions make misselection unlikely.

    Naming Consistency3/5

    The set mostly follows verb_noun, but it mixes get_ and list_ for collections, uses create_ for most resources but add_ for comments and worklogs, and uses search_issues versus find_users. jira_api also breaks the pattern, making the naming readable but not consistently structured.

    Tool Count2/5

    43 tools is well beyond the 25+ threshold, and the surface includes many fine-grained getters plus a catch-all jira_api tool. While Jira is a broad domain, the large count makes agent tool selection heavier than necessary, and some variants could reasonably be consolidated.

    Completeness4/5

    Core Jira workflows—issues, sprints, epics, projects, comments, worklogs, and users—are well covered with appropriate create/read/update/delete operations where relevant. Minor gaps exist, such as no update_comment, no delete_sprint, or no direct add-issue-to-sprint tool, but jira_api and update_issue provide usable workarounds.

    Maintenance

    ActivitySlowing
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers