Skip to main content
Glama

Notion MCP Server

Version 0.1.0

Stateless MCP server exposing the full Notion API as 33 tools over streamable-http transport. No server-side secrets — each user passes their own Notion integration token via Authorization header.

Prerequisites

  • Notion Integration Token — required for every user who connects

  • Docker (for deployment) or Python 3.13+ with uv (for local development)

Notion Integration Setup

Every user needs their own Notion integration token. Create one per user:

  1. Go to https://www.notion.so/profile/integrations

  2. Click "New integration"

  3. Give it a name (e.g., "MCP - John")

  4. Select the workspace

  5. Click Submit — you'll get a token starting with ntn_

  6. Share pages with the integration: open each page/database in Notion, click the ... menu → ConnectionsAdd connection → select your integration name

The integration only has access to pages explicitly shared with it. Without sharing, search_pages returns nothing.

Deploy with Docker

git clone https://github.com/LRGEX/notion-mcp.git
cd notion-mcp
docker compose build
docker compose up -d

Server starts on port 9201. Verify it's running:

curl -X POST http://localhost:9201/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'

Expected response: JSON with "result" containing server capabilities.

Connect an MCP Client

Oh My Pi

Add to ~/.omp/agent/mcp.json or .omp/mcp.json:

{
  "$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json",
  "mcpServers": {
    "notion": {
      "type": "http",
      "url": "http://YOUR_SERVER_IP:9201/mcp",
      "headers": {
        "Authorization": "Bearer ntn_your_integration_token_here",
        "Accept": "application/json, text/event-stream"
      }
    }
  }
}

Replace YOUR_SERVER_IP with the server address (e.g., 192.168.1.101). Replace ntn_your_integration_token_here with your actual ntn_ token from the integration setup above.

Claude Desktop / Other MCP Clients

For any MCP client that supports streamable-http transport, point it at:

  • Endpoint: http://YOUR_SERVER_IP:9201/mcp

Pass the token in the Authorization: Bearer ntn_xxx header.

Multi-User

Multiple users can connect to the same server simultaneously. Each user provides their own ntn_ token in the Authorization header. The server is fully stateless — no sessions, no stored tokens, no .env file.

10 users = 10 different tokens, same Docker container, same port.

Run Locally (without Docker)

Requires Python 3.13+ and uv:

git clone https://github.com/LRGEX/notion-mcp.git
cd notion-mcp
uv sync
uv run notion-mcp

Server starts on http://0.0.0.0:9201.

Tools (33)

All tools automatically use the token from the request's Authorization header. No token parameter is needed in any tool call.

Meta

Tool

Description

list_notion_tools

List all available Notion tools and their descriptions

Tool

Description

search_pages

Search pages by title, with sort/filter/pagination

Pages

Tool

Description

create_page

Create page with properties, content, icon, cover

retrieve_page

Get page by ID

update_page

Update page properties, content, icon, cover

trash_page

Move page to trash

move_page

Move page to new parent

retrieve_page_as_markdown

Get page content as markdown

update_page_markdown

Update page content via markdown string

Data Sources (Databases)

Tool

Description

create_data_source

Create a data source

retrieve_data_source

Get data source by ID

update_data_source

Update data source properties

query_data_source

Query with filters/sorts/pagination

list_data_source_templates

List available templates

Databases

Tool

Description

retrieve_database

Get database metadata and schema

Blocks

Tool

Description

retrieve_block

Get block by ID

retrieve_block_children

List child blocks

append_block_children

Append blocks to parent

update_block

Update a block

delete_block

Delete a block

Comments

Tool

Description

create_comment

Create a comment

list_comments

List comments with filters

retrieve_comment

Get comment by ID

update_comment

Update comment text

delete_comment

Delete a comment

Users

Tool

Description

list_users

List workspace users

retrieve_user

Get user by ID

retrieve_self

Get authenticated user info

File Uploads

Tool

Description

create_file_upload

Initiate file upload

send_file_upload

Send file data

complete_file_upload

Finalize upload

list_file_uploads

List file uploads

retrieve_file_upload

Get upload status

Architecture

  • Stateless — no stored tokens, no sessions, no .env file

  • Auth via header — reads Authorization: Bearer ntn_xxx from every request

  • Multi-user — different tokens per connection, zero shared state

  • Transport — streamable-http

  • Framework — FastMCP from the official mcp Python SDK

  • API clientnotion-client v3.1.0 (official Notion async client)

Port Allocation

Port

MCP Service

9201

Notion

9202

(reserved)

9203

(reserved)

Project Structure

notion_mcp/
├── Dockerfile
├── docker-compose.yml
├── pyproject.toml
├── README.md
├── src/notion_mcp/
│   ├── __init__.py            # Package metadata
│   ├── client.py              # create_client(token) — stateless factory
│   ├── server.py              # FastMCP server — all 33 tool definitions
│   └── tools/                 # (unused — tools are inline in server.py)
│       ├── blocks.py
│       ├── comments.py
│       ├── data_sources.py
│       ├── databases.py
│       ├── files.py
│       ├── pages.py
│       ├── search.py
│       └── users.py
└── mcp_configs/
    └── notion.json            # MCP client config reference

Dependencies

Package

Version

Purpose

mcp

>=1.6.0

MCP framework (FastMCP, transports)

notion-client

>=3.1.0

Official Notion API async client

pydantic

>=2.0.0

Parameter validation

License Apache-2.0 license

Proprietary — LRGEX. All rights reserved.