This is a submission for the Notion MCP Challenge
What I Built
Notion Cortex is a multi-agent AI research system that uses Notion as its operating system β not just an output destination, but the shared coordination layer where agents think, communicate, and await human approval.
Give it any topic, and five specialized AI agents fan out in parallel:
- Scout agents (x5) research different angles simultaneously, extracting structured entities into a Knowledge Graph
- Analyst cross-references all findings, identifies patterns and gaps
- Synthesizer streams a structured synthesis directly into Notion as it thinks
- Approval Gate pauses execution and waits for you to review in Notion β set Status to "Approved" to continue
- Writer produces a publication-ready intelligence brief with headings, entity tables, and conclusions
Every agent's reasoning streams into its own Working Memory page in real time. You can literally watch them think in Notion.
$ notion-cortex "The rise of autonomous AI agents in software engineering"
π§ Notion Cortex β starting run for: "The rise of autonomous AI agents..."
π Bootstrapping Notion workspace...
β
Workspace ready (1.6s)
π§© Decomposing topic into research angles...
5 angles identified
π Running 5 Scout agents (concurrency: 3)...
β
Scout 1 done
β
Scout 2 done
...
π All Scouts complete (103s). Running Analyst...
β
Analyst done (31s)
πΈοΈ Computing knowledge graph relations...
β
Relations linked (8s)
π Running Synthesizer...
β
Synthesis written (23s)
βοΈ Running Writer...
β
Writer done (43s)
π Done in 229s! Intelligence brief: https://notion.so/...
Video Demo
The demo shows a complete run from notion-cortex "topic" through all 5 agent phases to the final intelligence brief in Notion.
Show us the code
GitHub: github.com/tyy130/notion-cortex
Architecture
src/
index.ts CLI entry point + setup wizard
cleanup.ts Archives all cortex-* databases for a fresh start
orchestrator.ts Pipeline coordinator
llm.ts Dual-provider streaming (OpenAI + Anthropic)
streaming.ts Token buffer β timed Notion block flush
concurrency.ts Write queue (p-limit) + exponential backoff retry
types.ts Zod schemas for all database entry types
agents/
scout.ts Research + entity extraction via MCP
analyst.ts Cross-scout analysis + KG enrichment
synthesizer.ts Structured synthesis streamed to Working Memory
writer.ts Final brief written to Outputs database
notion/
bootstrap.ts Idempotent 5-database workspace creation
client.ts Notion SDK singleton
mcp-client.ts Notion MCP server (stdio transport)
task-bus.ts Agent task queue CRUD
working-memory.ts Streaming page writer + content reader
knowledge-graph.ts Entity store with serialized upsert
approval-gates.ts Human-in-the-loop polling
outputs.ts Final page publisher
markdown-blocks.ts Markdown β Notion block converter
utils.ts Shared helpers
Key Technical Decisions
Serialized KG upsert: Parallel scouts can discover the same entity simultaneously. A pLimit(1) queue wraps the check-then-create operation, making the upsert atomic without a database lock.
Two-queue concurrency design: writeQueue (pLimit(3)) handles Notion API rate limiting. kgUpsertQueue (pLimit(1)) handles logical atomicity. Different concerns, different queues.
Idempotent bootstrap with archived filtering: bootstrapWorkspace searches for existing cortex-* databases and reuses them. It filters out archived databases (Notion's search API returns them by default) and uses databases.update to ensure schema migrations apply to pre-existing databases.
Dual-provider LLM abstraction: Supports OpenAI (default) and Anthropic with streaming and multi-turn tool-use loops. Switch with one env var.
55 tests across 13 files: Full coverage of the orchestrator pipeline, all agents, concurrency utilities, markdown converter, and Notion data layer.
Quick Start
git clone https://github.com/tyy130/notion-cortex.git
cd notion-cortex
npm install
notion-cortex setup # interactive wizard
notion-cortex "your research topic"
How I Used Notion MCP
Notion isn't just where output ends up β it's the runtime substrate. The Notion MCP server (@notionhq/notion-mcp-server) runs as a stdio subprocess, giving Scout agents access to notion_search β they check what knowledge already exists in the workspace before extracting new entities, avoiding redundant work across runs.
Beyond MCP search, each database works as infrastructure through the Notion SDK:
1. Task Bus (agent coordination)
The orchestrator creates tasks, scouts claim them via assigned_agent, and status transitions (pending β active β done β blocked) drive the pipeline forward. This is a distributed task queue implemented entirely in Notion.
2. Working Memory (streaming scratchpad)
Each agent gets a dedicated Notion page. As tokens stream from the LLM, a timed buffer flushes them as paragraph blocks to the page every second. You can open a scout's Working Memory page and watch it think in real time.
3. Knowledge Graph (structured entity store)
Scouts extract entities (companies, products, trends, concepts) with claims, confidence levels, and source URLs. A serialized upsert queue (pLimit(1)) prevents duplicate entities when parallel scouts find the same thing. After the Analyst pass, computeAndStoreRelations scans all entities and auto-links them using Notion's relation property β if "GitHub Copilot" appears in another entity's claim, they get linked.
4. Approval Gates (human-in-the-loop)
Before the Writer runs, an approval gate creates a Notion database entry with status "Pending" and a link to the synthesis. The system polls with exponential backoff until you change the status to "Approved" or "Rejected" in Notion. This is genuine human-in-the-loop control β not a dialog box, but a Notion workflow.
5. Outputs (final deliverables)
The Writer converts its markdown output into native Notion blocks β headings, bullet lists, numbered lists, tables, code blocks, bold/italic, and links β using a custom markdownToNotionBlocks converter. The result is a proper Notion page, not a pasted text blob.
Final Thoughts
The most surprising thing about this project was how naturally Notion works as an agent coordination layer. Databases become task queues. Pages become working memory. Relations become a knowledge graph. Status properties become approval gates. It's not a hack β it's genuinely the right tool for this.
The human-in-the-loop approval gate is my favorite feature. Most agent systems are either fully autonomous or require you to babysit a terminal. With Cortex, you get a Notion notification, review the synthesis at your own pace, and approve when ready. The agents wait patiently.
MIT licensed. PRs welcome.
Top comments (0)