Notion Forge is a reverse-engineered operations toolkit for Notion AI, custom Notion agents, and Notion-backed agent workflows. It combines a browser extension, Tampermonkey userscript, Python CLI, MCP server, dashboard, and dispatch utilities for working with Notion beyond the public API surface.
The original chat exporter is still here: it captures live and historical Notion AI conversations as Markdown or JSON, including tool calls, model info, thread titles, and conversation structure. The project now also manages custom agent instructions, publishes agent versions, queries workspace data, mirrors Claude.ai Project assets, audits Lab workflow state, and drives programmatic dispatch loops.
- AI conversation capture — live and historical Notion AI thread capture with Markdown/JSON export
- High-fidelity transcripts — tool calls, model info, thread titles, mentions, and conversation metadata
- Custom agent management — read, update, create, publish, and grant access for Notion AI agents
- MCP server — expose Notion agent, database, dispatch, and Claude Project operations to external agent clients
- Compressed Lab querying — delegate broad Notion questions to
lab_query, a MiniMax M2.5 query agent that returns canonical answers without flooding context with raw database JSON - Operational dashboard — inspect Notion databases and aggregate workflow state from a local web UI
- Lab dispatch plane — validate gates, build dispatch packets, ingest normal and fallback returns, and reconcile workflow state
- Typed tool catalog — per-tool metadata (surface, access, idempotency, latency, lab-query safety, approval gating) drives Lab Query's allowlist
- Connection inspection — read-only auth surface records (
inspect_connections,connection_health) report freshness without reading token bytes - Durable transition log — sqlite event-sourced mirror of dispatch/return events with deterministic IDs, replay checks, and anomaly detection
- Lab topology graph — deterministic node/edge export of agents, triggers, tools, and databases as JSON / DOT / Mermaid, plus drift diff
- Claude.ai Project sync — list, read, upload, delete, and sync Claude Project instructions and documents
- Multiple delivery surfaces — Firefox extension, Tampermonkey userscript, Python CLI, MCP tools, and local dashboard
| Component | Purpose |
|---|---|
manifest.json, background/, popup/, agent-manager/ |
Firefox extension for Notion AI capture/export and browser-side agent management |
tampermonkey/notion-ai-scraper.user.js |
Userscript version of the conversation capture/export path |
cli/mcp_server.py |
MCP server for Notion agents, databases, dispatch workflows, and Claude Project operations |
cli/update_agent.py, cli/create_agent.py |
CLI tools for custom Notion agent instruction and publish workflows |
cli/dashboard_server.py, dashboard/ |
Local dashboard for Notion database inspection and aggregation |
cli/dispatch.py, cli/dispatch_tools.py, cli/contracts/ |
Dispatch contract builder, validation gates, schemas, MCP tools, and return handling |
cli/tool_catalog.py, cli/connections.py, cli/transitions.py, cli/graph_export.py |
Typed tool metadata, auth surface inspection, durable transition log, and lab topology graph export |
cli/lab_query_contract.py |
Count-answer scope-label validator for Lab Query responses |
cli/claude_cli.py, cli/claude_client.py |
Claude.ai Project instruction/document sync |
- Download the latest
.xpifrom Releases - In Firefox:
about:addons→ gear icon ⚙️ → Install Add-on From File... - Select the
.xpi— it installs permanently and survives restarts
- Install Tampermonkey for your browser
- Install from Greasy Fork — or open the userscript and click Raw
- Tampermonkey will prompt you to install it
If using both, disable one — they'll double-capture if both are active.
Firefox extension:
- Navigate to any Notion AI chat page (
notion.so/...?wfv=chator open the AI sidebar) - Click the extension icon in the toolbar
- Conversations appear as you open chats — click Export All → MD or JSON
Tampermonkey:
- Navigate to a Notion AI chat page
- Click the Tampermonkey icon → use the menu commands:
Export All → MarkdownExport All → JSONShow capture statsClear captured conversations
To capture historical chats: open each chat thread in Notion — the extension captures messages as Notion fetches them. Clear Notion's IndexedDB cache (F12 → Application → Storage → Clear site data) to force a fresh fetch of all cached messages.
# Dump, update, or publish custom Notion agent instructions
cli/.venv/bin/python cli/update_agent.py librarian --dump
cli/.venv/bin/python cli/update_agent.py librarian path/to/instructions.md
# Run the MCP server
cli/.venv/bin/python cli/mcp_server.py
# Start the local dashboard
cli/.venv/bin/python cli/dashboard_server.py --port 8099
# Use the Claude Project sync CLI
cli/.venv/bin/python cli/claude_cli.py --helpFor broad Lab questions, prefer the lab_query agent through the notion-agents
MCP server instead of pulling large raw database payloads into context. It runs on
MiniMax M2.5 (fireworks-minimax-m2.5) and should preserve canonical answer
sets while compressing output. Exact count answers must state their scope; the
current smoke check is:
Work Items: 581 total; Dispatch Ready: 22.
The dispatch return path has two MCP surfaces: handle_final_return for normal
execution-plane returns with a dispatch packet/run ID, and direct_closeout_return
for fallback closeout when no GitHub issue or trusted dispatch packet exists. Both
stamp Return Received At / Return Consumed At and append result blocks so the
Intake Clerk can continue the pipeline.
See cli/README.md, CLAUDE.md, and docs/LAB_LOOP_V1_PROTOCOL.md for the operational tooling.
[
{
"id": "thread-abc123",
"title": "Pre-Flight Controller validation task",
"model": "avocado-froyo-medium",
"turns": [
{ "role": "user", "content": "Create a pre-flight checklist page", "timestamp": 1234567890 },
{ "role": "assistant", "content": "I'll create that page now...", "thinking": "The user wants...", "timestamp": 1234567891 }
],
"toolCalls": [
{ "tool": "create_page", "input": { "title": "Pre-Flight Checklist" } }
],
"createdAt": 1234567890
}
]# Notion AI Chat — Pre-Flight Controller validation task (avocado-froyo-medium)
_ID: thread-abc123_
**You**
Create a pre-flight checklist page
---
**Notion AI**
I'll create that page now...Notion AI uses two private API endpoints:
| Endpoint | Purpose |
|---|---|
POST /api/v3/runInferenceTranscript |
Live streaming responses (NDJSON) |
POST /api/v3/syncRecordValuesSpaceInitial |
Historical thread + message records |
The interceptor patches window.fetch in the page's main JavaScript context (before Notion's SES lockdown runs) to observe both endpoints.
- Extension: uses
"world": "MAIN"in the manifest; a bridge script relays data to the background service worker viapostMessage - Tampermonkey: uses
@grant unsafeWindowto patch the real page fetch directly
See docs/ARCHITECTURE.md for protocol details.
# Lint
npx web-ext lint
# Sign for self-distribution (requires AMO API key)
npx web-ext sign --api-key=YOUR_KEY --api-secret=YOUR_SECRET --channel=unlisted‣page mentions in assistant text can't be resolved — Notion streams them as bare Unicode characters with no metadata. User message mentions are resolved to[page:id]/[user:id]/[agent:id].- Messages already in Notion's local OPFS/SQLite cache won't transit the network — clear site data to force a re-fetch.
See CREDITS.md.
MIT
