Confluence MCP Server
Search, read, create, update and comment on Confluence pages - Cloud or Data Center
The Confluence MCP server provides 6 tools to search, read, create and update Confluence pages, list child pages and add comments. It works with Confluence Cloud and with Confluence Data Center / Server.
Setup
Confluence Cloud and Data Center use different credentials.
- Get the credentials:
- Cloud (
*.atlassian.net): an Atlassian API token and the email of its Atlassian account. - Data Center / Server: a personal access token, created in your Confluence profile.
- Cloud (
- In FlowTrux, go to Resources > MCP Servers > Add Server (OWNER or ADMIN) and choose Confluence.
- Give it a Name and fill in:
| Field | Cloud | Data Center | Description |
|---|---|---|---|
| Base URL | Yes | Yes | Cloud: https://acme.atlassian.net/wiki - keep /wiki. Data Center: the site root, e.g. https://confluence.acme.com |
| Email (Cloud) | Yes | - | The Atlassian account email |
| API Token (Cloud) | Yes | - | The Atlassian API token |
| Personal Access Token (Data Center) | - | Yes | Leave empty on Cloud |
- Under Available in workspaces, pick the workspaces, then click Add Server.
A 401 means the credentials do not match the deployment (for example an API token used against Data Center). A 404 on every call on Cloud usually means /wiki is missing from Base URL.
Workflows act as the authenticated user: a page that user cannot view answers 404, one they cannot edit answers 403.
Tools
Finding pages
search_pages
Full-text search for pages. query is words to find; it may also be a CQL expression (title ~ "onboarding" AND label = "hr") when you need more than text matching. Returns id, title, space, url and an excerpt per hit.
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search words, or a CQL expression. |
space | string | No | Restrict to one space key (e.g. ENG). |
limit | number | No | Max results (default 10, max 50). |
list_child_pages
Direct child pages of a page (one level), in Confluence's tree order.
| Parameter | Type | Required | Description |
|---|---|---|---|
pageId | string | Yes | Numeric page id as a string (from search_pages, list_child_pages or the page URL …/pages/<id>/…). |
limit | number | No | Max children (default 50, max 200). |
search_pages takes plain words, or a CQL expression when text matching is not enough: title ~ "runbook" AND label = "ops", ancestor = 12345 for a whole subtree, lastmodified > now("-7d"). It returns page ids; the other tools take a pageId.
Reading and writing
get_page
Read one page: title, space, version, URL, parent chain, and the body converted to readable text.
| Parameter | Type | Required | Description |
|---|---|---|---|
pageId | string | Yes | Numeric page id as a string (from search_pages, list_child_pages or the page URL …/pages/<id>/…). |
create_page
Create a page in a space. body is plain text or light Markdown (converted for you); storage format is accepted as is. The title must be unique within the space.
| Parameter | Type | Required | Description |
|---|---|---|---|
space | string | Yes | Space key, e.g. ENG. |
title | string | Yes | Page title (unique per space). |
body | string | Yes | Page content - plain text or light Markdown, or Confluence storage format. |
parentId | string | No | Parent page id; omitted → top level of the space. |
update_page
Replace a page's body (and optionally its title). The current version is fetched and incremented for you. This replaces the whole body: read it with get_page first if you mean to append.
| Parameter | Type | Required | Description |
|---|---|---|---|
pageId | string | Yes | Numeric page id as a string (from search_pages, list_child_pages or the page URL …/pages/<id>/…). |
body | string | Yes | New content - plain text or light Markdown, or Confluence storage format. |
title | string | No | New title (keeps the current one when omitted). |
versionMessage | string | No | Optional note shown in the page history. |
add_comment
Add a footer comment to a page. body is plain text or light Markdown.
| Parameter | Type | Required | Description |
|---|---|---|---|
pageId | string | Yes | Numeric page id as a string (from search_pages, list_child_pages or the page URL …/pages/<id>/…). |
body | string | Yes | Comment text. |
Page bodies are converted both ways. get_page returns readable text: # headings, - bullets, fenced code, pipe tables and [text](url) links; macros keep their text and images appear as [image: file]. create_page, update_page and add_comment take plain text or light Markdown (blank line = new paragraph, #, -, 1., code fences, **bold**, links). A body that already is Confluence storage format is sent unchanged.
update_page replaces the whole body. To append, read the page with get_page and send the old text plus the addition. Pages heavy with macros can lose macro settings on such a round trip - edit those in the browser.
Titles are unique per space. create_page fails with A page with this title already exists when the title is taken - find the page and use update_page. space is the space key (ENG), not its name. A page without parentId lands at the top of the space. Comments created here are page (footer) comments, not inline comments.
Examples
Publish a weekly status page:
Schedule → Action:MCP(jira, search_issues, {jql: "project = OPS AND updated >= -7d"}) → Agent (write the title and summary) → Action:MCP(confluence, create_page, {space: "OPS", title: "{{steps.agent-1.output.response.title}}", body: "{{steps.agent-1.output.response.summary}}", parentId: "12345"})
Answer questions from the wiki:
Webhook (question) → Agent (tools: confluence:search_pages, confluence:get_page) → reply with the answer and the page links
Append to a runbook:
Action:MCP(confluence, get_page, {pageId: "67890"}) → Transform (old body + new entry, as `text`) → Action:MCP(confluence, update_page, {pageId: "67890", body: "{{steps.merge.output.text}}", versionMessage: "Added incident 42"})