# Notion Mcp Server

> Notion MCP server for Claude, Cursor, ChatGPT & Claude Desktop. Connect AI agents to Notion via Model Context Protocol — pages, databases, blocks, comments, files.

- **Type:** MCP server
- **Install:** `agentstack add mcp-awkoy-notion-mcp-server`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [awkoy](https://agentstack.voostack.com/s/awkoy)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [awkoy](https://github.com/awkoy)
- **Source:** https://github.com/awkoy/notion-mcp-server
- **Website:** https://www.npmjs.com/package/notion-mcp-server

## Install

```sh
agentstack add mcp-awkoy-notion-mcp-server
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Notion MCP Server — Connect Claude, Cursor & ChatGPT to Notion via Model Context Protocol

[](https://smithery.ai/server/@awkoy/notion-mcp-server)

An agent-first **Notion MCP server** (Model Context Protocol) that connects Claude, Cursor, ChatGPT, Claude Desktop, Cline, Zed and other MCP-compatible AI clients to Notion. Sign in once with your Notion **Personal Access Token (PAT)** — no per-page sharing dance, no extra integration to set up. Your AI sees the Notion pages you authorize the token for (typically your whole workspace) and can create pages, query databases, append blocks, leave comments, and upload files in natural language.

> **v2.4 — built for AI agents, not REST clients.** Two MCP tools instead of 36 endpoints, batched mutations, idempotency keys, automatic retries on Notion rate limits, self-healing validation errors (now path-sliced to 
  

## 📑 Table of Contents

- [5-minute install (no coding required)](#-5-minute-install-no-coding-required)
- [Why this server? (vs. the official Notion MCP)](#-why-this-server-vs-the-official-notion-mcp)
- [Developer install](#-developer-install)
  - [Authentication: PAT (recommended) vs. Internal Integration](#authentication-pat-recommended-vs-internal-integration)
  - [Get a Personal Access Token — full walkthrough](#get-a-personal-access-token--full-walkthrough)
  - [Backward compatibility from v1.x](#backward-compatibility-from-v1x)
  - [Claude Code / Cursor / Claude Desktop](#claude-code--cursor--claude-desktop)
  - [Docker / Podman / OrbStack](#docker--podman--orbstack)
  - [Optional `NOTION_PAGE_ID`](#optional-notion_page_id)
- [Remote / HTTP transport](#-remote--http-transport)
- [Features: what this Notion MCP server does](#-features-what-this-notion-mcp-server-does)
- [MCP tools for Notion (`notion_execute` & `notion_describe`)](#-mcp-tools-for-notion-notion_execute--notion_describe)
  - [`notion_execute`](#notion_execute)
  - [`notion_describe`](#notion_describe)
  - [Operations menu (35 ops, plus one alias)](#operations-menu-35-ops-plus-one-alias)
- [Development](#-development)
- [Technical details: how the Notion MCP server is built](#-technical-details-how-the-notion-mcp-server-is-built)
- [Troubleshooting the Notion MCP server](#-troubleshooting-the-notion-mcp-server)
- [FAQ: Notion MCP server](#-faq-notion-mcp-server)
- [Contributing](#-contributing)
- [License](#-license)

---

## 🪄 5-minute install (no coding required)

You don't need to know what a terminal is. If you can copy text and paste it into two boxes, you can finish this.

### What you'll get
After setup, you can tell Claude things like:

- *"Make a page in my Personal workspace called 'Q3 plan' and add a checklist of these five items."*
- *"Find every page in my Tasks database where Status is 'Doing' and tell me which are overdue."*
- *"Comment on yesterday's meeting notes with a one-paragraph summary."*

Claude reads and writes Notion directly — no copy/paste, no browser tabs.

### What you'll need
1. A Notion account.
2. The [Claude Desktop app](https://claude.ai/download) installed. (Cursor and Claude Code work too — see [Developer install](#-developer-install).)
3. About 5 minutes.

### Step 1 — Get your Notion Personal Access Token

A Personal Access Token (PAT) is like a key that lets the AI act as **you** inside Notion. It can see every page **you** can see — no per-page setup.

1. Open the Notion developer portal: **[notion.so/profile/integrations](https://www.notion.so/profile/integrations)** (while logged into Notion). Same page if you go through the app: **Settings → Connections → Develop or manage integrations**.
2. Open the **Personal access tokens** tab → click **+ New personal access token**.
3. Give it a name like `Claude`, pick the **workspace** the token should act in, leave the default capabilities checked, and click **Create token**.
4. **Copy** the token — Notion shows the full value **only once**. It starts with `ntn_`. Treat it like a password.

> PATs **expire 1 year after creation**. Set a calendar reminder to rotate before then, or auth will start failing.
>
> Don't see a "Personal access tokens" tab? Your workspace admin may have disabled them — use the [Internal Integration alternative](#authentication-pat-recommended-vs-internal-integration).
>
> Need more detail (rotation, revocation, what a PAT can/can't do)? See the [full PAT walkthrough](#get-a-personal-access-token--full-walkthrough) further down. Official reference: [Notion PAT guide](https://developers.notion.com/guides/get-started/personal-access-tokens).

### Step 2 — Tell Claude Desktop where the server lives

1. Open Claude Desktop → click **Claude** (top-left menu on Mac, or the hamburger menu on Windows) → **Settings** → **Developer** → **Edit Config**.
2. A file called `claude_desktop_config.json` opens in a text editor. **Don't panic at the curly braces** — it's just text. We're going to swap all of it out.
3. **Select all** the text in that file (`Cmd+A` on Mac, `Ctrl+A` on Windows), **delete it**, then paste the block below.

```json
{
  "mcpServers": {
    "notion": {
      "command": "npx",
      "args": ["-y", "notion-mcp-server"],
      "env": {
        "NOTION_TOKEN": "ntn_paste_your_token_here"
      }
    }
  }
}
```

> **What is this block?** It tells Claude Desktop how to launch the Notion connector. `npx` is a small tool that downloads and runs the connector automatically the first time — you don't install anything separately, it happens in the background (the first run may take a few seconds). `env` is where your Notion token goes. Leave every quote mark and bracket exactly as shown; the only thing you change is the token.

4. Replace `ntn_paste_your_token_here` with the token you copied in Step 1 — **leave the quotation marks around it**.
5. **Save** the file (`Cmd+S` / `Ctrl+S`).
6. **Quit Claude Desktop completely** (Mac: `Cmd+Q`, not just closing the window — Windows: right-click the tray icon → Quit) and reopen it.

### Step 2b — Did it work?

After Claude Desktop reopens, start a new chat and type **`/`** in the message box. You should see `notion_execute` and `notion_describe` appear in the slash-command list. If they don't, the connection didn't take — go back to **Settings → Developer → Edit Config**, check there's no typo in the token (it must stay between the quotation marks), and confirm you fully quit and reopened Claude Desktop. Common pitfalls are also covered in [Troubleshooting](#-troubleshooting-the-notion-mcp-server).

### Step 3 — Try it

In a new Claude chat, type:

> *"Use Notion to make a new page called 'Hello from Claude' under my workspace and add a checklist of three things I want to try today."*

You should see Claude call the `notion_execute` tool and report back with a page link. Click it — your new page is live in Notion.

That's it. If something doesn't work, the most common fix is in [Troubleshooting](#-troubleshooting-the-notion-mcp-server) below — usually a token typo or Claude Desktop not being fully quit and reopened. The rest of this README covers Docker, Cursor, Claude Code, and self-hosting for developers.

---

## ⚡ Why this server? (vs. the official Notion MCP)

There's a [first-party Notion MCP server](https://github.com/makenotion/notion-mcp-server). It works for simple one-off calls. For agent workloads — repeated queries, bulk mutations, long context windows — it gets expensive fast: one MCP tool per endpoint, no batching, no idempotency, raw response shapes. Those choices add up to real token cost and real latency.

This server is designed from the agent's side of the protocol.

| Capability | Official Notion MCP | **This server (designed for agents)** |
| --- | --- | --- |
| **Tool surface** | 22 tools (one per endpoint) loaded into context | **2 tools** (`notion_execute`, `notion_describe`) — the LLM loads ~90% less schema |
| **Operations covered** | ~22 endpoints | **35 operations** (plus a `trash_page` alias of `archive_page`) across pages, blocks, databases, data sources, comments, users, files |
| **Primary auth** | Internal Integration token + per-page "Connect" sharing | **Personal Access Token (PAT)** — uses the pages you've authorized for the token, zero per-page Connect step |
| **Batch mutations** | Not documented | ✅ Universal `{ items: [...] }` envelope; runs up to **10 in parallel** |
| **Atomic batches + rollback** | Not documented | ✅ `atomic: true` aborts on first failure, best-effort archives entities created earlier |
| **Idempotency** | Not documented | ✅ `idempotency_key` — same key + same op returns the cached result for 5 minutes |
| **Rate-limit handling** | Not documented (429s bubble up) | ✅ Shared token-bucket limiter (3 req/s default, configurable via `NOTION_RATE_LIMIT`) + exponential backoff on 429/5xx/timeouts, honors `Retry-After` |
| **Response shapes** | Raw Notion SDK JSON | **Slim shapers by default** — drops `archived: false`, `created_time`, `last_edited_time`, `in_trash: false`, empty descriptions, etc. `verbose: true` to opt out |
| **Database queries** | Raw `properties` bag per row | **Flattened** name → primitive map (title, rich_text, number, select, multi_select, status, date, people, files, checkbox, url, email, phone_number, formula, relation, rollup, unique_id, verification, created_by, last_edited_by, timestamps) |
| **Wire format** | Default SDK serialization | **Compact (un-indented) JSON** — ~30% smaller payloads vs. indented output, identical to parse |
| **Markdown input** | Page-level markdown editing supported | ✅ `markdown` shortcut on `create_page` / `append_blocks` / `update_block`, full markdown round-trip via `get_page_markdown` / `update_page_markdown`, plus markdown comment bodies — full GFM (paragraphs, headings 1–4, lists, to-dos with nested children, blockquotes, fenced code with language detection, images, dividers, inline bold/italic/strike/code/links) |
| **File uploads** | Not in the documented tool surface | ✅ `upload_file` handles single-part and multi-part (5 MB chunks) transparently; MIME inferred from filename; rejects `application/octet-stream` |
| **Validation errors** | Plain error string | **Self-healing**: `{ code, message, path, issues, schema, example, fix }` — agent corrects bad payloads in one round-trip without calling describe |
| **Notion API version** | Not pinned in client config | Pinned to `2025-09-03` (the modern data-sources line) |

### Real-world impact

- **Renaming 50 pages.** Without a batch envelope, the agent issues 50 separate `update-page` MCP calls — each one re-loading the tool schema and serialized through the agent's reasoning loop. With this server, the agent issues one `notion_execute` call with `{ items: [...], concurrency: 10 }`. Wall-clock improvement is roughly an order of magnitude on typical batch sizes; the bigger win is the tokens saved on prompt overhead.
- **Loading the tool list into the agent's context.** Official server: 22 schema blobs every conversation. This server: 2 schema blobs — and only those 2 ever appear in the agent's tool list, regardless of which of the 35 operations the agent ends up calling.
- **Reading a 100-row database.** Official server returns the raw Notion `properties` bag per row. This server flattens it; for a typical CRM table this is roughly **5–10× fewer tokens** without losing information.

---

## 🚀 Developer install

### Authentication: PAT (recommended) vs. Internal Integration

There are two ways to authenticate. Both use the `NOTION_TOKEN` env var — only how you obtain the token differs.

| | **Personal Access Token** (recommended) | **Internal Integration** (legacy) |
| --- | --- | --- |
| Where you get it | [notion.so/profile/integrations](https://www.notion.so/profile/integrations) → **Personal access tokens** tab → **+ New personal access token** | [notion.so/profile/integrations/internal](https://www.notion.so/profile/integrations/internal) → **+ New connection** |
| Token prefix | `ntn_…` | `ntn_…` (new) or `secret_…` (older) |
| Scope | Everything **you** can see | Only pages where you've clicked **• • • → Connect → \** |
| Setup friction | None — works immediately | Per-page Connect dance for every page or database the agent should touch |
| When to use | Default. Personal workspaces, team workspaces where you're authorized, prototyping. | When a workspace admin requires explicit per-resource scoping for compliance, or for shared production bots. |

The rest of this README assumes PAT. Swap in an integration secret if you prefer the scoped model — every command below is identical.

> 💡 **Heads-up:** most "object_not_found" errors are a wrong auth choice, not a bug. If your agent reports "Could not find page" on pages you can see in Notion, you're almost certainly using an Internal Integration token that hasn't been Connected to those pages — switch to a PAT.

### Get a Personal Access Token — full walkthrough

[Step 1 of the 5-minute install](#step-1--get-your-notion-personal-access-token) covers the happy path. This section covers what surrounds it: capabilities, expiry, revocation, and the admin-disabled fallback.

> 📖 Official: [Notion PAT guide](https://developers.notion.com/guides/get-started/personal-access-tokens) · [Authorization overview](https://developers.notion.com/docs/authorization).

#### What a PAT can and can't do

| Can | Can't |
| --- | --- |
| Read every page you have access to | Access workspaces or pages you personally can't see |
| Create / update pages and databases in workspaces where you have edit rights | Bypass workspace permission rules |
| Add comments under your identity | Act as another user |
| Upload files via the File Upload API | Modify workspace-level admin settings |

A PAT is a **scope = your account**. If you lose edit access to a page, the PAT loses it too. Issue separate tokens to teammates — don't share one.

#### Expiry and rotation

**PATs expire 1 year after creation** ([Notion docs](https://developers.notion.com/guides/get-started/personal-access-tokens)). After expiry, every API call returns an auth error until you replace the token. Set a calendar reminder for ~11 months out.

#### Revoking a PAT

1. Open **[notion.so/profile/integrations](https://www.notion.so/profile/integrations)** → **Personal access tokens** tab.
2. Find the token by name → **• • • → Revoke**.
3. Update `NOTION_TOKEN` in your MCP client config and restart the client.

Workspace admins can revoke any user's PATs from **Settings & members → Connections → All personal access tokens**. Revocation is immediate.

#### Workspace admin disabled PATs?

Some enterprise workspaces only allow scoped Internal Integrations. Two options:

1. **Ask your admin to enable PATs** for your account.
2. **Use the [Internal Integration](#authentication-pat-recommended-vs-internal-integration) path** — same `NOTION_TOKEN` env var; create it at **[notion.so/profile/integrations/internal](https://www.notion.so/profile/integrations/internal) → + New connection**, then click **• • • → Connect** on every page or database you want the agent to touch.

### Backward compatibility from v1.x

If you ran a v1.x setup, **nothing in your environment needs to change**. Both env vars still work:

| Env var | Status in v2.4 | Notes |
| --- | --- | --- |
| `NOTION_TOKEN` | ✅ Required | Accepts **PATs** (`ntn_…`, recommended) and **Internal Integration secrets** (`secret_…` or `ntn_…`, legacy). Identical handling. |
| `NOTION_PAGE_ID` | ✅ Optional | Still works as the default parent page for `create_page` / `create_database` when no `parent` is passed. v2 added a clean `missing_parent` validation error instead of v1's crash when neither is provided. |
| `NOTION_RATE_LIMIT` | ✅ New, optional | Requests per second for the shared limiter. Defaults to `3` (Notion's documented per-integration limit). |
| `NOTION_ALLOWED_OPERATIONS` | ✅ New, optional | Comma-separated allowlist of operations or group presets (`read`, `write`, `destructive`, plus per-domain groups `pages

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [awkoy](https://github.com/awkoy)
- **Source:** [awkoy/notion-mcp-server](https://github.com/awkoy/notion-mcp-server)
- **License:** MIT
- **Homepage:** https://www.npmjs.com/package/notion-mcp-server

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-awkoy-notion-mcp-server
- Seller: https://agentstack.voostack.com/s/awkoy
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
