Skip to main content
Glama

confluence-adf-mcp

License: MIT

MCP server for reading and writing Confluence pages in native ADF (Atlassian Document Format).

Why this exists

Confluence stores pages in ADF (Atlassian Document Format), a structured JSON format. Most tools convert to/from HTML or plain text, losing structure, formatting, and metadata in the process. This MCP server works with ADF directly, so edits are precise — find/replace, table updates, and mention swaps happen at the document node level without corrupting the surrounding content.

Related MCP server: MCP Atlassian Node Server

Setup

Requirements

  • Python 3.12+

  • A Confluence Cloud instance with API access

Environment variables

export CONFLUENCE_URL="https://your-domain.atlassian.net/wiki"
export CONFLUENCE_USERNAME="you@example.com"
export CONFLUENCE_API_TOKEN="your-api-token"

Generate an API token at https://id.atlassian.com/manage-profile/security/api-tokens.

OAuth 2.0 (optional)

Instead of basic auth, you can use OAuth 2.0 (3LO). Set these three environment variables:

export CONFLUENCE_OAUTH_CLIENT_ID="your-oauth-client-id"
export CONFLUENCE_OAUTH_CLIENT_SECRET="your-oauth-client-secret"
export CONFLUENCE_OAUTH_REFRESH_TOKEN="your-initial-refresh-token"

If all three are set, the server uses OAuth automatically; otherwise it falls back to basic auth (CONFLUENCE_USERNAME / CONFLUENCE_API_TOKEN).

Rotating refresh tokens are persisted to .oauth_tokens.json in the cache directory so the server can restart without re-authorizing. The cache directory defaults to $XDG_CACHE_HOME/confluence-adf-mcp (or ~/.cache/confluence-adf-mcp); set CACHE_DIR to override it.

See Atlassian OAuth 2.0 (3LO) documentation for how to create an OAuth app and obtain the initial refresh token.

Claude Code configuration

Copy .env.example to .env and fill in your credentials. The server loads .env automatically.

Add to .claude/settings.json:

{
  "mcpServers": {
    "confluence-adf": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/karbassi/confluence-adf-mcp", "confluence-adf-mcp"]
    }
  }
}

Shared HTTP server

By default every client starts its own stdio process. To run one long-lived server that many clients share:

CONFLUENCE_ADF_MCP_TRANSPORT=http CONFLUENCE_ADF_MCP_PORT=8506 confluence-adf-mcp
{
  "mcpServers": {
    "confluence-adf": { "type": "http", "url": "http://127.0.0.1:8506/mcp" }
  }
}

Variable

Default

Description

CONFLUENCE_ADF_MCP_TRANSPORT

stdio

stdio or http (streamable HTTP at /mcp)

CONFLUENCE_ADF_MCP_HOST

127.0.0.1

Bind address. Only 127.0.0.1, localhost, or ::1; anything else exits

CONFLUENCE_ADF_MCP_PORT

8506

TCP port

CONFLUENCE_ADF_MCP_ALLOWED_HOSTS

Extra comma-separated Host header values to accept, e.g. a reverse proxy's mcp.example.com

CONFLUENCE_ADF_MCP_ALLOWED_ORIGINS

Extra comma-separated Origin values to accept, e.g. https://mcp.example.com

FASTMCP_HOST / FASTMCP_PORT have no effect; use the variables above.

The endpoint has no authentication. It holds your Atlassian credentials, and its tools can edit, move, archive, and restrict pages and delete attachments. Anything that can connect to it acts as you. So:

  • The server only binds to loopback. Any local process can still connect, so only use HTTP mode on a machine where every local user and process is trusted with your Atlassian account.

  • DNS-rebinding protection is always on: requests whose Host is not 127.0.0.1:<port>, localhost:<port> (or an entry in CONFLUENCE_ADF_MCP_ALLOWED_HOSTS) are rejected with 421, and cross-site Origins with 403. That check only stops web pages from reaching the server through a rebound DNS name. It does not authenticate anyone.

  • To reach it from another machine, put it behind a reverse proxy that controls who can connect (bearer token, mTLS, an IP allowlist on a private network, or similar) and add the proxy's hostname to CONFLUENCE_ADF_MCP_ALLOWED_HOSTS. Never expose the port or the proxy publicly without access control.

File paths always refer to the filesystem of the machine running the server, not the client's:

  • confluence_get_page returns the absolute path of the cached copy to edit. A remote client can't open it, so use the edit tools (confluence_edit_page, confluence_find_replace, ...) instead of editing the file directly.

  • confluence_upload_attachment reads, and confluence_download_attachment writes, paths on the server machine.

Each MCP session gets its own page cache under <cache dir>/sessions/<session>/, so clients sharing one server can't see, overwrite, or clear each other's cached pages. If a client reconnects it gets a new session, so call confluence_get_page again before editing. Session directories untouched for CONFLUENCE_ADF_MCP_CACHE_TTL_HOURS (default 168, i.e. 7 days; 0 disables) are deleted at startup and at most hourly while the server runs.

Tools

Pages

Tool

Description

confluence_get_page

Fetch a page and cache it locally

confluence_create_page

Create a new page with ADF content

confluence_push_page

Push cached page edits to Confluence

confluence_extract_text

Extract plain text from a page

confluence_copy_page

Duplicate a page

confluence_archive_page

Archive a page (with confirmation)

confluence_move_page

Move a page to a new parent (with confirmation)

confluence_revert_page

Revert a page to a previous version

Editing

Tool

Description

confluence_edit_page

Find/replace text in cached page

confluence_find_replace

Fetch, find/replace, and push in one step

confluence_regex_replace

Regex find/replace on a page

confluence_replace_mention

Swap @mentions between users

confluence_add_link

Add a hyperlink to a page

Tables

Tool

Description

confluence_update_table_cell

Update a single table cell

confluence_insert_table_row

Insert a row into a table

confluence_delete_table_row

Delete a row from a table

Tasks

Tool

Description

confluence_update_task

Toggle task checkbox state (DONE/TODO)

Discovery

Tool

Description

confluence_search_pages

Search pages with CQL

confluence_list_pages

List pages in a space

confluence_get_child_pages

Get child pages

confluence_get_ancestors

Get parent chain

confluence_list_spaces

List spaces

confluence_get_contributors

Get unique page contributors

confluence_get_user

Resolve account ID to display name

Labels

Tool

Description

confluence_get_labels

Get labels on a page

confluence_add_labels

Add labels to a page

confluence_remove_label

Remove a label from a page

Versions

Tool

Description

confluence_list_versions

List version history

confluence_compare_versions

Diff two versions as text

Comments

Tool

Description

confluence_add_comment

Add a footer comment

confluence_list_comments

List footer comments

confluence_add_inline_comment

Add an inline annotation comment

confluence_list_inline_comments

List inline comments

Attachments

Tool

Description

confluence_list_attachments

List attachments on a page

confluence_upload_attachment

Upload a file as an attachment

confluence_download_attachment

Download an attachment to a local file

confluence_delete_attachment

Delete an attachment (with confirmation)

Properties

Tool

Description

confluence_get_page_properties

Get content properties

confluence_set_page_property

Set a content property

Access Control

Tool

Description

confluence_set_restrictions

Set read/update restrictions

confluence_watch_page

Watch or unwatch a page

Cache

Tool

Description

confluence_list_cache

List locally cached pages

confluence_clear_cache

Clear page cache

Contributing

See CONTRIBUTING.md.

Available Tools

43 tools
confluence_add_commentA

Add a footer comment to a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    body: The comment text (plain text, converted to simple ADF paragraph).
    parent_comment_id: Optional parent comment ID for threaded replies.

Inputs: body (required), page_id (required), parent_comment_id.

confluence_add_inline_commentA

Add an inline (annotation) comment anchored to specific text on a page.

The comment is attached to the first (or Nth) occurrence of text_selection
found in the page body.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    body: The comment text (plain text, converted to ADF paragraph).
    text_selection: The exact text on the page to attach the comment to.
    match_index: Which occurrence to annotate (0-based, default 0 = first match).

Inputs: body (required), page_id (required), text_selection (required), match_index.

confluence_add_labelsA

Add labels to a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    labels: List of label names to add, e.g. ["important", "reviewed"].

Inputs: labels (required), page_id (required).

confluence_archive_pageA

Archive a Confluence page.

DESTRUCTIVE: This removes the page from active view. By default this tool
runs in preview mode — call with confirm=True to actually archive.

You MUST show the preview to the user and get their explicit approval before
calling again with confirm=True.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    confirm: Must be True to actually archive. False (default) shows a preview.

Inputs: page_id (required), confirm.

confluence_clear_cacheA

Clear the local page cache.

Removes cached page data. Pass a page_id to clear a specific page,
or omit it to clear all cached pages.

Args:
    page_id: Optional page ID to clear. Empty clears all cached pages.

Inputs: page_id.

confluence_compare_versionsA

Compare two versions of a Confluence page as a unified text diff.

Fetches the ADF for both versions, extracts plaintext, and produces a
unified diff showing what changed.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    version_a: The "before" version number.
    version_b: The "after" version number.

Inputs: page_id (required), version_a (required), version_b (required).

confluence_copy_pageA

Copy a Confluence page.

Creates a duplicate of the page, optionally under a different parent.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    title: Title for the copy. Defaults to "Copy of {original title}".
    destination_parent_id: Parent page ID for the copy. Empty = same parent.
    copy_labels: Whether to copy labels (default True).
    copy_attachments: Whether to copy attachments (default True).

Inputs: page_id (required), title, copy_labels, copy_attachments, +1 more.

confluence_create_pageA

Create a new Confluence page with ADF content.

Args:
    space_id: The space ID to create the page in.
    title: The page title.
    adf_body: The full ADF document as a JSON string, e.g. {"type": "doc", "version": 1, "content": [...]}.
    parent_id: Optional parent page ID to nest under.

Inputs: title (required), adf_body (required), space_id (required), parent_id.

confluence_delete_attachmentA

Delete an attachment from a Confluence page.

DESTRUCTIVE: This permanently removes the attachment. By default this tool
runs in preview mode — call with confirm=True to actually delete.

You MUST show the preview to the user and get their explicit approval before
calling again with confirm=True.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    attachment_title: The filename of the attachment to delete.
    confirm: Must be True to actually delete. False (default) shows a preview.

Inputs: page_id (required), attachment_title (required), confirm.

confluence_delete_table_rowA

Delete a row from a table on a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    row_index: Zero-based row index to delete.
    table_index: Which table on the page (0-based, default first table).

Inputs: page_id (required), row_index (required), table_index.

confluence_download_attachmentA

Download an attachment from a Confluence page to a local file.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    attachment_title: The filename of the attachment to download (e.g. "report.pdf").
    save_path: Local file path to save the downloaded file.

Inputs: page_id (required), save_path (required), attachment_title (required).

confluence_edit_pageA

Find and replace text in a cached Confluence page.

Operates on the local cache file. Call confluence_get_page first to cache the page,
then use this to make edits, then confluence_push_page to publish.

Args:
    page_id: The page ID to edit.
    find: The text to find in the page content.
    replace: The text to replace it with.
    replace_all: If true, replace all occurrences. If false, replace only the first.

Inputs: find (required), page_id (required), replace (required), replace_all.

confluence_extract_textA

Extract plain text content from a Confluence page.

Fetches the page ADF and converts it to readable plaintext with basic
formatting (paragraphs, bullet lists, tables, code blocks, etc.).

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).

Inputs: page_id (required).

confluence_find_replaceA

Fetch a Confluence page, find and replace text, and push the result in one step.

Combines get_page + edit_page + push_page into a single call. Only replaces
within text content nodes — structural ADF elements are never modified.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    find: The text to find in the page content.
    replace: The text to replace it with.
    replace_all: If true, replace all occurrences. If false, replace only the first.
    version_message: Optional message describing the change.

Inputs: find (required), page_id (required), replace (required), replace_all, +1 more.

confluence_get_ancestorsA

Get the ancestor (parent) chain of a Confluence page.

Returns the page hierarchy from the space root down to the immediate parent.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).

Inputs: page_id (required).

confluence_get_child_pagesA

Get child pages of a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    limit: Maximum number of children to return (default 25, max 250).
    cursor: Pagination cursor from a previous result.

Inputs: page_id (required), limit, cursor.

confluence_get_contributorsA

Get unique contributors to a Confluence page from its version history.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).

Inputs: page_id (required).

confluence_get_labelsA

Get all labels on a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).

Inputs: page_id (required).

confluence_get_pageA

Fetch a Confluence page and cache it locally for editing.

Returns the page metadata and the local cache file path. Edit the cached file
directly, then call confluence_push_page to publish your changes.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).

Inputs: page_id (required).

confluence_get_page_propertiesC

Get content properties on a Confluence page.

Content properties are key-value metadata pairs stored on pages.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    limit: Maximum number of properties to return (default 25, max 100).

Inputs: page_id (required), limit.

confluence_get_userA

Get user details by account ID.

Resolves an account ID (as seen in version history, comments, etc.)
to a display name, email, and profile info.

Args:
    account_id: The Confluence/Atlassian account ID.

Inputs: account_id (required).

confluence_insert_table_rowA

Insert a new row into a table on a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    row_index: Position to insert at (0-based). Use -1 to append at the end.
    values: List of cell values for the new row.
    table_index: Which table on the page (0-based, default first table).

Inputs: values (required), page_id (required), row_index (required), table_index.

confluence_list_attachmentsA

List attachments on a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    limit: Maximum number of attachments to return (default 25, max 100).
    cursor: Pagination cursor from a previous result.

Inputs: page_id (required), limit, cursor.

confluence_list_cacheA

List all locally cached Confluence pages.

Shows page IDs, titles, and when they were last cached.

Inputs: no named parameters.

confluence_list_commentsA

List footer comments on a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    limit: Maximum number of comments to return (default 25, max 100).
    cursor: Pagination cursor from a previous result.

Inputs: page_id (required), limit, cursor.

confluence_list_inline_commentsA

List inline (annotation) comments on a Confluence page.

These are comments anchored to specific text selections, as opposed to
footer comments which appear at the bottom of the page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    limit: Maximum number of comments to return (default 25, max 100).
    cursor: Pagination cursor from a previous result.

Inputs: page_id (required), limit, cursor.

confluence_list_pagesB

List pages in a Confluence space.

Args:
    space_id: The numeric space ID.
    limit: Maximum number of pages to return (default 25, max 250).
    sort: Sort order — "title", "-title", "created-date", "-modified-date", etc.
    cursor: Pagination cursor from a previous result.

Inputs: space_id (required), sort, limit, cursor.

confluence_list_spacesB

List Confluence spaces.

Args:
    limit: Maximum number of spaces to return (default 25, max 250).
    type: Filter by space type — "global" or "personal". Empty for all.
    status: Filter by status — "current" (default) or "archived".
    cursor: Pagination cursor from a previous result.

Inputs: type, limit, cursor, status.

confluence_list_versionsA

List version history of a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    limit: Maximum number of versions to return (default 10, max 50).
    cursor: Pagination cursor from a previous result.

Inputs: page_id (required), limit, cursor.

confluence_move_pageA

Move a Confluence page to a new parent.

DESTRUCTIVE: This changes the page's location in the content tree. By default
this tool runs in preview mode — call with confirm=True to actually move.

You MUST show the preview to the user and get their explicit approval before
calling again with confirm=True.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    target_parent_id: The page ID of the new parent page.
    confirm: Must be True to actually move. False (default) shows a preview.

Inputs: page_id (required), target_parent_id (required), confirm.

confluence_push_pageA

Push the cached page to Confluence.

Reads title and ADF body from the local cache file, fetches the latest version
number from Confluence to avoid conflicts, then publishes.

Call confluence_get_page first, edit the cache file, then call this.

Args:
    page_id: The page ID to push.
    version_message: Optional message describing the change.

Inputs: page_id (required), version_message.

confluence_regex_replaceA

Find and replace text using a regex pattern on a Confluence page.

Applies re.sub() to every text node in the ADF. Supports capture groups
in the replacement string (e.g. r"\1").

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    pattern: Python regex pattern to match.
    replacement: Replacement string (supports backreferences like \1).
    version_message: Optional message describing the change.

Inputs: page_id (required), pattern (required), replacement (required), version_message.

confluence_remove_labelA

Remove a label from a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    label: The label name to remove.

Inputs: label (required), page_id (required).

confluence_replace_mentionA

Replace all @mentions of one user with another on a Confluence page.

Fetches the page, searches for mention nodes matching find_user, looks up
the replace_user's account ID, swaps the mentions, and pushes in one step.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    find_user: Name to find (partial match on mention text, e.g. "Ali").
    replace_user: Name to replace with (searched in Confluence users, e.g. "Mark").

Inputs: page_id (required), find_user (required), replace_user (required).

confluence_revert_pageA

Revert a Confluence page to a previous version.

Uses the v1 REST API restore operation to roll back a page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    version_number: The version number to revert to.
    version_message: Optional message describing the revert.

Inputs: page_id (required), version_number (required), version_message.

confluence_search_pagesA

Search Confluence pages using CQL (Confluence Query Language).

Returns page titles, IDs, and spaces matching the query. Supports CQL operators
like AND, OR, ~, =, etc. Simple text is treated as a title/content search.

Args:
    query: CQL query string, e.g. 'type=page AND title~"meeting notes"' or just "meeting notes".
    limit: Maximum number of results to return (default 10, max 50).
    cursor: Pagination cursor from a previous search result.

Inputs: query (required), limit, cursor.

confluence_set_page_propertyA

Set a content property on a Confluence page.

Creates the property if it doesn't exist, or updates it if it does.
The value is stored as a JSON string.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    key: The property key (e.g. "status", "priority").
    value: The property value as a JSON string (e.g. '"done"', '{"score": 5}').

Inputs: key (required), value (required), page_id (required).

confluence_set_restrictionsA

Set access restrictions on a Confluence page.

Replaces existing restrictions for the given operation. To remove all
restrictions, pass empty users and groups lists.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    operation: The operation to restrict — "read" or "update".
    users: List of account IDs to grant access.
    groups: List of group names to grant access.

Inputs: page_id (required), operation (required), users, groups.

confluence_update_table_cellA

Update a single cell in a table on a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    row: Zero-based row index.
    col: Zero-based column index.
    value: New text value for the cell.
    table_index: Which table on the page (0-based, default first table).

Inputs: col (required), row (required), value (required), page_id (required), +1 more.

confluence_update_taskA

Toggle a task (checkbox) item on a Confluence page.

Finds a taskItem whose text contains task_text and sets its state.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    task_text: Text substring to match the task item (e.g. "Review PR").
    state: New state — "DONE" or "TODO".

Inputs: state (required), page_id (required), task_text (required).

confluence_upload_attachmentC

Upload a file as an attachment to a Confluence page.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    file_path: Local file path to upload.
    comment: Optional comment for the attachment.

Inputs: page_id (required), file_path (required), comment.

confluence_watch_pageA

Watch or unwatch a Confluence page for the authenticated user.

Args:
    page_id: A numeric page ID or a Confluence URL (including short /wiki/x/ links).
    watch: True to start watching, False to stop watching.

Inputs: page_id (required), watch.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 43 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose, covering different Confluence operations like page CRUD, content editing, comments, labels, attachments, etc. No two tools perform the same action; even similar tools like 'edit_page' and 'find_replace' differ in their workflow (multi-step vs. single-step).

    Naming Consistency5/5

    All tool names follow a consistent 'confluence_verb_noun' pattern using snake_case (e.g., confluence_get_page, confluence_add_labels, confluence_delete_attachment). Compound operations combine verbs (confluence_find_replace) but remain predictable. No mixing of conventions.

    Tool Count4/5

    43 tools is on the high side but appropriate for a comprehensive Confluence integration covering pages, spaces, comments, labels, attachments, versions, caching, etc. Some tools (like cache management) could be considered auxiliary, but overall scope justifies the count.

    Completeness3/5

    Major operations are covered but notable gaps exist: no permanent page deletion (only archive), no direct ADF body retrieval, no comment editing or deletion, and no separate tool to update page title. The find/replace and cache-based editing approach may hinder programmatic workflows.

    Related MCP Connectors

    Related MCP Servers