·

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.

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.