notion-mcp-server
Provides tools for managing Notion pages, databases, blocks, comments, users, and search, with support for property filtering and token-efficient output.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@notion-mcp-serverGet tasks from my project database where status is 'In Progress'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
notion-mcp-server
English | 日本語
MCP (Model Context Protocol) server for Notion API. Enables AI assistants to interact with Notion pages, databases, and blocks.
API Version: 2025-09-03 (latest)
Why this repository?
Why I Built This
I wanted to use AI agents to process tasks from my Notion database with specific conditions:
"Get tasks where Status = 'Not Started' AND Assignee = 'Alice', sorted by Priority"
Here's what I found with existing options:
MCP Option | Property Filtering | Token Efficiency | Plan Required |
Metadata only (created_at, created_by) / Full (Enterprise+AI) | Good | Notion AI | |
✅ Full support | Large responses | None | |
This repository | ✅ Full support | Optimized | None |
The gap I wanted to fill:
Full database property filtering (AND/OR, select, checkbox, date, etc.)
Optimized response sizes for LLM token efficiency
No plan restrictions
This repository provides property filtering with fields parameter for 90% token reduction.
Related MCP server: Notion MCP Server
Quick Start
1. Get a Notion Token
Go to Notion Integrations
Click "New integration"
Give it a name and select the workspace
Copy the "Internal Integration Token" (starts with
ntn_)Share the pages/databases you want to access with your integration
2. Configure Your AI Client
Claude Desktop
Add to your configuration (~/.config/claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"notion": {
"command": "npx",
"args": ["-y", "@atikk-co-jp/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_xxxxxxxxxxxx"
}
}
}
}Claude Code
Add to your .mcp.json:
{
"mcpServers": {
"notion": {
"command": "npx",
"args": ["-y", "@atikk-co-jp/notion-mcp-server"],
"env": {
"NOTION_TOKEN": "ntn_xxxxxxxxxxxx"
}
}
}
}That's it! Restart your AI client and start using Notion.
Features
Page Operations: Create, retrieve, update, and move Notion pages
Database Operations: Create, retrieve, update, and query databases with filters and sorts
Block Operations: Retrieve, update, delete, and append blocks
Search: Search across pages and databases
Comments: Create and list comments
Users: List users and retrieve user info
Token-Efficient Output: Markdown/simple format reduces token usage by ~96%
Markdown Input: Create and append content using Markdown (80% fewer input tokens)
API Coverage
⭐ = Markdown input supported (reduces input tokens by ~80%)
📤 = Minimal response (id/url only) - reduces output tokens by ~90%
Category | Notion API | MCP Tool | Input | Output (default) |
Pages | ||||
| JSON |
| ||
| Markdown |
| ||
| JSON | simple/json | ||
| JSON |
| ||
| JSON | json | ||
| JSON |
| ||
| JSON |
| ||
Databases | ||||
| JSON |
| ||
| JSON | simple/json | ||
| JSON |
| ||
| JSON |
| ||
Data Sources | ||||
| JSON | simple/json | ||
| JSON | simple/json | ||
| JSON |
| ||
Blocks | ||||
| JSON | markdown/json | ||
| JSON |
| ||
| Markdown |
| ||
| JSON |
| ||
| JSON |
| ||
| JSON |
| ||
| JSON | markdown/simple/json | ||
| JSON |
| ||
| Markdown |
| ||
| Markdown |
| ||
| Markdown |
| ||
Comments | ||||
| JSON |
| ||
| Markdown |
| ||
| JSON | json | ||
Users | ||||
| JSON | json | ||
| JSON | json | ||
| JSON | json | ||
Search | ||||
| JSON | simple/json |
Available Tools
retrieve-page
Retrieve a Notion page by its ID.
Parameters:
page_id(required): The ID of the page to retrieveformat(optional): Output format -"simple"(default) or"json"simple: Returns simplified property values with reduced token usagejson: Returns raw Notion API response
include_content(optional): Include page content as markdown (default: true)
{
"page_id": "page-uuid-here",
"format": "simple",
"include_content": true
}create-page
Create a new page. Supports two parent types:
Child page: Use
parent.page_idto create a page under an existing pageDatabase entry: Use
parent.data_source_idto create a page in a database
Create a child page:
{
"parent": { "page_id": "parent-page-uuid-here" },
"properties": {
"title": {
"title": [{ "text": { "content": "Child Page Title" } }]
}
}
}Create a database entry:
{
"parent": { "data_source_id": "data-source-uuid-here" },
"properties": {
"Name": {
"title": [{ "text": { "content": "New Page Title" } }]
},
"Status": {
"status": { "name": "In Progress" }
}
}
}create-page-simple ⭐
Create a new page using Markdown. ~80% fewer input tokens compared to create-page.
Supports two parent types:
Child page: Use
parent.page_idto create a page under an existing pageDatabase entry: Use
parent.data_source_idto create a page in a database
Parameters:
parent(required): Either{ page_id }or{ data_source_id }title(required): Page title as a simple stringcontent(optional): Page content in Markdownproperties(optional): Additional Notion propertiesicon(optional): Emoji icon (e.g., "🐛")
Supported Markdown:
Headings:
# ## ###(#### and beyond → heading_3)Lists:
-or*(bulleted),1.(numbered)Checkboxes:
- [ ]/- [x]Code blocks:
```with languageQuotes:
>Dividers:
---Images:
Tables:
| col1 | col2 |with header separator|---|---|Inline:
**bold**,*italic*,~~strike~~,`code`,[link](url)
Extended Markdown (bidirectional):
Toggle:
<details><summary>title</summary>content</details>Callout:
> [!NOTE],> [!WARNING],> [!TIP],> [!IMPORTANT],> [!CAUTION]Equation:
$$E = mc^2$$(inline/block)Underline:
<u>text</u>or++text++Color:
{color:red}text{/color},{bg:yellow}text{/bg}Bookmark:
[bookmark](url)or[bookmark:caption](url)Columns:
:::columns/:::column/:::Media:
@[embed](url),@[video](url),@[audio](url),@[file](url),@[pdf](url)Table of contents:
[TOC]
Create a child page:
{
"parent": { "page_id": "parent-page-uuid-here" },
"title": "Meeting Notes",
"content": "## Agenda\n\n1. Review progress\n2. Next steps"
}Create a database entry:
{
"parent": { "data_source_id": "data-source-uuid-here" },
"title": "Bug Report",
"content": "## Steps to Reproduce\n\n1. Login\n2. Open settings\n\n## Expected Behavior\n\nShould display correctly",
"properties": {
"Status": { "status": { "name": "Open" } }
},
"icon": "🐛"
}Token Comparison:
Method | Tokens | Reduction |
create-page (blocks) | ~152 | - |
create-page-simple (markdown) | ~26 | 83% |
update-page
Update a page's properties, icon, cover, archive status, or lock status.
Parameters:
page_id(required): The ID of the page to updateproperties(optional): Properties to updateicon(optional): Icon (set to null to remove)cover(optional): Cover image (set to null to remove)archived(optional): Set to true to archiveis_locked(optional): Lock the page to prevent edits in the UI
{
"page_id": "page-uuid-here",
"properties": {
"Status": {
"status": { "name": "Done" }
}
},
"is_locked": true
}query-data-source
Query a data source with optional filters and sorts.
Parameters:
data_source_id(required): The ID of the data source to queryfilter(optional): Filter conditions as a JSON objectsorts(optional): Sort conditions as an arraystart_cursor(optional): Cursor for paginationpage_size(optional): Number of results to return (1-100)format(optional): Output format -"simple"(default) or"json"simple: Returns simplified property values with reduced token usagejson: Returns raw Notion API response
{
"data_source_id": "data-source-uuid-here",
"filter": {
"property": "Status",
"status": { "equals": "In Progress" }
},
"sorts": [
{ "property": "Created", "direction": "descending" }
],
"format": "simple"
}create-database
Create a new database as a subpage of an existing page.
Parameters:
parent_page_id(required): The ID of the parent pageproperties(required): Database schema with at least one title propertytitle(optional): Database title as rich text arrayicon(optional): Icon for the databasecover(optional): Cover image for the databaseis_inline(optional): If true, creates an inline database
{
"parent_page_id": "parent-page-uuid",
"properties": {
"Name": { "title": {} },
"Status": { "select": { "options": [{ "name": "Todo" }, { "name": "Done" }] } },
"Priority": { "number": {} }
},
"title": [{ "type": "text", "text": { "content": "Task Database" } }]
}update-database
Update an existing database container (title, description, icon, cover).
Note: For schema (properties/columns) updates, use update-data-source instead.
Parameters:
database_id(required): The ID of the database to updatetitle(optional): New title as rich text arraydescription(optional): New description as rich text arrayicon(optional): Icon (set to null to remove)cover(optional): Cover image (set to null to remove)is_inline(optional): If true, creates an inline databasearchived(optional): Set to true to archiveis_locked(optional): Lock the database to prevent edits in the UI
{
"database_id": "database-uuid-here",
"title": [{ "type": "text", "text": { "content": "New Title" } }],
"is_locked": true
}retrieve-data-source
Retrieve a data source schema by its ID.
Parameters:
data_source_id(required): The ID of the data sourceformat(optional): Output format -"simple"(default) or"json"
{
"data_source_id": "data-source-uuid-here",
"format": "simple"
}update-data-source
Update a data source schema (properties/columns).
Parameters:
data_source_id(required): The ID of the data source to updateproperties(optional): Properties to add, update, or delete (set to null)
{
"data_source_id": "data-source-uuid-here",
"properties": {
"NewColumn": { "rich_text": {} },
"OldColumn": null
}
}search
Search across all pages and data sources.
{
"query": "search term",
"filter": { "value": "page", "property": "object" }
}Filter values: "page" or "data_source"
get-block-children
Get the child blocks of a page or block.
Parameters:
block_id(required): The ID of the block or page to get children fromstart_cursor(optional): Cursor for paginationpage_size(optional): Number of results to return (1-100)format(optional): Output format -"markdown"(default),"simple", or"json"markdown: Returns human-readable markdown with significantly reduced token usage (~96% reduction)simple: Returns ID + type + markdown content (lightweight, for deletion target selection)json: Returns raw Notion API response
fetch_nested(optional): Whenformat="markdown", fetch nested children blocks recursively (default: false)
{
"block_id": "page-or-block-uuid-here",
"format": "markdown",
"fetch_nested": true
}Get block IDs for deletion:
{
"block_id": "page-or-block-uuid-here",
"format": "simple"
}Returns:
{
"blocks": [
{ "id": "abc123", "type": "heading_1", "content": "# Title" },
{ "id": "def456", "type": "paragraph", "content": "Some text" }
],
"has_more": false
}append-block-children
Append new blocks to a page or block.
{
"block_id": "page-or-block-uuid-here",
"children": [
{
"type": "paragraph",
"paragraph": {
"rich_text": [{ "text": { "content": "New paragraph" } }]
}
}
]
}append-blocks-simple ⭐
Append blocks using Markdown. ~80% fewer output tokens compared to append-block-children.
Parameters:
block_id(required): The page or block ID to append tocontent(required): Content in Markdownafter(optional): Insert after this block ID
Same Markdown support as create-page-simple.
{
"block_id": "page-or-block-uuid-here",
"content": "# New Section\n\nThis is **important** content with a [link](https://example.com).\n\n- Item 1\n- Item 2\n\n```javascript\nconst x = 1;\n```"
}Token Comparison:
Method | Tokens | Reduction |
append-block-children (blocks) | ~201 | - |
append-blocks-simple (markdown) | ~42 | 79% |
replace-page-content ⭐
Replace all content of a page with new Markdown content. Automatically preserves child_database and child_page blocks.
Parameters:
page_id(required): The page ID to updatecontent(required): New content in Markdowndry_run(optional): Preview which blocks will be deleted without making changes (default: false)
⚠️ Warning: Blocks not representable in Extended Markdown (table_of_contents, synced_block, etc.) will be DELETED. Use dry_run: true to preview before executing.
Use when: You want to completely rewrite page content without finding individual block IDs.
Same Markdown support as create-page-simple.
{
"page_id": "page-uuid-here",
"content": "# New Page Title\n\nThis is the new content.\n\n## Section 1\n\n- Item 1\n- Item 2"
}Preview deletions (dry run):
{
"page_id": "page-uuid-here",
"content": "# New content",
"dry_run": true
}find-and-replace-in-page ⭐
Find text in a page and replace it with new content. Supports regex patterns for advanced matching.
Parameters:
page_id(required): The page ID to search infind(required): Text to find (string or regex pattern)replace(required): Replacement text (supports Markdown:**bold**,*italic*, etc.)use_regex(optional): If true, treatfindas a regex pattern (default: false)
Use when: You want to update specific text without rewriting the entire page.
{
"page_id": "page-uuid-here",
"find": "old text",
"replace": "**new text**"
}With regex:
{
"page_id": "page-uuid-here",
"find": "item\\d+",
"replace": "updated item",
"use_regex": true
}delete-blocks-batch
Delete multiple blocks by their IDs. Blocks are deleted sequentially to respect API rate limits (3 req/s).
Parameters:
block_ids(required): Array of block IDs to delete (max 100)
Use when: You want to delete specific blocks. Use get-block-children with format="simple" to get block IDs first.
{
"block_ids": ["block-uuid-1", "block-uuid-2", "block-uuid-3"]
}Returns:
{
"deleted_count": 3,
"failed_count": 0,
"deleted": ["block-uuid-1", "block-uuid-2", "block-uuid-3"]
}clear-page-content
Delete all content from a page. By default, preserves child_database and child_page blocks.
Parameters:
page_id(required): The page ID to clearpreserve_types(optional): Block types to preserve (default:["child_database", "child_page"]). Set to[]to delete all.
Use when: You want to delete all content from a page without selecting individual blocks.
{
"page_id": "page-uuid-here"
}Delete everything (including child databases/pages):
{
"page_id": "page-uuid-here",
"preserve_types": []
}Returns:
{
"deleted_count": 15,
"failed_count": 0
}create-comment
Add a comment to a page.
{
"page_id": "page-uuid-here",
"rich_text": [{ "type": "text", "text": { "content": "This is a comment" } }]
}create-comment-simple ⭐
Add a comment using Markdown. Simpler than create-comment.
Parameters:
page_id(required): The ID of the pagecontent(required): Comment in Markdowndiscussion_id(optional): Reply to existing thread
{
"page_id": "page-uuid-here",
"content": "This is **important** with a [link](https://example.com)"
}Development
# Install dependencies
pnpm install
# Run in development mode
pnpm dev
# Build for production
pnpm build
# Type check
pnpm typecheck
# Lint
pnpm lint
# Format code
pnpm format
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watchLicense
MIT
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/atikk-co-jp/notion-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server