A simple MCP (Model Context Protocol) server that provides read-only access to Notion pages via SSE (Server-Sent Events) transport using FastMCP.
- Read-only access to Notion pages and databases
- SSE transport for real-time communication
- Bearer token authentication for secure SSE endpoints
- Docker deployment ready
- Simple configuration via environment variables
- Comprehensive error handling and logging
notion://pages/{page_id}- Get a specific page by IDnotion://search/{query}- Search for pages (use 'all' for all pages)notion://databases/{database_id}- Get database informationnotion://databases/{database_id}/query/{page_size}- Query database pages
- Go to https://www.notion.so/profile/integrations
- Create a new internal integration or select an existing one
- Configure it as read-only by giving only "Read content" access
- Copy the integration token (starts with
ntn_) - Grant the integration access to the pages/databases you want to expose
-
Copy the example environment file:
cp .env.example .env
-
Edit
.envand add your Notion token and base64-encoded RSA keys for authentication:NOTION_TOKEN=ntn_your_integration_token_here RSA_PUBLIC_KEY="<base64-encoded-PEM-public-key>" RSA_PRIVATE_KEY="<base64-encoded-PEM-private-key>" HOST=127.0.0.1 PORT=8000
Important: The keys must be base64-encoded PEM strings, not raw PEM. If you do not have base64-encoded keys, you can generate them as follows:
# Generate private key openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 # Extract public key openssl rsa -pubout -in private_key.pem -out public_key.pem # Encode keys as base64 (remove newlines for .env compatibility) base64 -w 0 private_key.pem > private_key.b64 base64 -w 0 public_key.pem > public_key.b64
Then copy the contents of
private_key.b64andpublic_key.b64into your.envas shown above.Alternatively, if you start the server or run
python generate_client_token.pywithout the keys set, it will print out base64-encoded keys for you to copy into your.envfile.Note: For RSA key generation, you can use OpenSSL:
# Generate private key openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 # Extract public key openssl rsa -pubout -in private_key.pem -out public_key.pem
# Install dependencies
pip install -r requirements.txt
# Run the server
fastmcp run server.py -t sse# Build and run with Docker Compose
docker-compose up --build
# Or build and run manually
docker build -t notion-mcp .
docker run -p 8000:8000 --env-file .env notion-mcpOnce running, the server exposes a set of tools that can be used by any MCP-compatible client (e.g., an LLM agent for function-calling). The server listens for SSE connections at http://localhost:8000/sse/ (or your configured host/port).
The following tools are available for interacting with Notion:
get_page(page_id: str): Retrieves a Notion page and its content by its ID.search_pages(query: str, page_size: int = 10): Searches for pages in your Notion workspace.get_database(database_id: str): Retrieves information about a specific Notion database.query_database(database_id: str, page_size: int = 10): Queries a Notion database and returns its pages.
This server implements Bearer token authentication for SSE endpoints using RSA key pairs:
- JWT Tokens: Authentication uses JWT tokens signed with RS256 algorithm
- RSA Key Pairs: Uses asymmetric cryptography for secure token validation
- Token Generation: Includes a utility endpoint to generate tokens for testing
-
Generate a token using the
/generate_auth_tokenendpoint:curl -X POST http://localhost:8000/generate_auth_token \ -H "Content-Type: application/json" \ -d '{"subject":"user123","scopes":["read"],"expiry_seconds":3600}'
-
Use the token in your SSE requests:
curl -N http://localhost:8000/sse \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
A test script is included to verify authentication is working correctly:
python test_auth.pyThis will test both authenticated and unauthenticated requests to ensure the Bearer token authentication is functioning properly.
- This server provides read-only access to Notion
- Bearer token authentication secures all SSE endpoints
- Configure your Notion integration with minimal permissions
- Use environment variables for sensitive configuration
- The server only exposes data that your integration has access to
fastmcp>=2.0.0- FastMCP framework for MCP server implementationnotion-client>=2.2.1- Official Notion API Python clientpython-dotenv>=1.0.0- Environment variable management
MIT License