Remote MCP connector wrapping notion-mcp with Notion OAuth 2.0 over Streamable HTTP
Project description
notion-mcp-remote
A remote MCP connector for notion-mcp — connect Claude.ai to your Notion workspace in one step.
For Users
Paste this URL into Claude.ai to connect:
https://archbox.tail5b443a.ts.net/mcp
- Go to claude.ai → Settings → Connectors
- Click "Add custom connector"
- Paste the URL above
- You'll be redirected to Notion — authorize access to your own workspace
- Done. Claude can now read and write your Notion pages, databases, and blocks.
Works on desktop, iOS, and Android. Requires Claude Pro, Max, Team, or Enterprise.
What you get
Full Notion API coverage via notion-mcp (v2025-05-09):
- Page and database CRUD
- Block-level operations (append, update, delete)
- Property retrieval and pagination
- Comment threading
- Search across your workspace
- User and team lookups
How it works
When you add this connector, Claude.ai initiates a standard OAuth 2.0 flow with Notion. You authenticate directly with Notion and choose which pages to share. Your access token is stored encrypted on the server and used only to make Notion API calls on your behalf. The operator of this server never sees your Notion credentials — only the OAuth token Notion issues.
Claude.ai This Server Notion
│ │ │
│ 1. Add connector (URL) │ │
│ ─────────────────────────► │ │
│ │ │
│ 2. Redirect to Notion │ │
│ ◄───────────────────────── │ │
│ │ │
│ 3. You authorize ─────────────────────────────────────► │
│ (your workspace, │ │
│ your pages) │ │
│ │ 4. Callback with auth code │
│ │ ◄────────────────────────── │
│ │ │
│ │ 5. Exchange for token │
│ │ ─────────────────────────► │
│ │ │
│ │ 6. Your access token │
│ │ ◄───────────────────────── │
│ │ │
│ 7. MCP tools now work │ 8. API calls to YOUR data │
│ ◄────────────────────────► │ ◄──────────────────────────► │
For Operators
Everything below is for deploying your own instance of this connector.
Why This Exists
Anthropic's built-in Notion connector uses an older API surface. notion-mcp provides significantly better coverage. This repo is a thin deployment wrapper that:
- Imports all tools from
notion-mcp - Serves them over Streamable HTTP (required for Claude.ai connectors)
- Handles Notion's public OAuth 2.0 flow (per-user authentication)
- Deploys behind any HTTPS tunnel (Tailscale Funnel, ngrok, Cloudflare Tunnel, etc.)
Each user who adds your connector authenticates with their own Notion workspace. You provide the infrastructure; they bring their own data.
Prerequisites
- Python 3.11+
- An HTTPS tunnel (Tailscale Funnel (free), ngrok, or Cloudflare Tunnel)
- Notion public integration (OAuth client credentials)
- A machine to host on (always-on Linux box, Raspberry Pi, etc.)
Notion OAuth Setup
You need a public Notion integration. This is what lets users OAuth into their own workspaces through your connector — the "public" label means your app can be authorized by any Notion user, not that their data becomes public.
- Go to notion.so/profile/integrations
- Click "New integration"
- Choose "Public" integration type
- Fill in required fields:
- Integration name: e.g. "Notion MCP Remote"
- Redirect URI:
https://<your-domain>/oauth/callback - Company name, Website, Privacy policy URL, Terms of use URL — Notion requires these even for hobby projects. Your GitHub repo URL and a simple privacy statement work fine.
- Under Capabilities, enable everything you want to expose
- Save and note your OAuth client ID and OAuth client secret
Installation
git clone https://github.com/ldraney/notion-mcp-remote.git
cd notion-mcp-remote
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Configuration
cp .env.example .env
# Notion OAuth (from your public integration)
NOTION_OAUTH_CLIENT_ID=your_client_id
NOTION_OAUTH_CLIENT_SECRET=your_client_secret
# Server
HOST=127.0.0.1
PORT=8000
BASE_URL=https://your-public-domain
# Session secret (generate with: python -c "import secrets; print(secrets.token_hex(32))")
SESSION_SECRET=your_random_secret
# Optional: Redis URL for token storage (defaults to local file-based storage)
# REDIS_URL=redis://localhost:6379
Running
# Terminal 1: Start the MCP server
source .venv/bin/activate
python server.py
# Terminal 2: Expose via HTTPS tunnel (pick one)
sudo tailscale funnel --bg 8000 # Tailscale Funnel (free, stable URL)
ngrok http 8000 --url=your-domain # ngrok (requires paid plan for static domain)
Verify:
curl https://your-public-domain/health
Then share your connector URL with users: https://your-public-domain/mcp
Deployment (Systemd)
For always-on hosting on a Linux box:
# Copy and enable service file
sudo cp systemd/notion-mcp-remote.service /etc/systemd/system/
# Edit paths in the service file to match your setup
sudo systemctl daemon-reload
sudo systemctl enable --now notion-mcp-remote
For the HTTPS tunnel, set up a separate systemd service or use your tunnel provider's daemon mode (e.g. tailscale funnel --bg, ngrok service install).
Project Structure
notion-mcp-remote/
├── server.py # Main entrypoint — FastMCP HTTP server
├── auth/
│ ├── __init__.py
│ ├── provider.py # Notion OAuth 2.0 flow handlers
│ └── storage.py # Per-user token storage (file or Redis)
├── requirements.txt
├── .env.example
├── systemd/
│ └── notion-mcp-remote.service
├── Makefile
└── README.md
Development
pip install -r requirements-dev.txt
pytest
python server.py --reload
ruff check .
Makefile
make run # Start the server
make tunnel # Start ngrok tunnel
make dev # Start both (requires tmux)
make test # Run tests
make lint # Run linter
make install # Install dependencies
Troubleshooting
"Connector failed to connect" in Claude.ai
- Verify tunnel is running:
curl https://your-public-domain/health - Check server logs:
journalctl -u notion-mcp-remote -f - Ensure your Notion OAuth redirect URI matches exactly
421 Misdirected Request
- The server automatically adds
BASE_URL's hostname to the MCP transport securityallowed_hosts. Make sureBASE_URLin.envmatches your public domain exactly.
OAuth callback errors
- Confirm
BASE_URLin.envmatches your public domain exactly - Check that your Notion integration is set to Public (not Internal)
- Verify redirect URI in Notion integration settings matches
{BASE_URL}/oauth/callback
Token refresh issues
- Notion access tokens don't expire by default, but users can revoke access
- If a user revokes, they'll need to re-authorize through Claude's connector settings
Privacy
See PRIVACY.md for our privacy policy.
Roadmap
- Core HTTP wrapper with FastMCP Streamable HTTP transport
- Notion public OAuth 2.0 flow
- Per-user token storage and injection
- Claude.ai connector integration testing
- Encrypted token storage at rest
- Redis adapter for multi-instance deployments
- Health check and monitoring endpoints
- Rate limiting and abuse prevention
- Docker deployment option
- One-click deploy templates (Railway, Render)
Related Projects
- notion-mcp — The underlying MCP server with full Notion API coverage (also by @ldraney)
- FastMCP — The MCP framework powering the HTTP transport
- MCP Specification — The Model Context Protocol standard
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file notion_mcp_remote_ldraney-0.2.0.tar.gz.
File metadata
- Download URL: notion_mcp_remote_ldraney-0.2.0.tar.gz
- Upload date:
- Size: 7.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3933ed9f86650081e7ba8c52a335a5d4f109e80f182b4f7090a40564746ebc2b
|
|
| MD5 |
782434b338645d726ca4b16ace9dee82
|
|
| BLAKE2b-256 |
e4bf22c8d595ab9575574f5656773dc25f5ef1dc7b452bde3f8be207ecbcf843
|
Provenance
The following attestation bundles were made for notion_mcp_remote_ldraney-0.2.0.tar.gz:
Publisher:
publish.yml on ldraney/notion-mcp-remote
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
notion_mcp_remote_ldraney-0.2.0.tar.gz -
Subject digest:
3933ed9f86650081e7ba8c52a335a5d4f109e80f182b4f7090a40564746ebc2b - Sigstore transparency entry: 974883716
- Sigstore integration time:
-
Permalink:
ldraney/notion-mcp-remote@93924613fcc1135dd518abf75ffa9d9bbb4e9483 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ldraney
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@93924613fcc1135dd518abf75ffa9d9bbb4e9483 -
Trigger Event:
push
-
Statement type:
File details
Details for the file notion_mcp_remote_ldraney-0.2.0-py3-none-any.whl.
File metadata
- Download URL: notion_mcp_remote_ldraney-0.2.0-py3-none-any.whl
- Upload date:
- Size: 8.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
841855eec3523851c0af79e6a888c1efba190bc25f0c37ae10231e9a1968c1f9
|
|
| MD5 |
70ec6740cad2d721d42543fd5e147f35
|
|
| BLAKE2b-256 |
1b5163253f9b026ddde454561e15f21624b131dd06a1201e7754de7f8422cced
|
Provenance
The following attestation bundles were made for notion_mcp_remote_ldraney-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on ldraney/notion-mcp-remote
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
notion_mcp_remote_ldraney-0.2.0-py3-none-any.whl -
Subject digest:
841855eec3523851c0af79e6a888c1efba190bc25f0c37ae10231e9a1968c1f9 - Sigstore transparency entry: 974883743
- Sigstore integration time:
-
Permalink:
ldraney/notion-mcp-remote@93924613fcc1135dd518abf75ffa9d9bbb4e9483 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ldraney
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@93924613fcc1135dd518abf75ffa9d9bbb4e9483 -
Trigger Event:
push
-
Statement type: