@stubbedev/atlassian-mcp
v0.4.1
Published
MCP server for self-hosted Jira and Bitbucket
Readme
atlassian-mcp
A Model Context Protocol (MCP) server for self-hosted Jira (Server / Data Center) and self-hosted Bitbucket (Server / Data Center). Exposes tools for natural-language workflows around tickets, pull requests, review threads, and git context.
Note: This server only supports self-hosted instances. Jira Cloud and Bitbucket Cloud use different APIs and are not supported.
Tools
Workflow
| Tool | Description |
|---|---|
| get_dev_context | Master entry point: git state + linked Jira ticket + open PR with reviewer/blocker status and next-step hints |
| start_work | Start a Jira ticket: fetches it, creates a local branch (feature/FOO-123-slug), and optionally transitions the ticket |
| complete_work | Close out finished work: merges the open PR and transitions the Jira ticket to Done |
Git
| Tool | Description |
|---|---|
| git_get_context | Branch, upstream state, remote URL, recent commits, working tree status, diff stat, and Jira keys in branch name |
| git_get_diff | Diff of uncommitted changes or between two refs; supports paging via charOffset |
Jira
| Tool | Description |
|---|---|
| jira_search | Discover resources: issues, projects, issue_types, boards, sprints, board_overview, versions, or users via resource param |
| jira_get | Full details for one issue: summary, description, status, sprint, transitions, comments, and attachment list |
| jira_get_attachment | Fetch a Jira attachment by ID. Images, videos, animated images (GIF/APNG/animated WebP), audio, and PDFs are all decoded inline so the model can see/hear them. Text/JSON inline. Oversized or non-renderable attachments are auto-saved to a temp file and the path is returned. saveTo=/absolute/path streams the original to disk |
| jira_mutate | Create, update, transition, comment, link, add to sprint, or log work — all in one call |
| jira_comment | Add, update, or delete a comment on an issue (action: add / update / delete) |
| jira_version | Manage fix versions/releases (action: create / update / release / archive / delete) |
Bitbucket
| Tool | Description |
|---|---|
| bitbucket_search | Discover resources: pull_requests (default), repos, or branches via resource param; mine=true for your inbox |
| bitbucket_get_pr | Full PR details: metadata, commits, comments, blockers, build status, optional diff, and any attachments referenced from the description or comments |
| bitbucket_get_attachment | Fetch a repo attachment by ID. Same decoding pipeline as jira_get_attachment (images, videos, animated images, audio, PDFs). Oversized or non-renderable attachments are auto-saved to a temp file and the path is returned; saveTo streams the original to disk |
| bitbucket_mutate | Create/update a PR, or perform lifecycle actions: approve, unapprove, merge, decline |
| bitbucket_comment | Add, update, or delete a PR comment; for code changes use suggestion so Bitbucket shows Apply suggestion (no trailing text after a suggestion block) |
| bitbucket_get_file | Raw file content from Bitbucket at a branch, tag, or commit |
| bitbucket_pr_tasks | Manage PR tasks (checklist items): list, create, resolve, reopen, delete |
Natural language examples
- "what am I working on?" →
get_dev_context - "make a branch for FOO-123" →
start_work - "ship this / merge and close the ticket" →
complete_work - "show my PRs waiting for review" →
bitbucket_searchwithmine=true - "list open PRs for this repo from feature/ABC-123" →
bitbucket_searchwithfromBranch - "give me a full overview of PR 42" →
bitbucket_get_pr - "open a PR from my current branch to master" →
bitbucket_mutatewithcreate - "approve / merge / decline PR 42" →
bitbucket_mutatewithaction - "reply to comment 123 on PR 42" →
bitbucket_commentwithcommentId=123 - "resolve this blocker on PR 42" →
bitbucket_commentwithaction=update,severity=BLOCKER,state=RESOLVED - "list PR checklist tasks" →
bitbucket_pr_taskswithaction=list - "find bugs assigned to me in PAY project" →
jira_searchwithmine=true,issueType=Bug - "what's in the current sprint?" →
jira_searchwithresource=board_overview - "move FOO-123 to In Progress" →
jira_mutatewithtransitionName="In Progress" - "log 2h on FOO-123" →
jira_mutatewithworklog - "create version 9.1.0 in PAY" →
jira_versionwithaction=create,projectKey=PAY,name=9.1.0 - "list releases for PAY" →
jira_searchwithresource=versions,project=PAY - "release version 12345" →
jira_versionwithaction=release,id=12345 - "set fix version 9.1.0 on FOO-123" →
jira_mutatewithupdate.fixVersion=9.1.0 - "create a task under epic FOO-100" →
jira_mutatewithcreate.issueType=Task,create.parent=FOO-100(auto-detects Epic and sets Epic Link) - "move FOO-123 under epic FOO-100" →
jira_mutatewithupdate.epicLink=FOO-100
Setup
1. Create a config file
Create ~/.atlassian-mcp.json:
{
"$schema": "https://raw.githubusercontent.com/stubbedev/atlassian-mcp/master/atlassian-mcp.schema.json",
"jira": {
"url": "https://jira.example.com",
"token": "your-jira-personal-access-token"
},
"bitbucket": {
"url": "https://bitbucket.example.com",
"token": "your-bitbucket-personal-access-token"
}
}The $schema field is optional but enables editor autocomplete and validation.
projectKeymeans a project code:- Jira example:
PAYin ticketPAY-123 - Bitbucket example: project
ENGin repo pathENG/payments-service
- Jira example:
- You can also use ergonomic aliases:
- Jira:
project(alias ofprojectKey) - Bitbucket:
projectandrepo(aliases ofprojectKeyandrepoSlug)
- Jira:
- For Bitbucket tools,
projectKeyandrepoSlugare usually auto-detected from your localoriginremote. bitbucket_create_pull_requestalso auto-detectsfromBranchfrom your current branch and returns the existing open PR if one already exists for that branch.- Jira project-scoped calls accept
projectKeyand work best when provided. - If
projectKeyis omitted for Jira issue creation/type lookup, the server tries to infer it from your current branch ticket key, falls back to auto-select when only one project is visible, and otherwise returns a numbered project list to pick from.
Alternatively, use environment variables (or a .env file in this directory):
JIRA_URL=https://jira.example.com
JIRA_ACCESS_TOKEN=your-jira-personal-access-token
BITBUCKET_URL=https://bitbucket.example.com
BITBUCKET_ACCESS_TOKEN=your-bitbucket-personal-access-tokenConfig is resolved in this order: --config <path> CLI arg → ATLASSIAN_MCP_CONFIG env var → ~/.atlassian-mcp.json → .atlassian-mcp.json in cwd → environment variables.
2. Connect to your AI tool
No cloning or building required — just point your tool at npx @stubbedev/atlassian-mcp@latest and it will install and run automatically.
Note:
--prefer-onlinecan break MCP startup in some clients. Keep the command simple and use the update steps below when you want to refresh.
Claude Code
claude mcp add atlassian -- npx -y @stubbedev/atlassian-mcp@latest --config ~/.atlassian-mcp.jsonCursor
Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project-only):
{
"mcpServers": {
"atlassian": {
"command": "npx",
"args": ["-y", "@stubbedev/atlassian-mcp@latest", "--config", "/Users/you/.atlassian-mcp.json"]
}
}
}Windsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"atlassian": {
"command": "npx",
"args": ["-y", "@stubbedev/atlassian-mcp@latest", "--config", "/Users/you/.atlassian-mcp.json"]
}
}
}Zed
Add to ~/.config/zed/settings.json:
{
"context_servers": {
"atlassian": {
"command": {
"path": "npx",
"args": ["-y", "@stubbedev/atlassian-mcp@latest", "--config", "/home/you/.atlassian-mcp.json"]
}
}
}
}OpenCode
Add to opencode.json in your project root (or ~/.config/opencode/opencode.json for global):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"atlassian": {
"type": "local",
"command": ["npx", "-y", "@stubbedev/atlassian-mcp@latest", "--config", "/home/you/.atlassian-mcp.json"]
}
}
}Codex CLI
Add to ~/.codex/config.yaml:
mcpServers:
atlassian:
command: npx
args:
- -y
- @stubbedev/atlassian-mcp@latest
- --config
- /home/you/.atlassian-mcp.jsonAny other MCP-compatible tool
Most tools that support MCP accept the same JSON format. Use npx as the command with ["-y", "@stubbedev/atlassian-mcp@latest", "--config", "/path/to/config.json"] as the args.
Updating existing installs
If your MCP client is already configured and you want the newest package version:
npx clear-npx-cacheThen restart your MCP client.
Manual install (optional)
If you prefer to clone and run locally:
git clone [email protected]:stubbedev/atlassian-mcp.git
cd atlassian-mcp
npm installThen use node /path/to/atlassian-mcp/dist/index.js instead of the npx command in the configs above.
Attachment decoding pipeline
The attachment tools (jira_get_attachment, bitbucket_get_attachment) decode binary attachments into model-readable content before returning them:
| Input | What gets returned | How |
| --- | --- | --- |
| Static images (PNG/JPEG/WebP/AVIF/SVG…) | Resized image content blocks | sharp (long edge ≤ maxDimension, default 1568) |
| Animated images (GIF/APNG/animated WebP) | N sampled frames as image content blocks | ffmpeg-static + sharp (default 6 frames @ 768 px) |
| Video (mp4/webm/mov/…) | N sampled frames as image content blocks | ffmpeg-static + sharp. Uniform or scene-change sampling. Re-call with start, end, frames, mode, sceneThreshold to zoom in |
| Audio (mp3/wav/ogg/…) | MCP audio content block | passthrough |
| PDFs | Extracted text — or rasterized pages if text is empty (scanned PDFs) | unpdf + @napi-rs/canvas |
| Text-like (json/xml/yaml/…) | Text content block | passthrough |
| Everything else (or oversized) | Auto-saved to a temp file; path is returned | os.tmpdir() with atlmcp- prefix |
Auto-saved files are periodically pruned by TTL and total-size quota — see Environment overrides below.
Native dependencies
sharp— image decode/resize. Ships prebuilt binaries for glibc Linux (x64/arm64), macOS, Windows. Alpine / musl users may neednpm install --cpu=x64 --os=linux --libc=musl sharp.ffmpeg-static+ffprobe-static— video/audio decode. ~80 MB bundled binary per platform. Override with env vars (below) if you have system ffmpeg.@napi-rs/canvas+unpdf— PDF text extraction and page rasterization.
Environment overrides
| Variable | Purpose | Default |
| --- | --- | --- |
| ATLASSIAN_MCP_FFMPEG_PATH | Path to ffmpeg binary. Overrides ffmpeg-static. Use this if you have system ffmpeg or ffmpeg-static doesn't ship for your platform (Alpine/musl, some ARM variants). | bundled ffmpeg-static |
| ATLASSIAN_MCP_FFPROBE_PATH | Path to ffprobe binary. Overrides ffprobe-static. | bundled ffprobe-static |
| ATLASSIAN_MCP_TMP_TTL_DAYS | Auto-saved attachments older than this are pruned. | 7 |
| ATLASSIAN_MCP_TMP_MAX_BYTES | Total-size quota for auto-saved attachments in os.tmpdir(). When exceeded, oldest are evicted. | 1073741824 (1 GB) |
Releases (Maintainers)
This package is published to npm as @stubbedev/atlassian-mcp.
Use semantic versioning for releases. Breaking tool-surface changes should bump the minor version while <1.0.0 (for example 0.0.x -> 0.1.0).
Automatic publish is configured in .github/workflows/publish.yml and runs when a new version tag is pushed.
Release flow:
# choose one: patch | minor | major
increment=patch
# bumps package.json + package-lock.json,
# creates a version commit, and creates a git tag (for example v0.1.17)
npm version "$increment"
# push commit and tag to GitHub
git push origin HEAD --follow-tagsGitHub Actions will publish the npm release from that pushed tag.
- The workflow is configured for npm Trusted Publisher (OIDC), so no
NPM_TOKENsecret is required
Required npm setup (one-time):
- In npm package settings, add this GitHub repo/workflow as a Trusted Publisher
Creating Personal Access Tokens
Jira Server / Data Center
Personal Access Tokens are supported from Jira 8.14 onwards.
- Log in to your Jira instance.
- Click your profile avatar in the top-right corner and select Profile.
- In the left sidebar, click Personal Access Tokens.
- Click Create token.
- Give the token a name (e.g.
atlassian-mcp) and optionally set an expiry date. - Click Create and copy the token — it will only be shown once.
Paste the token as the token value under jira in your config file.
If your Jira version is older than 8.14, you can use HTTP Basic Auth instead — but this server only supports Bearer token (PAT) authentication.
Bitbucket Server / Data Center
Personal Access Tokens are supported from Bitbucket Server 5.5 onwards.
- Log in to your Bitbucket instance.
- Click your profile avatar in the top-right corner and select Manage account.
- In the left sidebar, under Security, click Personal access tokens.
- Click Create a token.
- Give the token a name (e.g.
atlassian-mcp). - Set the permissions:
- Projects: Read
- Repositories: Read + Write (Write is needed to create pull requests and add comments)
- Optionally set an expiry date.
- Click Create and copy the token — it will only be shown once.
Paste the token as the token value under bitbucket in your config file.
Development
# Watch mode — recompiles on file changes
npm run dev
# Run the built server directly
node dist/index.js
# Test the tool list
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js
# Quick release smoke check
npm run smokeTo use a specific config file:
node dist/index.js --config /path/to/config.json