Connect Claude Desktop (and other MCP clients) directly to Notion using a real MCP server with SSE support.
No flaky local scripts. No tokens in URLs. Run it securely in the cloud.
The easiest way to run this securely 24/7 is on Apify.
-
Base URL (Apify Container URL):
https://<run-id>.runs.apify.net -
SSE endpoint:
GET /sse -
Client-to-server messages:
POST /message?sessionId=...
Authentication is done via:
- Authorization header:
Authorization: Bearer <SECRET_TOKEN>
- MCP Protocol with SSE
- Secure Bearer Authentication
- Notion API access (CRUD via OpenAPI tools)
- Rate-limiting & basic DDoS protection (
express-rate-limit) - Security headers (
helmet)
npm installnpm run buildnpm startIf you use Docker locally:
docker build -t notion-mcp-server .
docker run -p 8080:8080 --env-file .env notion-mcp-serverThis project is designed to read configuration from environment variables (and Apify Actor input).
NOTION_TOKEN- Your Notion integration token.
SECRET_TOKEN- Bearer token required to access
/sseand/message.
- Bearer token required to access
Optional (advanced):
NOTION_API_VERSION(default:2022-06-28)OPENAPI_MCP_HEADERS(JSON string of headers; overridesNOTION_TOKENwhen present)BASE_URL(override OpenAPI server base URL)
Add (or merge) something like this into claude_desktop_config.json:
{
"mcpServers": {
"notion": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/dist/start-apify.js"],
"env": {
"NOTION_TOKEN": "YOUR_NOTION_TOKEN",
"SECRET_TOKEN": "YOUR_SECRET_TOKEN"
}
}
}
}On Apify, you typically configure secrets via Actor input / secrets and use the Container URL as the server endpoint.
- Never commit
.envfiles or Apifystorage/directories. - Use a strong
SECRET_TOKENand rotate it if it leaks.
PRs are welcome!