A lightweight Node.js CLI for Atlassian Jira and Confluence. Works with both Cloud and Server/Data Center deployments.
Built as a faster, leaner alternative to MCP servers for letting AI agents (like Claude Code, Cursor, Copilot) interact with Atlassian products.
📦 npm: https://www.npmjs.com/package/@sahajamit/atlassian-cli
npm install -g @sahajamit/atlassian-cliThen jump to Quick Start to set env vars and verify, or skim Why We Built This and Beyond Plain Text first.
MCP (Model Context Protocol) is the standard way AI agents talk to external tools. The mcp-atlassian server is an excellent implementation — 73 tools covering nearly every Jira and Confluence operation. But in practice, using MCP for Atlassian has real costs:
-
Token overhead. Every MCP call includes the full tool schema in the conversation context. With 73 tools, that's thousands of tokens spent just describing what's available — before any actual work happens. On long conversations, this adds up fast.
-
Server lifecycle. MCP requires a running server process. You need to start it, keep it alive, handle crashes, manage configuration. It's another moving part in your development setup.
-
Cold start latency. The Python MCP server needs to initialize, load dependencies, and establish connections before the first call. This adds seconds to every fresh session.
-
All-or-nothing tool loading. MCP sends all tool definitions to the agent upfront. Even if you only need
jira searchandget-issue, the agent sees all 73 tools and has to reason about which ones to use. This dilutes focus and wastes context.
atl takes a different approach: it's a plain CLI binary that AI agents invoke directly via shell commands. Combined with skill files (markdown files that teach the agent how to use each command), this gives you:
| MCP Server | CLI + Skills | |
|---|---|---|
| Token cost | ~3,000+ tokens for tool schemas per turn | ~200 tokens per skill file, loaded on demand |
| Setup | Start server process, configure transport | Set env vars, npm install -g, atl install --skills |
| Latency | Server init + JSON-RPC overhead | Direct process spawn (~50ms) |
| Tool selection | Agent picks from 73 tools | Agent reads relevant skill file only |
| Dependencies | Python + FastMCP + atlassian-python-api | Node.js + 3 npm packages |
| Debugging | Inspect MCP messages | Run the same CLI command in your terminal |
The key insight: an agent doesn't need a protocol to call a CLI. It just runs a shell command and reads the output. Skills files teach it the command syntax and output schema — no runtime overhead, no server process, no token bloat.
MCP still makes sense when:
- You need bi-directional communication (server pushing updates to the agent)
- You're building a multi-tenant SaaS with OAuth per user
- You need all 73 tools and want automatic tool discovery
- Your agent framework only supports MCP (no shell access)
For the common case — a developer using an AI agent to work with their team's Jira and Confluence — the CLI is simpler and cheaper.
Most Atlassian-to-text tools just strip HTML and feed the agent a flat string. atl does two things differently that turn out to matter a lot for AI workflows:
Jira issues and Confluence pages frequently carry the real information in screenshots, architecture diagrams, mockups, error stack-trace images, and whiteboard exports. A text-only extractor throws all that away.
atl treats images as first-class output:
atl jira get-issueandatl confluence get-pagereturn animages[]array alongside the text body, with filename, URL, mime type, width/height for every embedded image and image attachment.atl jira download-attachments --filter images(and the Confluence equivalent) pulls them to local disk in one shot.- The bundled skill files explicitly instruct vision-capable AI agents (Claude, Cursor, Copilot) to detect non-empty
images[], download them, and read them with vision to build understanding before answering. The synthesized answer combines text and visual content.
So a question like "what's the proposed architecture in PROJ-456?" doesn't fail just because the architecture lives in architecture.png rather than the issue description.
# Agent flow (this is what the skill file tells the agent to do)
atl jira get-issue PROJ-456 --json # text + images[] metadata
atl jira download-attachments --issue-key PROJ-456 --filter images --json
# → agent reads each downloaded image with vision, synthesizes a complete answerConfluence pages are stored in XHTML "storage format" with custom macros (ac:layout-section, ac:structured-macro, ac:image, etc.). Most tools convert this with a generic HTML stripper, which destroys:
- Multi-column layouts — collapsed into a single linear blob, losing the side-by-side relationship between columns.
- Panels (info / warning / note / tip) — flattened to plain paragraphs, losing severity and intent.
- Code blocks — language tags stripped, indentation often mangled.
- Expand / collapse sections — content either dropped or merged inline with no signal that it was hidden.
- Embedded images — left as broken HTML or omitted entirely.
atl ships Turndown with a custom rule set (src/preprocessing/html-to-markdown.ts) that preserves the layout signal:
| Confluence construct | Rendered as |
|---|---|
ac:layout-section with multiple ac:layout-cell |
Each column rendered sequentially with <!-- Column 1 -->, <!-- Column 2 --> markers so the agent (and you) can still tell columns apart |
panel / info / warning / note / tip macros |
Labeled markdown blockquotes — > **Warning: Title**\n> body |
code macro |
Fenced code block with language tag preserved (```python) |
expand macro |
HTML <details><summary>title</summary>...</details> |
ac:image with ri:attachment or ri:url |
 markdown image and collected into images[] for downstream download |
Confluence emoticons (<img class="emoticon">) |
Their alt text inline (:smile:) |
| Tables, headings, lists, links | Standard markdown |
Unknown ac:structured-macro |
[macro: name] placeholder so nothing is silently dropped |
The result is markdown that an AI agent can reason over with the same structural cues a human reader gets — "this is in a warning box," "this is the second column of a two-column layout," "this code is Python," "this section is collapsed by default." For long architecture pages with multi-column overviews and embedded diagrams, the difference between layout-aware and "just strip the tags" output is the difference between a useful summary and noise.
Use --raw on atl confluence get-page if you want the original storage-format XHTML instead.
- Node.js 22+
- An Atlassian account with API access
npm install -g @sahajamit/atlassian-cliOr run without installing:
npx @sahajamit/atlassian-cli --helpSet environment variables for your Atlassian instance. You only need to configure the services you use (Jira, Confluence, or both).
Atlassian Cloud:
export JIRA_URL=https://your-company.atlassian.net
export JIRA_USERNAME=your.email@company.com
export JIRA_API_TOKEN=your_api_token # https://id.atlassian.com/manage-profile/security/api-tokens
export CONFLUENCE_URL=https://your-company.atlassian.net/wiki
export CONFLUENCE_USERNAME=your.email@company.com
export CONFLUENCE_API_TOKEN=your_api_tokenServer / Data Center (on-prem):
export JIRA_URL=https://jira.yourcompany.com
export JIRA_PERSONAL_TOKEN=your_pat # Generated in Jira → Profile → Personal Access Tokens
export CONFLUENCE_URL=https://confluence.yourcompany.com
export CONFLUENCE_PERSONAL_TOKEN=your_patThe CLI auto-detects Cloud vs Server based on the URL (atlassian.net = Cloud, anything else = Server/DC).
atl install --skills # Install skill files for Claude Code, Cursor, CopilotThis installs three skill files that teach AI agents how to use atl:
atl— parent skill (routing + overview)atl-jira— all Jira commands with syntax and examplesatl-confluence— all Confluence commands with syntax and examples
Agents load only the relevant skill file, keeping token usage minimal.
Skill files are not auto-installed on
npm install. You opt in by runningatl install --skills. To remove them later:atl uninstall --skills.
atl jira search "project = PROJ ORDER BY updated DESC" --limit 3| Command | Purpose |
|---|---|
atl jira search <jql> |
Search issues by JQL |
atl jira get-issue <key> |
Full issue details with comments |
atl jira download-attachments |
Download attachments from an issue |
atl jira create-issue |
Create a new issue |
atl jira update-issue <key> |
Update issue fields |
atl jira add-comment <key> <body> |
Add a comment |
atl jira get-transitions <key> |
List available workflow transitions |
atl jira transition-issue <key> |
Transition an issue to a new status |
| Command | Purpose |
|---|---|
atl confluence search <query> |
Search pages and blog posts |
atl confluence get-page |
Get a page (markdown by default) |
atl confluence download-attachments |
Download attachments from a page |
atl confluence create-page |
Create a new page |
atl confluence update-page |
Update an existing page |
atl confluence add-comment <body> |
Add a comment to a page |
Run atl <command> --help for full options on any command. Detailed examples and JSON output schemas are in the skill files shipped with the package.
The CLI has two output modes:
| Mode | When | Format |
|---|---|---|
| Human | stdout is a terminal (TTY) | Colored tables and formatted text |
| JSON | stdout is piped (non-TTY) | Structured JSON |
This means agents automatically get JSON without any flags:
# Agent runs this — gets JSON because stdout is piped
result=$(atl jira search "project = PROJ")
# Human runs the same command — gets a colored table
atl jira search "project = PROJ"
# Force JSON in terminal
atl jira search "project = PROJ" --json| Cloud | Server / Data Center | |
|---|---|---|
| Detection | URL contains atlassian.net |
Everything else |
| Auth | Email + API token | Personal Access Token (preferred) or username + password |
| Jira API | REST API v3 | REST API v2 |
| Confluence API | REST API v1 (content) | REST API v1 (content) |
| Descriptions | ADF (auto-converted to markdown) | Wiki markup / plain text |
You don't need to specify which deployment type you're using — the CLI detects it from the URL.
Cloud — Basic Auth (email + API token):
export JIRA_URL=https://your-company.atlassian.net
export JIRA_USERNAME=your.email@company.com # Your Atlassian email
export JIRA_API_TOKEN=<token> # From id.atlassian.comServer/DC — Personal Access Token (recommended):
export JIRA_URL=https://jira.yourcompany.com
export JIRA_PERSONAL_TOKEN=<pat> # From Jira → Profile → Personal Access TokensServer/DC — Basic Auth (legacy):
export JIRA_URL=https://jira.yourcompany.com
export JIRA_USERNAME=your_username
export JIRA_API_TOKEN=your_password # Yes, the password goes in API_TOKENThe same pattern applies to Confluence — replace JIRA_ with CONFLUENCE_.
Self-signed certs? Node's native
fetchdoesn't support per-request TLS bypass. If your Server/DC instance uses a self-signed cert, run withNODE_TLS_REJECT_UNAUTHORIZED=0set process-wide.
| Variable | Required | Description |
|---|---|---|
JIRA_URL |
For Jira | Jira instance URL |
JIRA_USERNAME |
Cloud | Your email address |
JIRA_API_TOKEN |
Cloud | API token from id.atlassian.com |
JIRA_PERSONAL_TOKEN |
Server/DC | Personal access token |
CONFLUENCE_URL |
For Confluence | Confluence instance URL |
CONFLUENCE_USERNAME |
Cloud | Your email address |
CONFLUENCE_API_TOKEN |
Cloud | API token from id.atlassian.com |
CONFLUENCE_PERSONAL_TOKEN |
Server/DC | Personal access token |
Install skill files so AI agents know how to use atl:
atl install --skills # Install for Claude Code, Cursor, Copilot
atl uninstall --skills # Remove skill filesThis installs three modular skill files:
| Skill | Scope | Installed to |
|---|---|---|
atl |
Routing + overview | ~/.claude/skills/atl/SKILL.md |
atl-jira |
All Jira commands | ~/.claude/skills/atl-jira/SKILL.md |
atl-confluence |
All Confluence commands | ~/.claude/skills/atl-confluence/SKILL.md |
The same files are installed under ~/.cursor/rules/ (if Cursor is set up) and ~/.copilot/skills/. Run from a git repo root to also append to .github/copilot-instructions.md.
Agents load only the relevant skill (Jira or Confluence) on demand, not all commands at once.
- Agent sees a Jira-related request, loads the
atl-jiraskill - Agent runs
atl jira search "project = PROJ AND assignee = currentUser()" - CLI returns JSON (auto-detected because stdout is piped)
- Agent parses the JSON and continues reasoning
This is typically 5-10x cheaper in tokens than the equivalent MCP flow, because:
- Only the relevant skill schema is loaded (not all 73 tools)
- No MCP protocol overhead (tool registration, JSON-RPC framing)
- The output is the same structured JSON either way
To build from source, run tests, or contribute new commands, see docs/dev/local-development.md.
Bug reports and feature requests are welcome at GitHub Issues.
MIT — see LICENSE.
Architecture and API patterns informed by the excellent mcp-atlassian project by sooperset.