Notion MCP Server
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:
Click "New integration"
Give it a name (e.g., "MCP - John")
Select the workspace
Click Submit — you'll get a token starting with
ntn_Share pages with the integration: open each page/database in Notion, click the
...menu → Connections → Add 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 -dServer 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-mcpServer 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 all available Notion tools and their descriptions |
Search
Tool | Description |
| Search pages by title, with sort/filter/pagination |
Pages
Tool | Description |
| Create page with properties, content, icon, cover |
| Get page by ID |
| Update page properties, content, icon, cover |
| Move page to trash |
| Move page to new parent |
| Get page content as markdown |
| Update page content via markdown string |
Data Sources (Databases)
Tool | Description |
| Create a data source |
| Get data source by ID |
| Update data source properties |
| Query with filters/sorts/pagination |
| List available templates |
Databases
Tool | Description |
| Get database metadata and schema |
Blocks
Tool | Description |
| Get block by ID |
| List child blocks |
| Append blocks to parent |
| Update a block |
| Delete a block |
Comments
Tool | Description |
| Create a comment |
| List comments with filters |
| Get comment by ID |
| Update comment text |
| Delete a comment |
Users
Tool | Description |
| List workspace users |
| Get user by ID |
| Get authenticated user info |
File Uploads
Tool | Description |
| Initiate file upload |
| Send file data |
| Finalize upload |
| List file uploads |
| Get upload status |
Architecture
Stateless — no stored tokens, no sessions, no
.envfileAuth via header — reads
Authorization: Bearer ntn_xxxfrom every requestMulti-user — different tokens per connection, zero shared state
Transport — streamable-http
Framework — FastMCP from the official
mcpPython SDKAPI client —
notion-clientv3.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 referenceDependencies
Package | Version | Purpose |
| >=1.6.0 | MCP framework (FastMCP, transports) |
| >=3.1.0 | Official Notion API async client |
| >=2.0.0 | Parameter validation |
License Apache-2.0 license
Proprietary — LRGEX. All rights reserved.