Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

2 Commits

Repository files navigation

notionproxy

A tiny local server + CLI that lets you talk to Notion's private API — including Notion AI — from your terminal, scripts, or curl.

It runs entirely on your machine, uses your own Notion login, and ships as a single file (notionproxy.js). No build step, no dependencies to install.

# ask Notion AI from your terminal
bun notionproxy.js ai "explain recursion in one sentence"# or run the HTTP server and use curl
bun notionproxy.js
curl -X POST http://127.0.0.1:3000/ai \
-H "Content-Type: application/json" \
-d '{"prompt":"explain recursion in one sentence"}'

Heads-up: This talks to Notion's internal API (/api/v3), which is undocumented and not officially supported. It's great for personal use and tinkering, but Notion could change it at any time. Use it on your own account.


Table of contents

  1. What you can do with it
  2. Requirements
  3. Setup (step by step)
  4. Quick start
  5. The ai CLI
  6. HTTP API reference
  7. Choosing a model
  8. Configuration (.env)
  9. What's in this repo
  10. Troubleshooting
  11. Security & privacy

What you can do with it

  • 💬 Ask Notion AI questions (one-shot or an interactive chat that remembers the conversation).
  • 🌐 Optionally let the AI search the web.
  • 🧠 Pick any model your account has (Claude, GPT, Gemini, Grok, and more) using friendly names like claude-opus-4.8.
  • 📡 Stream answers as they're generated (Server-Sent Events).
  • 📄 Read Notion pages and list your workspaces.
  • 🔌 Send raw requests to any /api/v3 endpoint (for power users).

Requirements

  • Bun (a fast JavaScript runtime). Install it once:

    # macOS / Linux
    curl -fsSL https://bun.sh/install | bash
    # Windows (PowerShell)
    powershell -c "irm bun.sh/install.ps1 | iex"

    Check it works: bun --version

  • A Notion account (the AI features need a workspace where Notion AI is enabled).

  • A Chromium browser (Chrome, Edge, Brave…) to grab your login token with the included extension — or you can copy the cookie manually.


Setup (step by step)

1. Get the files

Clone or download this repo. You only need two things to run it: notionproxy.js and your own .env.

2. Grab your Notion credentials

The proxy logs in as you using a browser session cookie called token_v2. The easiest way to get it is the one-click extension included in this repo.

Using the extension (recommended):

  1. Open your browser's extensions page: chrome://extensions (or edge://extensions).

  2. Turn on Developer mode (toggle, usually top-right).

  3. Click Load unpacked and select the extension/ folder in this project.

  4. Make sure you're logged in at notion.so in that browser.

  5. Click the "Notion Proxy Credentials" extension icon → Copy .env.

  6. It copies something like:

    NOTION_TOKEN_V2=v02%3A...
    NOTION_USER_ID=00000000-0000-0000-0000-000000000000
    

The extension only reads your cookies locally. Nothing is sent anywhere except Notion itself.

Manual alternative: open notion.so → DevTools → Application → Cookies → copy the value of token_v2.

3. Create your .env file

cp .env.example .env

Open .env and paste your token (and user id if you have it):

NOTION_TOKEN_V2=v02%3A... # requiredNOTION_USER_ID=... # recommended (the extension fills this in)# NOTION_SPACE_ID=... # optional: pin a specific workspace

That's it — you're ready. notionproxy.js auto-loads .env from the current folder.


Quick start

Option A — the CLI (simplest):

bun notionproxy.js ai "write a haiku about the sea"

Option B — the HTTP server:

bun notionproxy.js
# → [notionproxy] listening on http://127.0.0.1:3000

Then in another terminal:

# is my token working?
curl http://127.0.0.1:3000/health
# ask the AI
curl -X POST http://127.0.0.1:3000/ai \
-H "Content-Type: application/json" \
-d '{"prompt":"give me 3 productivity tips"}'

The ai CLI

Run bun notionproxy.js ai <command>. If you don't pass a known command, your words are treated as the prompt.

CommandWhat it does
bun notionproxy.js ai "your question"Ask a one-shot question
bun notionproxy.js ai chatInteractive chat that remembers the session
bun notionproxy.js ai modelsList every model your account can use
bun notionproxy.js ai spacesList your workspaces and whether Notion AI is available
bun notionproxy.js ai whoamiShow which account the token belongs to

Flags:

FlagMeaningExample
--model <id>Pick a model--model claude-opus-4.8
--webLet the AI search the web--web
--space <id>Use a specific workspace--space 1234abcd-...

Examples:

bun notionproxy.js ai --model gpt-5.5 "summarize the theory of relativity"
bun notionproxy.js ai --web "what shipped in the latest TypeScript release?"

Interactive chat supports in-session commands:

bun notionproxy.js ai chat
you> /model grok-4.3 # switch model
you> /web on # turn on web search
you> /reset # forget the conversation
you> /quit # exit

HTTP API reference

Start the server with bun notionproxy.js. Base URL (default): http://127.0.0.1:3000

GET /health

Checks that your token is valid.

curl http://127.0.0.1:3000/health
# { "ok": true, "notionStatus": 200 }

GET /models

Lists available models with friendly ids.

curl http://127.0.0.1:3000/models

GET /spaces

Lists your workspaces and account record (raw Notion getSpaces).

GET /page/:id

Loads a Notion page by id.

curl http://127.0.0.1:3000/page/1234abcd5678ef901234abcd5678ef90

POST /ai

Ask Notion AI. Body fields (only prompt is required):

FieldTypeDescription
promptstringrequired — your question
modelstringmodel id / name / codename (see below)
webbooleanenable web search
spacestringworkspace id to use
streambooleanstream the reply as it's generated

Normal (one JSON reply):

curl -X POST http://127.0.0.1:3000/ai \
-H "Content-Type: application/json" \
-d '{"prompt":"what is 2+2?","model":"claude-opus-4.8"}'
{
"reply": "2 + 2 = 4.",
"model": { "id": "claude-opus-4.8", "name": "Opus 4.8", "family": "anthropic", "codename": "ambrosia-tart-high", "default": false },
"prompt": "what is 2+2?"
}

Streaming (stream: true) — returns text/event-stream:

curl -N -X POST http://127.0.0.1:3000/ai \
-H "Content-Type: application/json" \
-d '{"prompt":"write a short poem","stream":true}'
data: {"delta":"Waves "}
data: {"delta":"roll in slow…"}
data: {"done":true,"model":{"id":"claude-opus-4.8", ...}}

(The -N flag tells curl not to buffer, so you see chunks live.)

POST /v3/:endpoint (advanced)

Raw passthrough to any Notion /api/v3 endpoint — the body is forwarded as-is.

curl -X POST http://127.0.0.1:3000/v3/getSpaces \
-H "Content-Type: application/json" -d '{}'

Choosing a model

See what your account offers:

bun notionproxy.js ai models
ID NAME FAMILY CODENAME
gpt-5.5 GPT-5.5 openai opal-quince-medium
claude-opus-4.8 Opus 4.8 anthropic ambrosia-tart-high
grok-4.3 Grok 4.3 xai xigua-mochi-medium
...

You can pass a model as the friendly id (claude-opus-4.8), the display name (Opus 4.8), or Notion's raw codename (ambrosia-tart-high) — all resolve to the same model. If you omit model, a sensible default is used.


Configuration (.env)

VariableRequiredDefaultDescription
NOTION_TOKEN_V2✅ yesYour Notion session cookie (full account access — keep secret).
NOTION_USER_IDrecommendedYour user id; some endpoints need it.
NOTION_SPACE_IDnoautoPin a workspace. If blank, one with AI enabled is auto-selected.
HOSTno127.0.0.1Network interface to bind. Keep it localhost.
PORTno3000Port to listen on.
NOTION_CLIENT_VERSIONno23.13.0.10Sent as notion-client-version; bump if Notion starts rejecting.

What's in this repo

.
├── notionproxy.js # the whole app — server + CLI in one file
├── extension/ # one-click browser extension to grab your token
├── .env.example # copy to .env and fill in
└── README.md

Run it with bun notionproxy.js (server) or bun notionproxy.js ai "..." (CLI). No bun install needed — it has no dependencies.


Troubleshooting

SymptomFix
Missing NOTION_TOKEN_V2 on startupYou haven't created .env or filled in the token. See Setup.
/health returns ok: false / status 401Your token_v2 expired. Re-grab it with the extension and update .env.
port 3000 is in useAnother copy is running. Stop it: lsof -ti tcp:3000 | xargs kill, or set a different PORT.
AI replies [Notion AI unavailable…]That workspace has no AI plan or you hit the usage limit. Try bun notionproxy.js ai spaces to find one with AI, then set NOTION_SPACE_ID.
"No Notion AI chats exist yet"Open Notion, send one message to Notion AI manually, then retry (the tool reuses a real chat thread).

Security & privacy

  • NOTION_TOKEN_V2 is a session cookie that grants full access to your Notion account. Treat it like a password: never commit it, never share it. .env is already in .gitignore.
  • The server binds to 127.0.0.1 (localhost) with no authentication. That's fine for personal local use. Do not change HOST to 0.0.0.0 or expose the port — anyone who could reach it would be using your Notion account.
  • Everything runs locally. The only outbound calls are to notion.so itself.
  • This uses Notion's private API and is intended for personal use; it isn't affiliated with or endorsed by Notion.

License

Licensed under a modified MIT license that requires attribution: the credit

Made By VK — https://discord.gg/bnZa5uDCmV

must be kept in copies of the software and in its output (including the startup banner). See LICENSE for the full terms.

About

Use AI models through Notion with a simple API. Lightweight proxy for integrating Notion AI into your applications.

Resources

Stars

9 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages