confluence-dc-mcp
by EllGree
README.md
# confluence-dc-mcp
Minimal MCP server for a self-hosted Confluence Data Center REST API.
## Tools
Reading:
- `confluence_search` — CQL search, with `start` for paging
- `confluence_get_page` — by id or `(space_key, title)`; `view` or `storage` body, and the page's attachments
- `confluence_get_children` — child pages
- `confluence_get_attachments` — a page's attachments: filename, media type, size, download URL
- `confluence_get_attachment` — one attachment by id or `(page_id, filename)`; images come back viewable, text files as text
Writing, unless the server is in read-only mode:
- `confluence_create_page` — needs `space_key`, `title`, `body_storage` (XHTML)
- `confluence_update_page` — needs `page_id`, the `version` you read, and `body_storage` (XHTML)
## Install
Needs Node 18 or newer.
```
npm install
```
## Config
Both values are required. Either `config.json` next to `index.js`:
```json
{
"baseUrl": "https://confluence.example.com",
"pat": "<personal access token>"
}
```
or the environment, which keeps the token out of the project folder:
```
CONFLUENCE_DC_BASE_URL
CONFLUENCE_DC_PAT
```
`config.json` wins over the environment, and it is gitignored. A value left at the example placeholder counts as absent, so a half-filled `config.json` falls through to the environment instead of sending the placeholder to Confluence and failing as a 401.
Mint the token at `<baseUrl>/plugins/personalaccesstokens/usertokens.action`. It inherits your permissions: the server sees exactly the spaces you see in the browser.
Register it with your MCP client as a stdio server — command `node`, argument the full path to `index.js`.
### Read-only mode
Set `CONFLUENCE_DC_READONLY=1`, or `"readOnly": true` in `config.json`, and the two write tools are not offered at all. Worth doing if you only ever read, since a tool that is not listed cannot be called by mistake.
## Writing safely
An update **replaces the whole body**. Anything you leave out of the XHTML is gone, macros included. Two guards sit in front of that:
- **You pass the version you read.** If the page has moved on since, the write is refused and tells you both numbers. Read it again, merge your change onto the current body, and retry. Without this an edit made between your read and your write is overwritten in silence.
- **Macros are counted.** If the body you pass drops a macro the page currently has, the write is refused and names the macros. Set `allow_macro_removal` when that is deliberate.
Neither guard helps with content you simply forgot to carry over, so read the page in `storage` format first and edit that string.
## Notes
- Body format is Confluence storage XHTML, not markdown. Storage is the canonical persisted form and includes `<ac:structured-macro>` and friends. Simple `<p>` / `<h1>` / `<ul>` work.
- Attachments over 4 MB, and anything that is not an image or a text-ish file, come back as a download URL rather than bytes.
- Errors include the raw response body, first 500 characters, so failed writes are debuggable.
- Behind TLS inspection, start node with `--use-system-ca` so it trusts the OS certificate store. If your node rejects the flag, it is too old for it.
## Tests
```
npm test
```
Covers the placeholder handling and the macro accounting — the parts where being wrong is quiet rather than loud.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues