A token-efficient CLI that brings mcp-atlassian functionality to the command line — optimized for LLM agent workflows on Atlassian Server/DC.
mcp-atlassian is great for Cloud setups, but on Server/DC its MCP protocol overhead and verbose JSON responses consume tokens fast. It also lacks lossless Confluence markup round-tripping — edits via MCP can silently alter page content.
atlassian-skills re-implements the same Jira and Confluence operations as a lightweight CLI with compact output, achieving ≥50% token reduction. It uses cfxmark for lossless Confluence XHTML ↔ Markdown conversion, enabling agents to pull a page as Markdown, edit it, and push it back without any content loss.
First-class integration with Claude Code and Codex. atls setup all registers atls as the default Atlassian tool for both — a comprehensive usage guide (command tree, format decision rules, write safety) is loaded via Claude's /atls slash command or Codex's auto-loaded skill, while a short preference directive in CLAUDE.md / AGENTS.md keeps the routing rule active in every conversation. Your agent translates "read PROJ-123" or "update the API page" into the right CLI call without further configuration.
| mcp-atlassian (MCP) | atlassian-skills (CLI) | |
|---|---|---|
| Interface | MCP protocol (JSON-RPC) | Shell CLI (atls) |
| Schema overhead per session | ~15,000 tokens | <400 tokens |
| Response payload size | Full JSON | 7–34% of MCP |
| Full workflow (end-to-end) | Baseline | 91% reduction |
| Confluence markup round-trip | Lossy (XHTML re-serialization) | Lossless via cfxmark (XHTML ↔ Markdown) |
| Jira body preservation | Drops special chars | Byte-preserving |
| Server/DC support | Partial | Full (primary target) |
| AI agent setup | Manual MCP config | One-line atls setup all for Claude Code + Codex |
| Bitbucket Server | Not supported | Full (0.2.0) — PR workflow, comments, tasks, build status |
| Bamboo | Not supported | Planned |
Recommended: uv tool install — isolates atls in its own environment and makes atls upgrade a single command. pipx (the pip-world equivalent of uv tool) and plain pip also work; atls upgrade auto-detects all three.
Pick one: uv (recommended) or pipx. If you'll use plain pip, skip this step entirely.
Option A — install uv (recommended)
Linux / macOS
curl -LsSf https://astral.sh/uv/install.sh | shWindows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Alternatives: brew install uv (macOS), winget install astral-sh.uv (Windows), pipx install uv (cross-platform). Full options in the uv installation docs.
Option B — install pipx
Linux / macOS
python3 -m pip install --user pipx
python3 -m pipx ensurepathWindows (PowerShell)
python -m pip install --user pipx
python -m pipx ensurepathAlternatives: apt install pipx (Ubuntu 23.04+), brew install pipx (macOS), scoop install pipx or winget install pipx (Windows). Full options in the pipx installation docs.
After ensurepath, open a new terminal so the updated PATH is picked up.
# Recommended — fastest, fully isolated
uv tool install atlassian-skills
# Alternative — pipx (pip-world equivalent of `uv tool`, also isolated per tool)
pipx install atlassian-skills
# Plain pip (installs into the current Python env; not recommended for CLI tools)
pip install atlassian-skills
# Verify
atls --version
# Later — upgrade the CLI (auto-detects uv / pipx / pip) and refresh skill assets
atls upgradeServer/DC only. Personal Access Token (PAT / Bearer) is the default auth method.
Generate tokens from your Atlassian instances:
- Jira: Profile → Personal Access Tokens → Create
- Confluence: Profile → Personal Access Tokens → Create
- Bitbucket: Profile → Manage Account → HTTP access tokens → Create (permissions: project read, repository read/write)
atls config set profiles.default.jira_url https://your-jira.example.com
atls config set profiles.default.confluence_url https://your-confluence.example.com
atls config set profiles.default.bitbucket_url https://your-bitbucket.example.comOr via environment variables:
export ATLS_DEFAULT_JIRA_URL="https://your-jira.example.com"
export ATLS_DEFAULT_CONFLUENCE_URL="https://your-confluence.example.com"
export ATLS_DEFAULT_BITBUCKET_URL="https://your-bitbucket.example.com"For non-default profiles, replace DEFAULT with the profile name (e.g. ATLS_CORP_JIRA_URL).
Environment variables (recommended)
Add to ~/.zshrc or ~/.bashrc:
# Standard names (compatible with existing MCP servers)
export JIRA_PERSONAL_TOKEN="your-jira-pat"
export CONFLUENCE_PERSONAL_TOKEN="your-confluence-pat"
export BITBUCKET_TOKEN="your-bitbucket-http-access-token"For multi-profile setups:
export ATLS_CORP_JIRA_TOKEN="..."
export ATLS_CORP_CONFLUENCE_TOKEN="..."
export ATLS_CORP_BITBUCKET_TOKEN="..."Secure file-based storage (alternative to plain env vars)
mkdir -p ~/.secrets && chmod 700 ~/.secrets
printf '%s' 'YOUR_JIRA_PAT' > ~/.secrets/jira_pat
printf '%s' 'YOUR_CONFLUENCE_PAT' > ~/.secrets/confluence_pat
printf '%s' 'YOUR_BITBUCKET_PAT' > ~/.secrets/bitbucket_pat
chmod 600 ~/.secrets/*_pat
# Then in ~/.zshrc or ~/.bashrc:
[ -f ~/.secrets/jira_pat ] && export JIRA_PERSONAL_TOKEN="$(cat ~/.secrets/jira_pat)"
[ -f ~/.secrets/confluence_pat ] && export CONFLUENCE_PERSONAL_TOKEN="$(cat ~/.secrets/confluence_pat)"
[ -f ~/.secrets/bitbucket_pat ] && export BITBUCKET_TOKEN="$(cat ~/.secrets/bitbucket_pat)"Windows — native equivalents (System Properties GUI / PowerShell / setx)
atls runs natively on Windows; the only platform-specific piece is how you set environment variables. Pick whichever of the three Windows-native paths you prefer — all produce the same result as the export snippets above.
System Properties GUI (recommended — permanent, no dotfile)
Press Win + R → type sysdm.cpl → Advanced tab → Environment Variables → under User variables click New:
JIRA_PERSONAL_TOKEN=<your-pat>CONFLUENCE_PERSONAL_TOKEN=<your-pat>BITBUCKET_TOKEN=<your-http-access-token>ATLS_DEFAULT_JIRA_URL=https://your-jira.example.com(and*_CONFLUENCE_URL,*_BITBUCKET_URL)
Open a new terminal afterward — existing shells and IDEs do not see the change until restarted.
PowerShell (current session only)
$env:ATLS_DEFAULT_JIRA_URL = "https://your-jira.example.com"
$env:JIRA_PERSONAL_TOKEN = "your-jira-pat"PowerShell (permanent, picked up by new sessions)
[Environment]::SetEnvironmentVariable("JIRA_PERSONAL_TOKEN", "your-jira-pat", "User")
[Environment]::SetEnvironmentVariable("ATLS_DEFAULT_JIRA_URL", "https://your-jira.example.com", "User")cmd / setx (permanent)
setx JIRA_PERSONAL_TOKEN "your-jira-pat"
setx ATLS_DEFAULT_JIRA_URL "https://your-jira.example.com"
atls config set ...works identically on Windows — config is stored at%APPDATA%\atlassian-skills\config.tomlviaplatformdirs. Tokens, however, must live in environment variables (config-based token storage is not yet implemented).
Basic auth (legacy instances without PAT support)
Older Jira (< 8.14) and Confluence (< 7.9) predate Personal Access Tokens. For those, switch to Basic auth with username + password (or API token):
export ATLS_DEFAULT_JIRA_AUTH=basic
export ATLS_DEFAULT_JIRA_USER=myname
export ATLS_DEFAULT_JIRA_TOKEN=<password-or-api-token>Or persist in config:
atls config set profiles.default.auth.jira basicThe same *_AUTH=basic / *_USER / *_TOKEN triple works for jira, confluence, and bitbucket. On Windows, set the three variables via the GUI or setx as shown above.
Priority: CLI flags > ATLS_* vars > standard names (JIRA_PERSONAL_TOKEN, CONFLUENCE_PERSONAL_TOKEN, BITBUCKET_TOKEN) > config file
atls auth statusatls setup all # installs atls skill for Claude Code + Codex
atls auth status # verify connectionWhat gets installed:
- Claude Code:
~/.claude/commands/atls.md(full usage guide, load with/atls) + preference directive in~/.claude/CLAUDE.md(active every conversation, tells Claude to route Atlassian work through atls and navigate with--help). - Codex:
~/.agents/skills/atls/SKILL.md(auto-loaded skill with command tree, format rules, write-safety protocol) + routing directive in~/.codex/AGENTS.md. - Run
atls setup statusto check what is installed. - Run
atls setup pathsto see every resolved install path for your platform.
Install paths (Windows / macOS / Linux):
atls resolves install paths in this order — interactive override → environment variable → platform default. No extra configuration is required on any OS; Path.home() expands to %USERPROFILE% on Windows and $HOME on macOS/Linux.
| Target | Env var override | Default (Windows) | Default (macOS / Linux) |
|---|---|---|---|
| Claude config dir | CLAUDE_CONFIG_DIR |
C:\Users\<you>\.claude |
~/.claude |
| Codex config dir | CODEX_HOME |
C:\Users\<you>\.codex |
~/.codex |
| Agents skill dir | AGENTS_HOME |
C:\Users\<you>\.agents |
~/.agents |
To customize at install time, run any setup command with --interactive (or -i):
atls setup all --interactive
# Detected platform: windows
# Claude config dir: C:\Users\you\.claude (source: default)
# Press Enter to accept, or paste a custom path: D:\Tools\Claude
# → using: D:\Tools\Claude
# Codex config dir: C:\Users\you\.codex (source: default)
# ...Alternatively, export environment variables before running setup:
# Windows (PowerShell)
$env:CLAUDE_CONFIG_DIR = "D:\Tools\Claude"
$env:CODEX_HOME = "D:\Tools\Codex"
atls setup all
# macOS / Linux
export CLAUDE_CONFIG_DIR=~/work/claude
atls setup allCodex users note: the Codex skill installs to <AGENTS_HOME>/skills/atls/ (primary) and <CODEX_HOME>/skills/atls/ (legacy compatibility). The routing directive in AGENTS.md keeps atls as the default Atlassian tool across conversations. Codex's session-start mechanism auto-loads SKILL.md — no manual load required.
Once set up, your AI agent knows how to use atls automatically. Just ask:
"Read PROJ-123 and summarize the acceptance criteria."
"Search for open bugs in the PLATFORM project assigned to me."
"Pull the API Overview page from Confluence, add a rate-limiting section, and push it back."
"Create a Story in PROJ: title 'Add retry logic to payment service', and paste the description from desc.md."
"What changed on the Release Notes page since last week?"
The agent translates these into atls CLI calls, picks the right output format, and handles pagination and error codes for you.
# Jira
atls jira issue get PROJ-1
atls jira issue search "project=PROJ AND status=Open" --limit=20
atls jira issue create --project PROJ --type Story --summary "New feature" --body-file=story.md --body-format=md
# Confluence
atls confluence page get 12345
atls confluence page search "space=DOCS AND title=API"
atls confluence page push-md 12345 --md-file=page.md --if-version 15
atls confluence page pull-md 12345 --output=page.md --resolve-assets=sidecar --asset-dir=assets/
# Jira description from markdown
atls jira issue update PROJ-1 --body-file=desc.md --body-format=md --heading-promotion=jira
# Jira comment / worklog from markdown
atls jira comment add PROJ-1 --body-file=comment.md --body-format=md
atls jira comment edit PROJ-1 12345 --body-file=comment.md --body-format=md
atls jira worklog add PROJ-1 --time-spent-seconds 1800 --comment "$(cat note.md)" --comment-format=md# 1. Token-efficient: compact format is the default (no extra flags needed)
atls jira issue search "project=PROJ AND status=Open"
# 2. Use md format only when you need to read the body
atls jira issue get PROJ-1 -f md
# 3. Use json format for automation/parsing
atls jira issue get PROJ-1 -f json | jq '{key, summary, status}'
# 4. Confluence page editing workflow
atls confluence page pull-md PAGE_ID -o page.md --resolve-assets=sidecar --asset-dir=assets/
# ... edit locally ...
atls confluence page push-md PAGE_ID --md-file page.md --if-version 15 --dry-run
atls confluence page push-md PAGE_ID --md-file page.md --if-version 15
# 5. Branch on exit codes
# 0=OK, 2=not found, 5=stale version, 6=auth failure, 11=rate limited| Format | Flag | Use case |
|---|---|---|
| compact | default | LLM scanning, minimal tokens |
| json | --format=json |
Automation, structured parsing |
| md | --format=md |
Body/description reading |
| raw | --format=raw |
Byte-preserving body access |
--format can be placed globally or locally on subcommands:
# Global placement
atls --format=json jira issue get PROJ-1
# Local placement (preferred for readability)
atls jira issue get PROJ-1 --format=jsonSome commands use
-ffor file input (e.g.push-md). After the subcommand, always use the long form--format=to avoid ambiguity.
jira issue get|search|create|update|delete|transition|transitions|dates|sla|imagesjira comment add|editjira field search|optionsjira project list|issues|versions|components|versions-createjira board list|issuesjira sprint list|issues|create|update|add-issuesjira link list-types|create|remote-list|remote-create|deletejira epic linkjira watcher list|add|removejira worklog list|addjira attachment download|upload|deletejira dev-info get|get-manyjira service-desk list|queues|queue-issuesjira user get
confluence page get|search|children|history|diff|images|create|update|delete|move|push-md|pull-md|diff-localconfluence space treeconfluence comment list|add|replyconfluence label list|addconfluence attachment list|download|download-all|upload|upload-batch|deleteconfluence user search
--passthrough-prefixis supported on Confluence markdown round-trip commands only:push-md,pull-md,diff-local.
bitbucket project listbitbucket repo list|getbitbucket pr list|get|diff|comments|commits|activity|create|update|merge|decline|approve|unapprove|needs-work|reopen|diffstat|statuses|pending-reviewbitbucket branch listbitbucket file getbitbucket comment add|reply|update|delete|resolve|reopenbitbucket task list|get|create|update|delete
All write commands support
--dry-run. PR diff and file get treat--format=mdas raw text passthrough.
auth login|status|listconfig get|set|pathsetup codex|claude|all|status|paths(add--interactiveto customize install paths per-platform)upgradeversion [--check]— show installed version;--checkcompares against the latest PyPI release (exit 1 if outdated)
All write commands support:
--dry-run: Preview without executing--body-file=-: Pipe body content via stdin--if-version N: Optimistic concurrency (Confluence page update & push-md)--if-updated ISO: Stale check (Jira)--attachment-if-exists skip|replace: Duplicate attachment handling (push-md)--asset-dir DIR: Batch upload all files in a directory (push-md)
For scripting, explicitly requested customfield_* keys are preserved in JSON output:
atls jira issue get PROJ-1 --fields=summary,customfield_10100 --format=json
atls jira issue search "project=PROJ" --fields=summary,customfield_10100 --format=jsonFor writes, --set-customfield verifies the result with a read-back check and exits with a validation error if Jira accepts the request but does not apply the value:
atls jira issue update PROJ-1 --set-customfield customfield_10100=EPIC-1If the field expects a structured payload instead of a plain string/key, use --fields-json instead of --set-customfield.
atlassian-skills is a CLI re-implementation of mcp-atlassian's Jira and Confluence operations. If you are currently using mcp-atlassian, here is what changes:
| mcp-atlassian | atlassian-skills |
|---|---|
| MCP protocol (JSON-RPC over stdio) | Shell CLI (atls <command>) |
| Full JSON responses every call | compact by default, json/md/raw on demand |
| ~15k token schema overhead per session | <400 tokens (CLI help only when needed) |
JIRA_PERSONAL_TOKEN env var |
Same env var works, plus ATLS_* for multi-profile |
| Cloud + Server/DC | Server/DC only (primary target) |
| Separate Jira wiki / Confluence XHTML handling | Unified via cfxmark — single dependency for all markup |
| Confluence edits can silently alter content | Lossless XHTML ↔ Markdown round-trip via cfxmark |
| Silent character dropping in Jira descriptions | Byte-preserving --format=raw mode |
Token-compatible auth: If you already have JIRA_PERSONAL_TOKEN and CONFLUENCE_PERSONAL_TOKEN set for mcp-atlassian, atls picks them up automatically — no reconfiguration needed.
- CLI-first: All functionality accessible via the
atlsbinary. AI agent skills are thin wrappers that invoke CLI commands. - Single HTTP client:
httpx-basedBaseClientwith retry (429/5xx), pagination, and auth. - cfxmark integration: Lossless Confluence XHTML ↔ Markdown ↔ Jira wiki conversion via a single dependency. Pages survive unlimited round-trips (
pull-md→ edit →push-md) with zero content drift. - Pydantic v2 models: Strict response parsing for stable fields, with Jira
customfield_*passthrough in JSON output.
| Package | Purpose |
|---|---|
| httpx | REST client (sync) |
| typer + rich | CLI framework |
| pydantic | Response models |
| cfxmark ≥ 0.4 | Markup conversion (Jira wiki + Confluence XHTML) |
| platformdirs | Config path resolution |
# Setup
uv sync
# Local install (editable)
uv tool install -e . # from repo root
uv tool install --force -e . # reinstall after entrypoint changes
# Test
uv run pytest
# Lint
uv run ruff check src/ tests/
uv run mypy src/
# Build
uv build- 0.1.x (current): Jira + Confluence read/write, push-md/pull-md/diff-local, benchmarks, skills, GitHub Actions CI/release
- 0.2.0: Bitbucket Server/DC — PR workflow (create, review, comment, merge, diff, tasks, build status)
- 0.3.0: Bamboo + workflow skills
- 0.4.0+: Async client, caching