atli
atli is a command-line interface for Jira, Confluence, and Bitbucket. It
exposes every operation of mcp-atlassian
as an ordinary shell command — no MCP client, server process, or daemon. Tools
are discovered at startup from the mcp-atlassian server itself, so new tools
appear automatically with pinned versions. The server comes from an install
extra: [atlassian] (Jira + Confluence) or [bitbucket]
(mcp-atlassian-with-bitbucket
— Jira, Confluence, and Bitbucket).
atli tools # list what your credentials unlock
atli jira get-issue --issue-key PROJ-1 # markdown, verbatim from the tool
atli confluence search --query "deploy"
atli bitbucket list-repositories # with the [bitbucket] extra
atli --profile work jira search --jql "assignee = currentUser()"
Install
Jira + Confluence (upstream mcp-atlassian):
$ pipx install "mcp-atlassian-cli[atlassian]"
Bitbucket support (via the fork — Jira, Confluence, and Bitbucket):
$ pipx install "mcp-atlassian-cli[bitbucket]"
A bare pipx install mcp-atlassian-cli (no extra) installs the CLI without a
server: the first tool command fails with a message naming both extras. The
two providers are mutually exclusive — both ship the same mcp_atlassian
package, so installing one over the other or uninstalling either corrupts
the shared files (pip only refuses when both extras are requested in a
single install). To switch providers, start fresh: pipx uninstall mcp-atlassian-cli && pipx install "mcp-atlassian-cli[bitbucket]".
With plain pip (no pipx venv to recreate), uninstall the provider and
fastmcp distributions before switching — pip skips file writes while a
package reads as installed, and it cannot undo two other overlaps: the
providers share mcp_atlassian, and fastmcp>=3 (upstream's pin) is a
meta-package whose fastmcp-slim payload writes into the same directory
as fastmcp 2.x (the fork's pin). The leftovers break imports with errors
like No module named 'mcp_atlassian.servers.main' or cannot import name 'PrivateKeyJWTClientAuthenticator' from 'fastmcp.server.auth.auth', and
no reinstall repairs them:
$ pip uninstall -y mcp-atlassian mcp-atlassian-with-bitbucket fastmcp fastmcp-slim
$ pip install "mcp-atlassian-cli[bitbucket]"
Or from a checkout:
$ git clone <this-repo> && cd mcp-atlassian-cli
$ python -m venv .venv
$ .venv/bin/pip install -e ".[atlassian]"
$ .venv/bin/atli tools
Requires Python 3.11+. The package pins cyclopts>=4.22,<5; the mcp-atlassian
provider ships only via an extra — mcp-atlassian>=0.23,<0.24 with
[atlassian] (fastmcp 3.4.x), or mcp-atlassian-with-bitbucket>=1.0.5,<1.1
with [bitbucket] (fastmcp 2.13–2.14). A base dependency cannot be
suppressed by an extra marker, so the provider cannot also be a default.
Onboarding (atli init)
One command takes you from install to a verified setup:
$ atli init jira # or confluence / bitbucket; bare `atli init` shows a menu
The wizard asks for the service URL, Cloud or Data Center/Server credentials (tokens are entered hidden and validated as you type), whether to verify TLS certificates (answer n behind a corporate proxy with a self-signed CA), where to store everything, the profile name, and which harness to prime:
- Scope —
global(default) writes~/.config/atli/config.tomlplus the home-level harness settings;projectwrites./.atli.tomlplus the repo-local settings. Add.atli.tomlto your.gitignore— profiles are plaintext credentials. - Harnesses — Claude Code (
.claude/settings.json), Codex (.codex/hooks.json; trust the hook via/hookson first run), Qwen Code (.qwen/settings.json), and GigaCode (.gigacode/settings.json). The SessionStart hook merges idempotently — existing settings are never clobbered.
Before anything is written, the wizard verifies the setup with one cheap
read-only call (a limit-1 search or repo list). On failure you re-enter or
abort with nothing written. The profile merges into an existing config
surgically — comments and other profiles survive byte-for-byte — and the
file is chmod 600 afterwards.
Hand-written profiles (next section) remain the power-user path — that is
where mTLS (*_CLIENT_CERT) and OAuth setups live.
Authentication
atli authenticates with the same environment variables as mcp-atlassian.
Tools appear only for services you have configured — with the [atlassian]
provider, 63 Jira commands with JIRA_* set, 35 Confluence commands with
CONFLUENCE_* set, 98 with both, none with neither. With the [bitbucket]
extra, configuring BITBUCKET_* adds the bitbucket service group (and the
fork's jira/confluence surface matches upstream's).
| Deployment | Jira | Confluence | Bitbucket |
|---|---|---|---|
| Cloud (basic auth) | JIRA_URL + JIRA_USERNAME + JIRA_API_TOKEN |
CONFLUENCE_URL + CONFLUENCE_USERNAME + CONFLUENCE_API_TOKEN |
BITBUCKET_URL + BITBUCKET_USERNAME + BITBUCKET_API_TOKEN (app passwords stopped working 2026-06-09) |
| Data Center / Server (PAT) | JIRA_URL + JIRA_PERSONAL_TOKEN |
CONFLUENCE_URL + CONFLUENCE_PERSONAL_TOKEN |
BITBUCKET_URL + BITBUCKET_PERSONAL_TOKEN |
| Data Center / Server (mTLS) | JIRA_URL + JIRA_CLIENT_CERT (+ JIRA_CLIENT_KEY) |
CONFLUENCE_URL + CONFLUENCE_CLIENT_CERT (+ CONFLUENCE_CLIENT_KEY) |
— |
Notes:
- On Cloud, username is the Atlassian account email; the API token comes from https://id.atlassian.com/manage-profile/security/api-tokens.
- On Bitbucket Cloud, use a scoped API token (
bb_pat_…): avatar → Personal settings → Security → Create and manage API tokens. Scopes follow the toolsets you use — Repositories: Read + Pull requests: Read covers read-only repository and pull-request work.BITBUCKET_USERNAMEis the Atlassian account email here. The older app-password method (BITBUCKET_APP_PASSWORD+ the Bitbucket username, not the email) is dead: app passwords could not be created after 2025-09-09 and stopped working on 2026-06-09 — and the fork readsBITBUCKET_APP_PASSWORDfirst, so unset any leftover or it shadows a valid API token. BITBUCKET_WORKSPACEoptionally pins a default workspace slug (Cloud only) — the part afterbitbucket.org/in repository URLs. The Bitbucket URL decides Cloud vs Server:bitbucket.org(or any host servingapi.bitbucket.org) means Cloud, everything else means Server/Data Center.- On Data Center/Server, the personal token is created under Profile → Personal Access Tokens.
- mTLS with an encrypted private key is not supported (the underlying
library rejects it). Decrypt the key first:
openssl rsa -in key.enc -out key. - Data Center/Server Jira and Confluence also accept username + API token via
the same
*_USERNAME/*_API_TOKENvariables if basic auth is enabled. Bitbucket Server/DC has no live basic-auth path:BITBUCKET_API_TOKENis Cloud-only, and its basic auth used the app password that stopped working 2026-06-09 — useBITBUCKET_PERSONAL_TOKENthere. *URLmay include/wikifor Confluence. The URL decides Cloud vs Data Center: hosts ending in.atlassian.net(also.jira.com,.jira-dev.com,.atlassian.com, and exact-matchapi.atlassian.com, plus the US-Gov domains) mean Cloud; everything else, includinglocalhostand private IPs, means Data Center/Server.- Tokens and usernames are plain ASCII in practice. If one picks up
characters beyond latin-1 — Cyrillic letters, smart quotes, or mojibake
from a legacy-encoded file (a Windows classic) — every request dies with
'latin-1' codec can't encode characters …: HTTP headers cannot carry such text.atlirejects such values up front (exit 2), naming the variable and the first offending character. Set credentials withsetx/$env:(not by echoing files), keep.atli.tomlsaved as UTF-8, and re-copy the token from its source when in doubt.
$ export JIRA_URL="https://your-company.atlassian.net"
$ export JIRA_USERNAME="you@your-company.com"
$ export JIRA_API_TOKEN="..."
$ atli tools | head -3
Bitbucket Cloud (with the [bitbucket] extra):
$ export BITBUCKET_URL="https://bitbucket.org"
$ export BITBUCKET_USERNAME="you@your-company.com"
$ export BITBUCKET_API_TOKEN="bb_pat_..."
$ atli bitbucket list-repositories
Profiles (multiple instances)
Storing credentials in a TOML file lets you switch instances with
--profile NAME and keep several side by side. Config lookup order:
$ATLI_CONFIG— if set, must point at an existing file (an error otherwise)./.atli.tomlin the current directory~/.config/atli/config.toml
The first existing file wins. Any key you set in a profile (including options
such as TOOLSETS = "all", which is unprefixed) replaces the ambient
environment for that service prefix; prefixes the profile doesn't mention are
left untouched. TOOLSETS only takes effect in a profile that also sets at
least one service-prefixed key (JIRA_*/CONFLUENCE_*/MCP_ATLASSIAN_*/
BITBUCKET_*) — a TOOLSETS-only profile changes nothing.
# ~/.config/atli/config.toml
default_profile = "work"
[profiles.work]
JIRA_URL = "https://your-company.atlassian.net"
JIRA_USERNAME = "you@your-company.com"
JIRA_API_TOKEN = "..."
CONFLUENCE_URL = "https://your-company.atlassian.net/wiki"
CONFLUENCE_USERNAME = "you@your-company.com"
CONFLUENCE_API_TOKEN = "..."
BITBUCKET_URL = "https://bitbucket.org"
BITBUCKET_USERNAME = "you@your-company.com"
BITBUCKET_API_TOKEN = "bb_pat_..."
[profiles.dc]
JIRA_URL = "https://jira.internal.example.com"
JIRA_PERSONAL_TOKEN = "..."
Warning: profiles are plaintext credentials. After creating the file, run:
$ chmod 600 ~/.config/atli/config.toml
Profile selection order: --profile NAME flag > $ATLI_PROFILE > the
default_profile key. The flag must appear before the subcommand; atli --profile=work tools and atli --profile work tools both work.
$ atli profiles # lists profiles and URLs — never tokens
* work (default)
jira: https://your-company.atlassian.net
confluence: https://your-company.atlassian.net/wiki
bitbucket: https://bitbucket.org
dc
jira: https://jira.internal.example.com
$ atli --profile dc jira get-issue --issue-key OPS-42
Priming AI agents (atli prime)
atli prime prints a compact primer of the local setup — configured services,
active profile, usage patterns, quirks — as AI-optimized markdown. It is
designed for SessionStart hooks, so agents re-learn atli after context
compaction. It never imports mcp-atlassian and costs milliseconds.
The one-command onboarding installs the hook for you — idempotent, never clobbering existing settings:
$ atli prime --install # detect harnesses, user scope
$ atli prime --install --scope project # .claude/settings.json in the repo
- Claude Code (
.claude/settings.json), Codex (.codex/hooks.json, one-time/hookstrust review on first run), Qwen Code (.qwen/settings.json), and GigaCode (.gigacode/settings.json) are supported, in user or project scope — Codex'shooks.jsonuses the same JSON hook shape as Claude Code's settings. - Gemini CLI is detected but not auto-installed: it runs SessionStart
hooks without injecting their context (gemini-cli issue #15413). The
atli prime --hook-jsonenvelope remains compatible if you wire it by hand.
Manual hook, if you prefer (same envelope as the installer writes for every supported harness; Gemini CLI would need it wired by hand):
{
"hooks": {
"SessionStart": [
{ "hooks": [{ "type": "command", "command": "atli prime --hook-json" }] }
]
}
}
$ atli prime [--hook-json] [--export]
SessionStart hook (the one envelope every supported harness consumes):
{
"hooks": {
"SessionStart": [
{ "hooks": [{ "type": "command", "command": "atli prime --hook-json" }] }
]
}
}
--hook-jsonwraps the output in the SessionStart hook envelope.--exportprints the default content (ignores overrides, works even when nothing is configured) — the starting point for customization.- With nothing configured and no override file,
primeprints nothing and exits 0 — zero token cost on machines where atli cannot act anyway. - The Configured line reads exported variables and profiles only;
.envfiles (consumed inside mcp-atlassian) are invisible to prime.
Override — a PRIME.md file replaces the default content entirely (no dynamic header, prints even when unconfigured). Lookup order, first existing file wins:
$ATLI_PRIME— must point at an existing file (an error otherwise)./.atli/PRIME.md— current directory; check it into the repo for project-specific conventions~/.config/atli/PRIME.md— personal default
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success (tool output on stdout) |
| 1 | Tool or server failure — the tool's error message on stderr |
| 2 | Usage or configuration error — bad flags, missing/invalid config file, unknown profile |
Notes for agents and scripts
atli tools --search TEXTshortlists tools by keyword across names and full descriptions.atli <service> <tool> --helpshows every parameter with its type and default, straight from the tool's schema.- Parameter descriptions in a tool's
--helpcome verbatim from the tool's schema — accepted formats and semantics, straight from the source. - Popular tools show real invocations under
Example invocations:in--help— identifiers like--page-id, JQL and relative-date formats,@filefor long content. - Repeatable list flags repeat:
--read-users alice --read-users bob(onconfluence set-page-restrictions) gives["alice", "bob"];--read-users alice,bobgives one element"alice,bob". - String values expand:
--body @comment.mdreads the file,-reads stdin (when piped),@@textpasses a literal@text. A missing file is a usage error (exit 2) whose message shows the escape. - Startup takes ~1 s warm, a few seconds cold (the mcp-atlassian import
dominates). For bulk work, prefer one
searchover many single-item calls.
Metadata
Release files for mcp-atlassian-cli 0.5.0
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 | |
|---|---|---|---|---|
| mcp_atlassian_cli-0.5.0.tar.gz | 87.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_atlassian_cli-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 136.0 kB
Release files / mcp_atlassian_cli-0.5.0.tar.gz
| Download URL | mcp_atlassian_cli-0.5.0.tar.gz |
|---|---|
| Size | 87.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
61a823ff4d27c6e850817c534fb9f1683fc059ac2c1f84da12d64bc50ea98a48
|
|
BLAKE2b-256 checksum How to use checksums |
4f640239d0963eb62eeb9c2e06da8f4672bfb879df37aee3792d5c7721437ed0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 17, 2026.
Transparency logRelease files / mcp_atlassian_cli-0.5.0-py3-none-any.whl
| Download URL | mcp_atlassian_cli-0.5.0-py3-none-any.whl |
|---|---|
| Size | 48.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1e3392150288da566ec7cbc688ac14cd14c579199e0afe6a57717bbdbe571491
|
|
BLAKE2b-256 checksum How to use checksums |
232f190649740c736e80ca3f414c66813a9ce4159650a17a6d6e93060511f7cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 17, 2026.
Transparency logSecurity for mcp-atlassian-cli 0.5.0
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
All 2 files in this release have been uploaded with provenance metadata.
Attestation for mcp_atlassian_cli-0.5.0.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 Sep 17, 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.