·

Confluence MCP With Cursor

Set up Confluence MCP in Cursor so your AI agent can read and write pages and documentation right from your editor.

Share:

Cursor's Agent mode treats MCP tools as first-class citizens alongside its native codebase tools, which makes the "read spec, write code" and "read code, write docs" loops feel more integrated than in a standalone CLI — you're not context-switching out of the editor at all. The trade-off is a less mature review surface for Confluence-specific writes compared to what you'd get reviewing a page diff in a browser. This topic covers the Cursor-specific config, a real spec-to-code and code-to-docs workflow, and the sharp edges worth knowing before you rely on it for anything customer-facing.

Connecting Confluence MCP to Cursor Agent Mode

Cursor reads MCP config from .cursor/mcp.json (project-scoped) or ~/.cursor/mcp.json (global). As of Cursor 1.x, the config format matches the broader MCP ecosystem convention closely enough that a Claude Code .mcp.json server block ports over with minimal changes.

{
  "mcpServers": {
    "confluence": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "CONFLUENCE_URL",
        "-e", "CONFLUENCE_USERNAME",
        "-e", "CONFLUENCE_API_TOKEN",
        "ghcr.io/sooperset/mcp-atlassian:latest"
      ],
      "env": {
        "CONFLUENCE_URL": "https://yourcompany.atlassian.net/wiki",
        "CONFLUENCE_USERNAME": "dat.hoang@yourcompany.com",
        "CONFLUENCE_API_TOKEN": "ATATT3xFfGF0...redacted"
      }
    }
  }
}

Unlike Claude Code and Gemini CLI, Cursor's mcp.json doesn't support $VAR shell interpolation inside env values reliably across all versions — in practice, teams either accept the token living in a gitignored .cursor/mcp.json (fine for solo/personal use, not for a shared repo config) or route through the OS keychain via a wrapper script that injects the env var before Cursor launches Docker.

#!/usr/bin/env bash
export CONFLUENCE_API_TOKEN=$(security find-generic-password -s confluence-mcp -w)
exec docker run -i --rm \
  -e CONFLUENCE_URL="https://yourcompany.atlassian.net/wiki" \
  -e CONFLUENCE_USERNAME="dat.hoang@yourcompany.com" \
  -e CONFLUENCE_API_TOKEN \
  ghcr.io/sooperset/mcp-atlassian:latest
{
  "mcpServers": {
    "confluence": {
      "command": "/bin/bash",
      "args": [".cursor/launch-confluence-mcp.sh"]
    }
  }
}

That pattern (macOS Keychain via security; on Linux, swap in secret-tool or a .env sourced from a permissions-locked file) keeps the token out of any file that might get committed by accident.

Enable and verify inside Cursor: open Settings → MCP, confirm confluence shows a green/connected indicator and a non-zero tool count. In Agent mode chat, typing @ and looking for MCP tool suggestions is a quick sanity check that Cursor picked up the server — Confluence tools should appear alongside your codebase's native symbols in the autocomplete.

Tips
- Don't rely on $VAR interpolation working consistently in .cursor/mcp.json across Cursor versions — a keychain-backed launch script is more portable than debugging why an env var silently resolved to an empty string.
- Check Settings → MCP for a connected status before trusting any Confluence prompt in Agent mode — a disconnected server fails tool calls with a generic "tool not available" message that's easy to misread as a prompt problem.
- Keep .cursor/mcp.json itself out of version control if it contains any credential material directly; commit only the wrapper-script version.


Reading Confluence Specs and Generating Boilerplate Code in Cursor

This is where Cursor's IDE-native context genuinely helps: Agent mode can read a Confluence spec, then generate the actual project files in the same turn, in the same editor, with the same diff-review UX you already use for every other Cursor code change.

Read the Confluence page "Notification Service — API Spec" in the ENG
space. Generate a FastAPI router matching its documented endpoints:
`POST /notifications`, `GET /notifications/{id}`,
`PATCH /notifications/{id}/read`. Put it in `services/notifications/router.py`,
with Pydantic models for each request/response schema in `models.py`.

Cursor calls confluence_search (or confluence_get_page directly if you gave it the exact title), reads the storage-format body, and — this is the part worth watching — has to correctly parse whatever schema notation the spec uses. If the Confluence page documents request/response shapes as a Confluence table (common) or as an embedded code block (also common, and easier for the agent to parse exactly), extraction accuracy differs meaningfully. Tables get parsed correctly for simple field/type/required columns; anything with nested objects described in prose inside a table cell is a real source of mis-generated Pydantic fields worth double-checking against the source page.

Spec page table (rendered from Confluence storage format):
| Field       | Type   | Required | Notes                    |
|-------------|--------|----------|---------------------------|
| user_id     | string | yes      | UUID                      |
| message     | string | yes      | max 500 chars             |
| metadata    | object | no       | free-form key-value pairs |

For the metadata row above, expect the generated Pydantic model to render it as dict[str, Any] or similar — reasonable, but confirm it matches what the spec author actually intended, since "free-form key-value pairs" is genuinely ambiguous and the agent has to guess a concrete type.

Cursor's inline diff view (the same one used for every AI code edit) applies here unchanged — you review the generated router and models file exactly as you'd review any other Cursor-proposed change, accept/reject per hunk. That consistency is the single biggest practical advantage of doing spec-to-code work inside Cursor versus a standalone CLI: no separate review surface to learn.

Tips
- Check whether your Confluence spec pages document schemas as tables or embedded code blocks — code-block schemas parse more reliably into typed models than prose-in-table-cells.
- Treat any "free-form" or loosely-typed field in a spec as a place the agent had to guess — verify the generated type against what you actually intend to store.
- Use Cursor's standard code diff review for AI-generated files from a spec exactly like you would for any other AI-generated code — no special workflow needed here, which is the point.


Pushing Auto-Generated Docs Back to Confluence via Cursor

The inverse flow — code to docs — works, but the review loop is weaker than the code-diff review above, because Confluence page updates don't render as a Cursor-native diff. You're trusting the agent's tool-call summary or manually checking the live page afterward.

Read `services/notifications/router.py` and `models.py`. Update the
Confluence page "Notification Service — API Spec" in ENG to match the
actual implementation: correct any field types or endpoints that have
drifted from the original spec.

This "sync docs to match implementation" direction is genuinely valuable — specs drift from code constantly, and having an agent reconcile them on demand beats manual reconciliation nobody has time for — but because there's no inline diff for the Confluence page itself, the practical workflow is:

  1. Run the update prompt.
  2. Open the actual Confluence page in a browser (or ask the agent to output the new body as Markdown in chat first, as a pre-check).
  3. Check the page's version history for a one-click revert path if something's off.

Asking the agent to show the proposed content before calling confluence_update_page is the closest Cursor gets to a pre-write review for Confluence specifically:

Before updating the page, show me the diff between the current spec
content and what you're about to write, as a side-by-side comparison
in this chat.

This works because it forces the agent to fetch the current page (confluence_get_page) and compare before writing, rather than jumping straight to confluence_update_page — effectively hand-rolling a review gate the tooling doesn't provide natively.

Tips
- For any code-to-Confluence update, ask the agent to show a before/after comparison in chat before calling the write tool — Cursor has no native diff view for Confluence page bodies.
- Rely on Confluence's own page version history as the safety net for AI-driven updates gone wrong; it's a one-click revert in the web UI.
- Schedule sync-docs-to-code prompts as a recurring manual check (e.g., before a release) rather than fully automating them — the lack of a native review surface makes unattended automation riskier here than for read-only prompts.


Known Limitations and Edge Cases

A few things worth knowing before you build a workflow around this combination:

  • No native diff for Confluence writes, as covered above — this is the single biggest gap versus the Claude Code VS Code extension's rendered diff view.
  • Env var interpolation inconsistency in .cursor/mcp.json across versions means teams often end up with the keychain-wrapper-script pattern shown earlier, which is one more moving part than the other three agents need.
  • Long spec pages get truncated silently in some Cursor versions when passed through the context window alongside a large open codebase — if a page is long (multi-thousand-word spec), consider asking the agent to fetch and process it in a fresh, minimal-context chat rather than one with a dozen files already open.
  • Table-in-table or deeply nested Confluence content (macros inside macros, common in older pages migrated from other wikis) sometimes fails to parse at all — confluence_get_page returns a body, but the storage-format-to-Markdown conversion can garble deeply nested macros into unreadable fragments. If a spec page predates your team's current Confluence conventions, a manual glance at the raw page before trusting the agent's read is worth the two minutes.
  • Cursor's Agent mode occasionally re-runs the same confluence_search call redundantly within a single multi-step task, burning a few extra seconds and API calls — harmless, but worth knowing so you don't mistake it for a hang.

Tips
- For very long spec pages, start a fresh Cursor chat scoped narrowly to the doc-generation task rather than reusing a chat with a large codebase already loaded into context.
- If a Confluence page predates a wiki migration or uses heavy nested macros, manually check the rendered page before trusting an AI summary of its content.
- Treat occasional redundant tool calls as a minor inefficiency, not a signal something's broken — it doesn't affect output correctness in practice.


Tips

Tips
- Cursor's biggest win here is the unified review surface for spec-to-code work — use it heavily for that direction, where the native diff view applies.
- For code-to-docs updates, build in a manual "show me the diff in chat first" step since there's no native equivalent — treat it as a required habit, not optional caution.
- Next: the closing module topic ties all of this together into one end-to-end workflow — reading specs into code, generating docs from code, and keeping the two in sync on an ongoing basis.

Share: