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

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Key Characteristics

Continue reading this section for the full explanation and source context.

Section High-Level Flow

Continue reading this section for the full explanation and source context.

Section Component Architecture

Continue reading this section for the full explanation and source context.

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

AttributeValue
Package Name@notionhq/notion-mcp-server
Current Version2.3.0
LicenseMIT
API Version2025-09-03 (Data Source Edition)
Node.js Support18+ (with Headers polyfill for older versions)
Transport Modesstdio, Streamable HTTP
Total Tools22

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 --> F

Sources: 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:

  1. Load OpenAPI Spec: The server loads scripts/notion-openapi.json which defines all Notion API endpoints in OpenAPI 3.1.0 format
  2. Validate Spec: The spec is validated against OpenAPI schema requirements
  3. Create MCPProxy: A new MCPProxy instance is created with the validated spec
  4. Register Tools: MCPProxy.setupHandlers() registers all discovered tools with the MCP SDK
  5. 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] --> F
  1. OpenAPIToMCPConverter.convertToMCPTools() iterates through all paths and operations in the OpenAPI spec
  2. Each operation becomes an MCP tool where the name is derived from operationId
  3. Operation parameters and request body are combined into the tool's inputSchema
  4. The response schema becomes the tool's returnSchema
  5. 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
FilePurposeLines
scripts/notion-openapi.jsonSource of truth for all tools-
src/init-server.tsLoads & validates spec, creates MCPProxy-
src/openapi-mcp-server/openapi/parser.tsConverts OpenAPI → MCP tools~529
src/openapi-mcp-server/mcp/proxy.tsMCP tool registration and execution~209
src/openapi-mcp-server/client/http-client.tsExecutes API calls via axios~198

Sources: CLAUDE.md:50-65

Installation and Configuration

Prerequisites

Environment Variables

VariableDescriptionRequired
NOTION_TOKENNotion integration secret (recommended)Yes
OPENAPI_MCP_HEADERSJSON string with custom headersAlternative
AUTH_TOKENBearer token for HTTP transport authenticationFor HTTP mode
NOTION_API_URLOverride Notion API base URLNo

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:

MethodDescription
Auto-generated tokennpx @notionhq/notion-mcp-server --transport http
CLI argument--auth-token "your-secret-token"
Environment variableAUTH_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

CategoryExample Tools
Pagescreate-a-page, retrieve-a-page, update-a-page, archive-a-page, move-page
Databasesretrieve-a-database, query-a-database
Data Sourcescreate-a-data-source, retrieve-a-data-source, update-a-data-source, query-data-source, list-data-source-templates
Searchsearch
Commentscreate-a-comment, retrieve-comments
Userslist-users, retrieve-a-user
BlocksVarious 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 ToolReason
post-database-queryReplaced by query-data-source
update-a-databaseReplaced by update-a-data-source
create-a-databaseReplaced by create-a-data-source

#### New Tools

New ToolDescription
query-data-sourceQuery a data source with filters and sorts
retrieve-a-data-sourceGet metadata and schema for a data source
update-a-data-sourceUpdate data source properties
create-a-data-sourceCreate a new data source
list-data-source-templatesList available templates in a data source
move-pageMove a page to a different parent location
retrieve-a-databaseGet database metadata including data source IDs

#### Parameter Changes

ChangeDescription
database_iddata_source_idAll database operations now use data source ID
Search filter valuesChanged from ["page", "database"] to ["page", "data_source"]
Page creationNow 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| G

This 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

  1. Run npm link from the repository root to create a machine-global symlink
  2. Add the following to your MCP client's configuration:
{
  "mcpServers": {
    "notion-local-package": {
      "command": "notion-mcp-server",
      "env": {
        "NOTION_TOKEN": "ntn_..."
      }
    }
  }
}
  1. Cleanup by running npm unlink from 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

OptionDescriptionDefault
--transport <type>Transport type: 'stdio' or 'http'stdio
--port <number>Port for HTTP server3000
--auth-token <token>Bearer token for HTTP authauto-generated
--disable-authDisable HTTP bearer auth-
--help, -hShow 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 result

Key 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 Headers objects
  • Error Handling: Missing operations throw descriptive errors

Sources: src/openapi-mcp-server/client/http-client.ts:1-80

Dependencies

DependencyVersionPurpose
@modelcontextprotocol/sdk^1.25.1MCP protocol implementation
axios^1.8.4HTTP client for Notion API
express^4.21.2HTTP transport server
form-data^4.0.1Multipart form handling
openapi-client-axios^7.5.5OpenAPI client generation
yargs^17.7.2CLI argument parsing
zod3.24.1Schema 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_TOKEN or OPENAPI_MCP_HEADERS
  • [ ] Test connectivity with a simple search or retrieval

File Paths Reference

PathDescription
scripts/notion-openapi.jsonOpenAPI 3.1.0 spec for all tools
src/init-server.tsServer initialization
src/openapi-mcp-server/openapi/parser.tsOpenAPI → MCP conversion
src/openapi-mcp-server/mcp/proxy.tsTool registration
src/openapi-mcp-server/client/http-client.tsAPI request execution
bin/cli.mjsBundled 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

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Architecture

Continue reading this section for the full explanation and source context.

Section Tool Generation Flow

Continue reading this section for the full explanation and source context.

Section Option 1: Using npm (Recommended)

Continue reading this section for the full explanation and source context.

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

StepComponentDescription
1OpenAPI SpecIterates all paths and operations
2Operation → ToolEach operationId becomes a tool name
3ParametersConverted to inputSchema
4ResponseConverted to returnSchema
5RegistrationMCPProxy.setupHandlers() registers with SDK

Sources: CLAUDE.md:32-38

Prerequisites

Before getting started, ensure you have:

  • Node.js 18+ (for native Headers support)
  • 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

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

  1. Go to https://www.notion.so/profile/integrations
  2. Create a new internal integration or select an existing one
  3. 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:

  1. Open the target page
  2. Click the three dots menu (⋯)
  3. 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

VariableDescriptionPriority
NOTION_TOKENIntegration token (recommended)Primary
OPENAPI_MCP_HEADERSJSON string with custom headersAlternative
AUTH_TOKENBearer token for HTTP transportLower

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

OptionDescriptionDefault
--transport <type>Transport type: stdio or httpstdio
--port <number>Port for HTTP server3000
--auth-token <token>Bearer token for HTTP authenticationAuto-generated
--disable-authDisable authentication for HTTP transportfalse
--help, -hShow 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:

ToolDescriptionVersion Change
query-data-sourceQuery a data source with filters and sortsNew in v2.0
retrieve-a-data-sourceGet metadata and schema for a data sourceNew in v2.0
create-a-data-sourceCreate a new data sourceNew in v2.0
update-a-data-sourceUpdate data source propertiesNew in v2.0
move-pageMove a page to a different parentNew in v2.0
list-data-source-templatesList available templates in a data sourceNew in v2.0
retrieve-a-databaseGet database metadata including data source IDsNew in v2.0
searchSearch pages and data sourcesUpdated filter values
Note: In v2.0.0, database_id parameters changed to data_source_id for 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

  1. Run npm link from repository root to create a machine-global symlink
  2. Add to Cursor's mcp.json:
{
  "mcpServers": {
    "notion-local-package": {
      "command": "notion-mcp-server",
      "env": {
        "NOTION_TOKEN": "ntn_..."
      }
    }
  }
}
  1. Cleanup: Run npm unlink from repository root

Publish

npm login
npm publish --access public

Sources: CLAUDE.md:1-40

Example Usage

Natural Language Examples

InstructionOperations
Comment "Hello MCP" on page "Getting started"searchcreate-a-comment
Add a page titled "Notion MCP" to page "Development"searchcreate-a-page
Get the content of page 1a6b35e6e67f802fa7e1d27686f017f2retrieve-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

IssueSolution
"No base URL found"Ensure OpenAPI spec has a valid server URL
Authentication errorsVerify NOTION_TOKEN is set correctly
Page access deniedConnect the integration to the target page in Notion
Port already in useUse --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

Sources: [CLAUDE.md:1-10]()

System Architecture

Related topics: Transport Layers, MCP Proxy Implementation, Available MCP Tools

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Component Architecture Table

Continue reading this section for the full explanation and source context.

Section OpenAPI to MCP Converter

Continue reading this section for the full explanation and source context.

Section MCP Proxy

Continue reading this section for the full explanation and source context.

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| G

Sources: CLAUDE.md:4-10

Core Components

Component Architecture Table

ComponentFile PathResponsibility
OpenAPI Specificationscripts/notion-openapi.jsonSingle source of truth for all API endpoints and schemas
Server Entry Pointsrc/init-server.tsLoads spec, creates MCPProxy instance
OpenAPI Parsersrc/openapi-mcp-server/openapi/parser.tsConverts OpenAPI → MCP tool definitions
MCP Proxysrc/openapi-mcp-server/mcp/proxy.tsTool registration and request handling
HTTP Clientsrc/openapi-mcp-server/client/http-client.tsExecutes Notion API calls
Auth Modulesrc/openapi-mcp-server/auth/Authentication and header management
Server CLIscripts/start-server.tsTransport 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:

  1. Iterates all paths and operations from the OpenAPI spec
  2. Extracts operation parameters and requestBody schemas
  3. Generates JSON Schema for input validation
  4. Extracts response schemas for return types
  5. 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 ListToolsRequestSchema to expose available tools
  • Tool Execution: Uses CallToolRequestSchema to handle tool invocations
  • Parameter Deserialization: Handles JSON string parsing for complex parameters
  • Annotation: Marks tools with readOnlyHint or destructiveHint based 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:

ResponsibilityImplementation
Base URL ConfigurationConfigured via OpenAPI spec server definition
Header ManagementMerges auth headers with operation-specific headers
Parameter RoutingSeparates path/query params from body params
Form Data SupportDetects and sets appropriate Content-Type headers
Response ConversionTransforms 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:

ModulePurpose
auth/types.tsTypeScript interfaces for auth configuration
auth/template.tsHeader template definitions and validation
auth/index.tsMain 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:

MethodEnvironment VariableFormat
Simple TokenNOTION_TOKENntn_**** integration token
Advanced HeadersOPENAPI_MCP_HEADERSJSON 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:

TransportDefaultCLI FlagPort
stdioYes--transport stdioN/A
Streamable HTTPNo--transport http3000

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 operationIdGenerated Tool Name
retrieve-a-databaseRetrieve-A-Database
create-a-pageCreate-A-Page
searchSearch

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 FeatureJSON Schema OutputNotes
format: binaryformat: uri-referenceFor file path handling
type: objecttype: objectIncludes properties and additionalProperties
type: arraytype: arrayConverts items recursively
oneOf/anyOf/allOfoneOf/anyOf/allOfPreserves discriminator info
enumenumPreserves allowed values
constconstImportant for discriminator keys
defaultdefaultProvides 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 TypePatternDescription
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

VariableRequiredDescription
NOTION_TOKENYes (recommended)Notion integration token
OPENAPI_MCP_HEADERSNoJSON string with custom headers
AUTH_TOKENNoBearer token for HTTP transport
PORTNoHTTP server port (default: 3000)

CLI Arguments

ArgumentTypeDefaultDescription
--transportstringstdioTransport type
--portnumber3000HTTP server port
--auth-tokenstringauto-generatedBearer token
--disable-authflagfalseDisable HTTP auth
--helpflag-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

Section Related Pages

Continue reading this section for the full explanation and source context.

Section stdio Transport (Default)

Continue reading this section for the full explanation and source context.

Section Streamable HTTP Transport

Continue reading this section for the full explanation and source context.

Section Environment Variables

Continue reading this section for the full explanation and source context.

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 --> F

Sources: 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-id header
  • 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:

OptionTypeDefaultDescription
--transport <type>stringstdioTransport type: stdio or http
--port <number>integer3000HTTP server port (only for HTTP transport)
--auth-token <token>stringauto-generatedBearer token for HTTP authentication
--disable-authflagfalseDisable bearer token authentication
--help, -hflag-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:

VariableDescriptionRequired
NOTION_TOKENNotion integration secret tokenYes (for API calls)
OPENAPI_MCP_HEADERSJSON string with custom headersAlternative to NOTION_TOKEN
AUTH_TOKENBearer token for HTTP transportFor 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

HeaderValueDescription
AuthorizationBearer <token>Bearer token for authentication
Content-Typeapplication/jsonRequest 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:#333

Sources: 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
    end

Client 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:

  1. Run npm link from repository root to create a machine-global symlink
  2. Add configuration to client's mcp.json
  3. Run npm unlink for 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 Headers object
  • 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 CaseRecommended TransportReason
Local desktop AI clientstdioSimple, no network required
Remote/distributed clientsHTTPNetwork accessible
Development/testingstdio or HTTP (auto-token)Flexibility
Production deploymentHTTP with custom tokenSecurity and scalability
Docker containersHTTPContainer networking
CI/CD pipelinesstdioEphemeral 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

Section Related Pages

Continue reading this section for the full explanation and source context.

Section MCPProxy Class

Continue reading this section for the full explanation and source context.

Section Tool Registration

Continue reading this section for the full explanation and source context.

Section Tool Annotations

Continue reading this section for the full explanation and source context.

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 --> H

Core 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

ParameterTypeDescription
namestringDisplay name for the MCP server
openApiSpecOpenAPIV3.DocumentParsed OpenAPI 3.1.0 specification
baseUrl`string \undefined`Optional base URL override
openApiSpecPathstringPath 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 ready

Tool 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:

  1. Iterates through all tools and their methods
  2. Constructs tool names using pattern: {toolName}-{methodName}
  3. Truncates names to 64 characters for MCP compliance
  4. 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:

  1. Extracts tool name from request
  2. Looks up operation in openApiLookup map
  3. Executes HTTP request via HttpClient
  4. Returns formatted response to MCP client

Tool Annotations

Each tool includes metadata annotations:

AnnotationTypeDescription
titlestringHuman-readable operation title
readOnlyHintbooleantrue for GET requests
destructiveHintbooleantrue 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

OptionTypeDescription
baseUrlstringNotion API base URL
headersRecord<string, string>Default request headers

Request Processing

  1. Parameter Extraction: Separates path, query, and body parameters
  2. Form Data Handling: Detects multipart/form-data content types
  3. Header Management: Sets appropriate Content-Type headers
  4. 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 TypeJSON Schema Type
objectobject
arrayarray
stringstring
integerinteger
numbernumber
booleanboolean
binaryuri-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

  1. Reads OpenAPI spec from filesystem
  2. Parses JSON content
  3. Overrides baseUrl if specified
  4. 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

OptionTypeDefaultDescription
--transportstdio \httpstdioTransport type
--portnumber3000HTTP server port
--auth-tokenstringauto-generatedBearer token for HTTP auth
--disable-authflagfalseDisable authentication
--help, -hflag-Show help message

Environment Variables

VariableDescription
NOTION_TOKENNotion integration token
OPENAPI_MCP_HEADERSJSON string with API headers
AUTH_TOKENBearer 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/Error

Dependencies

PackageVersionPurpose
@modelcontextprotocol/sdk^1.25.1MCP protocol implementation
axios^1.8.4HTTP client
express^4.21.2HTTP server transport
openapi-client-axios^7.5.5OpenAPI client generation
zod3.24.1Schema validation

Sources: package.json:22-40

Key Implementation Patterns

Tool Name Transformation

Tool names are generated from OpenAPI operationId values:

  1. Original: retrieve-a-database
  2. Transformation: Convert to title case → RetrieveADatabase
  3. 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 TypeHandling
Invalid operationError: Operation {id} not found
HTTP errorsPropagated from axios
JSON parse errorsConsole error + process exit
Spec validationValidationError with details

Performance Considerations

  1. Tool Lookup: O(1) lookup via openApiLookup Map
  2. Lazy Loading: Operations are loaded once at initialization
  3. Connection Pooling: Axios manages HTTP connection reuse
  4. 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

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Components

Continue reading this section for the full explanation and source context.

Section Removed Tools (3)

Continue reading this section for the full explanation and source context.

Section New Tools (7)

Continue reading this section for the full explanation and source context.

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
    end

Components

ComponentFilePurpose
OpenAPI Specscripts/notion-openapi.jsonSource of truth for all tools
Parsersrc/openapi-mcp-server/openapi/parser.tsConverts OpenAPI to MCP tools
Proxysrc/openapi-mcp-server/mcp/proxy.tsRegisters tools with MCP SDK
HTTP Clientsrc/openapi-mcp-server/client/http-client.tsExecutes API calls

Sources: CLAUDE.md:15-22

Tool Generation Flow

The tool generation process consists of five steps:

  1. OpenAPIToMCPConverter.convertToMCPTools() iterates over all paths and operations in the OpenAPI spec
  2. Each operation becomes an MCP tool with name derived from operationId
  3. Parameters and requestBody are converted to inputSchema
  4. Response schema becomes returnSchema
  5. 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: executeOperation

Sources: 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 ToolReplacement
post-database-queryquery-data-source
update-a-databaseupdate-a-data-source
create-a-databasecreate-a-data-source

New Tools (7)

New ToolPurpose
query-data-sourceQuery a data source (database) with filters and sorts
retrieve-a-data-sourceGet metadata and schema for a data source
update-a-data-sourceUpdate data source properties
create-a-data-sourceCreate a new data source
list-data-source-templatesList available templates in a data source
move-pageMove a page to a different parent location
retrieve-a-databaseGet database metadata including its data source IDs

Parameter Changes

Change TypeOld ParameterNew Parameter
Database IDdatabase_iddata_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-database becomes RetrieveADatabase
  • 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

VariableDescriptionRequired
NOTION_TOKENNotion integration token (recommended)Yes
OPENAPI_MCP_HEADERSJSON string with Notion API headersAlternative
AUTH_TOKENBearer token for HTTP transport authenticationOptional
OPENAPI_MCP_HEADERSCustom headers for Notion API requestsOptional

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: string with format: binary → converted to format: uri-reference
  • Handles oneOf, anyOf, allOf schema composition
  • Preserves enum values and const discriminators
  • Maintains required field 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:

  1. v1/search - Find the page "Getting started"
  2. 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

MethodPriorityUse Case
--auth-token CLI argHighestProduction
AUTH_TOKEN env varMediumProduction
Auto-generated tokenLowestDevelopment 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 TypePath 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

  1. Run npm link from repository root to create a machine-global symlink
  2. Update your MCP client's configuration:
{
  "mcpServers": {
    "notion-local-package": {
      "command": "notion-mcp-server",
      "env": {
        "NOTION_TOKEN": "ntn_..."
      }
    }
  }
}
  1. Cleanup with npm unlink when done

Sources: README.md:1-50

Sources: [CLAUDE.md:15-22]()

Data Sources (v2.0.0 Breaking Changes)

Related topics: Available MCP Tools

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Tools Removed

Continue reading this section for the full explanation and source context.

Section New Tools Added

Continue reading this section for the full explanation and source context.

Section Identifier Renaming

Continue reading this section for the full explanation and source context.

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 TypePath PatternPurpose
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 ToolReplacement ToolPurpose
post-database-queryquery-data-sourceQuery data source with filters and sorts
update-a-databaseupdate-a-data-sourceUpdate data source properties
create-a-databasecreate-a-data-sourceCreate a new data source

Sources: README.md

New Tools Added

Seven new tools have been introduced in version 2.0.0:

New ToolDescription
query-data-sourceQuery a data source (database) with filters and sorts
retrieve-a-data-sourceGet metadata and schema for a data source
update-a-data-sourceUpdate data source properties
create-a-data-sourceCreate a new data source
list-data-source-templatesList available templates in a data source
move-pageMove a page to a different parent location
retrieve-a-databaseGet 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 ValueNew 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 operationIdMCP Tool Name
query-data-sourcequery-data-source
retrieve-a-data-sourceretrieve-a-data-source
update-a-data-sourceupdate-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:

  1. Looks for success responses (200, 201, 202, 204)
  2. Extracts JSON schema from application/json content type
  3. Preserves response descriptions
  4. 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 Response

Sources: 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

TransportDefaultDescription
stdioYesStandard I/O transport
httpNoStreamable 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

PropertyValue
Package Name@notionhq/notion-mcp-server
Version2.3.0
LicenseMIT

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

DependencyVersionPurpose
@modelcontextprotocol/sdk^1.25.1MCP protocol implementation
axios^1.8.4HTTP client
openapi-client-axios^7.5.5OpenAPI client
zod3.24.1Schema 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

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Configuration Methods

Continue reading this section for the full explanation and source context.

Section Command Line Options

Continue reading this section for the full explanation and source context.

Section Token Validation Flow

Continue reading this section for the full explanation and source context.

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:

  1. Transport Authentication: Secures client-to-server communication when using the Streamable HTTP transport
  2. 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

MethodPriorityDescription
--auth-token CLI flagHighestPassed directly via command line
AUTH_TOKEN environment variableMiddleSet in shell environment
Auto-generated tokenFallbackGenerated 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 VariableDescriptionRecommended
NOTION_TOKENNotion integration secret token (recommended)
OPENAPI_MCP_HEADERSJSON string with custom headers including AuthorizationAlternative
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

ConcernMitigation
Token exposure in logsUse --auth-token flag instead of environment variable when possible
Plaintext token transmissionAlways use HTTPS in production deployments
Token rotationSupport multiple configuration methods for easy rotation
Unauthorized accessBearer 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:

  1. Visit the target page in Notion
  2. Click on the three dots menu
  3. 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

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Obtaining Your Notion Integration Token

Continue reading this section for the full explanation and source context.

Section Using npx (Recommended for Immediate Use)

Continue reading this section for the full explanation and source context.

Section Local Development Installation

Continue reading this section for the full explanation and source context.

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 ModeUse CaseAuthentication
stdioLocal MCP clients (Cursor, Claude Desktop)Via NOTION_TOKEN env var
httpRemote access, development serversBearer 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

  1. Navigate to Notion Developer Portal
  2. Create a new integration or select an existing one
  3. Copy the Internal Integration Token (format: ntn_...)
  4. Share the target Notion pages with your integration by opening the page and selecting "Connect to integration"

Sources: README.md

Installation Methods

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

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

VariableDescriptionRequiredPriority
NOTION_TOKENNotion integration token (ntn_...)Yes (for stdio)Recommended
OPENAPI_MCP_HEADERSJSON string with custom headersAlternative to NOTION_TOKENAlternative
AUTH_TOKENBearer token for HTTP transport authNo (for HTTP)Lower than CLI arg
NODE_ENVSet to test for running testsFor testingN/A

Sources: scripts/start-server.ts and README.md

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:

  1. Run npm link from the repository root
  2. Merge this configuration into ~/.cursor/mcp.json:
{
  "mcpServers": {
    "notion-local-package": {
      "command": "notion-mcp-server",
      "env": {
        "NOTION_TOKEN": "ntn_your_integration_token"
      }
    }
  }
}
  1. After testing, run npm unlink to cleanup

Sources: README.md

HTTP Transport Configuration

Command Line Options

npx @notionhq/notion-mcp-server --transport http [options]
OptionDescriptionDefault
--transport <type>Transport type: stdio or httpstdio
--port <number>Port for HTTP server3000
--auth-token <token>Bearer token for authenticationAuto-generated
--disable-authDisable bearer token authenticationfalse
--help, -hShow help messageN/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

ScriptDescription
npm run buildCompiles TypeScript and bundles the CLI
npm run devStarts dev server with hot reload using tsx
npm testRuns vitest tests
npm run test:watchRuns tests in watch mode
npm run test:coverageRuns tests with coverage report

Sources: package.json and CLAUDE.md

Package Metadata

PropertyValue
Package Name@notionhq/notion-mcp-server
Version2.3.0
LicenseMIT
CLI Entrybin/cli.mjs
Main Entryindex.js
TypeES Module

Sources: package.json

Troubleshooting

Common Issues

IssueSolution
Token not recognizedEnsure NOTION_TOKEN or OPENAPI_MCP_HEADERS is set in environment
JSON parsing errorsCheck that OPENAPI_MCP_HEADERS is properly escaped JSON
Client can't connectVerify integration has access to the target Notion pages
Local changes not reflectedRun 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

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Required Variables

Continue reading this section for the full explanation and source context.

Section Authentication Token (HTTP Transport)

Continue reading this section for the full explanation and source context.

Section Option 1: Using Official Docker Hub Image

Continue reading this section for the full explanation and source context.

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:

ApproachDescriptionUse Case
Official ImageUse pre-built image from Docker Hub (mcp/notion)Quick setup, no build required
Local BuildBuild image locally using docker composeDevelopment, 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

VariableDescriptionRequiredExample
NOTION_TOKENNotion integration secretYes (recommended)ntn_****
OPENAPI_MCP_HEADERSJSON string with custom headersNo (alternative){"Authorization": "Bearer ntn_****"}

Sources: README.md

Authentication Token (HTTP Transport)

When using the HTTP transport mode, an additional bearer token is required:

VariableCLI ArgumentPriority
AUTH_TOKEN--auth-tokenLower
Environment variable--auth-token argumentHigher (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:

  1. Visit the target Notion page
  2. Click on the three dots menu (⋮)
  3. Select "Connect to integration"

Sources: README.md

Client-Specific Configuration

ClientConfiguration FileExample
Cursor.cursor/mcp.jsonREADME.md
Claude Desktopclaude_desktop_config.json~/Library/Application Support/Claude/
Zedsettings.jsoncontext_servers section
GitHub Copilot CLI~/.copilot/mcp-config.jsonInteractive /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]
PriorityVariableNotes
1NOTION_TOKENRecommended for most use cases
2OPENAPI_MCP_HEADERSFor advanced header customization

Build Commands Reference

CommandDescription
npm run buildTypeScript compilation + CLI bundling
docker compose buildBuild Docker image locally
npm testRun 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

IssueSolution
Container exits immediatelyVerify NOTION_TOKEN is valid and set correctly
Authentication failuresCheck bearer token matches --auth-token argument
Port conflictsChange port using --port argument
Permission deniedEnsure 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.

high BUG: Tool `query_data_sources` not available

Users may get misleading failures or incomplete behavior unless configuration is checked carefully.

high Bug Report: Notion MCP — Status Property "in_progress" Group Options Not Recognized via API

Users may get misleading failures or incomplete behavior unless configuration is checked carefully.

high API-create-a-data-source and API-update-a-data-source return invalid_request_url — database creation unreliable + missi…

The project may affect permissions, credentials, data exposure, or host boundaries.

high Internal Server Error on OAuth callback when connecting via Claude.ai (Hosted MCP)

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_sources not 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.

Sources 12

Count of project-level external discussion links exposed on this manual page.

Use Review before install

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.

Source: Project Pack community evidence and pitfall evidence