Doramagic Project Pack · Human Manual
notion-mcp-server
The MCP server acts as a bridge between AI clients (such as Claude, Cursor, or GitHub Copilot) and the Notion API. Instead of manually implementing API calls, AI agents can discover and in...
Introduction to Notion MCP Server
Related topics: Quick Start Guide, System Architecture
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Quick Start Guide, System Architecture
Introduction to Notion MCP Server
The Notion MCP Server is an official implementation of the Model Context Protocol (MCP) server that exposes the Notion API as MCP tools. It enables AI assistants and agents to interact with Notion workspaces through a standardized protocol, allowing them to search, read, create, and modify Notion pages, databases, and content.
Overview
The MCP server acts as a bridge between AI clients (such as Claude, Cursor, or GitHub Copilot) and the Notion API. Instead of manually implementing API calls, AI agents can discover and invoke MCP tools dynamically, making it easier to build AI-powered Notion integrations.
Key Characteristics
| Attribute | Value |
|---|---|
| Package Name | @notionhq/notion-mcp-server |
| Current Version | 2.3.0 |
| License | MIT |
| API Version | 2025-09-03 (Data Source Edition) |
| Node.js Support | 18+ (with Headers polyfill for older versions) |
| Transport Modes | stdio, Streamable HTTP |
| Total Tools | 22 |
Sources: README.md:1-30package.json:7-10
Architecture
The Notion MCP Server follows a layered architecture that auto-generates tools from an OpenAPI specification. This design ensures that any updates to the Notion API are automatically reflected in the available MCP tools without requiring code changes.
High-Level Flow
graph TD
A[scripts/notion-openapi.json] --> B[OpenAPIToMCPConverter]
B --> C[MCPProxy]
C --> D[MCP SDK]
D --> E[AI Client]
F[User Request] --> E
E --> G[Tool Call]
G --> H[HTTP Client]
H --> I[Notion API]
I --> H --> G --> FSources: CLAUDE.md:1-30
Component Architecture
graph TD
subgraph "Entry Point"
A[scripts/start-server.ts]
end
subgraph "Server Initialization"
B[src/init-server.ts]
end
subgraph "Core Implementation"
C[openapi/parser.ts]
D[mcp/proxy.ts]
E[client/http-client.ts]
end
A --> B --> C
C --> D
D --> E
E --> F[Notion API]The server initialization process follows these steps:
- Load OpenAPI Spec: The server loads
scripts/notion-openapi.jsonwhich defines all Notion API endpoints in OpenAPI 3.1.0 format - Validate Spec: The spec is validated against OpenAPI schema requirements
- Create MCPProxy: A new MCPProxy instance is created with the validated spec
- Register Tools:
MCPProxy.setupHandlers()registers all discovered tools with the MCP SDK - Start Transport: The server starts listening on the configured transport (stdio or HTTP)
Sources: CLAUDE.md:15-45scripts/start-server.ts:1-50
Tool Generation Flow
Tools are automatically generated from the OpenAPI specification through a conversion process:
graph LR
A[OpenAPI Operation] --> B[Extract operationId]
B --> C[Parse Parameters]
C --> D[Parse Request Body]
D --> E[Parse Response Schema]
E --> F[Create MCP Tool]
G[Path + Method] --> A
H[inputSchema] --> F
I[returnSchema] --> FOpenAPIToMCPConverter.convertToMCPTools()iterates through all paths and operations in the OpenAPI spec- Each operation becomes an MCP tool where the name is derived from
operationId - Operation parameters and request body are combined into the tool's
inputSchema - The response schema becomes the tool's
returnSchema MCPProxy.setupHandlers()registers the tools with the MCP SDK
Sources: CLAUDE.md:30-50src/openapi-mcp-server/openapi/parser.ts:1-50
File Structure
The repository is organized as follows:
notion-mcp-server/
├── scripts/
│ ├── notion-openapi.json # OpenAPI 3.1.0 specification
│ └── start-server.ts # CLI entry point
├── src/
│ ├── init-server.ts # Server initialization
│ └── openapi-mcp-server/
│ ├── openapi/
│ │ └── parser.ts # OpenAPI to MCP conversion
│ ├── mcp/
│ │ └── proxy.ts # Tool registration & execution
│ └── client/
│ ├── http-client.ts # HTTP request execution
│ └── polyfill-headers.ts # Node.js Headers polyfill
├── bin/
│ └── cli.mjs # Bundled CLI
└── package.json # Package configuration
| File | Purpose | Lines |
|---|---|---|
scripts/notion-openapi.json | Source of truth for all tools | - |
src/init-server.ts | Loads & validates spec, creates MCPProxy | - |
src/openapi-mcp-server/openapi/parser.ts | Converts OpenAPI → MCP tools | ~529 |
src/openapi-mcp-server/mcp/proxy.ts | MCP tool registration and execution | ~209 |
src/openapi-mcp-server/client/http-client.ts | Executes API calls via axios | ~198 |
Sources: CLAUDE.md:50-65
Installation and Configuration
Prerequisites
- Node.js 18 or higher
- A Notion integration token (from Notion integrations page)
Environment Variables
| Variable | Description | Required |
|---|---|---|
NOTION_TOKEN | Notion integration secret (recommended) | Yes |
OPENAPI_MCP_HEADERS | JSON string with custom headers | Alternative |
AUTH_TOKEN | Bearer token for HTTP transport authentication | For HTTP mode |
NOTION_API_URL | Override Notion API base URL | No |
Sources: README.md:80-120
npm Installation
For Cursor, Claude Desktop, and similar clients:
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
For Zed editor:
{
"context_servers": {
"some-context-server": {
"command": {
"path": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"]
},
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ntn_****\", \"Notion-Version\": \"2025-09-03\"}"
}
}
}
}
Sources: README.md:100-140
Docker Installation
Using the official Docker Hub image:
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": ["run", "--rm", "-i", "-e", "NOTION_TOKEN", "mcp/notion"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Or building locally with docker-compose:
docker compose build
Sources: README.md:180-220
Transport Modes
The server supports two transport modes for communication with MCP clients.
Standard I/O (stdio)
The default transport mode where the server communicates via stdin/stdout. This is suitable for local integrations and most IDE plugins.
npx @notionhq/notion-mcp-server
# or
notion-mcp-server
Sources: README.md:70-80
Streamable HTTP
An HTTP-based transport that enables remote connections and is suitable for network deployments.
npx @notionhq/notion-mcp-server --transport http --port 3000
When using HTTP transport, the server is available at http://0.0.0.0:<port>/mcp.
#### HTTP Authentication
The HTTP transport requires bearer token authentication:
| Method | Description |
|---|---|
| Auto-generated token | npx @notionhq/notion-mcp-server --transport http |
| CLI argument | --auth-token "your-secret-token" |
| Environment variable | AUTH_TOKEN="your-secret-token" |
Example authenticated request:
curl -H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
-H "mcp-session-id: your-session-id" \
-d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": 1}' \
http://localhost:3000/mcp
Sources: scripts/start-server.ts:1-50README.md:150-175
Available Tools
The server exposes 22 MCP tools generated from the Notion API OpenAPI specification. Tools are named using the operationId from the OpenAPI spec.
Tool Naming Convention
- Tool names are derived from the OpenAPI
operationId(e.g.,retrieve-a-database) - Names are truncated to 64 characters and converted to title case for display
- Parameters and response schemas are automatically extracted from the OpenAPI specification
Sources: CLAUDE.md:45-50
Core Operations
| Category | Example Tools |
|---|---|
| Pages | create-a-page, retrieve-a-page, update-a-page, archive-a-page, move-page |
| Databases | retrieve-a-database, query-a-database |
| Data Sources | create-a-data-source, retrieve-a-data-source, update-a-data-source, query-data-source, list-data-source-templates |
| Search | search |
| Comments | create-a-comment, retrieve-comments |
| Users | list-users, retrieve-a-user |
| Blocks | Various block operations |
Version 2.0.0 Breaking Changes
Version 2.0.0 introduced significant changes to align with the Notion API 2025-09-03 (Data Source Edition):
#### Removed Tools
| Old Tool | Reason |
|---|---|
post-database-query | Replaced by query-data-source |
update-a-database | Replaced by update-a-data-source |
create-a-database | Replaced by create-a-data-source |
#### New Tools
| New Tool | Description |
|---|---|
query-data-source | Query a data source with filters and sorts |
retrieve-a-data-source | Get metadata and schema for a data source |
update-a-data-source | Update data source properties |
create-a-data-source | Create a new data source |
list-data-source-templates | List available templates in a data source |
move-page | Move a page to a different parent location |
retrieve-a-database | Get database metadata including data source IDs |
#### Parameter Changes
| Change | Description |
|---|---|
database_id → data_source_id | All database operations now use data source ID |
| Search filter values | Changed from ["page", "database"] to ["page", "data_source"] |
| Page creation | Now supports both page_id and database_id parents |
Sources: README.md:35-80
Parameter Handling
The MCP server includes sophisticated parameter deserialization to handle complex nested data structures passed through MCP clients.
JSON String Deserialization
When AI clients pass JSON data as string parameters, the server automatically parses them:
graph TD
A[String Parameter] --> B{Starts with { or [?}
B -->|Yes| C[Attempt JSON.parse]
C --> D{Parse Success?}
D -->|Yes| E{Result is Object/Array?}
E -->|Yes| F[Return parsed value]
E -->|No| G[Keep original string]
D -->|No| G
B -->|No| GThis logic handles:
- JSON objects passed as strings
- JSON arrays passed as strings
- Nested objects within arrays
- Recursively nested objects
Sources: src/openapi-mcp-server/mcp/proxy.ts:1-60
Development
Build and Test
npm run build # TypeScript compilation + CLI bundling
npm test # Run vitest tests
npm run dev # Start dev server with hot reload
Testing Changes Locally
- Run
npm linkfrom the repository root to create a machine-global symlink - Add the following to your MCP client's configuration:
{
"mcpServers": {
"notion-local-package": {
"command": "notion-mcp-server",
"env": {
"NOTION_TOKEN": "ntn_..."
}
}
}
}
- Cleanup by running
npm unlinkfrom the repository root
Adding New Endpoints
The architecture is designed so that only scripts/notion-openapi.json needs to be modified to add new tools. The tool generation is fully automated from the OpenAPI specification.
Sources: README.md:250-280CLAUDE.md:20-30
CLI Options
| Option | Description | Default |
|---|---|---|
--transport <type> | Transport type: 'stdio' or 'http' | stdio |
--port <number> | Port for HTTP server | 3000 |
--auth-token <token> | Bearer token for HTTP auth | auto-generated |
--disable-auth | Disable HTTP bearer auth | - |
--help, -h | Show help message | - |
# Examples
notion-mcp-server # stdio (default)
notion-mcp-server --transport http # HTTP transport
notion-mcp-server --transport http --port 8080 # Custom port
notion-mcp-server --transport http --auth-token abc # With auth
Sources: scripts/start-server.ts:1-50
HTTP Client Implementation
The HTTP client uses axios for making requests to the Notion API and handles the conversion between MCP tool parameters and HTTP request components.
Request Processing Flow
sequenceDiagram
participant MCP as MCP Client
participant Server as MCP Server
participant HTTP as HTTP Client
participant Notion as Notion API
MCP->>Server: Tool Call with params
Server->>Server: Extract URL params
Server->>Server: Extract body params
Server->>HTTP: Build request config
HTTP->>Notion: HTTP Request
Notion-->>HTTP: Response
HTTP-->>Server: Parsed response
Server-->>MCP: Tool resultKey Implementation Details
- Form Data Handling: When form data is present,
formData.getHeaders()is used for correct Content-Type - Body Parameters: JSON body is sent with
Content-Type: application/json - Header Conversion: Axios response headers are converted to standard
Headersobjects - Error Handling: Missing operations throw descriptive errors
Sources: src/openapi-mcp-server/client/http-client.ts:1-80
Dependencies
| Dependency | Version | Purpose |
|---|---|---|
@modelcontextprotocol/sdk | ^1.25.1 | MCP protocol implementation |
axios | ^1.8.4 | HTTP client for Notion API |
express | ^4.21.2 | HTTP transport server |
form-data | ^4.0.1 | Multipart form handling |
openapi-client-axios | ^7.5.5 | OpenAPI client generation |
yargs | ^17.7.2 | CLI argument parsing |
zod | 3.24.1 | Schema validation |
Sources: package.json:25-45
Future Considerations
[!NOTE]
Notion has introduced Notion MCP (remote), a new remote MCP server with OAuth-based authentication and tools optimized for AI agents, including Markdown editing capabilities.
The local MCP server repository may be sunset in the future. Issues and pull requests are not actively monitored. For the remote MCP server, please contact Notion support.
Sources: README.md:1-25
Quick Reference
Common Commands
# Install and run
npx @notionhq/notion-mcp-server
# Build from source
npm run build
npm test
# Development
npm run dev
npm link # For local testing
Integration Setup Checklist
- [ ] Create Notion integration at notion.so/profile/integrations
- [ ] Share target pages with the integration (Connections)
- [ ] Configure MCP client with
NOTION_TOKENorOPENAPI_MCP_HEADERS - [ ] Test connectivity with a simple search or retrieval
File Paths Reference
| Path | Description |
|---|---|
scripts/notion-openapi.json | OpenAPI 3.1.0 spec for all tools |
src/init-server.ts | Server initialization |
src/openapi-mcp-server/openapi/parser.ts | OpenAPI → MCP conversion |
src/openapi-mcp-server/mcp/proxy.ts | Tool registration |
src/openapi-mcp-server/client/http-client.ts | API request execution |
bin/cli.mjs | Bundled CLI entry point |
Sources: [README.md:1-30]()[package.json:7-10]()
Quick Start Guide
Related topics: Introduction to Notion MCP Server, Authentication System, npm Installation and Configuration
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Introduction to Notion MCP Server, Authentication System, npm Installation and Configuration
Quick Start Guide
This guide provides everything you need to get started with the Notion MCP Server, from installation to running your first AI-assisted Notion operations.
Overview
The Notion MCP Server is a Model Context Protocol (MCP) server that exposes the Notion API as MCP tools, enabling AI assistants to interact with Notion workspaces. It auto-generates tools from an OpenAPI specification, providing 22 tools for operations like searching pages, creating content, querying databases, and managing comments.
Sources: CLAUDE.md:1-10
Architecture
The server transforms the Notion REST API into an MCP-compatible interface:
graph TD
A["scripts/notion-openapi.json<br/>OpenAPI 3.1.0 Spec"] --> B["OpenAPIToMCPConverter"]
B --> C["MCP Tools<br/>22 Tools Generated"]
C --> D["MCPProxy.setupHandlers()"]
D --> E["HttpClient<br/>API Execution"]
E --> F["Notion API<br/>https://api.notion.com"]Tool Generation Flow
| Step | Component | Description |
|---|---|---|
| 1 | OpenAPI Spec | Iterates all paths and operations |
| 2 | Operation → Tool | Each operationId becomes a tool name |
| 3 | Parameters | Converted to inputSchema |
| 4 | Response | Converted to returnSchema |
| 5 | Registration | MCPProxy.setupHandlers() registers with SDK |
Sources: CLAUDE.md:32-38
Prerequisites
Before getting started, ensure you have:
- Node.js 18+ (for native
Headerssupport) - npm or yarn package manager
- A Notion integration with an API token
- Access to Notion pages you want the integration to access
Sources: src/openapi-mcp-server/client/polyfill-headers.ts:1-5
Installation
Option 1: Using npm (Recommended)
Run the server directly with npx:
npx -y @notionhq/notion-mcp-server
Sources: README.md:1-5
Option 2: Using Docker
#### Option 2a: Official Docker Hub Image
docker run --rm -i \
-e NOTION_TOKEN=ntn_**** \
mcp/notion
#### Option 2b: Build Locally
docker compose build
docker run --rm -i \
-e NOTION_TOKEN=ntn_**** \
notion-mcp-server
Sources: README.md:2-25
Option 3: Local Development
git clone https://github.com/makenotion/notion-mcp-server.git
cd notion-mcp-server
npm install
Sources: package.json:1-20
Configuration
Step 1: Create a Notion Integration
- Go to https://www.notion.so/profile/integrations
- Create a new internal integration or select an existing one
- Copy the integration token (starts with
ntn_)
Sources: README.md:1-8
Step 2: Grant Page Access
For each Notion page you want the integration to access:
- Open the target page
- Click the three dots menu (⋯)
- Select "Connect to integration"
Sources: README.md:1-5
Step 3: Configure Your MCP Client
#### Cursor & Claude Desktop
Add to .cursor/mcp.json or ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
#### Zed
Add to settings.json:
{
"context_servers": {
"some-context-server": {
"command": {
"path": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ntn_****\", \"Notion-Version\": \"2025-09-03\"}"
}
},
"settings": {}
}
}
}
#### GitHub Copilot CLI
/mcp add
Or edit ~/.copilot/mcp-config.json:
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Sources: README.md:1-70
Authentication
Environment Variables
| Variable | Description | Priority |
|---|---|---|
NOTION_TOKEN | Integration token (recommended) | Primary |
OPENAPI_MCP_HEADERS | JSON string with custom headers | Alternative |
AUTH_TOKEN | Bearer token for HTTP transport | Lower |
Sources: scripts/start-server.ts:1-30
HTTP Transport Authentication
When using the Streamable HTTP transport, bearer token authentication is required:
# Auto-generated token (development only)
npx @notionhq/notion-mcp-server --transport http
# Custom token via CLI (recommended for production)
npx @notionhq/notion-mcp-server --transport http --auth-token "your-secret-token"
# Custom token via environment variable
AUTH_TOKEN="your-secret-token" npx @notionhq/notion-mcp-server --transport http
The --auth-token CLI argument takes precedence over the AUTH_TOKEN environment variable.
Sources: scripts/start-server.ts:1-35
Making HTTP Requests
All requests must include the bearer token:
curl -H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
-H "mcp-session-id: your-session-id" \
-d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": 1}' \
http://localhost:3000/mcp
Sources: README.md:1-15
Command Line Options
| Option | Description | Default |
|---|---|---|
--transport <type> | Transport type: stdio or http | stdio |
--port <number> | Port for HTTP server | 3000 |
--auth-token <token> | Bearer token for HTTP authentication | Auto-generated |
--disable-auth | Disable authentication for HTTP transport | false |
--help, -h | Show help message | - |
Sources: scripts/start-server.ts:1-25
Usage Examples
# Default stdio transport
notion-mcp-server
# Explicit stdio transport
notion-mcp-server --transport stdio
# HTTP transport with custom port
notion-mcp-server --transport http --port 8080
# HTTP transport with custom auth token
notion-mcp-server --transport http --auth-token "my-secret"
Available Tools
The server exposes 22 MCP tools auto-generated from the Notion API. Key tools include:
| Tool | Description | Version Change |
|---|---|---|
query-data-source | Query a data source with filters and sorts | New in v2.0 |
retrieve-a-data-source | Get metadata and schema for a data source | New in v2.0 |
create-a-data-source | Create a new data source | New in v2.0 |
update-a-data-source | Update data source properties | New in v2.0 |
move-page | Move a page to a different parent | New in v2.0 |
list-data-source-templates | List available templates in a data source | New in v2.0 |
retrieve-a-database | Get database metadata including data source IDs | New in v2.0 |
search | Search pages and data sources | Updated filter values |
Note: In v2.0.0,database_idparameters changed todata_source_idfor data source operations.
Sources: CLAUDE.md:1-20
Development
Build & Test
npm run build # TypeScript compilation + CLI bundling
npm test # Run vitest tests
npm run dev # Start dev server with hot reload
Testing Local Changes in Cursor
- Run
npm linkfrom repository root to create a machine-global symlink - Add to Cursor's
mcp.json:
{
"mcpServers": {
"notion-local-package": {
"command": "notion-mcp-server",
"env": {
"NOTION_TOKEN": "ntn_..."
}
}
}
}
- Cleanup: Run
npm unlinkfrom repository root
Publish
npm login
npm publish --access public
Sources: CLAUDE.md:1-40
Example Usage
Natural Language Examples
| Instruction | Operations |
|---|---|
| Comment "Hello MCP" on page "Getting started" | search → create-a-comment |
| Add a page titled "Notion MCP" to page "Development" | search → create-a-page |
Get the content of page 1a6b35e6e67f802fa7e1d27686f017f2 | retrieve-a-block-children |
The AI will automatically plan the correct sequence of API calls to accomplish the task.
Sources: README.md:1-20
Parameter Handling
The MCP proxy automatically deserializes JSON-string parameters to support nested objects and arrays:
graph LR
A["String: '{\"key\":\"value\"}'"] --> B["deserializeParams()"]
B --> C["Object: {key: 'value'}"]
D["Array: ['[1,2,3]']"] --> B
B --> E["Array: [1, 2, 3]"]Sources: src/openapi-mcp-server/mcp/proxy.ts:1-60
Troubleshooting
Common Issues
| Issue | Solution |
|---|---|
| "No base URL found" | Ensure OpenAPI spec has a valid server URL |
| Authentication errors | Verify NOTION_TOKEN is set correctly |
| Page access denied | Connect the integration to the target page in Notion |
| Port already in use | Use --port to specify a different port |
Node.js Version
The server requires Node.js 18+ for native Headers class support. A polyfill is available for older versions.
Sources: src/openapi-mcp-server/client/polyfill-headers.ts:1-5
Next Steps
- Review the CLAUDE.md for architecture details
- Explore the OpenAPI specification for all available endpoints
- Check the repository issues for known limitations
Sources: [CLAUDE.md:1-10]()
System Architecture
Related topics: Transport Layers, MCP Proxy Implementation, Available MCP Tools
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Transport Layers, MCP Proxy Implementation, Available MCP Tools
System Architecture
Overview
The Notion MCP Server is an official Model Context Protocol (MCP) server implementation that exposes the Notion API as MCP tools. The server automatically generates MCP tools from an OpenAPI 3.1.0 specification, enabling AI assistants to interact with Notion workspaces through standardized MCP protocols.
Sources: CLAUDE.md
High-Level Architecture
The system follows a layered architecture where the OpenAPI specification serves as the single source of truth for tool definitions. Tools are auto-generated from the spec without requiring manual code changes for new endpoints.
graph TD
A[scripts/notion-openapi.json<br/>OpenAPI 3.1.0 Spec] --> B[OpenAPIToMCPConverter]
B --> C[MCPProxy]
C --> D[MCP SDK]
A --> E[HttpClient]
E --> F[Notion API v1]
B -.->|Converts to| G[MCPTools]
C -.->|Registers| GSources: CLAUDE.md:4-10
Core Components
Component Architecture Table
| Component | File Path | Responsibility |
|---|---|---|
| OpenAPI Specification | scripts/notion-openapi.json | Single source of truth for all API endpoints and schemas |
| Server Entry Point | src/init-server.ts | Loads spec, creates MCPProxy instance |
| OpenAPI Parser | src/openapi-mcp-server/openapi/parser.ts | Converts OpenAPI → MCP tool definitions |
| MCP Proxy | src/openapi-mcp-server/mcp/proxy.ts | Tool registration and request handling |
| HTTP Client | src/openapi-mcp-server/client/http-client.ts | Executes Notion API calls |
| Auth Module | src/openapi-mcp-server/auth/ | Authentication and header management |
| Server CLI | scripts/start-server.ts | Transport layer initialization |
Sources: src/openapi-mcp-server/openapi/parser.ts Sources: src/openapi-mcp-server/mcp/proxy.ts
OpenAPI to MCP Converter
The OpenAPIToMCPConverter class in parser.ts handles the transformation of OpenAPI operations into MCP-compatible tool definitions.
convertToMCPTools(): {
tools: Record<string, { methods: NewToolMethod[] }>
openApiLookup: Record<string, OpenAPIV3.OperationObject & { method: string; path: string }>
zip: Record<string, { openApi: OpenAPIV3.OperationObject; mcp: NewToolMethod }>
}
The conversion process:
- Iterates all paths and operations from the OpenAPI spec
- Extracts operation parameters and requestBody schemas
- Generates JSON Schema for input validation
- Extracts response schemas for return types
- Creates MCP tool definitions with operationId as tool name
Sources: src/openapi-mcp-server/openapi/parser.ts:75-150
MCP Proxy
The MCPProxy class manages tool registration and execution through the MCP SDK:
class MCPProxy {
constructor(openApiSpec: OpenAPIV3.Document)
private setupHandlers(): void
private truncateToolName(name: string): string
private operationIdToTitle(operationId: string): string
}
Key responsibilities:
- Tool Registration: Uses
ListToolsRequestSchemato expose available tools - Tool Execution: Uses
CallToolRequestSchemato handle tool invocations - Parameter Deserialization: Handles JSON string parsing for complex parameters
- Annotation: Marks tools with
readOnlyHintordestructiveHintbased on HTTP method
Sources: src/openapi-mcp-server/mcp/proxy.ts:60-120
HTTP Client Architecture
Request Execution Flow
graph LR
A[Tool Request] --> B[MCPProxy]
B --> C[Parameter Processing]
C --> D[Path/Query Separation]
D --> E[HttpClient.operationFn]
E --> F[Axios HTTP Call]
F --> G[Notion API]
G --> F
F --> H[Response Headers]
H --> I[MCPToolResult]The HTTP client handles:
| Responsibility | Implementation |
|---|---|
| Base URL Configuration | Configured via OpenAPI spec server definition |
| Header Management | Merges auth headers with operation-specific headers |
| Parameter Routing | Separates path/query params from body params |
| Form Data Support | Detects and sets appropriate Content-Type headers |
| Response Conversion | Transforms Axios headers to standard Headers object |
Sources: src/openapi-mcp-server/client/http-client.ts:50-100
Parameter Processing
// Path and query parameters are extracted to urlParameters
if (param.in === 'path' || param.in === 'query') {
if (params[param.name] !== undefined) {
urlParameters[param.name] = params[param.name]
}
}
// Body parameters remain separate for request body
// Form data uses multipart encoding
Sources: src/openapi-mcp-server/client/http-client.ts:30-45
Authentication System
Authentication Architecture
graph TD
A[Environment Variables] --> B[Auth Module]
B --> C{Header Type}
C -->|NOTION_TOKEN| D[Bearer Token]
C -->|OPENAPI_MCP_HEADERS| E[Raw JSON Headers]
D --> F[Authorization Header]
E --> F
F --> G[HttpClient Headers]Auth Module Structure
The authentication system is split into three modules:
| Module | Purpose |
|---|---|
auth/types.ts | TypeScript interfaces for auth configuration |
auth/template.ts | Header template definitions and validation |
auth/index.ts | Main export combining auth functionality |
Sources: src/openapi-mcp-server/auth/index.ts Sources: src/openapi-mcp-server/auth/types.ts
Authentication Methods
The server supports two authentication approaches:
| Method | Environment Variable | Format |
|---|---|---|
| Simple Token | NOTION_TOKEN | ntn_**** integration token |
| Advanced Headers | OPENAPI_MCP_HEADERS | JSON with Authorization and Notion-Version |
Sources: src/openapi-mcp-server/auth/template.ts
Transport Layer Architecture
Supported Transports
graph TD
A[MCP Client] --> B{Transport Type}
B -->|stdio| C[Standard I/O]
B -->|http| D[Streamable HTTP]
C --> E[scripts/start-server.ts]
D --> E
E --> F[MCPProxy]
F --> G[Notion API]The server supports two transport mechanisms configured via CLI arguments:
| Transport | Default | CLI Flag | Port |
|---|---|---|---|
| stdio | Yes | --transport stdio | N/A |
| Streamable HTTP | No | --transport http | 3000 |
Sources: scripts/start-server.ts:1-50
HTTP Transport Security
For HTTP transport, bearer token authentication is required:
# Auto-generated token (development only)
npx @notionhq/notion-mcp-server --transport http
# Custom token via CLI
npx @notionhq/notion-mcp-server --transport http --auth-token "your-token"
# Custom token via environment variable
AUTH_TOKEN="your-token" npx @notionhq/notion-mcp-server --transport http
Sources: scripts/start-server.ts:30-80
Tool Naming Conventions
Tool names are derived from OpenAPI operationId with the following transformations:
| Original operationId | Generated Tool Name |
|---|---|
retrieve-a-database | Retrieve-A-Database |
create-a-page | Create-A-Page |
search | Search |
Rules:
- Names are truncated to 64 characters maximum
- Converted to Title Case for display
- Prefixed with parent tool name and hyphen when multiple methods exist
Sources: src/openapi-mcp-server/mcp/proxy.ts:140-160
Schema Conversion
OpenAPI to JSON Schema Mapping
The convertOpenApiSchemaToJsonSchema method handles complex schema transformations:
| OpenAPI Feature | JSON Schema Output | Notes |
|---|---|---|
format: binary | format: uri-reference | For file path handling |
type: object | type: object | Includes properties and additionalProperties |
type: array | type: array | Converts items recursively |
oneOf/anyOf/allOf | oneOf/anyOf/allOf | Preserves discriminator info |
enum | enum | Preserves allowed values |
const | const | Important for discriminator keys |
default | default | Provides fallback values |
Sources: src/openapi-mcp-server/openapi/parser.ts:20-80
Server Initialization Flow
sequenceDiagram
participant CLI as scripts/start-server.ts
participant Init as src/init-server.ts
participant Proxy as MCPProxy
participant Auth as Auth Module
CLI->>Init: Loads notion-openapi.json
Init->>Auth: parseHeadersFromEnv()
Auth-->>Init: Headers configuration
Init->>Proxy: new MCPProxy(spec, headers)
Proxy->>Proxy: convertToMCPTools()
Proxy->>Proxy: setupHandlers()
Init->>CLI: Configured server
CLI->>CLI: Start transport (stdio/http)Sources: src/init-server.ts
API Version Management
The server uses Notion API version 2025-09-03 (Data Source Edition):
| Endpoint Type | Pattern | Description |
|---|---|---|
| Traditional | /v1/databases/{database_id} | Classic database operations |
| Data Source | /v1/data_sources/{data_source_id} | New data source endpoints |
Sources: CLAUDE.md:18-20
Configuration Options
Environment Variables
| Variable | Required | Description |
|---|---|---|
NOTION_TOKEN | Yes (recommended) | Notion integration token |
OPENAPI_MCP_HEADERS | No | JSON string with custom headers |
AUTH_TOKEN | No | Bearer token for HTTP transport |
PORT | No | HTTP server port (default: 3000) |
CLI Arguments
| Argument | Type | Default | Description |
|---|---|---|---|
--transport | string | stdio | Transport type |
--port | number | 3000 | HTTP server port |
--auth-token | string | auto-generated | Bearer token |
--disable-auth | flag | false | Disable HTTP auth |
--help | flag | - | Show help message |
Sources: scripts/start-server.ts:5-40
Sources: [CLAUDE.md](https://github.com/makenotion/notion-mcp-server/blob/main/CLAUDE.md)
Transport Layers
Related topics: System Architecture, Authentication System
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture, Authentication System
Transport Layers
The Notion MCP Server supports two distinct transport mechanisms for communication between AI clients and the server: stdio (Standard Input/Output) and Streamable HTTP. These transport layers define how MCP protocol messages are exchanged, authentication is handled, and the server exposes its capabilities to clients.
Overview
Transport layers in the MCP (Model Context Protocol) serve as the communication backbone between AI assistants and the server. The Notion MCP Server abstracts the underlying transport details, allowing clients to choose the mode that best fits their environment.
graph TD
subgraph "Transport Modes"
A["stdio Transport<br/>(Default)"]
B["Streamable HTTP Transport"]
end
subgraph "Client Types"
C["Cursor"]
D["Claude Desktop"]
E["Zed Editor"]
F["GitHub Copilot CLI"]
end
A --> C
A --> D
B --> E
B --> FSources: README.md
Transport Types
stdio Transport (Default)
The stdio transport is the default mode for the Notion MCP Server. It uses standard input and output streams for communication, making it ideal for local development and integration with desktop AI clients.
Characteristics:
- Bidirectional JSON-RPC communication via stdin/stdout
- No network binding required
- Suitable for local MCP clients
- Default mode when no transport is specified
Usage:
# Default stdio mode
notion-mcp-server
# Explicit stdio mode
notion-mcp-server --transport stdio
Sources: scripts/start-server.ts:1-45
Streamable HTTP Transport
The HTTP transport enables network-based communication, allowing remote or distributed clients to connect to the MCP server. This mode requires explicit configuration and includes built-in bearer token authentication.
Characteristics:
- HTTP-based protocol over TCP/IP
- Session-based communication with
mcp-session-idheader - Bearer token authentication (required unless disabled)
- Runs on configurable port (default: 3000)
- Endpoint available at
/mcp
Basic Usage:
# Default HTTP on port 3000
notion-mcp-server --transport http
# Custom port
notion-mcp-server --transport http --port 8080
# With custom auth token
notion-mcp-server --transport http --auth-token "your-secret-token"
Sources: scripts/start-server.ts:1-50
Command Line Options
The server accepts the following command line arguments to configure transport behavior:
| Option | Type | Default | Description |
|---|---|---|---|
--transport <type> | string | stdio | Transport type: stdio or http |
--port <number> | integer | 3000 | HTTP server port (only for HTTP transport) |
--auth-token <token> | string | auto-generated | Bearer token for HTTP authentication |
--disable-auth | flag | false | Disable bearer token authentication |
--help, -h | flag | - | Display help message |
Precedence: Command line arguments take precedence over environment variables.
Sources: scripts/start-server.ts:10-35
Authentication
Environment Variables
The server respects the following environment variables for authentication configuration:
| Variable | Description | Required |
|---|---|---|
NOTION_TOKEN | Notion integration secret token | Yes (for API calls) |
OPENAPI_MCP_HEADERS | JSON string with custom headers | Alternative to NOTION_TOKEN |
AUTH_TOKEN | Bearer token for HTTP transport | For HTTP transport |
Header Format for OPENAPI_MCP_HEADERS:
{
"Authorization": "Bearer ntn_****",
"Notion-Version": "2025-09-03"
}
HTTP Transport Authentication Modes
#### Auto-Generated Token (Development Only)
When running without explicit authentication configuration, the server generates a secure random token:
npx notion-mcp-server --transport http
Output:
Generated auth token: a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789ab
Use this token in the Authorization header: Bearer a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789ab
#### Custom Token via Command Line (Production)
notion-mcp-server --transport http --auth-token "your-secret-token"
#### Custom Token via Environment Variable
AUTH_TOKEN="your-secret-token" notion-mcp-server --transport http
#### Disabling Authentication
notion-mcp-server --transport http --disable-auth
Sources: README.md
HTTP Request Format
When using the Streamable HTTP transport, all requests must include specific headers:
Required Headers
| Header | Value | Description |
|---|---|---|
Authorization | Bearer <token> | Bearer token for authentication |
Content-Type | application/json | Request content type |
mcp-session-id | <session-id> | MCP session identifier |
Example Request
curl -H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
-H "mcp-session-id: your-session-id" \
-d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": 1}' \
http://localhost:3000/mcp
Server Endpoint: http://0.0.0.0:<port>/mcp
Sources: README.md
Architecture
Component Flow
graph TD
subgraph "Entry Point"
A["scripts/start-server.ts<br/>Parse CLI arguments"]
end
subgraph "Initialization"
B["src/init-server.ts<br/>Load OpenAPI spec"]
C["Create MCPProxy instance"]
end
subgraph "Transport Layer"
D["Transport Selection<br/>stdio vs http"]
end
subgraph "MCP Server"
E["MCPProxy.setupHandlers()<br/>Register tools"]
F["OpenAPIToMCPConverter<br/>Convert OpenAPI → MCP tools"]
end
subgraph "HTTP Client"
G["HttpClient<br/>Execute Notion API calls"]
end
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
style D fill:#f9f,stroke:#333Sources: CLAUDE.md
Request Processing Flow (HTTP Transport)
sequenceDiagram
participant Client
participant HTTPServer as HTTP Server<br/>(Express)
participant MCPServer as MCP Server<br/>(MCPProxy)
participant HTTPClient as HttpClient
participant NotionAPI as Notion API
Client->>HTTPServer: HTTP Request with Auth Header
HTTPServer->>HTTPServer: Validate Bearer Token
alt Token Valid
HTTPServer->>MCPServer: Forward MCP Request
MCPServer->>HTTPClient: Execute Tool Call
HTTPClient->>NotionAPI: API Request
NotionAPI-->>HTTPClient: API Response
HTTPClient-->>MCPServer: Structured Response
MCPServer-->>HTTPServer: MCP Response
HTTPServer-->>Client: HTTP Response
else Token Invalid
HTTPServer-->>Client: 401 Unauthorized
endClient Configuration Examples
Cursor & Claude Desktop
stdio Transport:
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
HTTP Transport:
{
"mcpServers": {
"notionApi": {
"command": "notion-mcp-server",
"env": {
"NOTION_TOKEN": "ntn_****",
"AUTH_TOKEN": "your-auth-token"
}
}
}
}
Zed Editor
{
"context_servers": {
"some-context-server": {
"command": {
"path": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ntn_****\", \"Notion-Version\": \"2025-09-03\" }"
}
},
"settings": {}
}
}
}
GitHub Copilot CLI
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Sources: README.md
Docker Deployment
Option 1: Official Docker Hub Image
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"NOTION_TOKEN",
"mcp/notion"
],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Option 2: Local Docker Build
docker compose build
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"NOTION_TOKEN=ntn_****",
"notion-mcp-server"
]
}
}
}
Sources: README.md
Local Development Testing
For testing changes locally in development environments:
- Run
npm linkfrom repository root to create a machine-global symlink - Add configuration to client's
mcp.json - Run
npm unlinkfor cleanup
npm link
{
"mcpServers": {
"notion-local-package": {
"command": "notion-mcp-server",
"env": {
"NOTION_TOKEN": "ntn_..."
}
}
}
}
Sources: README.md
HTTP Client Implementation
The internal HTTP client handles the actual API communication with Notion's backend:
Key Responsibilities:
- Base URL configuration from OpenAPI spec
- Request header management
- Form data handling for file uploads
- Response header conversion to standard
Headersobject - URL parameter vs body parameter routing
// Parameter routing logic
if (param.in === 'path' || param.in === 'query') {
urlParameters[param.name] = params[param.name]
}
// Body parameters for POST/PUT requests
if (!operation.requestBody && !formData) {
urlParameters[key] = bodyParams[key]
}
Sources: src/openapi-mcp-server/client/http-client.ts:1-50
Choosing a Transport
| Use Case | Recommended Transport | Reason |
|---|---|---|
| Local desktop AI client | stdio | Simple, no network required |
| Remote/distributed clients | HTTP | Network accessible |
| Development/testing | stdio or HTTP (auto-token) | Flexibility |
| Production deployment | HTTP with custom token | Security and scalability |
| Docker containers | HTTP | Container networking |
| CI/CD pipelines | stdio | Ephemeral execution |
Summary
The Notion MCP Server provides two transport mechanisms optimized for different deployment scenarios. The stdio transport offers simplicity for local use, while the Streamable HTTP transport enables networked deployments with built-in authentication. Both transports leverage the same underlying MCP tool registration and HTTP client infrastructure, ensuring consistent behavior regardless of the communication method chosen.
Sources: [README.md](https://github.com/makenotion/notion-mcp-server/blob/main/README.md)
MCP Proxy Implementation
Related topics: System Architecture, Available MCP Tools
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture, Available MCP Tools
MCP Proxy Implementation
Overview
The MCP Proxy is the core component of the Notion MCP Server that bridges the gap between the Notion OpenAPI specification and the Model Context Protocol (MCP). It transforms REST API endpoints defined in the OpenAPI spec into executable MCP tools that AI assistants can invoke.
Architecture
graph TD
A[OpenAPI Spec<br/>scripts/notion-openapi.json] --> B[OpenAPIToMCPConverter]
B --> C[MCP Tools Generation]
C --> D[MCPProxy]
D --> E[MCP SDK Server]
F[HTTP Client] --> G[Notion API]
D --> F
H[MCP Client<br/>Claude/Cursor] --> E
E --> H
I[Tool Call Request] --> E
E --> F
F --> G
G --> J[API Response]
J --> E
E --> K[Tool Result]
K --> HCore Components
MCPProxy Class
The MCPProxy class serves as the central orchestration layer. It initializes the MCP server, converts OpenAPI specifications into MCP tools, and handles all tool execution requests.
File Location: src/openapi-mcp-server/mcp/proxy.ts
#### Constructor Parameters
| Parameter | Type | Description | |
|---|---|---|---|
name | string | Display name for the MCP server | |
openApiSpec | OpenAPIV3.Document | Parsed OpenAPI 3.1.0 specification | |
baseUrl | `string \ | undefined` | Optional base URL override |
openApiSpecPath | string | Path to the OpenAPI spec file |
#### Initialization Flow
sequenceDiagram
participant Client
participant MCPProxy
participant Converter
participant HttpClient
participant MCPSDK
Client->>MCPProxy: new MCPProxy(name, spec)
MCPProxy->>HttpClient: Create HttpClient instance
MCPProxy->>Converter: Create OpenAPIToMCPConverter
Converter->>Converter: convertToMCPTools()
Converter-->>MCPProxy: tools, openApiLookup
MCPProxy->>MCPSDK: setupHandlers()
MCPSDK-->>Client: Server readyTool Registration
The setupHandlers() method registers two primary request handlers with the MCP SDK:
#### ListToolsRequestHandler
Returns all available MCP tools to clients. For each operation in the OpenAPI spec:
- Iterates through all tools and their methods
- Constructs tool names using pattern:
{toolName}-{methodName} - Truncates names to 64 characters for MCP compliance
- Determines read/write behavior based on HTTP method
Tool Naming Convention:
const toolNameWithMethod = `${toolName}-${method.name}`;
const truncatedToolName = this.truncateToolName(toolNameWithMethod);
Sources: src/openapi-mcp-server/mcp/proxy.ts:52-66
#### CallToolRequestHandler
Processes incoming tool execution requests:
- Extracts tool name from request
- Looks up operation in
openApiLookupmap - Executes HTTP request via
HttpClient - Returns formatted response to MCP client
Tool Annotations
Each tool includes metadata annotations:
| Annotation | Type | Description |
|---|---|---|
title | string | Human-readable operation title |
readOnlyHint | boolean | true for GET requests |
destructiveHint | boolean | true for non-GET requests |
annotations: {
title: this.operationIdToTitle(method.name),
...(isReadOnly
? { readOnlyHint: true }
: { destructiveHint: true }),
},
Sources: src/openapi-mcp-server/mcp/proxy.ts:60-67
HTTP Client Integration
The HttpClient class handles all outbound HTTP communication with the Notion API.
Configuration
| Option | Type | Description |
|---|---|---|
baseUrl | string | Notion API base URL |
headers | Record<string, string> | Default request headers |
Request Processing
- Parameter Extraction: Separates path, query, and body parameters
- Form Data Handling: Detects
multipart/form-datacontent types - Header Management: Sets appropriate Content-Type headers
- Response Conversion: Transforms axios responses to standard Headers objects
const hasBody = Object.keys(bodyParams).length > 0
const headers = formData
? formData.getHeaders()
: { ...(hasBody ? { 'Content-Type': 'application/json' } : { 'Content-Type': null }) }
Sources: src/openapi-mcp-server/client/http-client.ts:70-76
OpenAPI to MCP Conversion
The OpenAPIToMCPConverter class transforms OpenAPI operations into MCP tool definitions.
Schema Conversion
The converter handles:
- Object types: Properties, required fields, additionalProperties
- Binary formats: Converts to URI-reference format for file handling
- Enumerations: Preserves enum values
- Const values: Supports oneOf discriminators
- Default values: Includes default values in schemas
JSON Schema Mapping
| OpenAPI Type | JSON Schema Type |
|---|---|
object | object |
array | array |
string | string |
integer | integer |
number | number |
boolean | boolean |
binary | uri-reference |
Sources: src/openapi-mcp-server/openapi/parser.ts:45-72
Server Initialization
Entry Point
The server is initialized via src/init-server.ts:
graph LR
A[scripts/start-server.ts] --> B[src/init-server.ts]
B --> C[loadOpenApiSpec]
C --> D[Validate JSON Schema]
D --> E[new MCPProxy]
E --> F[Return proxy instance]Specification Loading
- Reads OpenAPI spec from filesystem
- Parses JSON content
- Overrides
baseUrlif specified - Validates against OpenAPI 3.1.0 schema
export async function initProxy(specPath: string, baseUrl: string | undefined) {
const openApiSpec = await loadOpenApiSpec(specPath, baseUrl)
const proxy = new MCPProxy('Notion API', openApiSpec)
return proxy
}
Sources: src/init-server.ts:43-48
Command Line Interface
The CLI entry point supports multiple transport modes and authentication options.
Supported Options
| Option | Type | Default | Description | |
|---|---|---|---|---|
--transport | stdio \ | http | stdio | Transport type |
--port | number | 3000 | HTTP server port | |
--auth-token | string | auto-generated | Bearer token for HTTP auth | |
--disable-auth | flag | false | Disable authentication | |
--help, -h | flag | - | Show help message |
Environment Variables
| Variable | Description |
|---|---|
NOTION_TOKEN | Notion integration token |
OPENAPI_MCP_HEADERS | JSON string with API headers |
AUTH_TOKEN | Bearer token for HTTP transport |
Sources: scripts/start-server.ts:1-30
Tool Execution Workflow
sequenceDiagram
participant AI as AI Assistant
participant MCPSDK as MCP SDK
participant Proxy as MCPProxy
participant Client as HttpClient
participant API as Notion API
AI->>MCPSDK: list_tools()
MCPSDK-->>AI: Available tools
AI->>MCPSDK: call_tool("retrieve-page-123")
MCPSDK->>Proxy: execute(toolName, params)
alt Tool Lookup
Proxy->>Proxy: openApiLookup[toolName]
Proxy-->>Proxy: Operation found
end
Proxy->>Client: execute(operationId, params)
Client->>API: HTTP Request
API-->>Client: API Response
Client-->>Proxy: Formatted response
Proxy-->>MCPSDK: Tool result
MCPSDK-->>AI: Success/ErrorDependencies
| Package | Version | Purpose |
|---|---|---|
@modelcontextprotocol/sdk | ^1.25.1 | MCP protocol implementation |
axios | ^1.8.4 | HTTP client |
express | ^4.21.2 | HTTP server transport |
openapi-client-axios | ^7.5.5 | OpenAPI client generation |
zod | 3.24.1 | Schema validation |
Sources: package.json:22-40
Key Implementation Patterns
Tool Name Transformation
Tool names are generated from OpenAPI operationId values:
- Original:
retrieve-a-database - Transformation: Convert to title case →
RetrieveADatabase - Truncation: Limit to 64 characters
Request Body Handling
// If no requestBody defined, promote body params to query params
if (!operation.requestBody && !formData) {
for (const key in bodyParams) {
if (bodyParams[key] !== undefined) {
urlParameters[key] = bodyParams[key]
delete bodyParams[key]
}
}
}
Sources: src/openapi-mcp-server/client/http-client.ts:50-56
Header Parsing
Headers can be configured via the OPENAPI_MCP_HEADERS environment variable:
private parseHeadersFromEnv(): Record<string, string> {
const headersStr = process.env.OPENAPI_MCP_HEADERS
if (headersStr) {
try {
return JSON.parse(headersStr)
} catch {
console.error('Failed to parse OPENAPI_MCP_HEADERS')
}
}
return {}
}
Error Handling
The proxy implements robust error handling at multiple levels:
| Error Type | Handling |
|---|---|
| Invalid operation | Error: Operation {id} not found |
| HTTP errors | Propagated from axios |
| JSON parse errors | Console error + process exit |
| Spec validation | ValidationError with details |
Performance Considerations
- Tool Lookup: O(1) lookup via
openApiLookupMap - Lazy Loading: Operations are loaded once at initialization
- Connection Pooling: Axios manages HTTP connection reuse
- Schema Caching: Resolved references cached in memory
Sources: [src/openapi-mcp-server/mcp/proxy.ts:52-66]()
Available MCP Tools
Related topics: Data Sources (v2.0.0 Breaking Changes), System Architecture
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Data Sources (v2.0.0 Breaking Changes), System Architecture
Available MCP Tools
Overview
The Notion MCP Server exposes the Notion API as MCP (Model Context Protocol) tools, enabling AI clients to interact with Notion workspaces programmatically. Each tool corresponds to a specific Notion API endpoint and is auto-generated from the OpenAPI specification at scripts/notion-openapi.json Sources: CLAUDE.md:1-12
The MCP tools serve as the bridge between AI assistants and Notion's API, providing capabilities to:
- Search and retrieve pages and databases
- Create, update, and manage content
- Work with comments and user information
- Query data sources with filters and sorting
Architecture
The tool generation and execution follows a clear architectural flow:
graph TD
A[scripts/notion-openapi.json<br/>OpenAPI 3.1.0 Spec] --> B[OpenAPIToMCPConverter]
B --> C[MCP Tools Registry]
C --> D[AI Client]
D --> E[Tool Invocation]
E --> F[deserializeParams]
F --> G[HttpClient.executeOperation]
G --> H[Notion API]
subgraph "src/openapi-mcp-server/"
B
F
G
endComponents
| Component | File | Purpose |
|---|---|---|
| OpenAPI Spec | scripts/notion-openapi.json | Source of truth for all tools |
| Parser | src/openapi-mcp-server/openapi/parser.ts | Converts OpenAPI to MCP tools |
| Proxy | src/openapi-mcp-server/mcp/proxy.ts | Registers tools with MCP SDK |
| HTTP Client | src/openapi-mcp-server/client/http-client.ts | Executes API calls |
Sources: CLAUDE.md:15-22
Tool Generation Flow
The tool generation process consists of five steps:
OpenAPIToMCPConverter.convertToMCPTools()iterates over all paths and operations in the OpenAPI spec- Each operation becomes an MCP tool with name derived from
operationId - Parameters and requestBody are converted to
inputSchema - Response schema becomes
returnSchema MCPProxy.setupHandlers()registers tools with the MCP SDK
sequenceDiagram
participant Spec as OpenAPI Spec
participant Parser as OpenAPIToMCPConverter
participant Proxy as MCPProxy
participant SDK as MCP SDK
participant Client as AI Client
Spec->>Parser: Load specification
Parser->>Parser: convertToMCPTools()
Parser->>Proxy: tools, openApiLookup
Proxy->>SDK: registerToolHandlers()
Client->>SDK: list_tools
SDK->>Client: Available tools
Client->>SDK: call_tool
SDK->>Proxy: executeOperationSources: CLAUDE.md:24-31
Version 2.0.0 Breaking Changes
Version 2.0.0 migrates to the Notion API 2025-09-03 which introduces data sources as the primary abstraction for databases Sources: README.md:1-50
Removed Tools (3)
| Old Tool | Replacement |
|---|---|
post-database-query | query-data-source |
update-a-database | update-a-data-source |
create-a-database | create-a-data-source |
New Tools (7)
| New Tool | Purpose |
|---|---|
query-data-source | Query a data source (database) with filters and sorts |
retrieve-a-data-source | Get metadata and schema for a data source |
update-a-data-source | Update data source properties |
create-a-data-source | Create a new data source |
list-data-source-templates | List available templates in a data source |
move-page | Move a page to a different parent location |
retrieve-a-database | Get database metadata including its data source IDs |
Parameter Changes
| Change Type | Old Parameter | New Parameter |
|---|---|---|
| Database ID | database_id | data_source_id |
| Search Filter | ["page", "database"] | ["page", "data_source"] |
Sources: README.md:1-50
Tool Naming Conventions
Tool names are derived directly from the OpenAPI operationId:
- Example:
retrieve-a-databasebecomesRetrieveADatabase - Names are truncated to 64 characters maximum
- Converted to title case for display purposes
// operationId: "retrieve-a-database"
// Resulting tool name: "RetrieveADatabase"
private operationIdToTitle(operationId: string): string {
return operationId
.split('-')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join('')
.slice(0, 64);
}
Sources: CLAUDE.md:33-34
Configuration
Environment Variables
| Variable | Description | Required |
|---|---|---|
NOTION_TOKEN | Notion integration token (recommended) | Yes |
OPENAPI_MCP_HEADERS | JSON string with Notion API headers | Alternative |
AUTH_TOKEN | Bearer token for HTTP transport authentication | Optional |
OPENAPI_MCP_HEADERS | Custom headers for Notion API requests | Optional |
Sources: README.md:1-50
Header Configuration Example
{
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ntn_****\", \"Notion-Version\": \"2025-09-03\"}"
}
Parameter Handling
Deserialization Process
The MCP server handles a known issue with double-serialized JSON parameters (GitHub issue #176). When parameters arrive as stringified JSON objects or arrays, they are automatically deserialized:
function deserializeParams(params: Record<string, unknown>): Record<string, unknown> {
for (const [key, value] of Object.entries(params)) {
if (typeof value === 'string') {
const trimmed = value.trim();
if ((trimmed.startsWith('{') && trimmed.endsWith('}')) ||
(trimmed.startsWith('[') && trimmed.endsWith(']'))) {
try {
const parsed = JSON.parse(value);
if (typeof parsed === 'object' && parsed !== null) {
result[key] = Array.isArray(parsed)
? parsed
: deserializeParams(parsed);
}
} catch { /* keep original string */ }
}
}
}
return result;
}
This function recursively processes nested objects and arrays to ensure proper parameter handling Sources: src/openapi-mcp-server/mcp/proxy.ts:1-50
Schema Conversion
The OpenAPIToMCPConverter converts OpenAPI schemas to JSON Schema format for MCP tool definitions:
type: stringwithformat: binary→ converted toformat: uri-reference- Handles
oneOf,anyOf,allOfschema composition - Preserves
enumvalues andconstdiscriminators - Maintains
requiredfield arrays
Sources: src/openapi-mcp-server/openapi/parser.ts:1-50
Example Usage
Search and Create
Comment "Hello MCP" on page "Getting started"
The AI correctly plans two API calls:
v1/search- Find the page "Getting started"v1/comments- Create the comment
Page Creation
Add a page titled "Notion MCP" to page "Development"
Direct ID Reference
Get the content of page 1a6b35e6e67f802fa7e1d27686f017f2
Sources: README.md:1-50
MCP Client Configuration
Cursor & Claude Desktop
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Zed
{
"context_servers": {
"notion-context-server": {
"command": {
"path": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"]
},
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ntn_****\"}"
}
}
}
}
GitHub Copilot CLI
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Sources: README.md:1-50
HTTP Transport Authentication
When using Streamable HTTP transport, bearer token authentication is required:
npx @notionhq/notion-mcp-server --transport http --auth-token "your-secret-token"
Authentication Options
| Method | Priority | Use Case |
|---|---|---|
--auth-token CLI arg | Highest | Production |
AUTH_TOKEN env var | Medium | Production |
| Auto-generated token | Lowest | Development only |
All requests must include the bearer token:
curl -H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
-H "mcp-session-id: your-session-id" \
-d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": 1}' \
http://localhost:3000/mcp
Sources: README.md:1-50
Error Handling
The MCP server provides structured error responses for HTTP errors:
if (error instanceof HttpClientError) {
const data = error.data?.response?.data ?? error.data ?? {};
return {
content: [
{
type: 'text',
text: JSON.stringify({ error: data }),
},
],
isError: true,
};
}
Errors are logged to console with descriptive messages for debugging Sources: src/openapi-mcp-server/mcp/proxy.ts:100-130
Adding New Tools
To add new tools, only modify the OpenAPI specification at scripts/notion-openapi.json. No code changes are required elsewhere—tools are automatically generated from the spec when the server starts Sources: CLAUDE.md:18-22
OpenAPI Specification
The server uses OpenAPI 3.1.0 specification with both traditional and new data source endpoints:
| Endpoint Type | Path Pattern |
|---|---|
| Traditional | /v1/databases/{database_id} |
| Data Source | /v1/data_sources/{data_source_id} |
Sources: CLAUDE.md:44-47
Development
Build & Test Commands
npm run build # TypeScript compilation + CLI bundling
npm test # Run vitest tests
npm run dev # Start dev server with hot reload
Local Testing
- Run
npm linkfrom repository root to create a machine-global symlink - Update your MCP client's configuration:
{
"mcpServers": {
"notion-local-package": {
"command": "notion-mcp-server",
"env": {
"NOTION_TOKEN": "ntn_..."
}
}
}
}
- Cleanup with
npm unlinkwhen done
Sources: README.md:1-50
Sources: [CLAUDE.md:15-22]()
Data Sources (v2.0.0 Breaking Changes)
Related topics: Available MCP Tools
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Available MCP Tools
Data Sources (v2.0.0 Breaking Changes)
Overview
Version 2.0.0 of the Notion MCP Server introduces a fundamental architectural change by migrating to the Notion API 2025-09-03, which adopts Data Sources as the primary abstraction for databases. This represents a significant shift in how the MCP server interacts with Notion's database functionality.
Sources: README.md
What Are Data Sources?
Data Sources serve as a new abstraction layer that wraps traditional Notion databases. They provide enhanced metadata and schema capabilities that align with Notion's evolving platform architecture. The data source model maintains compatibility with existing database endpoints while introducing new functionality.
Sources: CLAUDE.md
The Notion API 2025-09-03 version includes dual endpoint support:
| Endpoint Type | Path Pattern | Purpose |
|---|---|---|
| Traditional Database | /v1/databases/{database_id} | Legacy database operations |
| New Data Source | /v1/data_sources/{data_source_id} | Modern data source operations |
Sources: CLAUDE.md
Breaking Changes Summary
Tools Removed
The following three tools have been removed and replaced by their data source equivalents:
| Removed Tool | Replacement Tool | Purpose |
|---|---|---|
post-database-query | query-data-source | Query data source with filters and sorts |
update-a-database | update-a-data-source | Update data source properties |
create-a-database | create-a-data-source | Create a new data source |
Sources: README.md
New Tools Added
Seven new tools have been introduced in version 2.0.0:
| New Tool | Description |
|---|---|
query-data-source | Query a data source (database) with filters and sorts |
retrieve-a-data-source | Get metadata and schema for a data source |
update-a-data-source | Update data source properties |
create-a-data-source | Create a new data source |
list-data-source-templates | List available templates in a data source |
move-page | Move a page to a different parent location |
retrieve-a-database | Get database metadata including its data source IDs |
Sources: README.md
Parameter Changes
Identifier Renaming
All database operations now use data_source_id instead of database_id:
// Before (v1.x)
parameters: {
database_id: string;
}
// After (v2.0.0)
parameters: {
data_source_id: string;
}
Search Filter Values
The search operation filter values have been updated:
| Previous Value | New Value |
|---|---|
"database" | "data_source" |
// Before (v1.x)
filter: {
value: ["page", "database"];
}
// After (v2.0.0)
filter: {
value: ["page", "data_source"];
}
Sources: README.md
Page Creation Enhancement
Page creation now supports both page_id and database_id parents for data sources:
interface CreatePageParameters {
parent: {
page_id?: string;
database_id?: string; // Now includes database_id support
};
}
Architecture Flow
graph TD
A[MCP Client Request] --> B[MCP Server]
B --> C{Determine Operation Type}
C -->|Database Operation| D[Database Endpoints]
C -->|Data Source Operation| E[Data Source Endpoints]
D --> F[/v1/databases/{database_id}]
E --> G[/v1/data_sources/{data_source_id}]
F --> H[Notion API 2025-09-03]
G --> H
H --> I[Response with Schema]
I --> J[OpenAPI Parser]
J --> K[MCP Tool Response]Migration Guide
Do I Need to Migrate?
No code changes required. MCP tools are discovered automatically when the server starts. When you upgrade to v2.0.0, AI clients will automatically see the new tools.
Sources: README.md
Automatic Discovery
The MCP server auto-generates tools from the OpenAPI specification located at scripts/notion-openapi.json. Tool generation follows this flow:
graph LR
A[scripts/notion-openapi.json] --> B[OpenAPIToMCPConverter]
B --> C[convertToMCPTools]
C --> D[MCP Tools Registry]
D --> E[MCPProxy.setupHandlers]
E --> F[MCP SDK]Sources: CLAUDE.md
Tool Naming Conventions
Tool names derive from the OpenAPI operationId field:
| OpenAPI operationId | MCP Tool Name |
|---|---|
query-data-source | query-data-source |
retrieve-a-data-source | retrieve-a-data-source |
update-a-data-source | update-a-data-source |
Names are truncated to 64 characters and converted to title case for display purposes.
OpenAPI Schema Conversion
The parser converts OpenAPI schemas to JSON Schema format for MCP tool definitions. The convertOpenApiSchemaToJsonSchema method handles complex type conversions:
// Handles the following conversions:
// - binary format → uri-reference format
// - oneOf/anyOf/allOf → proper JSON Schema composition
// - const values for discriminators
// - default values preservation
Sources: src/openapi-mcp-server/openapi/parser.ts
Response Schema Handling
The extractResponseType method processes API responses:
- Looks for success responses (200, 201, 202, 204)
- Extracts JSON schema from
application/jsoncontent type - Preserves response descriptions
- Falls back to generic formats for non-JSON responses
private extractResponseType(responses: OpenAPIV3.ResponsesObject | undefined): IJsonSchema | null
HTTP Client Architecture
The HTTP client handles parameter serialization and request execution:
sequenceDiagram
participant MCP as MCP Client
participant Proxy as MCPProxy
participant Client as HttpClient
participant Notion as Notion API
MCP->>Proxy: Call Tool
Proxy->>Client: Execute with params
Client->>Client: Deserialize JSON strings
Client->>Notion: API Request
Notion-->>Client: Response
Client-->>Proxy: Formatted Result
Proxy-->>MCP: Tool ResponseSources: src/openapi-mcp-server/client/http-client.ts
Parameter Deserialization
The deserializeParams function recursively processes incoming parameters to convert JSON-like strings into actual objects:
function deserializeParams(params: Record<string, unknown>): Record<string, unknown>
This handles:
- JSON object strings → parsed objects
- JSON array strings → parsed arrays
- Nested object deserialization
- Array item deserialization
Sources: src/openapi-mcp-server/mcp/proxy.ts
API Version Configuration
The server uses the Notion API version 2025-09-03 (Data Source Edition):
# Via environment variable
NOTION_TOKEN=ntn_****
# Or via OPENAPI_MCP_HEADERS
OPENAPI_MCP_HEADERS='{"Authorization": "Bearer ntn_****", "Notion-Version": "2025-09-03"}'
Sources: scripts/start-server.ts
Configuration Options
Transport Modes
| Transport | Default | Description |
|---|---|---|
stdio | Yes | Standard I/O transport |
http | No | Streamable HTTP transport |
HTTP Transport Authentication
# Using command line
notion-mcp-server --transport http --port 3000 --auth-token your-token
# Or via environment variable
AUTH_TOKEN=your-token notion-mcp-server --transport http
The --auth-token command line argument takes precedence over the AUTH_TOKEN environment variable.
Build and Deployment
Version Information
| Property | Value |
|---|---|
| Package Name | @notionhq/notion-mcp-server |
| Version | 2.3.0 |
| License | MIT |
Build Commands
npm run build # TypeScript compilation + CLI bundling
npm test # Run vitest tests
npm run dev # Start dev server with hot reload
Docker Deployment
# Build locally
docker compose build
# Run with NOTION_TOKEN
docker run --rm -i -e NOTION_TOKEN=ntn_**** notion-mcp-server
Key Dependencies
| Dependency | Version | Purpose |
|---|---|---|
@modelcontextprotocol/sdk | ^1.25.1 | MCP protocol implementation |
axios | ^1.8.4 | HTTP client |
openapi-client-axios | ^7.5.5 | OpenAPI client |
zod | 3.24.1 | Schema validation |
See Also
Sources: [README.md](https://github.com/makenotion/notion-mcp-server/blob/main/README.md)
Authentication System
Related topics: Transport Layers, npm Installation and Configuration
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Transport Layers, npm Installation and Configuration
Authentication System
The Notion MCP Server implements a dual-layer authentication system that secures both the communication between MCP clients and the server, as well as the requests made to the Notion API.
Overview
The authentication system serves two distinct purposes:
- Transport Authentication: Secures client-to-server communication when using the Streamable HTTP transport
- Notion API Authentication: Authenticates requests to the Notion API using integration tokens
┌─────────────┐ Bearer Token Auth ┌──────────────────┐ Notion Token ┌─────────────┐
│ MCP Client │ ◄──────────────────────────► │ MCP Server │ ◄───────────────────► │ Notion API │
└─────────────┘ (HTTP Transport) └──────────────────┘ └─────────────┘
Transport Authentication (HTTP)
When running the server with --transport http, bearer token authentication is enforced to protect the MCP endpoint from unauthorized access.
Configuration Methods
| Method | Priority | Description |
|---|---|---|
--auth-token CLI flag | Highest | Passed directly via command line |
AUTH_TOKEN environment variable | Middle | Set in shell environment |
| Auto-generated token | Fallback | Generated automatically if neither is provided |
Command Line Options
# Recommended: Custom token via command line
npx @notionhq/notion-mcp-server --transport http --auth-token "your-secret-token"
# Alternative: Token via environment variable
AUTH_TOKEN="your-secret-token" npx @notionhq/notion-mcp-server --transport http
# Development: Auto-generated token
npx @notionhq/notion-mcp-server --transport http
# Disable authentication (NOT recommended for production)
npx @notionhq/notion-mcp-server --transport http --disable-auth
Token Validation Flow
graph TD
A[HTTP Request to /mcp] --> B{Auth Disabled?}
B -->|Yes| E[Process Request]
B -->|No| C{Token Present?}
C -->|No| F[Return 401 Unauthorized]
C -->|Yes| G{Token Valid?}
G -->|No| H[Return 403 Forbidden]
G -->|Yes| E
F --> I[Error: Missing bearer token]
H --> J[Error: Invalid bearer token]Error Responses
The server returns standardized JSON-RPC error responses for authentication failures:
Missing Token (401)
{
"jsonrpc": "2.0",
"error": {
"code": -32001,
"message": "Unauthorized: Missing bearer token"
},
"id": null
}
Invalid Token (403)
{
"jsonrpc": "2.0",
"error": {
"code": -32002,
"message": "Forbidden: Invalid bearer token"
},
"id": null
}
Sources: scripts/start-server.ts
Health Endpoint Exception
The /health endpoint is accessible without authentication, allowing health checks without bearer token validation:
app.get('/health', (req, res) => {
res.status(200).json({
status: 'healthy',
timestamp: new Date().toISOString(),
transport: 'http',
port: options.port
})
})
Sources: scripts/start-server.ts:1-100
Notion API Authentication
The server authenticates with the Notion API using integration tokens configured via environment variables.
Configuration Options
| Environment Variable | Description | Recommended |
|---|---|---|
NOTION_TOKEN | Notion integration secret token (recommended) | ✅ |
OPENAPI_MCP_HEADERS | JSON string with custom headers including Authorization | Alternative |
Using NOTION_TOKEN (Recommended)
NOTION_TOKEN=ntn_**** npx @notionhq/notion-mcp-server
Using OPENAPI_MCP_HEADERS (Advanced)
OPENAPI_MCP_HEADERS='{"Authorization": "Bearer ntn_****", "Notion-Version": "2025-09-03"}' \
npx @notionhq/notion-mcp-server
Header Parsing
The server parses authentication headers from the environment variable:
private parseHeadersFromEnv(): Record<string, string> {
const headers: Record<string, string> = {}
const headerConfig = process.env.OPENAPI_MCP_HEADERS
if (headerConfig) {
try {
const parsed = JSON.parse(headerConfig)
Object.assign(headers, parsed)
} catch {
// Invalid JSON, skip header parsing
}
}
return headers
}
Sources: src/openapi-mcp-server/client/http-client.ts:1-50
Docker Deployment
Option 1: Using NOTION_TOKEN
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": ["run", "--rm", "-i", "-e", "NOTION_TOKEN", "notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Option 2: Using OPENAPI_MCP_HEADERS
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": ["run", "--rm", "-i", "-e", "OPENAPI_MCP_HEADERS", "notionhq/notion-mcp-server"],
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\":\"Bearer ntn_****\",\"Notion-Version\":\"2025-09-03\"}"
}
}
}
}
Sources: README.md
Client Configuration Examples
Cursor / Claude Desktop
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Zed
{
"context_servers": {
"some-context-server": {
"command": {
"path": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ntn_****\", \"Notion-Version\": \"2025-09-03\" }"
}
},
"settings": {}
}
}
}
GitHub Copilot CLI
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
API Version Header
The server uses Notion API version 2025-09-03 (Data Source Edition) for all API requests:
const headers = {
'Authorization': `Bearer ${notionToken}`,
'Notion-Version': '2025-09-03'
}
Sources: scripts/start-server.ts
Making HTTP Requests
All requests to the Streamable HTTP transport must include the bearer token:
curl -H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
-H "mcp-session-id: your-session-id" \
-d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": 1}' \
http://localhost:3000/mcp
Security Considerations
| Concern | Mitigation |
|---|---|
| Token exposure in logs | Use --auth-token flag instead of environment variable when possible |
| Plaintext token transmission | Always use HTTPS in production deployments |
| Token rotation | Support multiple configuration methods for easy rotation |
| Unauthorized access | Bearer token required by default for HTTP transport |
Integration Token Setup
Before using the server, ensure your Notion integration has been granted access to the target pages:
- Visit the target page in Notion
- Click on the three dots menu
- Select "Connect to integration"
Sources: README.md
Sources: [scripts/start-server.ts](https://github.com/makenotion/notion-mcp-server/blob/main/scripts/start-server.ts)
npm Installation and Configuration
Related topics: Docker Deployment, Quick Start Guide
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Docker Deployment, Quick Start Guide
npm Installation and Configuration
The Notion MCP Server is a Model Context Protocol (MCP) server that exposes the Notion API as MCP tools. This page covers all aspects of installing and configuring the server using npm, including setup for various AI client applications, environment configuration, and local development workflows.
Overview
The server is distributed as an npm package (@notionhq/notion-mcp-server) and can be installed via npx for immediate use or added to projects for development. It supports two transport modes: stdio for local MCP clients and http for remote access with authentication.
| Transport Mode | Use Case | Authentication |
|---|---|---|
stdio | Local MCP clients (Cursor, Claude Desktop) | Via NOTION_TOKEN env var |
http | Remote access, development servers | Bearer token (auto-generated or custom) |
Sources: README.md
Prerequisites
Before installing the Notion MCP Server, ensure you have:
- Node.js version compatible with the package requirements
- npm or npx for package management
- A Notion integration token from the Notion Developer Portal
Obtaining Your Notion Integration Token
- Navigate to Notion Developer Portal
- Create a new integration or select an existing one
- Copy the Internal Integration Token (format:
ntn_...) - Share the target Notion pages with your integration by opening the page and selecting "Connect to integration"
Sources: README.md
Installation Methods
Using npx (Recommended for Immediate Use)
The simplest method to run the server without global installation:
npx -y @notionhq/notion-mcp-server
For stdio transport (default):
npx -y @notionhq/notion-mcp-server --transport stdio
For HTTP transport with auto-generated auth token:
npx -y @notionhq/notion-mcp-server --transport http
Sources: README.md
Local Development Installation
For testing changes or contributing to the project:
# Clone the repository
git clone https://github.com/makenotion/notion-mcp-server.git
cd notion-mcp-server
# Install dependencies
npm install
# Build the project
npm run build
The build script compiles TypeScript and bundles the CLI:
npm run build # TypeScript compilation + CLI bundling
npm test # Run vitest tests
npm run dev # Start dev server with hot reload
Sources: CLAUDE.md and package.json
Using npm link for Local Testing
To test local changes in AI clients without publishing:
# From repository root
npm link
# The command creates a machine-global symlink
# to the notion-mcp-server package
Sources: README.md
Environment Configuration
Environment Variables
| Variable | Description | Required | Priority |
|---|---|---|---|
NOTION_TOKEN | Notion integration token (ntn_...) | Yes (for stdio) | Recommended |
OPENAPI_MCP_HEADERS | JSON string with custom headers | Alternative to NOTION_TOKEN | Alternative |
AUTH_TOKEN | Bearer token for HTTP transport auth | No (for HTTP) | Lower than CLI arg |
NODE_ENV | Set to test for running tests | For testing | N/A |
Sources: scripts/start-server.ts and README.md
Using NOTION_TOKEN (Recommended)
NOTION_TOKEN="ntn_your_integration_token" npx -y @notionhq/notion-mcp-server
Using OPENAPI_MCP_HEADERS (Advanced)
For custom headers including Notion-Version specification:
OPENAPI_MCP_HEADERS='{"Authorization": "Bearer ntn_your_token", "Notion-Version": "2025-09-03"}' \
npx -y @notionhq/notion-mcp-server
Sources: README.md
MCP Client Configuration
Cursor & Claude Desktop
Add configuration to your client's MCP settings file:
Cursor: ~/.cursor/mcp.json Claude Desktop (macOS): ~/Library/Application Support/Claude/claude_desktop_config.json
#### Option 1: Using NOTION_TOKEN (Recommended)
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_your_integration_token"
}
}
}
}
#### Option 2: Using OPENAPI_MCP_HEADERS
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ntn_your_token\", \"Notion-Version\": \"2025-09-03\"}"
}
}
}
}
Sources: README.md
Zed Editor
Add to settings.json:
{
"context_servers": {
"some-context-server": {
"command": {
"path": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer ntn_your_token\", \"Notion-Version\": \"2025-09-03\"}"
}
},
"settings": {}
}
}
}
Sources: README.md
GitHub Copilot CLI
Use interactive addition:
/mcp add
Or manually edit ~/.copilot/mcp-config.json:
{
"mcpServers": {
"notionApi": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_your_integration_token"
}
}
}
}
Sources: README.md
Testing Local Changes in Cursor
For testing local development changes:
- Run
npm linkfrom the repository root - Merge this configuration into
~/.cursor/mcp.json:
{
"mcpServers": {
"notion-local-package": {
"command": "notion-mcp-server",
"env": {
"NOTION_TOKEN": "ntn_your_integration_token"
}
}
}
}
- After testing, run
npm unlinkto cleanup
Sources: README.md
HTTP Transport Configuration
Command Line Options
npx @notionhq/notion-mcp-server --transport http [options]
| Option | Description | Default |
|---|---|---|
--transport <type> | Transport type: stdio or http | stdio |
--port <number> | Port for HTTP server | 3000 |
--auth-token <token> | Bearer token for authentication | Auto-generated |
--disable-auth | Disable bearer token authentication | false |
--help, -h | Show help message | N/A |
The --auth-token argument takes precedence over the AUTH_TOKEN environment variable.
Sources: scripts/start-server.ts and README.md
Authentication Options for HTTP Transport
#### Option 1: Auto-generated Token (Development Only)
npx @notionhq/notion-mcp-server --transport http
The server displays the generated token:
Generated auth token: a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789ab
Use this token in the Authorization header: Bearer a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789ab
#### Option 2: Custom Token via CLI (Recommended for Production)
npx @notionhq/notion-mcp-server --transport http --auth-token "your-secret-token"
#### Option 3: Custom Token via Environment Variable
AUTH_TOKEN="your-secret-token" npx @notionhq/notion-mcp-server --transport http
Making HTTP Requests
All requests require the bearer token in the Authorization header:
curl -H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
-H "mcp-session-id: your-session-id" \
-d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": 1}' \
http://localhost:3000/mcp
Sources: README.md
Docker Installation
Option 1: Using Official Docker Hub Image
#### With NOTION_TOKEN
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e", "NOTION_TOKEN",
"mcp/notion"
],
"env": {
"NOTION_TOKEN": "ntn_your_integration_token"
}
}
}
}
#### With OPENAPI_MCP_HEADERS
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e", "OPENAPI_MCP_HEADERS",
"mcp/notion"
],
"env": {
"OPENAPI_MCP_HEADERS": "{\"Authorization\":\"Bearer ntn_your_token\",\"Notion-Version\":\"2025-09-03\"}"
}
}
}
}
Option 2: Building Locally
# Build the Docker image
docker compose build
# Run with local image
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"NOTION_TOKEN=ntn_your_token",
"notion-mcp-server"
]
}
}
}
Sources: README.md
Available Scripts
| Script | Description |
|---|---|
npm run build | Compiles TypeScript and bundles the CLI |
npm run dev | Starts dev server with hot reload using tsx |
npm test | Runs vitest tests |
npm run test:watch | Runs tests in watch mode |
npm run test:coverage | Runs tests with coverage report |
Sources: package.json and CLAUDE.md
Package Metadata
| Property | Value |
|---|---|
| Package Name | @notionhq/notion-mcp-server |
| Version | 2.3.0 |
| License | MIT |
| CLI Entry | bin/cli.mjs |
| Main Entry | index.js |
| Type | ES Module |
Sources: package.json
Troubleshooting
Common Issues
| Issue | Solution |
|---|---|
| Token not recognized | Ensure NOTION_TOKEN or OPENAPI_MCP_HEADERS is set in environment |
| JSON parsing errors | Check that OPENAPI_MCP_HEADERS is properly escaped JSON |
| Client can't connect | Verify integration has access to the target Notion pages |
| Local changes not reflected | Run npm unlink then npm link again |
Verifying Installation
Test the server can start:
npx -y @notionhq/notion-mcp-server --help
Expected output shows available options including --transport, --port, --auth-token, and --help.
Sources: scripts/start-server.ts
Sources: [README.md](https://github.com/makenotion/notion-mcp-server/blob/main/README.md)
Docker Deployment
Related topics: npm Installation and Configuration, Transport Layers
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: npm Installation and Configuration, Transport Layers
Docker Deployment
The notion-mcp-server provides official Docker container support for running the MCP server in a containerized environment. This deployment option is ideal for users who prefer not to install Node.js dependencies locally or want to ensure consistent runtime environments across different systems.
Overview
The Docker deployment for notion-mcp-server offers two primary approaches for containerization:
| Approach | Description | Use Case |
|---|---|---|
| Official Image | Use pre-built image from Docker Hub (mcp/notion) | Quick setup, no build required |
| Local Build | Build image locally using docker compose | Development, customization |
Sources: README.md
Architecture
graph TD
A[Client App<br/>Cursor/Claude/Zed] --> B[MCP Client Config]
B --> C[Docker Container<br/>notion-mcp-server]
C --> D[Notion API<br/>api.notion.com]
E[Environment Variables] --> C
E --> F[NOTION_TOKEN]
E --> G[OPENAPI_MCP_HEADERS]
E --> H[AUTH_TOKEN<br/>HTTP transport only]Environment Configuration
Required Variables
| Variable | Description | Required | Example |
|---|---|---|---|
NOTION_TOKEN | Notion integration secret | Yes (recommended) | ntn_**** |
OPENAPI_MCP_HEADERS | JSON string with custom headers | No (alternative) | {"Authorization": "Bearer ntn_****"} |
Sources: README.md
Authentication Token (HTTP Transport)
When using the HTTP transport mode, an additional bearer token is required:
| Variable | CLI Argument | Priority |
|---|---|---|
AUTH_TOKEN | --auth-token | Lower |
| Environment variable | --auth-token argument | Higher (overrides env var) |
Sources: scripts/start-server.ts
Deployment Options
Option 1: Using Official Docker Hub Image
The official image is available at mcp/notion on Docker Hub.
#### STDIO Transport Configuration
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"NOTION_TOKEN",
"mcp/notion"
],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Sources: README.md
#### HTTP Transport Configuration
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"NOTION_TOKEN",
"mcp/notion",
"--transport",
"http",
"--port",
"3000",
"--auth-token",
"your-secret-token"
],
"env": {
"NOTION_TOKEN": "ntn_****"
}
}
}
}
Option 2: Building Locally with Docker Compose
#### Build Process
# Build the Docker image
docker compose build
#### Configuration for Local Build
Replace mcp/notion with notion-mcp-server in your MCP client configuration:
{
"mcpServers": {
"notionApi": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"NOTION_TOKEN=ntn_****",
"notion-mcp-server"
]
}
}
}
Sources: README.md
HTTP Transport with Docker
When running with Docker, the HTTP transport requires special handling for headers and authentication.
Authentication Modes
graph LR
A[Docker Container] --> B{Transport Mode}
B -->|stdio| C[No Auth Required]
B -->|http| D[Bearer Token Required]
E[Request] --> F[Authorization Header]
F --> D
D --> G{Token Valid?}
G -->|Yes| H[Process Request]
G -->|No| I[401 Unauthorized]Request Format
curl -H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
-H "mcp-session-id: your-session-id" \
-d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": 1}' \
http://localhost:3000/mcp
Sources: README.md
Integration Setup
Notion Workspace Configuration
Before using the Docker container, ensure your integration has access to target pages:
- Visit the target Notion page
- Click on the three dots menu (⋮)
- Select "Connect to integration"
Sources: README.md
Client-Specific Configuration
| Client | Configuration File | Example |
|---|---|---|
| Cursor | .cursor/mcp.json | README.md |
| Claude Desktop | claude_desktop_config.json | ~/Library/Application Support/Claude/ |
| Zed | settings.json | context_servers section |
| GitHub Copilot CLI | ~/.copilot/mcp-config.json | Interactive /mcp add or manual edit |
Environment Variable Priority
graph TD
A[Runtime] --> B{Environment Check}
B --> C[NOTION_TOKEN Set?]
B --> D[OPENAPI_MCP_HEADERS Set?]
C -->|Yes| E[Use NOTION_TOKEN]
C -->|No| F[Use OPENAPI_MCP_HEADERS]
D -->|Yes| G[Use Custom Headers]
D -->|No| H[Error: Missing Token]| Priority | Variable | Notes |
|---|---|---|
| 1 | NOTION_TOKEN | Recommended for most use cases |
| 2 | OPENAPI_MCP_HEADERS | For advanced header customization |
Build Commands Reference
| Command | Description |
|---|---|
npm run build | TypeScript compilation + CLI bundling |
docker compose build | Build Docker image locally |
npm test | Run vitest tests |
Sources: package.json, README.md
Security Considerations
Token Handling
- Never commit tokens to version control
- Use environment variables or secret management tools
- Rotate tokens periodically through Notion developer portal
Network Security
- The HTTP transport binds to
http://0.0.0.0:<port>/mcp - Always use authentication tokens for HTTP transport in production
- Consider network isolation based on your deployment environment
Troubleshooting
| Issue | Solution |
|---|---|
| Container exits immediately | Verify NOTION_TOKEN is valid and set correctly |
| Authentication failures | Check bearer token matches --auth-token argument |
| Port conflicts | Change port using --port argument |
| Permission denied | Ensure Docker daemon is running and user has Docker permissions |
Sources: [README.md](https://github.com/makenotion/notion-mcp-server/blob/main/README.md)
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
The project may affect permissions, credentials, data exposure, or host boundaries.
The project may affect permissions, credentials, data exposure, or host boundaries.
Doramagic Pitfall Log
Doramagic extracted 16 source-linked risk signals. Review them before installing or handing real data to the project.
1. Configuration risk: BUG: Tool `query_data_sources` not available
- Severity: high
- Finding: Configuration risk is backed by a source signal: BUG: Tool
query_data_sourcesnot available. Treat it as a review item until the current version is checked. - User impact: Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/256
2. Configuration risk: Bug Report: Notion MCP — Status Property "in_progress" Group Options Not Recognized via API
- Severity: high
- Finding: Configuration risk is backed by a source signal: Bug Report: Notion MCP — Status Property "in_progress" Group Options Not Recognized via API. Treat it as a review item until the current version is checked.
- User impact: Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/232
3. Security or permission risk: API-create-a-data-source and API-update-a-data-source return invalid_request_url — database creation unreliable + missi…
- Severity: high
- Finding: Security or permission risk is backed by a source signal: API-create-a-data-source and API-update-a-data-source return invalid_request_url — database creation unreliable + missi…. Treat it as a review item until the current version is checked.
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/218
4. Security or permission risk: Internal Server Error on OAuth callback when connecting via Claude.ai (Hosted MCP)
- Severity: high
- Finding: Security or permission risk is backed by a source signal: Internal Server Error on OAuth callback when connecting via Claude.ai (Hosted MCP). Treat it as a review item until the current version is checked.
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/269
5. Security or permission risk: Notion MCP server does not work with Claude Code
- Severity: high
- Finding: Security or permission risk is backed by a source signal: Notion MCP server does not work with Claude Code. Treat it as a review item until the current version is checked.
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/277
6. Security or permission risk: OAuth token expires too frequently — requires re-authentication 3+ times per week
- Severity: high
- Finding: Security or permission risk is backed by a source signal: OAuth token expires too frequently — requires re-authentication 3+ times per week. Treat it as a review item until the current version is checked.
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/225
7. Installation risk: Feature Request: Property-based filtering in notion-search for database queries
- Severity: medium
- Finding: Installation risk is backed by a source signal: Feature Request: Property-based filtering in notion-search for database queries. Treat it as a review item until the current version is checked.
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/278
8. Installation risk: Ontheia listed as compatible client — works great with notion-mcp-server
- Severity: medium
- Finding: Installation risk is backed by a source signal: Ontheia listed as compatible client — works great with notion-mcp-server. Treat it as a review item until the current version is checked.
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/287
9. Configuration risk: Bug: notion-create-view silently drops FILTER on Status property (no error, no warning)
- Severity: medium
- Finding: Configuration risk is backed by a source signal: Bug: notion-create-view silently drops FILTER on Status property (no error, no warning). Treat it as a review item until the current version is checked.
- User impact: Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/283
10. Configuration risk: Enhancement: Expand blockObjectRequest to support all Notion block types
- Severity: medium
- Finding: Configuration risk is backed by a source signal: Enhancement: Expand blockObjectRequest to support all Notion block types. Treat it as a review item until the current version is checked.
- User impact: Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/282
11. Configuration risk: [Bug] FILTER directive in view DSL silently drops filters for Relation and Rollup properties
- Severity: medium
- Finding: Configuration risk is backed by a source signal: [Bug] FILTER directive in view DSL silently drops filters for Relation and Rollup properties. Treat it as a review item until the current version is checked.
- User impact: Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/makenotion/notion-mcp-server/issues/281
12. Capability assumption: README/documentation is current enough for a first validation pass.
- Severity: medium
- Finding: README/documentation is current enough for a first validation pass.
- User impact: The project should not be treated as fully validated until this signal is reviewed.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: capability.assumptions | github_repo:946169991 | https://github.com/makenotion/notion-mcp-server | README/documentation is current enough for a first validation pass.
Source: Doramagic discovery, validation, and Project Pack records
Community Discussion Evidence
These external discussion links are review inputs, not standalone proof that the project is production-ready.
Count of project-level external discussion links exposed on this manual page.
Open the linked issues or discussions before treating the pack as ready for your environment.
Community Discussion Evidence
Doramagic exposes project-level community discussion separately from official documentation. Review these links before using notion-mcp-server with real data or production workflows.
- Ontheia listed as compatible client — works great with notion-mcp-server - github / github_issue
- synced_block_reference: URL inside url= attribute gets auto-converted to - github / github_issue
- API-create-a-data-source and API-update-a-data-source return invalid_req - github / github_issue
- v2.2.1 ships stale bin/cli.mjs — PR #212 double-serialization fix not in - github / github_issue
- Feature Request: Support local file upload for images and files - github / github_issue
- Bug Report: Notion MCP — Status Property "in_progress" Group Options Not - github / github_issue
- Bug: notion-create-view silently drops FILTER on Status property (no err - github / github_issue
- Enhancement: Expand blockObjectRequest to support all Notion block types - github / github_issue
- BUG: Tool
query_data_sourcesnot available - github / github_issue - [[Bug] FILTER directive in view DSL silently drops filters for Relation a](https://github.com/makenotion/notion-mcp-server/issues/281) - github / github_issue
- Schema quality: 8 required parameters missing descriptions - github / github_issue
- OAuth token expires too frequently — requires re-authentication 3+ times - github / github_issue
Source: Project Pack community evidence and pitfall evidence