Atlassian MCP Server
# š Atlassian MCP Server
[](https://www.npmjs.com/package/@jagadeesh52423/atlassian-mcp-server)
[](https://opensource.org/licenses/MIT)
An MCP (Model Context Protocol) server that gives AI assistants full access to Jira, Confluence, and Bitbucket Cloud APIs -- 102 tools covering deep CRUD across all three products.
## What It Does
This server acts as a bridge between any MCP-compatible AI client (Claude Desktop, etc.) and your Atlassian Cloud instance. Instead of switching between browser tabs, you ask your AI assistant to search Confluence, create Jira tickets, review pull requests, and more -- all through natural language.
### Key Features
- **Confluence** (22 tools) -- Search (text or raw CQL), create, read, update, and delete pages. Manage spaces, child pages, comments (full CRUD, replies, and text-anchored inline comments), attachments, labels, and version history. Input accepts Markdown (auto-converted to ADF); output is native ADF JSON.
- **Jira** (50 tools) -- Full issue lifecycle: search (with `nextPageToken` paging), CRUD, assign, comments, transitions (with an optional comment), attachments, issue links, worklogs, watchers, subtasks, labels, history, agile boards, sprints (incl. moving issues into a sprint), versions, batch creation (up to 50 issues), dev status, epic linking, and user lookup.
- **Bitbucket** (30 tools) -- Repository management, branches, commits, pull requests (create/update/list, reviewers, approve/request changes, merge/decline), PR comments with resolve/unresolve, PR diffstat and per-file diffs, file content at a ref, CI/pipeline status and step logs, and issue tracking.
- **Smart Field Handling** -- AI-driven field suggestions during Jira transitions. Analyzes issue context to auto-suggest values for required fields (e.g., DB scripts, test cases), reducing manual input.
- **Snapshot Safety Net** -- Automatic local snapshots of mutating operations (create/update/delete) with configurable retention, so you can recover from accidental changes.
## Prerequisites
- **Node.js** >= 18
- **Atlassian Cloud** account(s) with API tokens
- An MCP-compatible client (e.g., [Claude Desktop](https://claude.ai/download))
## Installation
### From npm (recommended)
```bash
npm install -g @jagadeesh52423/atlassian-mcp-server
```
Or run without installing:
```bash
npx @jagadeesh52423/atlassian-mcp-server
```
### From source
```bash
git clone https://github.com/jagadeeshpulamarasetti/atlassian-mcp-server.git
cd atlassian-mcp-server
npm install
npm run build
```
## Configuration
### 1. Set environment variables
Copy the template and fill in your credentials:
```bash
cp .env.example .env
```
```env
# Confluence
CONFLUENCE_DOMAIN=your-domain.atlassian.net
CONFLUENCE_EMAIL=your-email@example.com
CONFLUENCE_API_TOKEN=your-confluence-api-token
# Jira
JIRA_DOMAIN=your-domain.atlassian.net
JIRA_EMAIL=your-email@example.com
JIRA_API_TOKEN=your-jira-api-token
# Bitbucket
BITBUCKET_WORKSPACE=your-workspace
BITBUCKET_USERNAME=your-username
BITBUCKET_API_TOKEN=your-bitbucket-api-token
```
You can also set legacy `ATLASSIAN_*` variables as a fallback for Confluence and Jira. Bitbucket always requires its own credentials.
<details>
<summary>Optional: Jira OAuth and Snapshot settings</summary>
```env
# Jira OAuth (advanced auth)
JIRA_CLIENT_ID=your-client-id
JIRA_CLIENT_SECRET=your-client-secret
# Snapshot safety net (defaults shown)
MCP_SNAPSHOTS_ENABLED=true
MCP_SNAPSHOT_DIR=~/.atlassian-mcp-snapshots
MCP_SNAPSHOT_RETENTION_DAYS=30
```
</details>
### 2. Get an API token
1. Go to [Atlassian API Tokens](https://id.atlassian.com/manage-profile/security/api-tokens)
2. Click **Create API token**, give it a name, and copy the value
3. For Bitbucket, create a token under **Personal settings > Access tokens** with repo, issue, and PR scopes
## Usage
### Running the server
```bash
# Global install
atlassian-mcp-server
# From source
npm start
# Development (auto-reload)
npm run dev
```
### Claude Desktop integration
Add one of the following to your Claude Desktop config:
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows:** `%APPDATA%/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"atlassian": {
"command": "npx",
"args": ["-y", "@jagadeesh52423/atlassian-mcp-server"],
"env": {
"CONFLUENCE_DOMAIN": "your-domain.atlassian.net",
"CONFLUENCE_EMAIL": "your-email@example.com",
"CONFLUENCE_API_TOKEN": "your-token",
"JIRA_DOMAIN": "your-domain.atlassian.net",
"JIRA_EMAIL": "your-email@example.com",
"JIRA_API_TOKEN": "your-token",
"BITBUCKET_WORKSPACE": "your-workspace",
"BITBUCKET_USERNAME": "your-username",
"BITBUCKET_API_TOKEN": "your-token"
}
}
}
}
```
<details>
<summary>Alternative: global install or from-source config</summary>
**Global install:**
```json
{
"mcpServers": {
"atlassian": {
"command": "atlassian-mcp-server",
"env": { "..." : "same env vars as above" }
}
}
}
```
**From source:**
```json
{
"mcpServers": {
"atlassian": {
"command": "node",
"args": ["/path/to/atlassian-mcp-server/dist/index.js"]
}
}
}
```
</details>
## Available Tools
### Confluence (22 tools)
| Tool | Description |
|------|-------------|
| `confluence_search_pages` | Search pages by text query or raw `cql` (results restricted to pages for `query`) |
| `confluence_get_page` | Get a page by ID (returns ADF JSON body) |
| `confluence_create_page` | Create a page (accepts Markdown) |
| `confluence_update_page` | Update a page (accepts Markdown). Re-anchors inline comments automatically; reports any it could not |
| `confluence_reattach_inline_comments` | Repair inline comments detached by an earlier update, using page history. `dryRun` defaults to `true` |
| `confluence_delete_page` | Delete a page |
| `confluence_get_spaces` | List all spaces |
| `confluence_get_pages_by_space` | Get pages in a space |
| `confluence_get_page_children` | Get child pages |
| `confluence_get_page_history` | Get page version history |
| `confluence_get_attachments` | List page attachments |
| `confluence_add_attachment` | Upload an attachment |
| `confluence_delete_attachment` | Delete an attachment |
| `confluence_get_comments` | Get footer and/or inline comments (ADF JSON). `commentType`: `footer` \| `inline` \| `all` (default `all`) |
| `confluence_add_comment` | Add a comment (Markdown), or reply via `parentCommentId` |
| `confluence_add_inline_comment` | Add an inline comment anchored to exact page text |
| `confluence_update_comment` | Update a comment (Markdown) |
| `confluence_delete_comment` | Delete a comment |
| `confluence_get_labels` | Get page labels |
| `confluence_add_labels` | Add labels to a page |
| `confluence_remove_label` | Remove a label |
| `confluence_embed_image` | Deprecated: not supported, always returns an error (use `confluence_add_attachment`) |
### Jira (50 tools)
| Category | Tools |
|----------|-------|
| **Core** | `search_issues`, `get_issue`, `create_issue`, `update_issue`, `delete_issue`, `get_projects`, `get_issue_types`, `get_fields`, `lookup_user`, `assign_issue` |
| **Comments** | `add_comment`, `get_comments`, `update_comment`, `delete_comment` |
| **Transitions** | `get_issue_transitions`, `transition_issue`, `transition_issue_interactive` (smart field handling); both accept an optional `comment` |
| **Attachments** | `get_attachments`, `add_attachment`, `delete_attachment` |
| **Issue Links** | `get_issue_links`, `create_issue_link`, `delete_issue_link`, `get_link_types` |
| **Worklogs** | `get_worklogs`, `add_worklog`, `update_worklog`, `delete_worklog` |
| **Watchers** | `get_watchers`, `add_watcher`, `remove_watcher` |
| **Subtasks** | `get_subtasks`, `create_subtask` |
| **Labels** | `get_labels`, `add_labels`, `remove_labels` |
| **History** | `get_issue_history` |
| **Agile** | `get_agile_boards`, `get_board_issues`, `get_sprints`, `get_sprint_issues`, `create_sprint`, `update_sprint`, `move_issues_to_sprint` |
| **Versions** | `get_project_versions`, `create_version`, `update_version` |
| **Batch/Dev** | `batch_create_issues`, `get_dev_status` |
| **Epic** | `link_to_epic` |
All Jira tools are prefixed with `jira_`.
### Bitbucket (30 tools)
| Tool | Description |
|------|-------------|
| `bitbucket_get_repositories` | List workspace repositories |
| `bitbucket_get_repository` | Get repository details |
| `bitbucket_create_repository` | Create a repository |
| `bitbucket_get_pull_requests` | List pull requests |
| `bitbucket_get_pull_request` | Get a PR with diff |
| `bitbucket_create_pull_request` | Create a pull request |
| `bitbucket_update_pull_request` | Update a pull request |
| `bitbucket_get_branches` | List branches |
| `bitbucket_get_commits` | List commits |
| `bitbucket_get_issues` | List repository issues |
| `bitbucket_create_issue` | Create an issue |
| `bitbucket_get_pr_comments` | Get PR comments |
| `bitbucket_add_pr_comment` | Add a PR comment |
| `bitbucket_update_pr_comment` | Update a PR comment |
| `bitbucket_delete_pr_comment` | Delete a PR comment |
| `bitbucket_resolve_pr_comment` | Mark a PR comment thread as resolved |
| `bitbucket_unresolve_pr_comment` | Reopen (unresolve) a PR comment thread |
| `bitbucket_approve_pr` | Approve a pull request |
| `bitbucket_unapprove_pr` | Remove your approval from a pull request |
| `bitbucket_request_changes_pr` | Request changes on a pull request |
| `bitbucket_remove_change_request_pr` | Remove your change request from a pull request |
| `bitbucket_merge_pr` | Merge a pull request (optional strategy, message, close source branch) |
| `bitbucket_decline_pr` | Decline a pull request |
| `bitbucket_get_pr_diffstat` | Get per-file change summary for a PR |
| `bitbucket_get_pr_file_diff` | Get the diff of a single file in a PR |
| `bitbucket_get_file_content` | Get file content at a branch or commit |
| `bitbucket_get_pr_statuses` | Get CI/build statuses for a PR with a summary |
| `bitbucket_get_pipelines` | List recent Pipelines runs, optionally by branch |
| `bitbucket_get_pipeline_steps` | Get per-step status of a pipeline run |
| `bitbucket_get_pipeline_step_log` | Get the log of a pipeline step (last 200KB) |
### PR comment resolution (v1.3.0+)
- `bitbucket_resolve_pr_comment` / `bitbucket_unresolve_pr_comment` use Bitbucket's dedicated resolution sub-resource (`POST`/`DELETE .../comments/{id}/resolve`) and return the refreshed comment.
- **Top-level comments only** -- Bitbucket only allows resolving/unresolving top-level review comments, not replies. Calling these on a reply returns `Comment is not a top-level comment`.
- Comments returned by `bitbucket_get_pr_comments`, `bitbucket_resolve_pr_comment`, and `bitbucket_unresolve_pr_comment` now include a `resolved` boolean. When a comment is resolved, the single-comment responses also include `resolvedOn` (ISO timestamp) and `resolvedBy` (display name); these resolution details are not present in the bulk list response.
## Confluence Content Format (v1.2.0+)
Confluence pages and comments use **ADF (Atlassian Document Format)** natively:
- **Input** -- `create_page`, `update_page`, `add_comment`, `update_comment` accept **Markdown**, which the server converts to ADF using the official `@atlaskit/editor-markdown-transformer`.
- **Output** -- `get_page`, `get_comments` return ADF JSON (an object, not a string).
- **Comments** -- `get_comments` returns **both footer (page-level) and inline (text-anchored) comments** by default. Use the `commentType` param (`footer` | `inline` | `all`, default `all`) to filter. Every comment carries a `type` field (`"footer"` or `"inline"`). Inline comments additionally include `anchoredText` (the highlighted page text the comment is attached to), `resolutionStatus` (e.g. `"open"`, `"resolved"`), `markerRef`, and `webuiLink`. _Backwards-compatibility note: callers that previously relied on `get_comments` returning footer comments only will now also receive inline comments under the default `all`; pass `commentType: "footer"` to restore the old footer-only behaviour. The new `type` field is additive and does not remove any existing field._
- **Inline comment anchors** -- An inline comment is not a separate resource: it anchors to page text via an `annotation` mark **inside the page body**. Any update that rebuilds the body therefore detaches every inline comment on the page. `update_page` guards against this by reading the live body first and re-anchoring each marker onto text that survived the edit, then reporting `inlineComments: { preserved, dropped, ambiguous }`. A comment whose text you reworded or deleted appears in `dropped`; one whose text now occurs in more than one place appears in `ambiguous`, because the server refuses to pick an occurrence ā a wrong guess silently moves a reviewer's question onto unrelated text while reporting success. Either way the comment stays on the page but unattached, which is exactly what Confluence does today. **Prefer leaving commented sentences intact.** To repair comments detached by an earlier update (including ones made before this feature existed), use `confluence_reattach_inline_comments`: it walks page history to find where each orphan was anchored, re-marks only unambiguous matches, and reports the rest rather than guessing. It never alters page text, and searches back at most 50 versions. Anchors are keyed by surrounding content (table header + first-column value, or block type + text) rather than by position, so they survive rows and paragraphs being inserted above them ā which is what lets a comment on a repeated field name like `unique_id` resolve even though that text appears ten times on the page. Note that `anchoredText` from `get_comments` is truncated by Confluence at ~250 characters (252 observed); the history lookup recovers the full anchor.
- **Inline images** -- Not currently supported via ADF media nodes (requires Atlassian Media API tokens). Use `confluence_add_attachment` instead.
## Project Structure
```
src/
āāā index.ts # Server entry point and tool routing
āāā config.ts # Environment variable loading and validation
āāā types.ts # TypeScript interfaces
āāā constants.ts # Shared constants
āāā error-handler.ts # Structured error responses
āāā formatters/ # Markdown-to-ADF and ADF-to-text converters
āāā clients/ # HTTP clients (one per Atlassian product)
āāā services/ # Business logic for each product
ā āāā jira/ # Jira sub-modules (agile, comments, transitions, etc.)
āāā handlers/ # MCP request handlers
āāā tools/ # MCP tool definitions (schemas)
āāā registry/ # Tool dispatch registry
āāā snapshot/ # Snapshot safety net (auto-backup before mutations)
```
## Security
- Credentials are read from environment variables only; never committed to source control.
- All API calls use HTTPS with Basic Auth (base64-encoded `email:token`).
- Grant tokens the minimum required permissions.
- Snapshots are stored locally in `~/.atlassian-mcp-snapshots` by default.
## License
[MIT](LICENSE)
## Links
- **npm:** [@jagadeesh52423/atlassian-mcp-server](https://www.npmjs.com/package/@jagadeesh52423/atlassian-mcp-server)
- **Source:** [GitHub](https://github.com/jagadeeshpulamarasetti/atlassian-mcp-server)
- **Issues:** [GitHub Issues](https://github.com/jagadeeshpulamarasetti/atlassian-mcp-server/issues)
TDQS
Scored across 86 tools
All tools are clearly prefixed by product (confluence_, jira_, bitbucket_) and have distinct verb-noun pairs. Even closely related tools like jira_transition_issue and jira_transition_issue_interactive are differentiated by description. There is no ambiguity between tools.
All tool names follow a consistent pattern: product_verb_noun in snake_case. For example, confluence_get_page, jira_create_issue, bitbucket_get_pull_requests. No mixing of conventions.
86 tools is high, but the server covers three major products (Confluence, Jira, Bitbucket) each requiring many operations. Some tools like confluence_embed_image (not supported) are unnecessary. The count is borderline heavy but justifiable for the scope.
The tool surface is comprehensive for common workflows: CRUD for issues, pages, repos, comments, attachments, worklogs, etc. Minor gaps exist such as missing inline image embedding in Confluence and some advanced Jira features, but overall coverage is strong.