Cursor's Agent mode is where Notion MCP earns a different kind of value than in a terminal tool — the model has your actual codebase open in the same context as the Notion page, so "read this spec and scaffold the implementation" isn't a two-step copy-paste exercise, it's a single agentic pass that reads Notion, writes code files, and (if you ask) writes back to Notion when it's done. That tight loop is the main reason to reach for Cursor specifically over a terminal-only client for this kind of work.
This topic covers connecting the server inside Cursor, using it to go from a Notion spec straight to scaffolded code, pushing implementation notes back to the source page, and the real limitations worth knowing about before you rely on this for anything customer-facing.
Connecting Notion MCP to Cursor Agent Mode
Cursor reads MCP config from .cursor/mcp.json in the project root (shareable via git) or ~/.cursor/mcp.json for global servers available across all projects. The schema matches the now-familiar mcpServers shape.
{
"mcpServers": {
"notion": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ${NOTION_TOKEN}\", \"Notion-Version\": \"2022-06-28\"}"
}
}
}
}
export NOTION_TOKEN="ntn_your_internal_integration_secret_here"
To confirm it's live: open Cursor's Settings → MCP panel — connected servers show a green indicator and a tool count. If it shows red or a spinner that never resolves, the usual suspects are the same as everywhere else in this module: npx not resolving in Cursor's spawned environment (particularly on macOS if Cursor was launched from Finder rather than a terminal with your shell's PATH), or a malformed OPENAPI_MCP_HEADERS string.
For the hosted OAuth server:
{
"mcpServers": {
"notion": {
"url": "https://mcp.notion.com/mcp"
}
}
}
Cursor handles the OAuth redirect cleanly inside its own UI — a popup completes the consent flow without leaving the app, which is a smoother experience than either OpenCode's or Gemini CLI's current handling of the same flow.
Once connected, enable the Notion tools for Agent mode specifically (Cursor lets you toggle which MCP servers a given Agent conversation can use — for spec-to-code work you generally want Notion tools on, but it's worth toggling them off for pure refactoring sessions so the agent isn't tempted to go searching Notion when it should be reading your codebase).
Cursor Agent prompt (verification):
"Confirm the notion MCP tools are available, then call API-get-self to show
which integration is connected."
Tips
- Launch Cursor from a terminal at least once if MCP servers show aPATH-related spawn failure — it's a common, easily-missed cause on macOS specifically.
- Toggle Notion tools off for Agent conversations that don't need them — it keeps the agent from wandering into an irrelevant Notion search mid-refactor.
- Use.cursor/mcp.json(project-scoped) over the global config for team projects so everyone gets the same server definition through version control.
Reading a Notion Spec and Scaffolding Implementation Code
This is the workflow that makes Cursor worth using over a terminal-only client for Notion-adjacent work: reading a spec and generating code in the same pass, with both the spec and the existing codebase in context simultaneously.
Cursor Agent prompt:
"Read the Notion page at https://notion.so/eng-wiki/Saved-Searches-Spec-abc123.
It describes a 'saved searches' feature. Then, in this repo:
1. Look at src/models/ to understand our existing model patterns
2. Generate a SavedSearch model matching our conventions
3. Generate a repository class with methods matching the CRUD operations
implied by the spec's acceptance criteria
4. Generate a test file with one test per acceptance criterion listed on the
page — name each test after the criterion it covers
Don't write anything to Notion yet — just show me the generated files."
The reason this works better here than pasting the spec text manually into a prompt is that the agent can go back to the Notion page mid-task if it needs clarification — re-reading a specific block, checking whether an acceptance criterion to_do is checked (meaning already implemented elsewhere) or not, without you re-pasting anything.
Follow-up, once the spec references a numeric limit buried in a paragraph:
"The spec mentions a limit on saved searches per user but I don't see it in
the acceptance criteria list — check the full page body, including any
callout or toggle blocks, for a specific number."
This is a real, recurring pattern: numeric constraints and edge-case notes often live in a callout block or inside a collapsed toggle, not in the main acceptance criteria list, and a shallow read of just the top-level paragraphs misses them. Explicitly asking the agent to check callouts and toggles (both of which have children that require a separate API-retrieve-a-block call to expand) catches details that would otherwise silently vanish from the generated code.
For generating tests directly tied to the spec's stated acceptance criteria:
// Generated by Cursor Agent from the spec's to_do acceptance criteria
describe('SavedSearch', () => {
it('rejects a 21st saved search when the user already has 20', async () => {
// Acceptance criterion: "Support up to 20 saved searches per user"
// ...
});
});
Naming the criterion in a comment above the test, verbatim from the spec, is a small habit that pays off later — when the spec changes, grep-ing for the old wording finds every test that needs revisiting.
Tips
- Explicitly ask the agent to checkcalloutandtoggleblocks, not just top-level paragraphs — numeric limits and edge cases hide in collapsed content more often than you'd expect.
- Have generated tests reference the exact acceptance criterion wording in a comment — it makes future spec changes traceable back to affected tests via a simple text search.
- Keep spec-reading and code-writing as one pass, but hold off on writing back to Notion until the code is reviewed — conflating "draft code" with "confirmed implementation" in the spec itself causes real confusion later.
Pushing Implementation Notes Back to Notion from Cursor
Once code is written and reviewed, closing the loop — updating the spec page with implementation notes, marking acceptance criteria as done, linking the PR — is what actually keeps Notion from drifting out of sync with reality.
Cursor Agent prompt:
"The saved searches implementation is done and the PR is merged
(https://github.com/org/repo/pull/842). Go back to the spec page and:
1. Check off each acceptance criterion to_do block that's now satisfied
2. Append a new 'Implementation Notes' section at the end of the page with:
- A link to the PR
- Which files were touched (list the key ones)
- Any deviation from the original spec, and why
3. Update the page's Status property to 'Shipped'"
Checking off an existing to_do block requires first retrieving its block ID (via API-retrieve-a-block on the page's children, matching by text), then calling the block update endpoint with checked: true — it's a targeted single-block update, not a page-level property change, which is a distinction worth knowing when you're debugging why "mark this done" didn't touch what you expected.
{
"to_do": {
"checked": true
}
}
For the "deviation from spec" note specifically — this is worth insisting on every time, because it's the detail that erodes trust in a spec-driven workflow fastest if it's skipped. If the implementation quietly diverged from what the page describes (a different validation limit, a skipped edge case deferred to a follow-up), and nobody records that in the page, the spec becomes actively misleading rather than just stale.
"Be honest in the deviation note — if we didn't implement rate limiting on
the search creation endpoint because it was descoped, say that explicitly,
don't just omit it."
That kind of explicit "be honest, don't omit inconvenient details" instruction matters more than it should — left unprompted, models writing status updates tend toward an optimistic gloss that undersells what was actually skipped.
Tips
- Update individualto_doblocks for acceptance criteria rather than a single page-level "done" flag — a granular checklist stays useful for partial completion and future audits.
- Always include a "deviations from spec" note when pushing implementation status back, and prompt explicitly for honesty about anything descoped or skipped.
- Link the PR and list touched files in the implementation notes — it turns the spec page into a real changelog anchor point, not just a historical artifact.
Known Limitations and Workarounds for Notion MCP in Cursor
- Agent context competition. When both a large codebase context and a large Notion page are in play, Cursor's context window fills faster than either alone would suggest — a long spec page combined with a big diff can push older context out, causing the agent to "forget" an early acceptance criterion by the time it writes the tenth test. Workaround: summarize or excerpt the spec's relevant section explicitly in the prompt rather than relying on the agent to keep the whole page in working memory throughout a long session.
- Tool output truncation on large pages. A spec page with deeply nested toggles and a large block count can return a payload Cursor trims in the UI (though the underlying data was fetched) — if a section you expect to see referenced doesn't show up in the agent's summary, ask it to specifically re-check that section rather than assuming it's not there.
- No built-in spec-to-code diffing. There's no native feature that flags "this generated code doesn't match this spec section" automatically — that check is entirely on you or an explicit follow-up prompt asking the agent to cross-reference its own output against the spec one more time before you commit.
- Checkbox/to_do block matching by text is fragile. Marking a
to_doblock as checked works by matching its text content, which breaks if the spec's criterion wording was edited after the code was scaffolded against an earlier version. Keep spec edits and implementation status updates close together in time to avoid this drift. - Rate limiting on rapid iterative editing. Because Cursor's agent loop can call Notion tools frequently during an interactive session (re-reading the spec after every clarifying question), it's easier to hit Notion's ~3 req/sec average limit here than in a more batch-oriented terminal workflow. A burst of
429s mid-session usually just needs a short pause, not a config change.
Tips
- Excerpt the relevant spec section directly into long prompts rather than trusting the agent to hold an entire large page in context through a long session.
- If a spec section seems to be missing from a summary, explicitly ask the agent to re-check that block/toggle rather than assuming it doesn't exist.
- Keep spec edits and "mark as done" updates close together in time — text-basedto_domatching breaks if the criterion's wording drifted between scaffolding and completion.
Tips
Cursor's advantage for Notion MCP work is the single-context loop between spec and code — nothing else in this module lets an agent flip between "what does the spec say" and "what does the code do" as cheaply. The trade-off is a real context budget cost on long sessions with large pages, and matching logic (to_do text matching) that's fragile to spec drift.
Tips
- Reserve Notion-connected Agent sessions for genuine spec-to-code work — toggle the server off for unrelated refactoring to protect context budget.
- Insist on an honest "deviations from spec" note every time implementation status gets pushed back — it's the detail that keeps a spec-driven workflow trustworthy over months, not just for the first sprint.
- Treat a429mid-session as a pause-and-retry situation, not a sign something's broken — Notion's rate limit is tight enough that iterative Cursor sessions hit it more than batch workflows do.