Intended change
This issue proposes two closely related enhancements to updateConfluencePage / createConfluencePage that, together, would make Confluence page editing via MCP reliable for real-world documents of any size:
-
Lossless macro round-trip in markdown format — Preserve Confluence macros (Table of Contents, panels, status lozenges, etc.) as HTML comment placeholders when converting ADF to markdown, and restore them when converting markdown back to ADF.
-
bodyFile parameter for large content — Allow passing a local file path instead of an inline body string, so the MCP server reads the file directly. This eliminates both the server-side conversion timeout on large payloads and the LLM output-token overhead of generating the entire page body inline.
Problem
Macro loss on markdown round-trip
When a Confluence page containing macros (e.g., Table of Contents) is read with contentFormat: "markdown", macros are silently dropped because markdown has no equivalent syntax. When the page is subsequently updated via markdown, all macros are permanently removed.
Reproduction (verified 2025-05-02):
-
Create a Confluence page with a Table of Contents macro and a heading.
-
Read the page with getConfluencePage(contentFormat="adf"):
{
"type": "extension",
"attrs": {
"extensionType": "com.atlassian.confluence.macro.core",
"extensionKey": "toc",
...
}
}
→ TOC extension node is present.
-
Read the same page with getConfluencePage(contentFormat="markdown"):
→ TOC macro is completely absent.
-
Update the page with updateConfluencePage(contentFormat="markdown", body="# Heading\nNew content").
-
Read the page again with contentFormat="adf" → TOC extension node is gone.
Large content timeout
updateConfluencePage with contentFormat: "markdown" hangs indefinitely on payloads around 56KB+, timing out after ~300 seconds with no error returned. Even if the timeout were resolved, LLM agents cannot practically generate 50KB+ of content as an inline tool-call parameter (this would consume ~15,000+ output tokens for the body alone).
Proposed solution
1. Macro placeholders in markdown
When converting ADF to markdown (read path), represent macros as HTML comments:
<!-- confluence:toc style="none" -->
# Introduction
Some content here.
<!-- confluence:panel type="info" -->
This is an info panel.
<!-- /confluence:panel -->
## Section 2
More content.
When converting markdown to ADF (write path), recognize these placeholders and restore the corresponding ADF extension nodes at the exact positions.
Why HTML comments?
- Valid markdown per the CommonMark spec — existing markdown renderers ignore them
- No collision with actual page content
- Namespaced (
confluence:) to avoid ambiguity
- Human-readable and editable
- LLM agents naturally preserve HTML comments when editing markdown, since they are not visible content
Placeholder format:
| Macro type |
Read output |
Write input |
| Self-closing (TOC, status) |
<!-- confluence:toc key="value" --> |
Same |
| Body macro (panel, expand) |
<!-- confluence:panel type="info" -->content<!-- /confluence:panel --> |
Same |
2. bodyFile parameter
Add an optional bodyFile: string parameter to updateConfluencePage and createConfluencePage. When provided:
- The MCP server reads the file from the given local path.
- Applies the same content-format conversion (markdown → ADF, including macro placeholder restoration).
- Submits the result to the Confluence REST API.
The body and bodyFile parameters would be mutually exclusive. This keeps backward compatibility — existing clients using body are unaffected.
Token savings example (113KB markdown file):
| Approach |
LLM output tokens |
body (inline) |
~45,000 tokens |
bodyFile (file path) |
~10 tokens |
Related issues
| Issue |
Relationship |
| #59 |
Large markdown payload timeout — bodyFile eliminates this by moving I/O to the server |
| #60 |
Lossy ADF-markdown round-trip (partially fixed) — macro placeholders complete the fix |
| #106 |
Large pages unusable, bodyFile proposed — this issue adds a concrete spec |
| #126 |
TOC and images removed on update — macro placeholders solve the TOC case |
Workaround (current)
- Use
contentFormat: "adf" and manually include extension nodes for macros. This preserves macros but increases payload size ~5x and is impractical for large pages.
- For large content, bypass MCP entirely and call the Confluence REST API v2 directly from a script.
Neither workaround is sustainable for agent-driven workflows.
Intended change
This issue proposes two closely related enhancements to
updateConfluencePage/createConfluencePagethat, together, would make Confluence page editing via MCP reliable for real-world documents of any size:Lossless macro round-trip in markdown format — Preserve Confluence macros (Table of Contents, panels, status lozenges, etc.) as HTML comment placeholders when converting ADF to markdown, and restore them when converting markdown back to ADF.
bodyFileparameter for large content — Allow passing a local file path instead of an inlinebodystring, so the MCP server reads the file directly. This eliminates both the server-side conversion timeout on large payloads and the LLM output-token overhead of generating the entire page body inline.Problem
Macro loss on markdown round-trip
When a Confluence page containing macros (e.g., Table of Contents) is read with
contentFormat: "markdown", macros are silently dropped because markdown has no equivalent syntax. When the page is subsequently updated via markdown, all macros are permanently removed.Reproduction (verified 2025-05-02):
Create a Confluence page with a Table of Contents macro and a heading.
Read the page with
getConfluencePage(contentFormat="adf"):{ "type": "extension", "attrs": { "extensionType": "com.atlassian.confluence.macro.core", "extensionKey": "toc", ... } }→ TOC
extensionnode is present.Read the same page with
getConfluencePage(contentFormat="markdown"):→ TOC macro is completely absent.
Update the page with
updateConfluencePage(contentFormat="markdown", body="# Heading\nNew content").Read the page again with
contentFormat="adf"→ TOCextensionnode is gone.Large content timeout
updateConfluencePagewithcontentFormat: "markdown"hangs indefinitely on payloads around 56KB+, timing out after ~300 seconds with no error returned. Even if the timeout were resolved, LLM agents cannot practically generate 50KB+ of content as an inline tool-call parameter (this would consume ~15,000+ output tokens for the body alone).Proposed solution
1. Macro placeholders in markdown
When converting ADF to markdown (read path), represent macros as HTML comments:
When converting markdown to ADF (write path), recognize these placeholders and restore the corresponding ADF
extensionnodes at the exact positions.Why HTML comments?
confluence:) to avoid ambiguityPlaceholder format:
<!-- confluence:toc key="value" --><!-- confluence:panel type="info" -->content<!-- /confluence:panel -->2.
bodyFileparameterAdd an optional
bodyFile: stringparameter toupdateConfluencePageandcreateConfluencePage. When provided:The
bodyandbodyFileparameters would be mutually exclusive. This keeps backward compatibility — existing clients usingbodyare unaffected.Token savings example (113KB markdown file):
body(inline)bodyFile(file path)Related issues
bodyFileeliminates this by moving I/O to the serverbodyFileproposed — this issue adds a concrete specWorkaround (current)
contentFormat: "adf"and manually includeextensionnodes for macros. This preserves macros but increases payload size ~5x and is impractical for large pages.Neither workaround is sustainable for agent-driven workflows.