jira-aie-mcp
An MCP server for the AIE team's Jira instance. Exposes the two things
mcp-atlassian can't do natively:
- Rich Atlassian Document Format (ADF) issue creation/update — info / warning / success / error / note panels, inline status lozenges, date chips, expand/collapse blocks, and task lists. Accepts a Markdown string, a compact block-list DSL, or a pre-built ADF doc.
- Working-day gantt scheduler — reads Blocks dependencies and
Original Estimates from a JQL-scoped set of issues, computes start/end
dates on the Norwegian public-holiday calendar, and optionally writes
the end dates back to each issue's
duedatefield.
Plus a semantic link shortcut (jira_link_issues) that picks the
right inward/outward direction for Blocks, Relates, Duplicates, Clones,
and Causes without forcing the caller to memorise Jira's link model.
mcp-atlassian still handles everything else — search, transitions,
comments, watchers, worklogs, etc. This server is a gap-filler, not
a replacement.
Install
Run it on demand with uvx — no install step needed; uvx fetches the
package from PyPI into an ephemeral environment on first use and caches
it for subsequent runs:
uvx jira-aie-mcp
Or install it as a persistent tool:
uv tool install jira-aie-mcp
jira-aie-mcp
Either form starts the server on stdio, which is what MCP clients expect.
Configure (MCP client)
All configuration lives in the MCP client's server definition — no separate config file. Minimum required env vars:
| Variable | Required | Default |
|---|---|---|
JIRA_BASE_URL |
yes | — |
JIRA_EMAIL |
yes | — |
JIRA_API_TOKEN |
yes | — |
JIRA_DEFAULT_PROJECT_KEY |
no | — (fallback for jira_create_issue when the tool call omits project_key) |
JIRA_WORKSTREAM_FIELD_ID |
no | — (tenant-specific custom field ID, e.g. customfield_10742, that schedule_compute groups by in the Mermaid gantt) |
Generate an API token at https://id.atlassian.com/manage-profile/security/api-tokens.
Cowork / Claude Desktop config
{
"mcpServers": {
"jira-aie": {
"command": "uvx",
"args": ["jira-aie-mcp"],
"env": {
"JIRA_BASE_URL": "https://apply-team.atlassian.net",
"JIRA_EMAIL": "you@apply.no",
"JIRA_API_TOKEN": "atlassian-api-token-here"
}
}
}
}
To pin a specific version (recommended, so upstream releases don't silently change behaviour):
"args": ["jira-aie-mcp==0.1.2"]
Reload the client after editing the config.
⚠️ If you ran 0.1.0 against a real Jira instance with
write_duedate=True, the persisted duedates are inverted — upgrade to ≥0.1.1 and re-runschedule_compute(..., write_duedate=True)once to overwrite them. SeeCHANGELOG.mdfor the fix details.
Tools
| Tool | What it does |
|---|---|
jira_create_issue |
Create one issue. description accepts Markdown, block-DSL, or raw ADF. |
jira_update_issue |
Update summary/labels/fields/description on an existing issue. |
jira_get_issue_raw |
Fetch the raw REST payload (including ADF description). |
jira_link_issues |
Create an issue link. Semantic shortcuts for Blocks/Relates/Duplicates/Clones/Causes. |
jira_batch_ops |
Mixed array of `{op: "create" |
schedule_compute |
Forward-pass gantt from a JQL scope. Format: json / markdown / mermaid. Optional write_duedate. |
schedule_holidays |
Print the Norwegian red-day calendar for a given year. |
Block DSL (descriptions)
[
{"h": 2, "text": "What broke"},
{"p": "Reranker started returning 500s on ~30% of requests at 14:20 UTC."},
{"panel": "warning", "content": [
{"p": "Customer-facing; search relevance degraded but not down."}
]},
{"h": 2, "text": "Timeline"},
{"ul": [
"🔴 14:20 UTC — first 500s observed",
"🟡 14:26 UTC — paged on-call",
"🟢 14:41 UTC — rolled back cross-encoder to v1"
]},
{"h": 2, "text": "Follow-ups"},
{"tasks": [
{"text": "Postmortem", "done": false},
{"text": "Add 5xx alarm to SLO dashboard", "done": false}
]}
]
All block keys (full list):
h — heading (1-6) p — paragraph
ul — bullet list ol — numbered list
code — code block (+ `lang`) quote — blockquote
rule — horizontal rule panel — info|note|success|warning|error
status — inline status lozenge date — inline date chip
expand — collapsible block tasks — task list with done flags
table — {headers, rows} raw — pass-through ADF node
Inline specs (inside p / h text or a list item):
{"text": "bold", "marks": ["strong"]}
{"text": "link", "link": "https://..."}
{"mention": "account-id", "text": "@Alice"}
{"emoji": ":rocket:", "text": "🚀"}
{"status": "In progress", "color": "yellow"}
{"date": "2026-04-20"}
{"hard_break": true}
Scheduler
The forward pass follows Blocks dependencies, uses Jira's
timetracking.originalEstimate (1w 2d 3h 30m syntax) for durations, and
skips weekends and 12 Norwegian public holidays per year (Easter-derived).
schedule_compute(
jql="project = AIE AND \"Epic Link\" = AIE-5 AND statusCategory != Done",
start="2026-05-04",
format="markdown",
write_duedate=False
)
Returns a JSON plan (project_start, project_end, critical_path,
issues[], warnings[]) and, for markdown/mermaid formats, a
rendered string.
Rescheduling is just re-running with overrides:
pins = {"AIE-15": "2026-06-01"} # force start date
delays = {"AIE-7": "3d"} # shift start N working days later
Module layout
src/jira_aie_mcp/
__main__.py # entry point — starts FastMCP over stdio
server.py # MCP tool registrations
config.py # env-var loading → Config dataclass
client.py # httpx-based Jira REST v3 client + link shortcuts
adf.py # block DSL + Markdown → ADF
holidays.py # Easter + Norwegian red days + duration parser
scheduler.py # graph build + forward pass + critical path
formats.py # JSON / Markdown / Mermaid plan output
tests/
test_scheduler.py # Blocks-direction contract + diamond end-to-end
Development
Install with the dev extras and run the test suite:
uv pip install -e ".[dev]"
pytest
The test suite is intentionally small and focused on the pieces most
likely to regress (the Blocks-direction contract, the working-day forward
pass, and the critical path). The REST client and the FastMCP wiring are
exercised via the live smoke tests in the team's Jira — if you want those
to be unit-level too, mock httpx.Client.post / .put.
License
MIT.
Metadata
Release files for jira-aie-mcp 0.6.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| jira_aie_mcp-0.6.2.tar.gz | 76.1 kB | With provenance | Details for jira_aie_mcp-0.6.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| jira_aie_mcp-0.6.2-py3-none-any.whl | Python 3 | none | any | Details for jira_aie_mcp-0.6.2-py3-none-any.whl |
Total release size: 123.9 kB
Release files / jira_aie_mcp-0.6.2.tar.gz
| Download URL | jira_aie_mcp-0.6.2.tar.gz |
|---|---|
| Size | 76.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6fe16b726629e07efda0ca229dcb0c9f4ba854d4a9269fd900affe7033169d14
|
|
BLAKE2b-256 checksum How to use checksums |
4c989e1d645ca7183e95ebd33ea827ecbde126c7ea236e152bcb21e5f7fb1acf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 24, 2026.
Transparency logRelease files / jira_aie_mcp-0.6.2-py3-none-any.whl
| Download URL | jira_aie_mcp-0.6.2-py3-none-any.whl |
|---|---|
| Size | 47.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
46c2da3b87dedade476dab12641da1157d14e4389a778d2a9238fc18ca285b04
|
|
BLAKE2b-256 checksum How to use checksums |
6af5c5ac2150119154d4efddbb7119b46c92d5f8e9d1c7f886baf45dfa1a7120
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 24, 2026.
Transparency logSecurity for jira-aie-mcp 0.6.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for jira_aie_mcp-0.6.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.