A Model Context Protocol (MCP) server that provides comprehensive access to Notion API endpoints with OAuth authentication.
This MCP server provides the following Notion operations:
Using pip:
pip install -r requirements.txtYou need to create a Notion integration with OAuth support:
http://localhost:8080 or your client URLAdd this to your Claude Desktop MCP settings file:
Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"notion": {
"command": "python",
"args": [
"D:\\Code\\Curious Layer\\notion_mcp_server\\notion_mcp_server.py"
],
"cwd": "D:\\Code\\Curious Layer\\notion_mcp_server"
}
}
}You can run the server with different transport modes:
Streamable HTTP (default):
python notion_mcp_server.py --transport streamable-http --host 0.0.0.0 --port 8080stdio:
python notion_mcp_server.py --transport stdio{
"tool": "search_notion",
"arguments": {
"oauth_token": "your_oauth_token",
"query": "meeting notes",
"filter_type": "page",
"page_size": 10
}
}{
"tool": "create_page_under_page",
"arguments": {
"oauth_token": "your_oauth_token",
"parent_page_id": "parent-page-id",
"title": "My New Page",
"position": { "type": "page_end" }
}
}{
"tool": "fetch_page_content",
"arguments": {
"oauth_token": "your_oauth_token",
"page_id": "page-id",
"include_children": true,
"recursive": true,
"max_depth": 3
}
}{
"tool": "append_text_block",
"arguments": {
"oauth_token": "your_oauth_token",
"block_id": "page-id",
"type": "paragraph",
"content": "This is a new paragraph",
"color": "blue",
"position": "end"
}
}{
"tool": "update_page",
"arguments": {
"oauth_token": "your_oauth_token",
"page_id": "page-id",
"properties": {
"title": {
"title": [
{
"text": {
"content": "Updated Title"
}
}
]
}
},
"archived"
{
"tool": "query_data_source",
"arguments": {
"oauth_token": "your_oauth_token",
"data_source_id": "database-id",
"filter": {
"property": "Status",
"status": {
"equals": "In Progress"
}
},
"sorts": [
{
"property": "Created"
{
"tool": "create_database",
"arguments": {
"oauth_token": "your_oauth_token",
"parent_id": "parent-page-id",
"title": "My Database",
"properties": {
"Name": {
"title": {}
},
"Status": {
"select": {
"options": [
{ "name"
paragraph - Regular paragraph textheading_1 - Heading level 1heading_2 - Heading level 2heading_3 - Heading level 3bulleted_list_item - Bulleted list itemnumbered_list_item - Numbered list itemto_do - Todo/checkbox itemtoggle - Toggle/collapsible blockquote - Quote blockcallout - Callout/alert blockdefault, gray, brown, orange, yellow, green, blue, purple, pink, red_background suffix (e.g., blue_background)page - Filter for pages onlydata_source - Filter for databases onlypage_end / end - Insert at the endpage_start / start - Insert at the beginningThis server is configured for Railway deployment with railway.json:
# Deploy to Railway
railway upThe server will run on port 8080 using streamable-http transport.
For production deployment, set:
NOTION_CLIENT_ID - Your Notion OAuth client IDNOTION_CLIENT_SECRET - Your Notion OAuth client secretEnsure your Notion integration has the required capabilities:
Notion API has rate limits. If you experience rate limit errors (HTTP 429):
page_size parametersIf the server fails to start:
NOTION_CLIENT_SECRET secureoauth_tokenThe server logs all operations with timestamps:
INFO: Normal operations and API callsWARNING: Rate limits and warningsERROR: API failures and authentication issuesLogs include:
This is a stateless server that:
oauth_token parameter in every requestnotion_mcp_server/
├── tools/
│ ├── __init__.py
│ ├── read_operations.py # Search, get, fetch operations
│ └── write_operations.py # Create, update, append operations
|__ user_operations.py # User-related operations
|__ database_operations.py # Database-related operations
├── utils/
│ └── notion_utils.py # HTTP request utilities
├── notion_mcp_server.py # Main server file
├── requirements.txt # Python dependencies
└── railway.json # Railway deployment config