nedasvi/notion-mcp-server-remote
If you are the rightful owner of notion-mcp-server-remote and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
A Cloudflare Workers-based MCP server for secure interaction with Notion workspaces via OAuth.
Notion MCP Remote Server
A Cloudflare Workers-based MCP (Model Context Protocol) server that provides comprehensive Notion API tools via OAuth authentication. This server allows AI assistants like Claude to interact with Notion workspaces through a secure OAuth flow.
All credits goes to https://github.com/vakharwalad23/google-mcp-remote and since it was taken as an example and Claude 4 Sonnet was prompted to make Remote MCP server for Notion based on it
ā ļø SECURITY WARNING: Do not use someone else's deployed instance of this server as it requires access to your Slack workspace and personal data. Always deploy your own instance to maintain control over your data and API access.
Overview
This project provides:
- OAuth Authentication: Secure Notion OAuth 2.0 flow for workspace access
- MCP Protocol: Implements the Model Context Protocol for AI assistant integration
- Complete Notion API Coverage: All major Notion API endpoints as MCP tools
- Cloudflare Workers: Serverless deployment with durable objects for session management
- Production Ready: Deployed and tested with Claude AI
Architecture
Core Components
src/index.ts
: Main entry point with NotionMCP durable objectsrc/auth-handler.ts
: Notion OAuth 2.0 flow implementationsrc/utils/upstream-utils.ts
: OAuth token exchange utilitiessrc/utils/workers-oauth-utils.ts
: Cookie management and approval dialogssrc/tools/
: MCP tool implementations for all Notion API operations
OAuth Flow
- User authorization via Notion OAuth
- Token exchange using Notion's OAuth endpoints
- Secure session management with Cloudflare Workers
- MCP tool access with authenticated API calls
Environment Variables
Setting Secrets with Wrangler CLI
For production deployment, use Wrangler to set secrets:
# Set Notion OAuth Client ID
npx wrangler secret put NOTION_OAUTH_CLIENT_ID
# Set Notion OAuth Client Secret
npx wrangler secret put NOTION_OAUTH_CLIENT_SECRET
# Set Cookie Encryption Key (32 characters)
npx wrangler secret put COOKIE_ENCRYPTION_KEY
Each command will prompt you to enter the secret value securely.
Local Development
For local development, create a .dev.vars
file:
COOKIE_ENCRYPTION_KEY=your_32_character_key_here
NOTION_OAUTH_CLIENT_ID=your_client_id
NOTION_OAUTH_CLIENT_SECRET=your_client_secret
Notion OAuth Setup
- Go to Notion Integrations
- Create a new integration
- Configure as a Public Integration
- Set redirect URI to:
https://your-worker-domain.workers.dev/callback
- Copy the Client ID and Client Secret to your environment variables
Cloudflare Setup
- Install dependencies:
npm install
- Configure Wrangler:
npx wrangler login
- Create KV namespace:
npx wrangler kv:namespace create "OAUTH_KV"
-
Update the namespace ID in
wrangler.jsonc
-
Deploy:
npm run deploy
Configure as Remote MCP Server
To add this as a remote MCP server in your MCP client configuration:
MCP Server URL: https://your-worker-domain.workers.dev/sse
Claude Desktop configuration:
{
"mcpServers": {
"notion-remote": {
"command": "mcp-client",
"args": ["--transport", "sse", "https://your-worker-domain.workers.dev/sse"]
}
}
}
Available Tools
Page Tools
create_page
: Create new pages with optional content and parentcreate_page_post
: Alternative page creation (OpenAPI compatibility)get_page
: Retrieve page information and metadataretrieve_page
: Alternative page retrieval (OpenAPI compatibility)update_page
: Update page properties like titlepatch_page
: Alternative page update (OpenAPI compatibility)get_page_content
: Retrieve page content blocks
Database Tools
query_database
: Query databases with filters and sortsget_database
: Retrieve database schema and metadatacreate_database
: Create new databasesupdate_database
: Update database properties and schema
Block Tools
get_block_children
: Retrieve children of a blockappend_block_children
: Add new blocks to a page or blockget_block
: Retrieve a specific blockupdate_block
: Update block contentdelete_block
: Delete a block
User Tools
get_user
: Retrieve user information by IDget_users
: List all workspace usersget_self
: Get current bot user information
Search & Property Tools
search
: Search across workspace contentget_page_property
: Retrieve specific page propertiesget_comment
: Retrieve comments
Key Features
Complete API Coverage
This implementation provides access to all major Notion API endpoints through MCP tools, matching the functionality of the local OpenAPI-based server.
Manual vs Auto-Generated Tools
Unlike the local server that auto-generates tools from OpenAPI specs, this remote server implements tools manually for:
- Better error handling with specific messages
- Optimized responses for Claude AI
- Type safety with direct TypeScript implementation
- Smaller bundle size (418KB vs larger with OpenAPI parser)
OAuth Authentication
- Secure OAuth 2.0 flow with Notion
- Base64 state parameter encoding for compatibility
- Proper redirect handling back to Claude
- Session management with Cloudflare KV storage
Development
Local Development
npm run dev
This starts the Wrangler dev server on http://localhost:8788
.
Project Structure
notion-mcp-remote/
āāā src/
ā āāā index.ts # Main entry point
ā āāā auth-handler.ts # OAuth flow implementation
ā āāā utils/
ā ā āāā upstream-utils.ts # OAuth utilities
ā ā āāā workers-oauth-utils.ts # Cookie/session management
ā āāā tools/
ā āāā index.ts # Tool registration
ā āāā pages.ts # Page management tools
ā āāā databases.ts # Database tools
ā āāā blocks.ts # Block management tools
ā āāā users.ts # User tools
ā āāā search.ts # Search and other tools
āāā wrangler.jsonc # Cloudflare Workers config
āāā package.json # Dependencies
āāā .dev.vars # Local environment variables
āāā worker-configuration.d.ts # TypeScript definitions
Adding New Tools
- Create or update files in
src/tools/
- Implement tools using the MCP server API
- Register tools in
src/tools/index.ts
- Use
props.accessToken
for authenticated Notion API calls
Example:
export function registerDatabaseTools(server: McpServer, props: Props) {
server.tool(
"query_database",
"Query a Notion database",
{
database_id: z.string().describe("The ID of the database to query"),
filter: z.any().optional().describe("Filter object for the query")
},
async ({ database_id, filter }) => {
const response = await fetch(`https://api.notion.com/v1/databases/${database_id}/query`, {
method: "POST",
headers: {
Authorization: `Bearer ${props.accessToken}`,
"Notion-Version": "2022-06-28",
"Content-Type": "application/json",
},
body: JSON.stringify({ filter }),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Failed to query database: ${response.status} ${errorText}`);
}
const data = await response.json();
return {
content: [
{
type: "text",
text: JSON.stringify(data, null, 2),
},
],
};
}
);
}
Troubleshooting
Common Issues
- OAuth redirect mismatch: Ensure redirect URI in Notion integration matches your deployed URL exactly
- Token errors: Verify client ID and secret are correctly set in Workers environment
- API permissions: Ensure pages/databases are shared with your Notion integration
- CORS issues: Cloudflare Workers handle CORS automatically
- Database vs Page ID: Make sure you're using the correct function for the resource type
Debugging
- Check Cloudflare Workers logs:
npx wrangler tail
- Test OAuth flow with browser developer tools
- Verify environment variables in Cloudflare dashboard
- Check Notion integration permissions and capabilities
Error Messages
"Provided ID is a database, not a page"
: Useget_database
instead ofget_page
"Invalid OAuth flow"
: OAuth state parameter issue, restart the flow"Missing or invalid access token"
: Check environment variables and OAuth completion
Usage with Claude
- Deploy your worker to Cloudflare
- In Claude, add an MCP server with your worker URL
- Complete the OAuth flow when prompted
- Use natural language to interact with your Notion workspace
Example commands:
- "Show me my recent pages"
- "Create a new page called 'Meeting Notes'"
- "Search for pages about 'project planning'"
- "Get the content of page [page-id]"
License
MIT License - see LICENSE file for details.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly with both local and deployed versions
- Submit a pull request
Related Projects
- Notion API Documentation
- Model Context Protocol
- Cloudflare Workers OAuth Provider
- Claude AI - Works with this MCP server