A lightweight Go CLI built for use with Claude Code to view and edit Confluence pages efficiently — no dependencies beyond the Go standard library.
Give Claude direct access to your Confluence content: fetch pages as Markdown, search with CQL, and push edits back — all from within a Claude Code session.
# Install directly with Go
go install github.com/garykww/confluence-cli/cmd/confluence-cli@latestOr clone and build from source:
git clone git@github.com:garykww/confluence-cli.git
cd confluence-cli
make buildSet credentials (one-time):
confluence-cli config-set -base-url https://garykww.atlassian.net -email your.name@example.com -token your_tokenThen run:
confluence-cli list-spaces -limit 5confluence-cli uses Atlassian API tokens for Basic authentication — your Atlassian account password will not work.
- Log in to https://id.atlassian.com/manage-profile/security/api-tokens
- Click Create API token
- Give it a label (e.g.
confluence-cli) and click Create - Copy the token — it is only shown once
The recommended approach is the config-set subcommand, which writes credentials to ~/.confluence-cli:
confluence-cli config-set \
-base-url https://garykww.atlassian.net \
-email your.name@example.com \
-token your_token_hereAlternatively, export environment variables in your shell profile:
# Add to ~/.zshrc or ~/.bashrc
export CONFLUENCE_BASE_URL=https://garykww.atlassian.net
export CONFLUENCE_EMAIL=your.name@example.com
export CONFLUENCE_API_TOKEN=your_token_hereEnvironment variables take precedence over the config file when both are set.
confluence-cli list-spaces -limit 3 -humanIf you see a list of spaces, authentication is working. A 401 error means the token or email is wrong.
Security note: Never commit your API token to source control. Use a password manager or your OS keychain to store it securely.
| Source | Precedence | Notes |
|---|---|---|
| Environment variable | Higher | Takes precedence over the config file |
~/.confluence-cli |
Lower | Written by config-set; KEY=VALUE format |
| Variable | Description | Required |
|---|---|---|
CONFLUENCE_BASE_URL |
Base URL, e.g. https://garykww.atlassian.net |
Yes |
CONFLUENCE_EMAIL |
Your Atlassian account email | Yes |
CONFLUENCE_API_TOKEN |
Atlassian API token (not your password) | Yes |
CONFLUENCE_TIMEOUT |
HTTP timeout, e.g. 60s (default: 30s, env only) |
No |
The to-storage subcommand is offline-only and requires none of them.
| Subcommand | Description |
|---|---|
config-set |
Write credentials to ~/.confluence-cli |
get-page |
Fetch a page by ID or full URL |
create-page |
Create a new page from a Markdown file (or stdin) |
update-page |
Update a page from a Markdown file (or stdin) |
search |
Search pages using a CQL query |
get-space |
Get space details by key |
list-spaces |
List available spaces |
get-children |
List child pages of a parent page |
list-attachments |
List attachments on a page |
upload-attachment |
Upload a local file as a page attachment |
to-storage |
Convert Markdown to Confluence storage format XHTML (offline) |
version |
Print version information |
Run confluence-cli <subcommand> -h for flag details on any subcommand.
Write credentials to ~/.confluence-cli so you don't need to set environment variables manually.
Flags:
-base-url string Confluence base URL (required)
-email string Atlassian account email (required)
-token string Atlassian API token (required)
confluence-cli config-set -base-url https://garykww.atlassian.net -email me@example.com -token TOKENFetch a single page. Default output is Markdown with YAML frontmatter (suitable for piping into update-page).
Flags:
-id string Page ID (also accepted as -page-id)
-url string Full Confluence page URL (ID extracted automatically)
-expand string Comma-separated expand fields (default: space,history,body.storage,body.view,version,ancestors)
-human Human-readable summary (title, space, version, body)
-json Full JSON response from the Confluence API
# Markdown output (default) — includes frontmatter with id, title, space, version
confluence-cli get-page -id 131166
# Also accepted by LLM agents
confluence-cli get-page -page-id 131166
# Human-readable summary
confluence-cli get-page -id 131166 -human
# Full API JSON
confluence-cli get-page -id 131166 -json
# Extract page ID from a URL automatically
confluence-cli get-page -url "https://garykww.atlassian.net/wiki/spaces/TEST/pages/131166"Create a new Confluence page from a Markdown file or stdin.
Flags:
-file string Markdown file with optional frontmatter (reads stdin if omitted)
-title string Page title (overrides frontmatter)
-space string Space key (overrides frontmatter)
-parent string Parent page ID — creates page as a child (overrides frontmatter parent_id)
# From a file with frontmatter
confluence-cli create-page -file new-page.md
# Inline flags
confluence-cli create-page -title "My New Page" -space TEST -parent 131166 -file content.md
# From stdin
echo "# Hello\n\nContent here." | confluence-cli create-page -title "Hello" -space TESTFrontmatter format:
---
title: "My New Page"
space: "TEST"
parent_id: "131166"
---
Page content here...Search pages using CQL (Confluence Query Language).
Flags:
-cql string CQL query string (required)
-limit int Max results (default: 10)
-start int Pagination offset (default: 0)
-human Human-readable table instead of JSON
# Search in a specific space
confluence-cli search -cql 'type=page AND space=TEST' -limit 5
# Search by title keyword
confluence-cli search -cql 'type=page AND title~"deployment"' -human
# Pages modified in the last 7 days
confluence-cli search -cql 'type=page AND lastModified >= now("-7d")' -limit 20
# Paginate through results
confluence-cli search -cql 'type=page AND space=TEST' -limit 10 -start 10Flags:
-key string Space key (required)
-human Human-readable output instead of JSON
confluence-cli get-space -key TEST
confluence-cli get-space -key TEST -humanFlags:
-limit int Max spaces to return (default: 10)
-start int Pagination offset (default: 0)
-human Human-readable table instead of JSON
confluence-cli list-spaces -limit 20 -humanFlags:
-id string Parent page ID (required; also accepted as -page-id)
-limit int Max child pages (default: 25)
-human Human-readable table instead of JSON
confluence-cli get-children -id 131166 -human
confluence-cli get-children -page-id 131166 -humanUpdate an existing Confluence page from a Markdown file. The file must contain YAML frontmatter with id and version fields (both are emitted by get-page automatically).
Flags:
-file string Markdown file to read (reads stdin if omitted)
-title string Override the page title from frontmatter
The version is auto-incremented — pass the current version number, not current + 1.
If the version is stale (someone else edited the page), a conflict error is returned with a hint to re-fetch.
# Edit-in-place roundtrip
confluence-cli get-page -id 131166 > page.md
vim page.md
confluence-cli update-page -file page.mdFrontmatter format (produced by get-page):
---
id: "131166"
title: "My Page Title"
space: "TEST"
version: 12
---
Your Markdown content here...Flags:
-id string Page ID (required; also accepted as -page-id)
-url string Full Confluence page URL (ID extracted automatically)
-limit int Max attachments to return (default: 25)
-human Human-readable output instead of JSON
confluence-cli list-attachments -id 131166 -humanUpload a local file as an attachment to a Confluence page.
Flags:
-id string Target page ID (required; also accepted as -page-id)
-url string Full Confluence page URL (ID extracted automatically)
-file string Local file to upload (required)
-human Human-readable output instead of JSON
confluence-cli upload-attachment -id 131166 -file diagram.pngOffline conversion from Markdown to Confluence storage format XHTML. No network calls, no credentials required.
Flags:
-file string Read Markdown from file instead of stdin
# From stdin
echo "# Hello\n\nSome **bold** text." | confluence-cli to-storage
# From file
confluence-cli to-storage -file page.md
# Preview what update-page would send
confluence-cli get-page -id 131166 | confluence-cli to-storageSupported Markdown features:
| Markdown | Confluence Storage Output |
|---|---|
# H1 – ###### H6 |
<h1> – <h6> |
**bold** |
<strong> |
*italic* |
<em> |
`code` |
<code> |
~~strike~~ |
<del> |
[text](url) |
<a href="..."> |
 |
<ac:image><ri:url .../> |
 |
<ac:image><ri:attachment .../> |
```lang code block |
ac:structured-macro code macro |
- item / 1. item |
<ul> / <ol> |
| table | |
<table> with <thead> / <tbody> |
--- |
<hr /> |
> quote |
<blockquote> |
> **Info:** text |
ac:structured-macro info macro |
> **Note:** text |
ac:structured-macro note macro |
> **Warning:** text |
ac:structured-macro warning macro |
> **Tip:** text |
ac:structured-macro tip macro |
# 1. Fetch the page as Markdown (frontmatter carries id + version)
confluence-cli get-page -id 131166 > my-page.md
# 2. Edit in your favourite editor
vim my-page.md
# 3. Push the update back — version is auto-incremented
confluence-cli update-page -file my-page.md
# → Updated "My Page Title" (id:131166) to version 13To let Claude read and edit Confluence pages during a session, add this to your CLAUDE.md. Claude will use the CLI via Bash to fetch, search, and update pages without any manual steps.
- **Confluence**: Use the CLI (`<path-to>/confluence-cli`) via Bash to view and edit pages — fetch with `get-page`, search with `search`, create pages with `create-page`, push changes with `update-page`, and manage attachments with `list-attachments` / `upload-attachment`.make test
# Verbose
go test -v ./...
# Specific test
go test -run TestMarkdownToStorage ./internal/confluence/# Current platform
make build
# All platforms (output in dist/)
make build-allmake lintconfluence-cli/
├── cmd/
│ └── confluence-cli/
│ ├── main.go # Entry point, subcommand dispatch, config loading
│ ├── main_test.go # Config loading tests
│ └── output.go # Terminal formatters (JSON, human-readable, Markdown)
├── internal/
│ └── confluence/
│ ├── client.go # HTTP client, auth, all Confluence API methods and types
│ ├── client_test.go # Client and URL extraction tests
│ ├── convert.go # HTML ↔ Markdown / Markdown → Storage converters
│ └── convert_test.go # Conversion tests
├── .github/
│ └── workflows/
│ └── ci.yml # CI: test, lint, cross-platform build, release
├── .gitignore
├── .golangci.yml # Linter configuration
├── .goreleaser.yaml # Release configuration
├── go.mod
└── Makefile