A comprehensive Model Context Protocol (MCP) server that provides secure, per-user Notion integration for AI development tools like Claude Desktop, Cline, and other MCP-compatible clients.
execute-soql- Execute SOQL queries with auto-bulk switching and paginationexecute-sosl- Multi-object search with result aggregationdescribe-sobject- SObject metadata with intelligent caching
execute-apex- Anonymous Apex execution with debug log capturerun-apex-tests- Apex test execution with coverage reportingget-apex-logs- Debug log retrieval with filtering
create-record- Single/bulk record creation with auto-bulk switchingget-record- Record retrieval with field selectionupdate-record- Single/bulk record updates with validationdelete-record- Single/bulk record deletionupsert-record- External ID-based upsert operations
list-metadata-types- Discover metadata typesdeploy-metadata- Deploy individual metadata components (e.g., ApexClass, CustomObject) from files or JSONdeploy-bundle- Deploy a metadata bundle (e.g., LWC) from a directory pathretrieve-metadata- Retrieve individual metadata components, with an option to save to a filecheck-deploy-status- Check the status of a deployment
test-connection- Connection validation and health monitoring
- π Auto-Bulk Switching - Intelligent API selection for optimal performance
- π Secure OAuth2 Authentication - Per-user access with individual limits and permissions
- β‘ Smart Caching - 1-hour TTL for SObject metadata
- π‘οΈ Type Safety - Full TypeScript implementation with runtime validation
- π Comprehensive Logging - Detailed debugging and monitoring
- π Raw Error Exposure - Preserve exact Notion errors for debugging
This server uses OAuth2 authentication for secure, per-user access to Notion. This approach ensures individual user access limits and proper security compliance.
β οΈ Security Notice: Username/password authentication is deprecated for security reasons. OAuth2 provides better security, individual user tracking, and respects organizational access policies.
-
Navigate to Setup:
- Log into your Notion org
- Go to Setup β App Manager
- Click New Connected App
-
Basic Information:
Connected App Name: MCP Notion Server API Name: MCP_Notion_Server Contact Email: [email protected] -
API (Enable OAuth Settings):
- Check Enable OAuth Settings
- Callback URL:
http://localhost:3000/callback(for local development) - Selected OAuth Scopes:
- Access and manage your data (api)
- Perform requests on your behalf at any time (refresh_token, offline_access)
- Access your basic information (id, profile, email, address, phone)
-
Additional Settings:
- Require Secret for Web Server Flow: Checked
- Require Secret for Refresh Token Flow: Checked
- Enable Client Credentials Flow: Unchecked (not needed)
-
Save and Note Credentials:
- After saving, note the Consumer Key (Client ID)
- Click Click to reveal for the Consumer Secret (Client Secret)
You need to complete the OAuth2 authorization code flow to get a refresh token. Here are several methods:
# Install Notion CLI if not already installed
npm install -g @notion/cli
# Authorize your org (this will open a browser)
sf org login web --set-default-dev-hub --alias my-org
# Get the refresh token
sf org display --verbose --target-org my-org-
Authorization URL:
https://login.notion.com/services/oauth2/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=http://localhost:3000/callback&scope=api%20refresh_tokenReplace
YOUR_CLIENT_IDwith your Connected App's Consumer Key. -
Complete Authorization:
- Open the URL in your browser
- Log in and approve the app
- You'll be redirected to
http://localhost:3000/callback?code=AUTHORIZATION_CODE - Copy the
codeparameter value
-
Exchange Code for Tokens:
curl -X POST https://login.notion.com/services/oauth2/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET" \ -d "redirect_uri=http://localhost:3000/callback" \ -d "code=YOUR_AUTHORIZATION_CODE"
-
Extract Refresh Token: From the JSON response, save the
refresh_tokenvalue.
- Create a new POST request to:
https://login.notion.com/services/oauth2/token - Set headers:
Content-Type: application/x-www-form-urlencoded - In the body (x-www-form-urlencoded), add:
grant_type: authorization_code client_id: YOUR_CLIENT_ID client_secret: YOUR_CLIENT_SECRET redirect_uri: http://localhost:3000/callback code: YOUR_AUTHORIZATION_CODE
- Instance URL:
https://yourcompany.my.notion.com - Login URL: Use the instance URL above
- Instance URL:
https://yourcompany--sandbox.sandbox.my.notion.com - Login URL: Replace with your sandbox instance URL
{
"mcp.servers": {
"notion": {
"command": "npx",
"args": [
"-y",
"@jjar/notion-mcp-server"
],
"env": {
"NOTION_CLIENT_ID": "your-oauth2-client-id",
"NOTION_CLIENT_SECRET": "your-oauth2-client-secret",
"NOTION_REFRESH_TOKEN": "your-refresh-token",
"NOTION_INSTANCE_URL": "https://yourorg.my.notion.com",
// Optional: Enable Enterprise optimizations for Claude Enterprise accounts
"NOTION_ENTERPRISE_MODE": "true",
"NOTION_MAX_RESPONSE_SIZE": "75000",
"NOTION_MAX_RECORDS_PER_RESPONSE": "300"
},
"disabled": false,
"alwaysAllow": [
"test-connection",
"execute-soql",
"describe-sobject",
"get-record",
"get-apex-logs",
"list-metadata-types"
]
}
}
}{
"mcp.servers": {
"notion": {
"command": "cmd",
"args": [
"/c",
"npx",
"-y",
"@jjar/notion-mcp-server"
],
"env": {
"NOTION_CLIENT_ID": "your-oauth2-client-id",
"NOTION_CLIENT_SECRET": "your-oauth2-client-secret",
"NOTION_REFRESH_TOKEN": "your-refresh-token",
"NOTION_INSTANCE_URL": "https://yourorg.my.notion.com",
// Optional: Enable Enterprise optimizations for Claude Enterprise accounts
"NOTION_ENTERPRISE_MODE": "true",
"NOTION_MAX_RESPONSE_SIZE": "75000",
"NOTION_MAX_RECORDS_PER_RESPONSE": "300"
},
"disabled": false,
"alwaysAllow": [
"test-connection",
"execute-soql",
"describe-sobject",
"get-record",
"get-apex-logs",
"list-metadata-types"
]
}
}
}Claude Desktop
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Cline (VS Code)
- Windows:
%APPDATA%\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json - macOS:
~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json - Linux:
~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json
β οΈ Important: After adding or modifying the MCP server configuration, you must restart VS Code for the changes to take effect.
Cursor
- Windows:
%USERPROFILE%\.cursor\mcp.json - macOS:
~/.cursor/mcp.json - Linux:
~/.cursor/mcp.json
For Claude Enterprise accounts with 200K+ token context windows, this MCP server includes specialized optimizations to maximize data throughput while preventing context overflow.
- 75K character responses (vs 4K standard) - 18x larger responses
- 300 records per response (vs 25-50 standard) - 6-12x more data
- Intelligent response optimization - Automatic size management for Enterprise context windows
- Enhanced bulk operations - Higher thresholds for bulk API usage
- Auto-aggregation support - Intelligent data consolidation for complex queries
Add these environment variables to your MCP configuration:
{
"mcp.servers": {
"notion": {
"env": {
"NOTION_CLIENT_ID": "your-oauth2-client-id",
"NOTION_REFRESH_TOKEN": "your-refresh-token",
"NOTION_INSTANCE_URL": "https://yourorg.my.notion.com",
// Enterprise Optimization
"NOTION_ENTERPRISE_MODE": "true",
"NOTION_MAX_RESPONSE_SIZE": "75000",
"NOTION_MAX_RECORDS_PER_RESPONSE": "300",
"NOTION_BULK_QUERY_THRESHOLD": "5000",
"NOTION_BULK_DML_THRESHOLD": "500",
"NOTION_ENABLE_AUTO_AGGREGATION": "true"
}
}
}
}When Enterprise mode is enabled:
- Smart Record Limiting: Automatically balances record count vs response size
- Context Window Monitoring: Real-time estimation of context usage
- Priority Field Optimization: Configurable field prioritization for large objects
- Bulk API Intelligence: Higher thresholds trigger bulk operations earlier
- Response Metadata: Detailed optimization information included in responses
| Mode | Max Response Size | Max Records | Bulk Query Threshold | Bulk DML Threshold |
|---|---|---|---|---|
| Standard | 4,000 chars | 50 records | 2,000 records | 200 records |
| Enterprise | 75,000 chars | 300 records | 5,000 records | 500 records |
// Enterprise mode automatically optimizes responses:
{
"records": [...], // Up to 300 records
"totalDisplayed": 300,
"totalOriginal": 1500,
"truncated": true,
"truncationReason": "Limited to 300 records for Enterprise context optimization",
"contextWindowUsage": "~65,000 chars (~16,250 tokens)",
"_enterpriseOptimization": {
"enabled": true,
"contextOptimized": "Optimized for Claude Enterprise 200K+ context window"
}
}| Variable | Required | Description | Example |
|---|---|---|---|
NOTION_CLIENT_ID |
β | Consumer Key from Connected App | 3MVG9PE4Q... |
NOTION_CLIENT_SECRET |
β | Consumer Secret from Connected App | A1B2C3D4E5... |
NOTION_REFRESH_TOKEN |
β | OAuth2 refresh token | 5Aep861TSESvWeug_w... |
NOTION_INSTANCE_URL |
β | Your Notion instance URL | https://mycompany.my.notion.com |
NOTION_ALLOW_WRITE |
Enable write operations (default: false) |
true |
| Variable | Required | Description | Default | Enterprise Default |
|---|---|---|---|---|
NOTION_ENTERPRISE_MODE |
π’ | Enable Enterprise optimizations | false |
true |
NOTION_MAX_RESPONSE_SIZE |
π’ | Maximum response size in characters | 4000 |
75000 |
NOTION_MAX_RECORDS_PER_RESPONSE |
π’ | Maximum records per response | 50 |
300 |
NOTION_BULK_QUERY_THRESHOLD |
π’ | Records threshold for bulk queries | 2000 |
5000 |
NOTION_BULK_DML_THRESHOLD |
π’ | Records threshold for bulk DML | 200 |
500 |
NOTION_ENABLE_AUTO_AGGREGATION |
π’ | Enable automatic data aggregation | false |
true |
NOTION_API_VERSION |
βοΈ | Notion API version | 59.0 |
59.0 |
NOTION_TIMEOUT |
βοΈ | Request timeout in milliseconds | 120000 |
120000 |
- Individual User Access: Each user authenticates with their own credentials
- Granular Permissions: Respects user permissions and organizational policies
- Audit Trail: All actions are tracked under the specific user
- Security Compliance: Meets enterprise security requirements
- Token Management: Refresh tokens can be revoked if compromised
- No Password Exposure: Passwords are never stored or transmitted
By default, the server runs in read-only mode for enhanced security. This means:
- β Allowed: Query data, describe objects, retrieve metadata, get debug logs
- β Blocked: Create, update, delete records, execute Apex, deploy metadata
To enable write operations, set the NOTION_ALLOW_WRITE environment variable:
NOTION_ALLOW_WRITE=trueWrite operations include:
create-record,update-record,delete-record,upsert-recordexecute-apex,run-apex-testsdeploy-metadata,deploy-bundle
- Read-only mode prevents accidental data modification
- Ideal for analytics, reporting, and development environments
- Enable write operations only when necessary and with appropriate user permissions
- All write operations still respect Notion user permissions and organizational policies
β
Safe for Auto-Approval (alwaysAllow)
test-connection- Connection validation (read-only)execute-soql- SOQL queries (read-only)describe-sobject- Metadata inspection (read-only)get-record- Single record retrieval (read-only)get-apex-logs- Debug log access (read-only)list-metadata-types- Metadata type discovery (read-only)
create-record,update-record,delete-record,upsert-record- Data modificationdeploy-metadata- Metadata deploymentexecute-apex,run-apex-tests- Code executionexecute-sosl- Search operations (can be resource-intensive)retrieve-metadata- Metadata retrieval (can be large)
-
Invalid Client ID/Secret:
- Verify the Connected App credentials
- Ensure the app is deployed and active
-
Invalid Refresh Token:
- Re-generate the refresh token using the authorization flow
- Check token expiration in Connected App settings
-
Instance URL Mismatch:
- Use the exact instance URL from your Notion org
- For sandboxes, include the full sandbox URL
-
Permission Issues:
- Verify OAuth scopes in the Connected App
- Check user permissions for specific operations
Use the test-connection tool to verify your setup:
# The MCP server will use this tool automatically when you ask about connection status
# Example: "Test my Notion connection"- OAuth2 Authentication Manager - Secure token-based authentication
- Connection Manager - Singleton pattern with health monitoring
- Tool Classes - Organized by functionality (Query, Apex, Data, Metadata)
- Error Handler - Comprehensive error formatting with context
- Cache Manager - TTL-based caching for performance optimization
- Auto-Bulk Switching - Automatically uses Bulk API for large operations
- Intelligent Caching - SObject metadata cached for 1 hour
- Connection Reuse - Single connection across all operations
- Polling Optimization - Efficient monitoring of long-running operations
# Test individual tools
node tests/test-query-tools.js
node tests/test-data-tools.js
node tests/test-apex-tools.js
node tests/test-metadata-tools.js- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Model Context Protocol - The protocol this server implements
- jsforce - Notion API library used in this project
- Claude Desktop - AI assistant that supports MCP servers
- Cline - VS Code extension for AI-assisted development
JarosΕaw Jaworski
Part of this implementation was developed with assistance from Claude Sonnet 4 using the Cline VS Code extension, demonstrating the power of AI-assisted development in creating comprehensive developer tools.
This project is licensed under the MIT License - see the LICENSE file for details.
β οΈ Deprecated: Username/Password Authentication
Security Warning: Username/password authentication is deprecated and not recommended for production use. Please migrate to OAuth2 authentication for better security and compliance.
For legacy systems that require username/password authentication, the following environment variables were supported:
NOTION_USERNAME- Notion usernameNOTION_PASSWORD- Notion passwordNOTION_SECURITY_TOKEN- Security token (if required)NOTION_LOGIN_URL- Login URL (production or sandbox)
Migration Path: Follow the OAuth2 setup instructions above to upgrade to secure authentication.
This project includes automated deployment to Kandji MDM for macOS environments. The deployment workflow automatically uploads PKG installers to Kandji when releases are published.
Configure the following GitHub Secrets:
MW_KANDJI_API_TOKEN- Kandji API token (Settings > Integrations > API Token)MW_KANDJI_API_URL- Kandji API URL (e.g.,https://<tenant>.api.kandji.io)MW_SLACK_BOT_TOKEN(optional) - Slack bot token for deployment notifications
The workflow triggers automatically when:
- A GitHub release is published
- Manual trigger via
workflow_dispatch
To deploy a specific release to Kandji:
- Go to the Actions tab in GitHub
- Select "Push PKG to Kandji" workflow
- Click "Run workflow"
- Configure options:
- Release tag: Specific version (e.g.,
v1.1.0) or leave empty for latest - App name: Custom name for Kandji (default: "Notion MCP Server")
- Enforcement: Deployment policy (
install_and_enforce,install_once, orself_service) - Category: Self-service category (default: "Productivity")
- Release tag: Specific version (e.g.,
- π¦ Automatic PKG Download - Retrieves signed PKG from GitHub releases
- π Dynamic Lookup - Updates existing Kandji Custom Apps or creates new ones
- π‘οΈ Version Management - Follows
NAME-VERSION.pkgnaming convention - π± Slack Notifications - Optional deployment success notifications
- π Validation - PKG signature verification and integrity checks
After deployment:
- New Custom Apps: Must be manually assigned to Blueprints in Kandji
- Updated Apps: Retain existing Blueprint assignments
- Enforcement Policies: Configured via workflow parameters
- Self-Service Categories: Organized for end-user discovery
- HTTP 503 Errors: kpkg automatically retries with delays
- Version Conflicts: Use dynamic lookup to update existing apps
- Blueprint Assignment: New apps require manual Blueprint configuration in Kandji
- Quarantine Issues: Workflow automatically clears quarantine attributes
For detailed logs, check the GitHub Actions workflow run output.
This project features a fully automated release system that ensures consistent versioning and seamless deployment:
When you update package.json version (in a commit to master):
- π€ Auto-release workflow detects version changes
- π·οΈ Creates GitHub release with proper tag
- π¦ Triggers build workflow to create PKG installer
- π Deploys to Kandji automatically (5-minute delay for build completion)
# Bump version and trigger automated release
./scripts/bump-version.sh patch # 1.1.2 β 1.1.3
./scripts/bump-version.sh minor # 1.1.2 β 1.2.0
./scripts/bump-version.sh major # 1.1.2 β 2.0.0
# Fix current version situation (create missing release)
./scripts/create-missing-release.sh
# Sync versions across all files manually
./scripts/sync-version.sh [version]- π Version Detection - Automatic detection of
package.jsonchanges - π Auto-Generated Release Notes - Dynamic release content based on version
- ποΈ PKG Build Integration - Seamless integration with existing build workflow
- βοΈ Kandji Auto-Deployment - Automatic MDM deployment after successful build
- π Version Synchronization - Keeps all files in sync (package.json, Xcode, etc.)
The system maintains version consistency across:
- π
package.json- Primary version source - π
package-lock.json- Automatically synced - π»
src/index.ts- Server version reporting - π Xcode project
MARKETING_VERSION- macOS app versioning - π·οΈ Git tags - Release tagging
- π GitHub release notes - Dynamic version references
We're currently transitioning to this automated system. The project is at v1.1.2 in package.json, with automated workflows in place for future releases.
Complete documentation is available in the docs/ directory:
- π Setup Guide - OAuth 2.0 configuration
- π’ Deployment - Installation and packaging
- π οΈ Development - Technical implementation guides
- π Examples - Usage examples and patterns
- π§ Troubleshooting - Issue resolution guides
π Start with the Documentation Index for a complete overview.