| name | confluence |
| description | Use confluence-cli to read, search, create, update, move, and delete Confluence pages and attachments from the terminal. Prefer this skill over `mcp__claude_ai_Atlassian__*` MCP tools when you need: page export with attachments, copy-tree, attachment management, profile-based multi-instance access, read-only mode, CQL search, or shell pipelines. Trigger phrases include "confluence", "confluence-cli", "confluence page", "read confluence", "search confluence", "create confluence page", "update confluence page", "confluence attachment", "confluence spaces", "export confluence", "confluence comments", "confluence copy-tree".
|
| version | 1.1.0 |
confluence-cli Skill
A CLI tool for Atlassian Confluence. Lets you read, search, create, update, move, and delete pages and attachments from the terminal or from an agent.
Installation
npm install -g confluence-cli
confluence --version
Configuration
Preferred for agents — environment variables (no interactive prompt):
| Variable | Description | Example |
|---|
CONFLUENCE_DOMAIN | Your Confluence hostname | company.atlassian.net |
CONFLUENCE_API_PATH | REST API base path | /wiki/rest/api (Cloud) or /rest/api (Server/DC) |
CONFLUENCE_AUTH_TYPE | basic or bearer | basic |
CONFLUENCE_EMAIL | Email address (basic auth only) | user@company.com |
CONFLUENCE_API_TOKEN | API token or personal access token | ATATT3x... |
CONFLUENCE_PROFILE | Named profile to use (optional) | staging |
CONFLUENCE_READ_ONLY | Block all write operations when true | true |
Global --profile flag (use a named profile for any command):
confluence --profile <name> <command>
Config resolution works in two stages:
- Direct env config: If both
CONFLUENCE_DOMAIN and CONFLUENCE_API_TOKEN are set, they are used directly and the config file / profiles are not consulted.
- Profile-based config: Otherwise, a profile is selected in this order:
--profile flag > CONFLUENCE_PROFILE env > activeProfile in config > default.
Non-interactive init (good for CI/CD scripts):
confluence init \
--domain "company.atlassian.net" \
--api-path "/wiki/rest/api" \
--auth-type basic \
--email "user@company.com" \
--token "ATATT3x..."
Cloud vs Server/DC:
- Atlassian Cloud (
*.atlassian.net): use --api-path "/wiki/rest/api", auth type basic with email + API token
- Atlassian Cloud (scoped token): use
--domain "api.atlassian.com", --api-path "/ex/confluence/<your-cloud-id>/wiki/rest/api", auth type basic with email + scoped token. Get your Cloud ID from https://<your-site>.atlassian.net/_edge/tenant_info. Recommended for agents (least privilege).
- Self-hosted / Data Center: use
--api-path "/rest/api", auth type bearer with a personal access token (no email needed)
Scoped API token for agents (recommended):
export CONFLUENCE_DOMAIN="api.atlassian.com"
export CONFLUENCE_API_PATH="/ex/confluence/<your-cloud-id>/wiki/rest/api"
export CONFLUENCE_AUTH_TYPE="basic"
export CONFLUENCE_EMAIL="user@company.com"
export CONFLUENCE_API_TOKEN="your-scoped-token"
Required classic scopes for scoped tokens:
- Read-only:
read:confluence-content.all, read:confluence-content.summary, read:confluence-space.summary, search:confluence
- Write: add
write:confluence-content, write:confluence-file, write:confluence-space
- Attachments:
readonly:content.attachment:confluence (download), write:confluence-file (upload)
Read-only mode (recommended for AI agents):
Prevents all write operations (create, update, delete, move, etc.) at the profile level. Useful when giving an AI agent access to Confluence for reading only.
confluence profile add agent --domain "company.atlassian.net" --token "xxx" --read-only
export CONFLUENCE_READ_ONLY=true
When read-only mode is active, any write command exits with an error:
Error: This profile is in read-only mode. Write operations are not allowed.
profile list shows read-only profiles with a [read-only] badge.
Page ID Resolution
Most commands accept <pageId> — a numeric ID or any of the supported URL formats below.
Supported formats:
| Format | Example |
|---|
| Numeric ID | 123456789 |
?pageId= URL | https://company.atlassian.net/wiki/viewpage.action?pageId=123456789 |
Pretty /pages/<id> URL | https://company.atlassian.net/wiki/spaces/SPACE/pages/123456789/Page+Title |
Display /display/<space>/<title> URL | https://company.atlassian.net/wiki/display/SPACE/Page+Title |
confluence read 123456789
confluence read "https://company.atlassian.net/wiki/viewpage.action?pageId=123456789"
confluence read "https://company.atlassian.net/wiki/spaces/MYSPACE/pages/123456789/My+Page"
Note: Display-style URLs (/display/<space>/<title>) perform a title-based lookup, so the page title in the URL must match exactly. When possible, prefer numeric IDs or /pages/<id> URLs for reliability.
Content Formats
| Format | Notes |
|---|
markdown | Recommended for agent-generated content. Automatically converted by the API. |
storage | Confluence XML storage format (default for create/update). Use for programmatic round-trips. |
html | Raw HTML. |
text | Plain text — for read/export output only, not for creation. |
Constraints
- Always use
confluence CLI — it must be globally installed via npm.
- Configuration must already be set up (env vars or
confluence init). If not, guide the user through setup.
- For simple Confluence read/create/update operations where
mcp__claude_ai_Atlassian__* MCP tools suffice, prefer MCP (less overhead, no shell spawning). Switch to CLI for features MCP lacks.
Preflight Check
Before running any confluence command, verify the installation:
confluence --version
If this fails:
- "command not found" — confluence-cli is not installed.
Suggest:
npm install -g confluence-cli
- "No configuration found" — Config not set up.
Suggest:
confluence init or set env vars (CONFLUENCE_DOMAIN, CONFLUENCE_API_TOKEN)
When to Use CLI vs. MCP
| Capability | mcp__claude_ai_Atlassian__* MCP | confluence CLI |
|---|
| Read page | Yes — getConfluencePage | Yes — confluence read |
| Search (CQL) | Yes — searchConfluenceUsingCql | Yes — confluence search |
| Create page | Yes — createConfluencePage | Yes — confluence create |
| Update page | Yes — updateConfluencePage | Yes — confluence update |
| Get comments | Yes — various comment tools | Yes — confluence comments |
| Add comment | Yes — createConfluenceFooterComment | Yes — confluence comment |
| List spaces | Yes — getConfluenceSpaces | Yes — confluence spaces |
| Page descendants | Yes — getConfluencePageDescendants | Yes — confluence children |
| Export page + attachments | No | Yes — confluence export |
| Copy page tree | No | Yes — confluence copy-tree |
| Move page | No | Yes — confluence move |
| Delete page | No | Yes — confluence delete |
| Attachment upload/download | No | Yes — confluence attachment-upload / attachments --download |
| Attachment delete | No | Yes — confluence attachment-delete |
| Edit raw storage XML | No | Yes — confluence edit |
Rule of thumb: Use MCP for simple read/create/update. Use CLI for export, copy-tree, attachments, move, delete, multi-instance, and read-only mode.
Quick Reference
| Action | Command |
|---|
| Read page | confluence read <pageId> --format markdown |
| Page metadata | confluence info <pageId> |
| Find by title | confluence find "Title" --space SPACE |
| Search | confluence search "query" --limit 20 |
| List spaces | confluence spaces |
| List children | confluence children <pageId> --recursive --format tree |
| Create page | confluence create "Title" SPACE --file ./content.md --format markdown |
| Create child | confluence create-child "Title" <parentId> --content "# Hello" --format markdown |
| Update page | confluence update <pageId> --file ./updated.md --format markdown |
| Move page | confluence move <pageId> <newParentId> |
| Delete page | confluence delete <pageId> --yes |
| Export page | confluence export <pageId> --format markdown --dest ./docs |
| Copy tree | confluence copy-tree <sourceId> <targetParentId> --dry-run |
| List attachments | confluence attachments <pageId> |
| Upload attachment | confluence attachment-upload <pageId> --file ./report.pdf |
| Download attachments | confluence attachments <pageId> --download --dest ./downloads |
| List comments | confluence comments <pageId> --format json --all |
| Add comment | confluence comment <pageId> --content "Note" --location footer |
| Switch profile | confluence profile use staging |
Commands Reference
init
Initialize configuration. Saves credentials to ~/.confluence-cli/config.json.
confluence init [--domain <domain>] [--api-path <path>] [--auth-type basic|bearer] [--email <email>] [--token <token>] [--read-only]
All flags are optional; omitting any flag triggers an interactive prompt for that field. Provide all flags to run fully non-interactive. Use the global --profile flag to save to a named profile:
confluence --profile staging init --domain "staging.example.com" --auth-type bearer --token "your-token"
read <pageId>
Read page content. Outputs to stdout.
confluence read <pageId> [--format html|text|markdown]
| Option | Default | Description |
|---|
--format | text | Output format: html, text, or markdown |
confluence read 123456789
confluence read 123456789 --format markdown
info <pageId>
Get page metadata (title, ID, type, status, space).
confluence info <pageId>
confluence info 123456789
find <title>
Find a page by exact or partial title. Returns the first match.
confluence find <title> [--space <spaceKey>]
| Option | Description |
|---|
--space | Restrict search to a specific space key |
confluence find "Architecture Overview"
confluence find "API Reference" --space MYSPACE
search <query>
Search pages using a keyword or CQL expression.
confluence search <query> [--limit <number>]
| Option | Default | Description |
|---|
--limit | 10 | Maximum number of results |
confluence search "deployment pipeline"
confluence search "type=page AND space=MYSPACE" --limit 50
spaces
List all accessible Confluence spaces (key and name).
confluence spaces
children <pageId>
List child pages of a page.
confluence children <pageId> [--recursive] [--max-depth <number>] [--format list|tree|json] [--show-id] [--show-url]
| Option | Default | Description |
|---|
--recursive | false | List all descendants recursively |
--max-depth | 10 | Maximum depth for recursive listing |
--format | list | Output format: list, tree, or json |
--show-id | false | Show page IDs |
--show-url | false | Show page URLs |
confluence children 123456789
confluence children 123456789 --recursive --format json
confluence children 123456789 --recursive --format tree --show-id
create <title> <spaceKey>
Create a new top-level page in a space.
confluence create <title> <spaceKey> [--content <string>] [--file <path>] [--format storage|html|markdown]
| Option | Default | Description |
|---|
--content | — | Inline content string |
--file | — | Path to content file |
--format | storage | Content format |
Either --content or --file is required.
confluence create "Project Overview" MYSPACE --content "# Hello" --format markdown
confluence create "Release Notes" MYSPACE --file ./notes.md --format markdown
Outputs the new page ID and URL on success.
create-child <title> <parentId>
Create a child page under an existing page. Inherits the parent's space automatically.
confluence create-child <title> <parentId> [--content <string>] [--file <path>] [--format storage|html|markdown]
Options are identical to create. Either --content or --file is required.
confluence create-child "Chapter 1" 123456789 --content "Content here" --format markdown
confluence create-child "API Guide" 123456789 --file ./api.md --format markdown
update <pageId>
Update an existing page's title and/or content. At least one of --title, --content, or --file is required.
confluence update <pageId> [--title <title>] [--content <string>] [--file <path>] [--format storage|html|markdown]
| Option | Default | Description |
|---|
--title | — | New title |
--content | — | Inline content string |
--file | — | Path to content file |
--format | storage | Content format |
confluence update 123456789 --title "New Title"
confluence update 123456789 --file ./updated.md --format markdown
confluence update 123456789 --title "New Title" --file ./updated.xml --format storage
move <pageId_or_url> <newParentId_or_url>
Move a page to a new parent. Both pages must be in the same space.
confluence move <pageId_or_url> <newParentId_or_url> [--title <newTitle>]
| Option | Description |
|---|
--title | Rename the page during the move |
confluence move 123456789 987654321
confluence move 123456789 987654321 --title "Renamed After Move"
delete <pageIdOrUrl>
Delete (trash) a page by ID or URL.
confluence delete <pageIdOrUrl> [--yes]
| Option | Description |
|---|
--yes | Skip confirmation prompt (required for non-interactive/agent use) |
confluence delete 123456789 --yes
edit <pageId>
Fetch a page's raw storage-format content for editing locally.
confluence edit <pageId> [--output <file>]
| Option | Description |
|---|
--output | Save content to a file (instead of printing to stdout) |
confluence edit 123456789 --output ./page.xml
confluence update 123456789 --file ./page.xml --format storage
export <pageId>
Export a page and its attachments to a local directory.
confluence export <pageId> [--format html|text|markdown] [--dest <directory>] [--file <filename>] [--attachments-dir <name>] [--pattern <glob>] [--referenced-only] [--skip-attachments]
| Option | Default | Description |
|---|
--format | markdown | Content format for the exported file |
--dest | . | Base directory to export into |
--file | page.<ext> | Filename for the content file |
--attachments-dir | attachments | Subdirectory name for attachments |
--pattern | — | Glob filter for attachments (e.g. *.png) |
--referenced-only | false | Only download attachments referenced in the page content |
--skip-attachments | false | Do not download attachments |
confluence export 123456789 --format markdown --dest ./docs
confluence export 123456789 --format markdown --dest ./docs --skip-attachments
confluence export 123456789 --pattern "*.png" --dest ./output
Creates a subdirectory named after the page title under --dest.
attachments <pageId>
List or download attachments for a page.
confluence attachments <pageId> [--limit <n>] [--pattern <glob>] [--download] [--dest <directory>]
| Option | Default | Description |
|---|
--limit | all | Maximum number of attachments to fetch |
--pattern | — | Filter by filename glob (e.g. *.pdf) |
--download | false | Download matching attachments |
--dest | . | Directory to save downloads |
confluence attachments 123456789
confluence attachments 123456789 --pattern "*.pdf" --download --dest ./downloads
attachment-upload <pageId>
Upload one or more files to a page. --file can be repeated for multiple files.
confluence attachment-upload <pageId> --file <path> [--file <path> ...] [--comment <text>] [--replace] [--minor-edit]
| Option | Description |
|---|
--file | File to upload (required, repeatable) |
--comment | Comment for the attachment(s) |
--replace | Replace an existing attachment with the same filename |
--minor-edit | Mark the upload as a minor edit |
confluence attachment-upload 123456789 --file ./report.pdf
confluence attachment-upload 123456789 --file ./a.png --file ./b.png --replace
attachment-delete <pageId> <attachmentId>
Delete an attachment from a page.
confluence attachment-delete <pageId> <attachmentId> [--yes]
| Option | Description |
|---|
--yes | Skip confirmation prompt |
confluence attachment-delete 123456789 att-987 --yes
comments <pageId>
List comments for a page.
confluence comments <pageId> [--format text|markdown|json] [--limit <n>] [--start <n>] [--location inline,footer,resolved] [--depth all] [--all]
| Option | Default | Description |
|---|
--format | text | Output format: text, markdown, or json |
--limit | 25 | Maximum comments per page |
--start | 0 | Start index for pagination |
--location | — | Filter by location: inline, footer, resolved (comma-separated) |
--depth | — | Leave empty for root-only; all for all nested replies |
--all | false | Fetch all comments (ignores pagination) |
confluence comments 123456789
confluence comments 123456789 --format json --all
confluence comments 123456789 --location footer --depth all
comment <pageId>
Create a comment on a page (footer or inline).
confluence comment <pageId> [--content <string>] [--file <path>] [--format storage|html|markdown] [--parent <commentId>] [--location footer|inline] [--inline-selection <text>] [--inline-original-selection <text>] [--inline-marker-ref <ref>] [--inline-properties <json>]
| Option | Default | Description |
|---|
--content | — | Inline content string |
--file | — | Path to content file |
--format | storage | Content format |
--parent | — | Reply to a comment by ID |
--location | footer | footer or inline |
--inline-selection | — | Highlighted selection text (inline only) |
--inline-original-selection | — | Original selection text (inline only) |
--inline-marker-ref | — | Marker reference (inline only) |
--inline-properties | — | Full inline properties as JSON (advanced) |
Either --content or --file is required.
confluence comment 123456789 --content "Looks good!" --location footer
confluence comment 123456789 --content "See note" --parent 456 --location footer
Note on inline comments: Creating a brand-new inline comment requires editor highlight metadata (matchIndex, lastFetchTime, serializedHighlights) that is only available in the Confluence editor. This metadata is not accessible via the REST API, so inline comment creation will typically fail with a 400 error. Use --location footer or reply to an existing inline comment with --parent <commentId> instead.
comment-delete <commentId>
Delete a comment by its ID.
confluence comment-delete <commentId> [--yes]
| Option | Description |
|---|
--yes | Skip confirmation prompt |
confluence comment-delete 456789 --yes
copy-tree <sourcePageId> <targetParentId> [newTitle]
Copy a page and all its children to a new location.
confluence copy-tree <sourcePageId> <targetParentId> [newTitle] [--max-depth <depth>] [--exclude <patterns>] [--delay-ms <ms>] [--copy-suffix <suffix>] [--dry-run] [--fail-on-error] [--quiet]
| Option | Default | Description |
|---|
--max-depth | 10 | Maximum depth to copy |
--exclude | — | Comma-separated title patterns to exclude (supports wildcards) |
--delay-ms | 100 | Delay between sibling creations in ms |
--copy-suffix | " (Copy)" | Suffix appended to the root page title |
--dry-run | false | Preview operations without creating pages |
--fail-on-error | false | Exit with non-zero code if any page fails |
--quiet | false | Suppress progress output |
confluence copy-tree 123456789 987654321 --dry-run
confluence copy-tree 123456789 987654321 "Backup Copy"
confluence copy-tree 123456789 987654321 --exclude "Draft*,Archive*"
profile list
List all configuration profiles with the active profile marked.
confluence profile list
profile use <name>
Switch the active configuration profile.
confluence profile use <name>
confluence profile use staging
profile add <name>
Add a new configuration profile. Supports the same options as init (interactive, non-interactive, or hybrid).
confluence profile add <name> [--domain <domain>] [--api-path <path>] [--auth-type basic|bearer] [--email <email>] [--token <token>] [--protocol http|https] [--read-only]
Profile names may contain letters, numbers, hyphens, and underscores only.
confluence profile add staging --domain "staging.example.com" --auth-type bearer --token "xyz"
profile remove <name>
Remove a configuration profile (prompts for confirmation). Cannot remove the only remaining profile.
confluence profile remove <name>
confluence profile remove staging
stats
Show local usage statistics.
confluence stats
install-skill
Copy the Claude Code skill documentation into your project's .claude/skills/ directory so Claude Code can learn confluence-cli automatically.
confluence install-skill [--dest <directory>] [--yes]
| Option | Default | Description |
|---|
--dest | ./.claude/skills/confluence | Target directory |
--yes | false | Skip overwrite confirmation |
confluence install-skill
Common Agent Workflows
Read → Edit → Update (round-trip)
confluence edit 123456789 --output ./page.xml
confluence update 123456789 --file ./page.xml --format storage
Surgical edits on storage XML — safety rules
When scripting targeted replacements on a fetched page.xml:
-
Re-fetch immediately before every update. Pages get edited concurrently
(humans, other agent sessions). confluence edit prints the current version —
if any time passed since your fetch, fetch again and re-apply the edits on the
fresh copy; otherwise update silently clobbers the newer version.
-
Never anchor replacements on local-id attributes. The Confluence editor
normalizes or strips local-ids whenever a human edits the page, so id-based
anchors break without warning. Anchor on unique literal text instead.
-
Assert uniqueness per replacement so a drifted anchor fails loudly instead
of corrupting the page:
def rep(old, new):
global src
assert src.count(old) == 1, f"anchor drift: {old[:60]!r}"
src = src.replace(old, new, 1)
-
New elements you insert may omit local-id — Confluence assigns ids on save.
Build a documentation hierarchy
confluence create "Project Overview" MYSPACE --content "# Overview" --format markdown
confluence create-child "Architecture" 111222333 --content "# Architecture" --format markdown
confluence create-child "API Reference" 111222333 --file ./api.md --format markdown
confluence create-child "Runbooks" 111222333 --content "# Runbooks" --format markdown
Copy a full page tree
confluence copy-tree 123456789 987654321 --dry-run
confluence copy-tree 123456789 987654321 "Backup Copy"
Export a page for local editing
confluence export 123456789 --format markdown --dest ./local-docs
Process children as JSON
confluence children 123456789 --recursive --format json | jq '.[].id'
Search and process results
confluence search "release notes" --limit 20
Agent Tips
- Always use
--yes on destructive commands (delete, comment-delete, attachment-delete) to avoid interactive prompts blocking the agent.
- Prefer
--format markdown when creating or updating content from agent-generated text — it's the most natural format and the API converts it automatically.
- Use
--format json on children and comments for machine-parseable output.
- ANSI color codes: stdout may contain ANSI escape sequences. Pipe through
| cat or use NO_COLOR=1 if your downstream tool doesn't handle them.
- Page ID vs URL: when you have a Confluence URL, extract
?pageId=<number> and pass the number. Do not pass pretty/display URLs — they are not supported.
- Cross-space moves:
confluence move only works within the same space. Moving across spaces is not supported.
- Multiple instances: Use
--profile <name> or CONFLUENCE_PROFILE env var to target different Confluence instances without reconfiguring.
- Read-only mode: Set
CONFLUENCE_READ_ONLY=true or use --read-only when creating profiles to prevent accidental writes. This is enforced at the CLI level — all write commands will be blocked.
Error Patterns
| Error | Cause | Fix |
|---|
No configuration found | No config file and no env vars set | Set env vars or run confluence init |
Cross-space moves are not supported | move used across spaces | Copy with copy-tree instead |
| 400 on inline comment creation | Editor metadata required | Use --location footer or reply to existing inline comment with --parent |
File not found: <path> | --file path doesn't exist | Check the path before calling the command |
At least one of --title, --file, or --content must be provided | update called with no content options | Provide at least one of the required options |
Profile "<name>" not found! | Specified profile doesn't exist | Run confluence profile list to see available profiles |
Cannot delete the only remaining profile. | Tried to remove the last profile | Add another profile before removing |
This profile is in read-only mode | Write command used with a read-only profile | Use a writable profile or remove readOnly from config |
Behavior Scenarios
Scenario 1: Read a Confluence page
Given confluence-cli is installed and configured
When the user asks to read a Confluence page (by ID or URL)
Then run `confluence read <pageId> --format markdown`
And present the page content
Scenario 2: Search Confluence
Given confluence-cli is installed and configured
When the user asks to search Confluence for a term
Then run `confluence search "<term>" --limit 10`
And present matching pages with titles and IDs
Scenario 3: Create or update a page
Given confluence-cli is installed and configured
When the user asks to create or update a Confluence page
Then prefer `--format markdown` for agent-generated content
And use `--file` for larger content (write to a temp file first)
And report the page ID and URL on success
Scenario 4: Export a page tree
Given confluence-cli is installed and configured
When the user asks to export a Confluence page
Then run `confluence export <pageId> --format markdown --dest <directory>`
And report the exported files and attachment count
Scenario 5: confluence-cli not installed
Given confluence-cli is not installed or not configured
When the user asks to perform any Confluence CLI operation
Then check with `confluence --version`
And guide the user to install: `npm install -g confluence-cli`
And guide config setup: `confluence init` or set env vars
Scenario 6: Multi-instance operation
Given the user works with multiple Confluence instances
When the user specifies an instance or profile
Then use the `--profile <name>` flag on the command
And if no profile exists, guide setup with `confluence profile add <name>`