Your Notion workspace, fully accessible through AI.
A Model Context Protocol (MCP) server that exposes Notion's API for managing pages, databases, blocks, and users across your workspace.
Overview
The Notion MCP Server provides a complete interface to your Notion workspace:
Search, read, and write pages with full block-level content control
Create and query databases (data sources) with filters, sorts, and pagination
Manage workspace users and retrieve bot/workspace identity
Perfect for:
AI assistants that need to read or update Notion pages and databases
Automating content creation, knowledge base updates, and task management
Building tools that integrate Notion with other services
Tools
Pages — Read
Search all pages and databases by title or list all pages
Inputs:
- `query` (string, optional, default: "") — Search query string, keep it empty to list all pages- `filter_type` (string, optional) — Filter by 'page' or 'data_source'.- `page_size` (int, optional, default: 20) — Number of pages to return (max 100)- `start_cursor` (string, optional) — Cursor from a previous response to page through results.
Retrieve a Notion page with its full content including all child blocks and properties
Inputs:
- `page_id` (string, required) — Notion page ID (UUID) to fetch content for.- `include_children` (bool, optional, default: true) — Whether to fetch and include the page's child blocks.- `recursive` (bool, optional, default: false) — Recursively fetch nested children of child blocks, up to max_depth.- `max_depth` (int, optional, default: 3) — Maximum recursion depth when recursive=True.- `page_size` (int, optional, default: 100) — Number of child blocks to fetch per page when recursive=False (max 100).- `start_cursor` (string, optional) — Cursor from a previous response to page through child blocks (non-recursive only).
Pages — Write
Create a new page under a parent page
Inputs:
- `parent_page_id` (string, required) — The ID of the parent page this new page will be created under.- `title` (string, optional, default: "Untitled New page Created") — The title for the new page. Defaults to 'Untitled New page Created' if omitted.- `position` (object, optional) — Insert postion. strict Format:{"type": "page_end"} or {"type": "page_start"}
output data schema:
Create a new page at a workspace level (without parent page)
Inputs:
- `title` (string, optional, default: "Untitled New page Created") — The title for the new page. Defaults to 'Untitled New page Created' if omitted.
Update an existing Notion page's properties and metadata. Providing properties, icon, cover, or other fields replaces the corresponding current values rather than merging with them — the original state is not stored by the API after the call. Call get_page first to see current property values before updating. The response includes both the before and after state so you have a full record of what changed.
Inputs:
- `page_id` (string, required) — The ID of the Notion page to update.- `properties` (object, optional) — A dict of Notion page property updates keyed by property name; replaces the corresponding existing property values rather than merging with them. Omit to leave properties unchanged.- `icon` (object, optional) — A Notion file, emoji, or external object to set as the page icon. Omit to leave the icon unchanged.- `cover` (object, optional) — A Notion file or external object to set as the page cover image. Omit to leave the cover unchanged.- `archived` (bool, optional) — Whether to archive (true) or restore (false) the page. Omit to leave archival state unchanged.
Append a text block to a page
Inputs:
- `block_id` (string, required) — The ID could be page ID or parent block ID- `type` (string, required, one of: paragraph | heading_1 | heading_2 | heading_3 | bulleted_list_item | numbered_list_item | to_do | toggle | quote | callout) — The type of text block to create- `content` (string, required) — The text content for the block- `checked` (bool, optional) — For to_do blocks only - whether the item is checked- `color` (string, optional) — text color or background color. available colors : [ 'default', 'gray', 'brown', 'orange', 'yellow', 'green'
Databases
Retrieve a database object by ID with title, parent, and data sources
Inputs:
- `database_id` (string, required) — The ID of the database to retrieve
Query a data source to get pages with optional filtering and sorting
Inputs:
- `data_source_id` (string, required) — The ID of the data source to query- `filter` (object, optional) — Notion filter object to restrict which pages are returned- `sorts` (list, optional) — List of Notion sort objects controlling result order- `page_size` (int, optional, default: 100) — Maximum number of results per page (silently capped at 100)- `start_cursor` (string, optional) — Cursor from a previous response's next_cursor to page through results
output data schema:
Create a new database as a child of an existing page
Inputs:
- `parent_id` (string, required) — The ID of the parent page to create the database under- `title` (string, optional, default: "Untitled Database") — Title of the new database- `description` (string, optional) — Plain-text description of the database- `properties` (object, optional) — Database schema properties keyed by column name (defaults to a single 'Name' title property)- `is_inline` (bool, optional, default: false) — Whether the database should render inline within its parent page- `icon` (object, optional) — Icon object to set on the database- `cover` (object, optional) — Cover object to set on the database
output schema:
Users
List all users in the workspace (guests not included)
Inputs:
- `page_size` (int, optional, default: 100) — Maximum number of users to return per page (values above 100 are clamped).- `start_cursor` (string, optional) — Cursor from a previous response's next_cursor, used to page through results.
output data schema:
{ results: { id: string | null;
Retrieve a specific user by their ID
Inputs:
- `user_id` (string, required) — ID of the user to retrieve.
page_size — Maximum number of results per page. Accepted by search_notion, fetch_page_content, query_data_source, and list_users; each tool silently caps it at 100.
start_cursor — Cursor value from a previous response's next_cursor field, used to page through results. Omit for the first page.
filter — Restricts which results are returned. Shape differs by tool: search_notion takes filter_type ('page' or 'data_source'), while takes a full Notion filter object.
- `in_trash` (bool, optional) — Whether to move the page to (true) or restore it from (false) the trash. Omit to leave trash state unchanged.
- `is_locked` (bool, optional) — Whether to lock (true) or unlock (false) the page to prevent further edits. Omit to leave the lock state unchanged.
- `template` (object, optional) — A Notion page template object to reapply to the page. Omit to leave the current template unchanged.
- `erase_content` (bool, optional) — Whether to clear the page's existing block content before applying the update. Omit to leave existing content in place.