confluence-fetch turns a Confluence Cloud page URL into clean Markdown or structured JSON for agents, scripts, and local workflows. It can include comments, download page images, and produce payload-only output for reliable automation.
Install uv first. The tool requires Python 3.11 or newer. uv can obtain a suitable interpreter when needed. Initial execution needs access to package downloads.
Run setup in a terminal on the machine where your agent executes commands. Replace the example URL with a Confluence Cloud page you can read.
PowerShell:
uvx confluence-fetch setup "https://example.atlassian.net/wiki/spaces/ENG/pages/123456789/Team+Handbook"Bash:
uvx confluence-fetch setup "https://example.atlassian.net/wiki/spaces/ENG/pages/123456789/Team+Handbook"Setup asks only for missing information. It provides the token-creation link and required scopes. Enter your Atlassian account email and paste the API token into the terminal prompt. Asterisks mask the token. Never paste credentials into agent chat or put token values in command arguments.
Setup verifies the supplied page, saves the connection and token, and installs the managed agent skill. No separate test fetch is needed. Settings live in ~/.confluence-fetch/config.toml. Tokens live separately in ~/.confluence-fetch/credentials.toml as plain text with normal inherited filesystem permissions. Setup does not change ACLs or require a keyring.
In Codex, send:
Use $confluence-fetch to fetch this page and summarize its decisions:
https://example.atlassian.net/wiki/spaces/ENG/pages/123456789/Team+Handbook
For Claude Code, select its personal skill directory during setup. This command works in PowerShell and Bash:
uvx confluence-fetch setup "https://example.atlassian.net/wiki/spaces/ENG/pages/123456789/Team+Handbook" --skills-dir "$HOME/.claude/skills"
Then invoke /confluence-fetch followed by the URL. Start a new agent session if the skill does not appear. Custom locations require explicit skill updates. See the official Codex skill locations and Claude Code skill instructions.
uvx confluence-fetch config check
uvx confluence-fetch config check "https://example.atlassian.net/wiki/spaces/ENG/pages/123456789/Team+Handbook"
Without a URL, the check selects the only configured domain, or the profile supplied with --profile. Multiple domains require an explicit selection. It checks local readiness without network calls. With a page URL, it also verifies page retrieval and Markdown conversion. Add --comments to setup or a URL-based check to verify the discussion path.
Checks never prompt or write application files. They skip automatic skill synchronization. The uvx launcher may still populate its package cache. Checks return redacted JSON by default. Use --format text for a readable report. Reports distinguish credential sources, selected profiles, skill status, and remote verification. They never display tokens.
A verified page does not prove access to every page, attachments, author profiles, or another execution host. Anonymous page access alone does not establish the authenticated identity. Empty discussions do not verify author-name lookup. Setup does not download images or contact external embeds. REST reads do not intentionally modify content or notification state. Analytics, access logging, and rendered-macro side effects have not been verified.
To replace a saved token, run:
uvx confluence-fetch setup "https://example.atlassian.net/wiki/spaces/ENG/pages/123456789/Team+Handbook" --replace-token
Clear any environment override first. Setup verifies the replacement before saving it. Revoke the old token through Atlassian after replacement succeeds. Repeated setup preserves other profiles and unrelated settings. Skill conflicts preserve the existing skill and report incomplete setup. Any completed configuration or credential writes are retained and reported.
If existing configuration selects an environment variable, remove that selection before switching to a saved token. Use the command for the selection you have configured. These commands preserve other settings:
uvx confluence-fetch config remove-domain-token-env example.atlassian.net
uvx confluence-fetch config clear-default-token-env
Then rerun setup. Removing a whole domain with config remove-domain retains its profiles and credentials. Those profiles remain available through --profile NAME.
Setup sends prompts and its default completion report to stderr. Stdout stays empty. setup --format json emits one redacted result on stdout. --non-interactive never reads terminal input. Missing required input fails without changing application files. --no-skill skips skill installation. --skills-dir PATH selects another skill root.
A shell variable affects that shell and its child processes. An already-running desktop agent does not automatically receive it. A remote host or container needs its own runtime, skill installation, and credential provisioning. A sandbox must allow CLI execution, credential-file reads, and network access to the site and api.atlassian.com.
Run config check through the agent when diagnosing differences. Use --config-dir PATH on fetch, setup, or individual config commands to select a mounted directory containing config.toml and credentials.toml. Provision credentials through the host's secret-injection mechanism or a mounted file. Never read a credentials file or print environment values into agent context. Keep credentials out of repositories, shared exports, and container images.
The standard location is ~/.agents/skills/confluence-fetch/SKILL.md. Normal invocations of an installed CLI, including help and version output, automatically synchronize an already-installed managed skill to the running CLI version. Missing and unmanaged skills are left alone. Skill-management commands skip this automatic check.
Synchronization is local only. It does not query a package index, refresh uv's cache, or update the CLI. The running CLI version is the authority. PEP 440 version comparison prevents downgrades and leaves equal versions unchanged. The skill continues to instruct agents to use uvx confluence-fetch.
Each generated SKILL.md stores lifecycle data in its YAML metadata mapping:
metadata:
managed-by: confluence-fetch
managed-version: "1.2.0"
managed-content-sha256: "sha256:<64 lowercase hexadecimal characters>"The version above is illustrative. The generated value exactly matches uvx confluence-fetch --version. The SHA-256 hash detects modifications to managed content. It is not a signature or security boundary. No sidecar files are used.
Inspect the path, ownership, versions, integrity, and automatic synchronization eligibility without changing anything:
uvx confluence-fetch skill status
uvx confluence-fetch skill status --format textA normal explicit install creates a missing skill or updates a pristine older one. It refuses to overwrite modified or unverifiable managed content. To restore the bundled skill and discard edits to managed content:
uvx confluence-fetch skill install --forceInstall-time --force still refuses unmanaged skills and never downgrades a newer version. Removal accepts current and legacy managed skills:
uvx confluence-fetch skill removeAll three commands accept --skills-dir PATH. Custom locations require explicit updates because normal CLI invocations inspect only the standard location. Local source checkouts, direct source installs, and editable builds do not synchronize automatically. Installed wheels remain eligible.
Explicit commands still work during development:
uvx --from . confluence-fetch skill installAutomatic replacements are atomic and recheck the installed file before replacement. Maintenance failures do not change the primary command's exit status. Notices go to stderr, so payloads on stdout stay valid. Changes affect future skill loading and may require a new agent session.
Markdown is the default output:
# 123456789 Example Page
# Page
The converted page content appears here.With --comments, the document also contains a # Discussion section. JSON output contains structured page, discussion, and asset data together with the rendered Markdown.
An abbreviated JSON result looks like this:
{
"page": {
"id": "123456789",
"title": "Example Page",
"url": "https://your-domain.atlassian.net/wiki/spaces/ENG/pages/123456789/Example+Page",
"site": "https://your-domain.atlassian.net"
},
"content": {
"body_markdown": "The converted page content appears here.",
"document_markdown": "# 123456789 Example Page\n\n# Page\n\nThe converted page content appears here."
},
"discussion": {
"included": false,
"markdown": null,
"footer_comments": [],
"inline_comments": []
},
"assets": {
"downloaded": false,
"directory": null,
"files": []
}
}After setup, fetch a page by passing its URL:
uvx confluence-fetch "https://your-domain.atlassian.net/wiki/spaces/ENG/pages/123456789/Example+Page"The explicit form is also supported:
uvx confluence-fetch fetch "https://your-domain.atlassian.net/wiki/spaces/ENG/pages/123456789/Example+Page"Full page URLs and Confluence /wiki/x/ short URLs are supported. Bare page IDs are not supported. The requested domain is derived from the URL.
To install the command as a persistent tool instead:
uv tool install confluence-fetchThe examples below continue to use uvx confluence-fetch so they work without a global installation.
The fetch model has five core rules:
- Every fetch starts with a full Confluence page URL or a Confluence
/wiki/x/short URL. - The URL determines the Confluence tenant and page. Bare page IDs are rejected.
- Authentication is resolved from the requested domain, configuration, and environment variables.
- Confluence page HTML is converted to GitHub-flavored Markdown. Relative page links and image URLs become absolute.
- The requested payload goes to stdout by default. Progress, diagnostics, and errors go to stderr.
This makes the common case deterministic:
uvx confluence-fetch "<Confluence URL>"Add options only when you need JSON, file output, comments, downloaded images, or verbose diagnostics.
uvx confluence-fetch "<Confluence URL>" --format jsonJSON mode includes structured fields and Markdown fields, including the complete document_markdown value.
uvx confluence-fetch "<Confluence URL>" --output page.mdWhen --output is used, the payload is written to the file and stdout stays empty.
uvx confluence-fetch "<Confluence URL>" --commentsComments are opt-in. The default document order places anchored inline comments according to their first matching location in the page body. Comments without a matching anchor appear afterward in creation order.
Use a time-based order when you want an unambiguous chronological list:
uvx confluence-fetch "<Confluence URL>" --comments --comment-order created
uvx confluence-fetch "<Confluence URL>" --comments --comment-order updatedLimit or filter the rendered comments:
uvx confluence-fetch "<Confluence URL>" --comments --comment-limit 20
uvx confluence-fetch "<Confluence URL>" --comments --comment-kinds inlineuvx confluence-fetch "<Confluence URL>" --download-images --assets-dir ./page-assetsImage downloads are best-effort. Failed downloads are reported without failing an otherwise successful page fetch. Markdown image links are rewritten for assets that download successfully.
If --assets-dir is omitted, assets are written to <output-name>.assets when file output is used. Otherwise they are written to <page-id>.assets in the current directory.
confluence-fetch uses Basic auth with an Atlassian account email and API token. New setups should use scoped API tokens. Create one at Atlassian account security, select Confluence, and grant the scopes needed below. API tokens last 1 to 365 days. Follow your organization's expiration policy. Tokens are replaced rather than refreshed. See Atlassian's token instructions.
An administrator can restrict token creation, use, or lifetime. Scopes do not override page and space permissions. See authentication policy settings.
Setup saves tokens entered at its masked prompt in credentials.toml. It never saves environment token values automatically. Non-secret settings and credential references remain in config.toml. No shell environment variables are persisted. A copied API token retains its server-side permissions. Local profile mappings do not reduce its authority.
The existing Basic-auth gateway route is retained. Live compatibility with unscoped tokens and all attachment URL forms has not been verified. OAuth flows and Confluence Data Center are not supported.
The token environment variable is selected in this order:
--token-env ENV_VAR- A matching domain override in config
[defaults].token_env_varin config- The built-in
CONFLUENCE_TOKENdefault - The selected profile's saved token when the built-in variable is absent or empty
An explicitly selected or configured variable must be non-empty. Missing values fail instead of falling back to a saved token. A selected environment token bypasses the credentials file, even if that file is malformed or inaccessible.
The account email is selected in this order:
--email EMAILor--email-env ENV_VAR- The selected profile's email
- A matching domain email in config
[defaults].emailin configCONFLUENCE_EMAIL- The compatibility fallback
confluence_email
--email-env requires a non-empty variable. It never silently falls back to another account.
Grant only the scopes needed for the features you use:
| Feature | Required scope |
|---|---|
| Fetch page Markdown or JSON | read:page:confluence |
Include comments with --comments |
read:comment:confluence |
Download image assets with --download-images |
read:attachment:confluence |
| Resolve comment author display names | read:user:confluence |
For all current features, grant:
read:page:confluence
read:comment:confluence
read:attachment:confluence
read:user:confluence
If read:user:confluence is missing, comments still render. Author names fall back to stable account IDs when Confluence does not return display names.
Setup creates one named profile for the site, using the hostname as its default name. Each domain selects its default profile. For another account on the same site:
uvx confluence-fetch setup "https://example.atlassian.net/wiki/spaces/ENG/pages/123456789/Team+Handbook" --profile contractor
uvx confluence-fetch fetch "https://example.atlassian.net/wiki/spaces/ENG/pages/123456789/Team+Handbook" --profile contractor
A second profile preserves the existing site default. Add --make-default during setup to select it as the default. Profile and URL sites must match. Existing domain email and token-variable commands remain supported. Removing a domain override does not delete saved profiles or credentials.
A generated profile looks like this:
[domains."example.atlassian.net"]
profile = "example.atlassian.net"
[profiles."example.atlassian.net"]
site = "https://example.atlassian.net"
email = "you@example.com"
credential_ref = "example.atlassian.net"The matching token is stored under [credentials."example.atlassian.net"] in the separate credentials file. Setup manages that file. Configuration updates preserve unrelated fields and use atomic replacement with concurrent-change checks.
Optional user config lives at ~/.confluence-fetch/config.toml. It stores email addresses and environment variable names, never token values.
Example:
[defaults]
token_env_var = "CONFLUENCE_TOKEN"
email = "you@example.com"
[domains."sona-systems.atlassian.net"]
token_env_var = "SONA_CONFLUENCE_TOKEN"
email = "you@sona.example"
[domains."example.atlassian.net"]
token_env_var = "EXAMPLE_CONFLUENCE_TOKEN"Inspect the effective configuration and whether each referenced token variable is set:
uvx confluence-fetch config showconfig show never prints token values.
Update configuration with these commands:
uvx confluence-fetch config set-default-token-env CONFLUENCE_TOKEN
uvx confluence-fetch config set-email "you@example.com"
uvx confluence-fetch config clear-email
uvx confluence-fetch config set-domain-token-env sona-systems.atlassian.net SONA_CONFLUENCE_TOKEN
uvx confluence-fetch config set-domain-email sona-systems.atlassian.net "you@sona.example"
uvx confluence-fetch config remove-domain-email sona-systems.atlassian.net
uvx confluence-fetch config remove-domain sona-systems.atlassian.netPayload output goes to stdout by default. Diagnostics, progress, and errors go to stderr. This keeps Markdown and JSON output safe for pipes and automation.
uvx confluence-fetch "<Confluence URL>" --format json --no-progressUse --verbose for detailed diagnostics on stderr.
Exit codes:
| Code | Meaning |
|---|---|
0 |
Success |
2 |
Usage error |
10 |
Authentication or permission error |
20 |
Page not found |
30 |
Rate limited after retries |
1 |
Other failure |
Useful discovery and metadata commands:
uvx confluence-fetch --help
uvx confluence-fetch fetch --help
uvx confluence-fetch config --help
uvx confluence-fetch setup --help
uvx confluence-fetch config check --help
uvx confluence-fetch skill --help
uvx confluence-fetch --about
uvx confluence-fetch --versionSupported fetch options include:
| Option | Purpose |
|---|---|
| `--format markdown | json` |
-o, --output PATH |
Write the payload to a file. |
--download-images |
Download image assets and rewrite Markdown links. |
--assets-dir PATH |
Select the asset directory. Requires --download-images. |
--comments |
Include a # Discussion section. |
--comment-limit N |
Limit root comments per section. The valid range is 1 through 50. |
| `--comment-kinds all | footer |
| `--comment-order created | updated |
--token-env ENV_VAR |
Read the token from the named environment variable. |
--verbose |
Write detailed diagnostics to stderr. |
--no-progress |
Disable progress output on stderr. |
Agent skill commands return JSON by default. skill status also supports text output:
uvx confluence-fetch skill status --format textThe install-skill and remove-skill commands remain available as aliases for compatibility.
Fetch a page and identify the decisions it records:
Use $confluence-fetch to fetch
<Confluence URL>. Summarize the decisions, open questions, and named owners.
Include the discussion when reviewing a proposal:
Use $confluence-fetch to fetch
<Confluence URL>with comments. Separate feedback that has been resolved from feedback that still needs action.
Download images when page diagrams matter:
Use $confluence-fetch to fetch
<Confluence URL>and download its images. Explain the page using both the written content and the diagrams.
Install the development environment and run the tests:
uv sync --locked --extra dev
uv run pytestBuild the distributions:
uv build --no-sourcesThe repository also contains a thin PEP 723 wrapper for local execution:
uv run confluence_fetch.py --helpTests isolate the home directory. The wheel smoke test uses temporary skill locations and runs without network access.
Project: github.com/pseudosavant/confluence-fetch
MIT. See LICENSE.