A Model Context Protocol Server for Atlassian Confluence Cloud
This Confluence MCP server demonstrates solid definition quality with strong naming conventions, comprehensive parameter descriptions, and well-documented edit workflows. All 17 tools follow clear verb_noun naming patterns (list_, get_, create_, update_, replace_, append_, insert_, search_, add_, remove_, move_, find_, validate_). Descriptions are generally detailed and workflow-aware, particularly for the edit-loop tools (get_confluence_page, replace_confluence_section, etc.) which include explicit multi-step guidance. Input schemas are present and mostly well-formed with type definitions and parameter descriptions. However, there are gaps: output schemas are not formally documented in the tool definitions (violating pattern:tool requirement), parameter constraints are sometimes implicit rather than explicit enums, and some descriptions could be more concise. The server demonstrates good composition design, tools are single-responsibility and chain logically (e.g., list_confluence_spaces → get_confluence_space → list_confluence_pages → get_confluence_page). Error handling is present but minimal, the source shows basic validation but lacks recovery guidance. No tool annotations (readOnlyHint/destructiveHint) are visible despite clear risk categorization (READ_ONLY vs WRITE). Security-wise, the server relies on environment-based instance configuration rather than parameter-exposed credentials, which is correct, but audit logging is not evident in the visible code.
Add a label to a page. Labels are used for categorization and discovery. Returns the label's ID, name, prefix, and creation date.
Append a new section to a page after an addressable heading. Everything before and including that heading is preserved byte-for-byte. Use this to add new content after a specific section.
Create a new page in a Confluence space. Returns the new page's ID, version and URL. "content" must be Confluence storage format (XHTML): ordinary elements such as <p>, <h2>, <ul>/<li>, <table>, plus Confluence's own <ac:...> macro markup. Markdown is REJECTED, not converted -- Confluence stores "## Heading" and "**bold**" as those literal characters. Markup that is not well-formed, this server's "[Confluence Macro: ...]" placeholder text, and "$1" markdown-conversion artifacts are rejected too. Every check runs before any request, so a rejected create leaves nothing behind. To match an existing page's house style, read one with get_confluence_page (format: "storage") and author against that markup.
Find a page by its exact title and return it in full. The response is identical to get_confluence_page -- "content" (markdown, for reading), "storage" (XHTML, for writing), "version", "lossy" and the heading "outline" -- so see that tool for the read-edit-write loop these fields support. Use this when you know the page name but not its ID. Searches every space unless spaceId is given, and errors asking you to narrow by spaceId when more than one page has the title.
Output schemas not documented. Tool definitions declare input schemas but nowhere in the visible source are output schemas (response structures) formally documented. This violates pattern:tool and pattern:response-shaper requirements, LLMs cannot plan downstream operations or extract chaining IDs without knowing what fields to expect.
No tool annotations (readOnlyHint/destructiveHint) despite clear risk categorization. The spec lists each tool with Risk: READ_ONLY or WRITE, but these are not registered in the tool definitions via readOnlyHint/destructiveHint annotations. This forces LLMs to infer write vs. read semantics from the description text alone, increasing the risk of unintended mutations.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 55 | <=2025-11-25 | v2 |
Get all labels assigned to a page. Returns label IDs, names, and prefixes.
Read a Confluence page by ID. Returns "content" (a markdown rendering, for READING), "storage" (the raw Confluence storage format XHTML, the only representation a write may be authored against), "version", "lossy", a heading "outline", and metadata. THE EDIT LOOP -- follow it exactly: 1. Read the page here. Keep the default format ("both") or use "storage". 2. Changing PART of the page? Pick the heading from "outline" and use replace_confluence_section, append_confluence_section or insert_confluence_section, passing the "version" returned here as their expectedVersion. They splice one section by byte offset, so every byte outside it survives untouched. Prefer this. Rewriting the WHOLE body? Use update_confluence_page. 3. Author the new content as storage-format XHTML, modelled on the "storage" you just read. NEVER send the markdown from "content" to a write tool: Confluence stores markdown syntax literally, so "## Heading" and "**bold**" render as those characters. Write tools reject markdown rather than converting it. "lossy": true means the markdown rendering flattened something it cannot faithfully represent -- a macro, a layout, or markup this server does not model. When it is true, do not rebuild the page from the markdown; edit the "storage". "outline": every heading in document order, each with level, text, occurrence (1-based, distinguishing repeated heading text) and addressable. Only addressable headings can be targeted by the section tools. A heading is addressable when it sits at the page root or directly inside a layout container (ac:layout, ac:layout-section, ac:layout-cell). Headings inside macro bodies, table cells, or ordinary wrappers such as <div> are not addressable -- reach those with update_confluence_page.
Get detailed information about a specific Confluence space. Useful after list_confluence_spaces to examine a space more closely. Returns space metadata including type, status, and homepage information.
Insert a new section before an addressable heading. Everything from that heading onward is preserved byte-for-byte. Use this to add new content before a specific section.
List all configured Confluence instances. Shows available instances, their domains, and configuration details. Use this tool to discover which instances are available and how to use them.
List pages in a specific Confluence space. Essential for content navigation and discovery within a space. Returns page IDs, titles, versions and parent IDs -- but no page bodies; read a body with get_confluence_page. TIP: Use status filter to find specific page states (current, archived, draft, trashed).
List all available Confluence spaces. Best used as the first step in a content discovery workflow. Returns space IDs, names, and keys that you can use with other tools. TIP: Use a higher limit (e.g., 100) on first call to get a comprehensive view of available spaces.
Move a page to a different parent page or space. Returns the updated page's ID, version, and URL.
Remove a label from a page.
Replace a single section (addressable heading) of a page by its text and nesting level. The target heading is found in the current version; everything else on the page is preserved byte-for-byte. Use this for surgical edits to one section of a multi-section page.
Search Confluence pages using CQL (Confluence Query Language). Returns matching pages with titles, excerpts, and metadata. Use this to find pages across spaces by content, title, or other criteria.
Update a Confluence page's title and/or content. The write path is guarded by preflight validation and version conflict detection. Returns the updated page's ID, version, and URL.
Validate Confluence page content before writing. Runs the same preflight checks as create and update tools without making any API requests. Use this to catch markup or formatting errors early.
Minimal error recovery guidance. Error responses are not visible in the source, and there is no evidence of pattern:recovery-guide implementation. Error messages should tell LLMs what to do next (e.g., 'Page not found. Try search_confluence_pages() with a keyword.').
remove_confluence_label has an incomplete description (65 chars). It only says 'Remove a label from a page.' without explaining when to use it, what it returns, or how it differs from other label tools. Descriptions under 34 chars risk LLM selection errors.
Parameter constraints sometimes implicit. Several tools accept 'limit' and 'cursor' parameters for pagination, but the baseline ranges (default: 25, max: 250) are documented in descriptions rather than enforced via minLength/maxLength/minimum/maximum JSON Schema constraints. This invites LLMs to pass invalid values that the server must validate and reject.
No idempotency guarantees documented. Tools like create_confluence_page, update_confluence_page, and add_confluence_label should declare idempotency behavior (pattern:idempotent-operation) so agents know whether retries are safe. Example: 'idempotent: true, calling twice with the same input returns the same result; the second call is a no-op.'
No audit logging visible. The source does not show logging of who called what tool, with which parameters, at what time, and what happened. This violates pattern:audit-trail and makes compliance/debugging difficult.