Skip to main content
Glama

better-jira-mcp

A thin MCP pass-through to the Jira and Confluence Cloud REST APIs. Built because mcp-atlassian mangles Jira descriptions: it regex-converts markdown into Jira wiki markup and posts that through REST v2, so aws_vpc_endpoint becomes aws*vpc*endpoint, {id} and a + b get eaten as macros, and **bold** comes back escaped.

This server instead parses markdown with a real CommonMark parser (markdown-it-py), emits ADF directly, and talks to Jira REST v3 and Confluence REST v2 (atlas_doc_format), which both speak ADF natively. One converter, no server-side re-interpretation, so bodies round-trip. Every write returns the object re-read so the agent verifies what landed.

Tools

Tool

Description

atlassian_request

Raw method + path + body pass-through to any endpoint (/rest/api/3/..., /rest/agile/1.0/..., /wiki/api/v2/...). The escape hatch.

Jira

jira_get_issue

Issue with description (and optionally comments) as markdown

jira_search_issues

JQL search via /rest/api/3/search/jql

jira_create_issue

Markdown description → ADF; component names must match exactly or the call fails; returns the created issue re-read

jira_update_issue

Same, for updates. Refuses status (use a transition)

jira_add_comment

Markdown comment → ADF

jira_get_transitions / jira_transition_issue

Workflow moves. No inline comment parameter, on purpose

jira_list_components

Component names and ids for a project

jira_find_user

Look up accountIds by name or email, for assignee/reporter fields

Confluence

confluence_search

CQL search

confluence_get_page

Page by id, or space key + title; body (and optionally footer comments) as markdown

confluence_get_page_children

Direct children of a page

confluence_create_page

Markdown → ADF page under a space (optionally under a parent)

confluence_update_page

Replace body and/or title; handles the version bump

confluence_add_page_comment

Markdown footer comment

Tool names are prefixed so they don't collide with other MCP servers (GitHub's search_issues, for example).

Quirks from the team guide this addresses directly:

  • Lossy markdown / paired _ / {} / paired + – gone; text is text in ADF.

  • Long descriptions break on create – gone; the body is JSON, no newline escaping.

  • Components fail open – names are resolved to ids against the project and unknown names are rejected with a "did you mean" hint.

  • Transition comments can be public – transitions don't accept a comment.

  • Read back what you wrote – done automatically.

Jira's own behaviour (Team field wants a bare UUID, resolution is one-way, status only moves by transition) is documented in the tool descriptions rather than papered over.

Related MCP server: Confluence MCP Server

Installation

No clone needed — uvx can run it straight from GitHub:

uvx --from git+https://github.com/aviddiviner/better-jira-mcp better-jira-mcp

Or, for local development:

git clone https://github.com/aviddiviner/better-jira-mcp
cd better-jira-mcp
uv sync

You'll need an Atlassian API token. One token covers Jira and Confluence on the same site.

Zed MCP configuration

Add to settings.json under "context_servers". Same env var names as mcp-atlassian, so you can copy them across; no separate Confluence variables are needed:

{
  "context_servers": {
    "better-jira": {
      "enabled": true,
      "command": "uvx",
      "args": ["--from", "git+https://github.com/aviddiviner/better-jira-mcp", "better-jira-mcp"],
      "env": {
        "JIRA_URL": "https://your.atlassian.net",
        "JIRA_USERNAME": "you@example.com",
        "JIRA_API_TOKEN": "<token>"
      }
    }
  }
}

If you cloned it instead, use "command": "uv" with "args": ["run", "--project", "/path/to/better-jira-mcp", "better-jira-mcp"].

Tests

uv run pytest

Available Tools

16 tools
atlassian_requestAtlassian RequestA

Raw pass-through to any Jira or Confluence REST endpoint. Use when no other tool fits.

Inputs: path (required), method (required), body, params. Returns: result

confluence_add_page_commentConfluence Add Page CommentC

Add a footer comment (markdown) to a page.

Inputs: body (required), page_id (required). Returns: result

confluence_create_pageConfluence Create PageA

Create a Confluence page from markdown and return it re-read.

Inputs: body (required), title (required), space_key (required), parent_id. Returns: result

confluence_get_pageConfluence Get PageA

Get a Confluence page by id, or by space key + exact title. Body is returned as markdown.

Inputs: title, page_id, space_key, include_comments. Returns: result

confluence_get_page_childrenConfluence Get Page ChildrenB

List the direct child pages of a page.

Inputs: page_id (required), limit. Returns: result

confluence_update_pageConfluence Update PageA

Update a page's body (markdown) and/or title. Handles versioning; returns the page re-read.

The body replaces the whole page. Read it first with confluence_get_page if you want to edit rather than overwrite.

Inputs: page_id (required), body, title, message. Returns: result

jira_add_commentJira Add CommentA

Add a comment (markdown) to an issue.

Inputs: key (required), body (required). Returns: result

jira_create_issueJira Create IssueA

Create an issue and return it re-read from Jira so you can verify it.

Inputs: project (required), summary (required), issue_type (required), fields, +1 more. Returns: result

jira_find_userJira Find UserA

Find users by name or email. Returns accountIds, which is what assignee/reporter fields need: {"assignee": {"accountId": "..."}}.

Inputs: query (required), limit. Returns: result

jira_get_issueJira Get IssueB

Get an issue. Description and comments are returned as markdown.

Inputs: key (required), fields, include_comments. Returns: result

jira_get_transitionsJira Get TransitionsB

List the workflow transitions currently available for an issue.

Inputs: key (required). Returns: result

jira_list_componentsJira List ComponentsA

List a project's components with their ids (names must match exactly when writing).

Inputs: project (required). Returns: result

jira_search_issuesJira Search IssuesC

Search issues with JQL.

Inputs: jql (required), limit, fields, next_page_token. Returns: result

jira_transition_issueJira Transition IssueA

Move an issue through a workflow transition (see jira_get_transitions).

Comments are deliberately not accepted here; add one with jira_add_comment afterwards so its visibility is under your control.

Inputs: key (required), transition_id (required). Returns: result

jira_update_issueJira Update IssueB

Update an issue and return it re-read from Jira.

Inputs: key (required), fields, description. Returns: result

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 16 tools

    Disambiguation5/5

    Every typed tool is scoped to a specific Jira or Confluence resource and action (get, search, create, update, transition, comment). The raw atlassian_request tool is explicitly framed as a fallback, so there is little realistic confusion between tools.

    Naming Consistency4/5

    Most tools follow a clear domain_verb_noun pattern (jira_get_issue, confluence_create_page, jira_transition_issue). Minor deviations exist: confluence_search omits the object noun, and atlassian_request breaks the domain prefix convention, but these are understandable exceptions.

    Tool Count4/5

    16 tools is slightly above the typical sweet spot, but the scope covers two substantial Atlassian products (Jira and Confluence), and each tool has a distinct role. The count feels justified rather than bloated.

    Completeness4/5

    The set covers core Jira issue workflows (search, get, create, update, transition, comment) and Confluence page workflows (search, get, create, update, comment). Some operations like deletes or attachments are absent, but the raw atlassian_request tool provides an escape hatch for edge cases.

    Maintenance

    ActivityStale
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers