Skip to main content
Glama

notion

mcp-name: io.github.n24q02m/better-notion-mcp

Markdown-first Notion for AI agents -- pages, databases, blocks, and comments in one call.

Mode CI codecov npm Docker License: Apache-2.0

TypeScript Node.js Notion semantic-release Renovate

Project

Tagline

Tag

agent-chat-plugin

Peer AI agents chat in a shared folder — no human relay, no orchestrator, wor...

Tooling

better-code-review-graph

Knowledge graph for token-efficient code reviews -- semantic search and call-...

MCP

better-drive

2-way Google Drive sync with .driveignore filter — rclone engine, Windows tray

Tooling

better-email-mcp

IMAP/SMTP email for AI agents -- read, send, organize folders, and manage att...

MCP

better-godot-mcp

Composite MCP server for Godot Engine -- 17 composite tools for AI-assisted g...

MCP

better-notion-mcp

Markdown-first Notion for AI agents -- pages, databases, blocks, and comments...

MCP

better-semantic-release

Drop-in python-semantic-release fork with built-in release-safety guards (orp...

Tooling

better-telegram-mcp

Telegram for AI agents -- messages, chats, media, and contacts across both bo...

MCP

better-workspace-mcp

Google Workspace MCP server (Docs/Drive/Calendar/Gmail/Sheets/Slides/Tasks/Ch...

MCP

claude-plugins

Claude Code plugin marketplace for the n24q02m MCP servers -- install web sea...

Marketplace

imagine-mcp

Image and video understanding + generation for AI agents -- across Gemini, Op...

MCP

jules-task-archiver

Chrome Extension for bulk operations on Jules tasks via batchexecute API -- a...

Tooling

mcp-core

Shared foundation for building MCP servers -- Streamable HTTP transport, OAut...

MCP

mnemo-mcp

Persistent AI memory with hybrid search and embedded sync. Open, free, unlimi...

MCP

qwen3-embed

Lightweight Qwen3 text embedding and reranking via ONNX Runtime and GGUF

Library

skret

Secrets without the server.

CLI

tacet

A self-distilling neuro-symbolic cascade that amortises LLM cost across knowl...

Tooling

web-core

Shared web infrastructure package for search, scraping, HTTP security, and st...

Library

wet-mcp

Open-source MCP server for AI agents: web search, content extraction, and lib...

MCP

Table of contents

Related MCP server: WET - Web Extended Toolkit

Features

  • Markdown in, Markdown out -- human-readable content instead of raw JSON blocks

  • 8 composite tools, 39 actions -- one call instead of chaining 2+ atomic Notion endpoints (plus config and help)

  • Auto-pagination and bulk operations -- no manual cursor handling or looping

  • Tiered token optimization -- ~77% reduction via compressed descriptions + on-demand help tool

  • Dual transport -- local stdio (integration token) or remote HTTP (per-user or shared bearer token)

Install

Run with npx (Node.js >= 24) and a Notion integration token from https://www.notion.so/my-integrations (starts with ntn_):

// MCP client config (e.g. .mcp.json / Claude Code / Cursor)
{
  "mcpServers": {
    "notion": {
      "command": "npx",
      "args": ["--yes", "@n24q02m/notion@latest"],
      "env": { "NOTION_TOKEN": "ntn_your_token_here" }
    }
  }
}

The package is @n24q02m/notion (formerly @n24q02m/better-notion-mcp; old package receives one final release then freezes). The MCP Registry id stays io.github.n24q02m/better-notion-mcp, and the legacy better-notion-mcp command is kept as an alias of notion.

Or run the published Docker image (stdio):

docker run --rm -i -e NOTION_TOKEN=ntn_your_token_here n24q02m/notion:latest

Install matrix

Client

Install

Claude Code

/plugin marketplace add n24q02m/claude-plugins + /plugin install better-notion-mcp@n24q02m-plugins (stdio; prompts for NOTION_TOKEN), or an mcpServers entry in .mcp.json / client settings

Codex CLI

[mcp_servers.notion] block in ~/.codex/config.toml (stdio command/args or HTTP type/url)

OpenCode

mcpServers block in opencode.json

Cursor / Windsurf / Gemini CLI / any MCP client

mcpServers JSON in the client's config — same shape as the example above

Full per-client walkthroughs: docs.n24q02m.com/servers/notion/setup/. See the Documentation section for per-client setup (Claude Code, Codex, Gemini CLI, Cursor, Windsurf) and HTTP mode.

CLI

Installing the package exposes a notion binary (plus the legacy better-notion-mcp alias; run it with npx or after a global install). With no arguments it starts the MCP server and speaks the protocol over stdin/stdout, so it is normally launched by an MCP client rather than by hand. Subcommands: auth stores the Notion integration token; config, status, logout, doctor, and token come from the shared hull CLI.

# Start the stdio server (default transport; requires NOTION_TOKEN)
NOTION_TOKEN=ntn_your_token_here npx --yes @n24q02m/notion@latest

# Start the remote HTTP server (bearer token) instead of stdio
npx --yes @n24q02m/notion@latest --http

Argument / env

Effect

(none)

stdio transport (default); requires NOTION_TOKEN

--http

HTTP transport; auth chosen by MCP_AUTH_MODE (multi default, token, or no-auth)

See Configuration for the full environment-variable reference.

Remote (HTTP mode)

Deployed with the HTTP transport, the server is a remote endpoint gated by bearer-token auth -- no integration token in the server config. Point an MCP client that supports remote HTTP servers at the host you deployed it on:

// MCP client config -- remote HTTP (bearer token)
{
  "mcpServers": {
    "notion": {
      "type": "http",
      "url": "https://<your-host>/mcp",
      "headers": { "Authorization": "Bearer <your-token>" }
    }
  }
}

In multi mode (default) each user is listed in the users file (MCP_USERS_FILE, default ~/.hull/users.toml) and gets their own token and credential namespace. In token mode every client shares one token whose scrypt hash is set in MCP_AUTH_TOKEN_HASH. To stand up such an instance, see Self-Hosting (Remote Mode).

Smithery

The repo ships a smithery.yaml config for Smithery. Smithery launches the server over stdio (npx -y @n24q02m/notion) and requires no install-time config -- provide your Notion credentials at runtime through NOTION_TOKEN or the config tool (see Configuration).

Status

2026-05-02 -- Architecture stabilization update

Past months saw significant churn around credential handling and the daemon-bridge auto-spawn pattern. This caused multi-process races, browser tab spam, and inconsistent setup UX across plugins. The architecture is now stable: 2 clean modes (stdio + HTTP), no daemon-bridge layer, no auto-spawn from stdio.

Apologies for the instability period. If you encountered issues with prior versions, please update to the latest release and follow the current Setup guide -- most prior workarounds are no longer needed.

Related plugins from the same author:

All plugins share the same architecture -- install once, learn pattern transfers.

Documentation

Full docs at docs.n24q02m.com/servers/notion/:

  • Setup -- install methods for Claude Code, Codex, Gemini CLI, Cursor, Windsurf, mcp.json

Install with AI agent -- paste this to your AI coding agent:

Install MCP server notion following the steps at https://raw.githubusercontent.com/n24q02m/claude-plugins/main/plugins/better-notion-mcp/setup-with-agent.md

Tools

Eight composite Notion tools (39 actions) plus two infrastructure tools (config, help):

Tool

Actions

Description

pages

create, get, get_property, update, move, archive, restore, duplicate

Create, read, update, and organize pages

databases

create, get, query, create_page, update_page, delete_page, create_data_source, update_data_source, update_database, list_templates

Database CRUD and page management within databases

blocks

get, children, append, update, delete

Read and manipulate block content

users

list, get, me, from_workspace

List and retrieve user information

workspace

info, search

Workspace metadata and cross-workspace search

comments

list, get, create

Page comments and discussion replies

content_convert

markdown-to-blocks, blocks-to-markdown

Convert between Markdown and Notion blocks (uses a direction parameter)

file_uploads

create, send, complete, retrieve, list

Upload files to Notion (single or multi-part)

config

status, setup_status, setup_start, setup_reset, setup_complete, set, cache_clear

Inspect and manage credential state and configuration lifecycle

help

-

Get full documentation for any composite tool (tool_name parameter)

MCP Resources

URI

Description

notion://docs/pages

Page operations reference

notion://docs/databases

Database operations reference

notion://docs/blocks

Block operations reference

notion://docs/users

User operations reference

notion://docs/workspace

Workspace operations reference

notion://docs/comments

Comment operations reference

notion://docs/content_convert

Content conversion reference

notion://docs/file_uploads

File upload reference

Configuration

Variable

Required

Default

Description

NOTION_TOKEN

Yes (stdio)

-

Notion integration token

TRANSPORT_MODE / MCP_TRANSPORT

No

stdio

Set either to http for remote mode (or pass --http)

MCP_AUTH_MODE

No (http)

multi

multi (per-user tokens from MCP_USERS_FILE), token (one shared token, needs MCP_AUTH_TOKEN_HASH), or no-auth (trusted/local use only)

MCP_USERS_FILE

No (http, multi)

~/.hull/users.toml

Users file for multi mode

MCP_AUTH_TOKEN_HASH

Yes (token mode)

-

scrypt$ hash of the shared token (mint with token hash)

MCP_RPM

No (token mode)

-

Optional per-minute request cap in token mode

PORT

No

0 (OS-assigned)

Server port; set explicitly (e.g. 8080) to bind a fixed port

HOST

No

127.0.0.1

Bind address (http mode)

Self-Hosting (Remote Mode)

Run the HTTP server on your own host and choose an auth mode with MCP_AUTH_MODE:

  • multi (default): list each user in MCP_USERS_FILE; each user's Notion token is stored in their own namespace (~/.better-notion/subs/<ns>/config.json).

  • token: one shared bearer token. Mint the hash with token hash and pass it as MCP_AUTH_TOKEN_HASH.

  • no-auth: no bearer check. Use only on a trusted local network.

docker run -p 8080:8080 \
  -e TRANSPORT_MODE=http \
  -e PORT=8080 \
  -e MCP_AUTH_MODE=token \
  -e MCP_AUTH_TOKEN_HASH='scrypt$...' \
  n24q02m/notion:latest

Docker Compose (loopback)

docker-compose.http.yml builds the http image target and publishes it on the host loopback interface only (127.0.0.1:8081), so the server is never reachable from other machines directly:

export MCP_AUTH_MODE=token
export MCP_AUTH_TOKEN_HASH='scrypt$...'
docker compose -f docker-compose.http.yml up

The server listens on http://localhost:8081/mcp. To expose it, put your own TLS reverse proxy in front of the loopback port.

Release images are published multi-arch (amd64 + arm64) to Docker Hub (n24q02m/notion) and GHCR (ghcr.io/n24q02m/notion). There is no n24q02m-hosted HTTP endpoint.

Comparison

How notion stacks up against direct competitors in each pillar:

Capability

notion

makenotion/notion-mcp-server

suekou/mcp-notion-server

awkoy/notion-mcp-server

Markdown in / out

Yes (round-trip on pages + blocks)

No (raw Notion JSON)

partial (experimental, append + opt-in convert)

Yes (round-trip + GFM)

Composite tool design

Yes (8 composite tools, 39 actions)

No (22 endpoint-mapped tools)

partial (simplified + raw JSON tools)

Yes (2 dispatch tools, 35+ ops)

File uploads to Notion

Yes (file_uploads, single + multi-part)

No

No

Yes (upload_file, single + multi-part)

Comments

Yes (comments: list/get/create)

Yes

Yes

Yes

Remote HTTP + bearer-token auth

Yes (per-user namespaces or shared token)

partial (HTTP + bearer token)

No (stdio token only)

No (stdio token only)

Self-hostable

Yes (Docker, own bearer token)

Yes

Yes

Yes

License

Apache-2.0

?

MIT

MIT

Security

  • Bearer token auth -- per-user tokens (multi) or one scrypt-hashed shared token (token)

  • Rate limiting -- 120 req/min/IP on HTTP transport

  • Session owner binding -- IP check + TTL for pending token binds

  • Null safety -- Handles Notion API quirks (comments.list 404, undefined rich_text)

Build from Source

git clone https://github.com/n24q02m/notion.git
cd notion
bun install
bun run dev

Trust Model

Credentials are never sent to n24q02m: there is no hosted endpoint.

Mode

Storage

Protection

Who can read your data?

HTTP self-host (multi)

~/.better-notion/subs/<ns>/config.json on the server host

File mode 0600 under the server's data dir

The server operator and anyone with access to that host

HTTP self-host (token)

~/.better-notion/config.json on the server host

File mode 0600 under the server's data dir

The server operator and anyone with access to that host

stdio (local)

~/.better-notion/config.json

File mode 0600; machine key in ~/.better-notion/.secret

Only your OS user

License

Apache-2.0 -- See LICENSE.

Available Tools

10 tools
blocksA

Read and modify block-level content within pages.

Actions (required params -> optional):

  • get (block_id): retrieve single block

  • children (block_id): list child blocks

  • append (block_id, content -> position, after_block_id): add markdown content at position

  • update (block_id, content): replace text block content

  • delete (block_id): remove block

Use pages for page metadata/properties. Page IDs are valid block IDs. update only works on text blocks (paragraph, headings, lists, quote, to_do, code). Image/file blocks contain signed URLs (1h expiry). append supports position: "start" (prepend), "end" (default), "after_block" (requires after_block_id).

Inputs: action (required), block_id (required), content, position, +1 more. Returns: object

commentsA

Manage page comments.

Actions (required params -> optional):

  • list (page_id): all comments on a page

  • get (comment_id): single comment

  • create (content -> page_id for new discussion, discussion_id for reply)

Inputs: action (required), content, page_id, comment_id, +1 more. Returns: object

configA

Manage server configuration and credential state.

Actions:

  • status: current credential state and token source

  • setup_status: credential/setup state only (alias-equivalent to status for notion; kept for cross-server parity)

  • setup_start (-> force): show how to store a Notion token with notion auth

  • setup_reset: clear stored credentials, return to awaiting_setup

  • setup_complete: re-check credentials after external config changes

  • set: update a runtime setting (notion has no mutable settings; returns info)

  • cache_clear: clear any cached state (no-op for notion)

Inputs: action (required), key, force, value. Returns: object

content_convertA
Read-onlyIdempotent

Convert between markdown and Notion block JSON. Directions: markdown-to-blocks (input: markdown string), blocks-to-markdown (input: JSON array of Notion blocks or JSON string). Most tools (pages, blocks) handle markdown automatically -- use this only for preview/validation. Supported markdown: headings, lists, to-do, code blocks, blockquotes, dividers, callouts (> [!NOTE]), toggles (), tables, images, bookmarks, embeds, equations ($$), columns (:::columns), [toc], [breadcrumb]. Inline: bold, italic, code, strike, link.

Inputs: content (required), direction (required). Returns: object

databasesA

Database schema, query, and bulk row operations.

Actions (required params -> optional):

  • create (parent_id -> title, properties, is_inline, icon, cover)

  • get (database_id)

  • query (database_id -> filters, sorts, limit, search)

  • create_page (database_id, pages[{properties}])

  • update_page (database_id, page_id, page_properties)

  • delete_page (database_id, page_ids)

  • create_data_source / update_data_source / update_database / list_templates

Use pages instead for single page CRUD. Accepts both database_id (from URL) and data_source_id (from workspace search) -- auto-resolved.

Inputs: action (required), icon, cover, limit, +14 more. Returns: object

file_uploadsA

Upload files to Notion.

Actions (required params -> optional):

  • create (filename -> content_type, mode="single"|"multi_part", number_of_parts)

  • send (file_upload_id, file_content -> part_number): base64-encoded content

  • complete (file_upload_id)

  • retrieve (file_upload_id)

  • list (-> limit)

Max 20MB direct, multi-part for larger files.

Inputs: action (required), mode, limit, filename, +5 more. Returns: object

helpA
Read-onlyIdempotent

Get full documentation for a tool. Use when compressed descriptions are insufficient.

Inputs: tool_name (required).

pagesA

Page CRUD for individual pages and database rows.

Actions (required params -> optional):

  • create (parent_id -> title, content, properties, icon, cover)

  • get (page_id -> content_limit, content_cursor): returns markdown content; bounded reads return content_truncated and next_cursor

  • get_property (page_id, property_id)

  • update (page_id -> title, content, append_content, properties, icon, cover, archived)

  • move (page_id, parent_id)

  • archive (page_id) / restore (page_id)

  • duplicate (page_id -> parent_id)

Use databases instead for querying or bulk row operations. Property format: simple values auto-convert -- string for title/rich_text/select/status, number for number, boolean for checkbox, string[] for multi_select, ISO date "2025-01-15" for date. Example: properties: {"Name": "My Page", "Status": "In Progress", "Tags": ["urgent", "work"]}

Inputs: action (required), icon, cover, title, +10 more. Returns: object

usersA
Read-onlyIdempotent

Get user information.

Actions (required params):

  • list: all workspace users (requires admin permissions)

  • get (user_id): single user info

  • me: current bot/integration user

  • from_workspace: extract users from accessible pages (use if list fails)

Inputs: action (required), user_id. Returns: object

workspaceA
Read-onlyIdempotent

Search workspace and get workspace info.

Actions (required params -> optional):

  • info: workspace name, plan, and bot user

  • search (-> query, filter.object="page"|"data_source", sort, limit): find pages/databases shared with integration

Inputs: action (required), sort, limit, query, +1 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 10 tools

    Disambiguation4/5

    Tools are largely separated by Notion resource (pages, blocks, databases, comments, users, workspace), so most selections are clear. There is some overlap between pages.update/append_content and blocks.append, and between databases row operations and pages CRUD, though the descriptions provide guidance.

    Naming Consistency4/5

    The dominant pattern is resource-noun tools with action subcommands, which is predictable and readable. Minor deviations include singular config/workspace, plural file_uploads/users/pages, and utility names like help and content_convert.

    Tool Count5/5

    At 10 tools, the server is well-scoped for the Notion API surface. Each tool groups a meaningful resource area without forcing an excessive number of separate tools.

    Completeness4/5

    The surface covers the main Notion workflows: pages, blocks, databases, comments, users, workspace search, file uploads, and content conversion. Minor gaps or unclear areas remain around database-level archive/delete and block reordering/moving.

    Maintenance

    ActivityActive
    ResponsivenessUsually handled

    Related MCP Connectors

    Related MCP Servers