- Go 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .github | ||
| cmd/confluence-mcp | ||
| internal | ||
| .gitignore | ||
| .golangci.yml | ||
| .goreleaser.yaml | ||
| CHANGELOG.md | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| README.md | ||
| Taskfile.yml | ||
confluence-mcp
A Model Context Protocol server that exposes
Confluence Cloud tools to MCP clients (such
as Claude, VS Code, or any MCP-compatible host). Built with the official
github.com/modelcontextprotocol/go-sdk.
Supports stdio and streamable HTTP transports, and a readonly / readwrite mode switch so you can control whether write operations are exposed.
Installation
Download the latest release for your platform from the Releases page.
Quick start
# Set required environment variables
export CONFLUENCE_BASE_URL=https://your-domain.atlassian.net
export CONFLUENCE_EMAIL=you@example.com
export CONFLUENCE_API_TOKEN=your-api-token
# Run in readonly mode over stdio (safe for exploration)
go run ./cmd/confluence-mcp --mode=readonly --transport=stdio
Generate an API token at Atlassian account settings.
Configuration
All settings can be provided via environment variables or CLI flags. Flags take precedence over environment variables.
| Environment variable | CLI flag | Default | Description |
|---|---|---|---|
CONFLUENCE_BASE_URL |
--confluence-base-url |
(required) | Confluence Cloud base URL, e.g. https://your-domain.atlassian.net |
CONFLUENCE_EMAIL |
--confluence-email |
(required) | Confluence account email (used for Basic auth) |
CONFLUENCE_API_TOKEN |
--confluence-api-token |
(required) | Confluence API token |
CONFLUENCE_MODE |
--mode |
readonly |
readonly or readwrite |
MCP_TRANSPORT |
--transport |
stdio |
stdio or http |
MCP_HTTP_ADDR |
--http-addr |
127.0.0.1:8080 |
Listen address when --transport=http |
MCP_ALLOWED_ORIGINS |
--allowed-origins |
(empty) | Comma-separated browser origins allowed to call the HTTP transport |
Run confluence-mcp --version to print the build version.
Tools
Read-only tools (always available)
| Tool | Description |
|---|---|
confluence_get_page |
Get a single Confluence page by ID |
confluence_search_pages |
Search Confluence pages with filters and pagination |
confluence_get_page_children |
List direct child content of a page |
confluence_get_page_ancestors |
List a page's ancestors, from the root downwards |
confluence_list_page_versions |
List a page's version history |
confluence_get_space_pages |
List the pages in a space |
confluence_search_cql |
Search Confluence content with CQL |
confluence_get_space |
Get a single Confluence space by key or ID |
confluence_list_spaces |
List Confluence spaces with filters and pagination |
confluence_get_page_labels |
Get labels attached to a Confluence page |
confluence_list_page_comments |
List footer or inline comments on a page |
confluence_get_comment |
Get a footer or inline comment by ID |
confluence_list_comment_children |
List replies to a footer or inline comment |
confluence_get_page_attachments |
Get attachments on a Confluence page |
confluence_get_attachment |
Get attachment metadata by ID |
confluence_download_attachment |
Download a Confluence attachment's content (base64-encoded) |
Write tools (only in readwrite mode)
| Tool | Description |
|---|---|
confluence_create_page |
Create a new Confluence page |
confluence_update_page |
Update title and/or content of a page |
confluence_delete_page |
Delete a Confluence page |
confluence_add_page_label |
Add a label to a Confluence page |
confluence_remove_page_label |
Remove a label from a Confluence page |
confluence_create_footer_comment |
Create a footer comment or reply |
confluence_update_footer_comment |
Update the body of a footer comment |
confluence_delete_footer_comment |
Delete a footer comment |
confluence_upload_attachment |
Upload a file attachment to a page |
confluence_delete_attachment |
Delete a Confluence attachment |
The default mode is readonly. Set CONFLUENCE_MODE=readwrite (or
--mode=readwrite) explicitly to enable write tools.
Page and comment content uses Confluence storage format
(XHTML) by default, or Atlas Document Format (ADF). For write tools, set
body_type to plain_text to have text safely escaped and converted to storage
format, storage for XHTML, or atlas_doc_format for ADF JSON. Markdown is not a
supported write format. XHTML syntax and the ADF document root (type: "doc",
version: 1, and a content array) are validated before sending a write;
Confluence validates supported elements, macros, and ADF nodes.
Read tools return a best-effort plain text content summary. confluence_get_page
and confluence_get_comment also return the original raw_content and its
body_format, defaulting to storage. Use raw_content for editing: the plain
text summary loses tables, macros, links, and attachment references. view is
rendered HTML for reading and cannot be used as a write format.
Writing and editing articles
Enable readwrite mode, then resolve a space ID with confluence_get_space if
you only have a space key. confluence_create_page publishes immediately and
returns the new page ID and version. For example:
{
"space_id": "123",
"title": "Release guide",
"parent_id": "456",
"body_type": "storage",
"content": "<h1>Release guide</h1><p>Check the <strong>release notes</strong>.</p>"
}
For existing articles:
- Call
confluence_get_pagewithpage_idandbody_format: "storage"(or"atlas_doc_format"for ADF). - Edit
raw_content, keeping the surrounding markup and content you intend to retain. - Call
confluence_update_pagewith the complete edited body ascontent, the same format asbody_type, and the currentversionreturned by the read. The server increments the version for Confluence. Omittitleto keep it. - Read the page again to verify the saved content and version.
For example, if the read returned version 3:
{
"page_id": "789",
"version": 3,
"version_note": "Clarify release steps",
"body_type": "storage",
"content": "<h1>Release guide</h1><p>Review the release notes before publishing.</p>"
}
Content updates replace the entire body. An explicit empty content string
clears the body; omitting it leaves the body unchanged. A title-only rename
uses the dedicated title endpoint and accepts just page_id and title.
To use version or version_note when renaming, also supply the unchanged
raw_content and its format in a versioned content update.
On a version conflict, retrieve the latest page, merge your changes, and submit that version. The server does not retry writes automatically. If a request times out or returns an unusable response, inspect Confluence before retrying: the write may already have succeeded.
For plain text, body_type: "plain_text" escapes special characters and converts
blank lines to paragraphs, including Windows CRLF line endings. For rich storage
content, use Confluence XHTML, including ac: macros, ri: attachment references,
and CDATA for code macro bodies. See the storage format reference
and page API.
Transports
stdio
The default transport. The server communicates over stdin/stdout using newline-delimited JSON (the standard MCP transport for subprocess-based tools).
confluence-mcp --transport=stdio
HTTP (streamable)
The server exposes a streamable HTTP endpoint on the configured address.
confluence-mcp --transport=http --http-addr=127.0.0.1:8080
The HTTP transport has no built-in authentication. It binds to loopback by
default, and browser requests are rejected unless the Origin header is a
loopback origin or is listed in MCP_ALLOWED_ORIGINS, which guards against DNS
rebinding attacks. Requests without an Origin header (ordinary non-browser MCP
clients) are unaffected.
If you bind to a non-loopback address, secure it at the network or deployment
layer (authenticating reverse proxy, firewall) to prevent unauthorized access,
especially in readwrite mode.
confluence-mcp --transport=http --allowed-origins=https://mcp.example.com
Limits
- Tool
limitparameters default to 25 and are clamped to Confluence's maximum of 250. - Page-version requests that include
body_formatare clamped to Confluence's lower maximum of 50. - CQL searches expanding
body.export_vieworbody.styled_vieware clamped to Confluence's maximum of 25. - API responses are capped at 4 MiB.
- Attachment downloads larger than 8 MiB are rejected rather than base64-encoded into a tool result.
Authentication
The server authenticates to Confluence Cloud using HTTP Basic auth with your Confluence account email as the username and an API token as the password.
Required token permissions
Atlassian API tokens do not grant more access than the Atlassian account has. Use a dedicated account with the smallest Confluence space permissions needed for the tools you expose.
You can use either:
- A classic/unscoped API token with
CONFLUENCE_BASE_URLset to your site URL, e.g.https://your-domain.atlassian.net. - A scoped API token. Scoped tokens must call the Atlassian API gateway, e.g.
CONFLUENCE_BASE_URL=https://api.atlassian.com/ex/confluence/{cloudId}.
For scoped tokens, grant these Confluence scopes:
| Mode | Token scopes | Confluence permissions the account still needs |
|---|---|---|
readonly |
read:page:confluence, read:space:confluence, read:attachment:confluence, read:comment:confluence, read:content-details:confluence, read:content.metadata:confluence, read:hierarchical-content:confluence |
Confluence product access (Can use) and view permission for the spaces/pages/comments/attachments to read. Page restrictions still apply. |
readwrite |
All readonly scopes, plus write:page:confluence, read:label:confluence, write:label:confluence, write:attachment:confluence, write:comment:confluence, delete:page:confluence, delete:attachment:confluence, delete:comment:confluence |
The readonly permissions, plus only the space permissions required by the write tools you use: add/update/delete pages, add/remove labels, add attachments, add/update/delete comments, and/or delete attachments. |
confluence-mcp does not need Confluence admin scopes or space-management
scopes because it does not create spaces or change space settings.
Development
Requirements
- Go 1.27.1+
Build
go build ./...
Test
go test ./...
Tests cover:
- Config loading, validation, and flag/env precedence
- Confluence REST API client against
httptest.Servermocks for pages, spaces, labels, comments, CQL search, and attachments (success, error mapping, response size limits, multipart attachment uploads) - Tool handler input mapping, limit clamping, and result summarization
- Mode-gated tool registration (
readonlyexcludes write tools) - HTTP transport origin validation
- Article lifecycle tests through the official SDK client over stdio (a server subprocess) and streamable HTTP: creation, exact rich-body readback, updates, renames, version notes, label addition, conflicts, and explicit body clearing
Tests use local Confluence API fixtures; they do not publish to a live tenant. The live service may normalize markup or apply tenant-specific macro and editor rules, so use the readback step to verify published articles.
MCP client configuration
Claude Desktop (stdio)
{
"mcpServers": {
"confluence": {
"command": "confluence-mcp",
"args": [],
"env": {
"CONFLUENCE_BASE_URL": "https://your-domain.atlassian.net",
"CONFLUENCE_EMAIL": "you@example.com",
"CONFLUENCE_API_TOKEN": "your-api-token",
"CONFLUENCE_MODE": "readonly"
}
}
}
}
VS Code / GitHub Copilot (stdio)
Add to .vscode/mcp.json (or your user-level mcp.json):
{
"servers": {
"confluence": {
"command": "confluence-mcp",
"args": [],
"env": {
"CONFLUENCE_BASE_URL": "https://your-domain.atlassian.net",
"CONFLUENCE_EMAIL": "you@example.com",
"CONFLUENCE_API_TOKEN": "your-api-token",
"CONFLUENCE_MODE": "readonly"
}
}
}
}
API Coverage
This server primarily uses the Confluence Cloud REST API v2. CQL search, attachment upload/download, and label addition/removal use Confluence REST API v1 endpoints because those operations are not exposed by v2. The server covers a core subset focused on pages, spaces, labels, comments, attachments, page history, and CQL search.
Not currently supported:
- Blog posts
- Content properties
- Space permissions
- User management
License
MIT
Related Projects
- jira-mcp - MCP server for Jira Cloud
- Model Context Protocol
- MCP Go SDK