notion-mcp
Provides tools for interacting with Notion's API, enabling management of pages, databases, comments, users, and files, including markdown read/write, database queries, and file upload/download with PDF OCR.
Click on "Deploy 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-mcpSearch my Notion for pages about 'Q3 planning' and summarize the first one."
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
An MCP server for the Notion API: pages, databases (2025-09+ data-source model handled transparently), native markdown read/write, comments, users, and a full file pipeline — upload/replace/import/download with positional inserts, page icons/covers, multi-part upload for large files, and in-place PDF reading with optional OCR. Built on the Python MCP SDK (FastMCP); runs as a local stdio server or a containerized Streamable HTTP service with bearer auth. 44 tools.
Unofficial project, not affiliated with or endorsed by Notion.
Table of Contents
Related MCP server: Markdown-To-Notion
Quick Start
# Prerequisites: Python 3.12+, uv
uv sync
# Set your Notion integration token
export NOTION_TOKEN=ntn_...
# Run the server
uv run notion-mcp
# Server starts on http://0.0.0.0:8322/mcpCreate a Notion internal integration and share the pages/databases you want to access with it.
Tool Reference
Search & Discovery
notion_search_pages
Search for pages the integration can access.
Parameter | Type | Required | Default | Description |
| string | yes | Text to search for | |
| int | no | 10 | Max results (1-100) |
| bool | no |
| Search trashed pages instead of active ones (2026-07 API addition; restore hits with |
Returns page titles, IDs, and URLs. Use the page ID with any tool that accepts page_id.
Notion API: POST /search with
filter.value = "page"
notion_search_databases
Search for databases the integration can access. Returns schema summaries.
Parameter | Type | Required | Default | Description |
| string | yes | Text to search for | |
| int | no | 10 | Max results |
Returns database_id, data_source_id, property names and types. Use the database_id with database tools.
Notion API: POST /search with
filter.value = "data_source"(changed from"database"in API 2025-09-03)
notion_list_files_on_page
List all file/image/pdf/video/audio blocks on a page.
Parameter | Type | Required | Description |
| string | yes | The page to scan |
Returns block IDs, filenames, block types, and source types. Use the block_id with notion_download_file.
Notion API: GET /blocks/{id}/children, filtered to file-type blocks
notion_list_local_files
List files in either the server's local file store (/data/files inside the container) or the cross-MCP shared mount (/shared).
Parameter | Type | Required | Default | Description |
| string | no |
| Substring filter on filename |
| string | no |
|
|
notion_purge_shared_files
Delete files from the cross-MCP shared mount (SHARED_DIR, /shared in the container) whose modification time is older than max_age_hours. Pair with a host-side cron/timer TTL sweep if you want automatic cleanup; this tool is mainly for agents that want to clean up proactively at the end of a workflow.
Parameter | Type | Required | Default | Description |
| float | no |
| Minimum file age before deletion. Must be ≥ 0. |
| bool | no |
| List victims without deleting |
Regular files only — subdirectories are left alone on principle.
Reading Pages
There are two ways to read page content, optimized for different use cases.
notion_read_page
Read page content by fetching blocks and rendering them as markdown. Best for structured reading with optional block-level targeting.
Parameter | Type | Required | Default | Description |
| string | yes | The page to read | |
| int | no | 3 | Recursion depth for nested blocks (1-5) |
| bool | no | false | Suffix each line with |
When include_block_ids is true, each rendered line includes the block's UUID in an HTML comment. Use these IDs with notion_update_block or notion_delete_block for surgical edits.
Notion API: GET /blocks/{id}/children (recursive). Blocks are converted to markdown by
blocks.py.
notion_read_page_markdown
Read page content using Notion's native markdown API. Faster (single API call) and returns Notion-flavored markdown including special tags for embedded databases, files, and page links.
Parameter | Type | Required | Description |
| string | yes | The page to read |
The output includes Notion-specific tags like <database url="...">, <file src="...">, and <page url="..."> that aren't standard markdown but are useful for understanding page structure.
Notion API: GET /pages/{id}/markdown (API 2025-09-03+)
When to use which:
notion_read_page— when you need block IDs for editing, or want clean standard markdownnotion_read_page_markdown— when you need speed, or want to see Notion-native structure (databases, synced blocks, etc.)
Creating & Writing Pages
notion_create_page
Create a new page with optional markdown body content.
Parameter | Type | Required | Default | Description |
| string | yes | Page title | |
| string | no |
| Markdown body content |
| string | no |
| Create as child of this page |
| string | no |
| Create as row in this database |
| string | no |
| JSON object of Notion property values |
| string | no |
| Emoji for page icon (e.g. |
Provide either parent_page_id (standalone page) or database_id (database row). The title property name is auto-detected from the database schema.
For database rows, pass additional properties via properties_json using Notion property value format:
{
"Status": {"select": {"name": "In Progress"}},
"Priority": {"number": 5},
"Due": {"date": {"start": "2026-03-15"}}
}The content parameter accepts markdown which is parsed into Notion blocks (see Markdown Format).
Notion API: POST /pages with
childrenblocks
notion_append_content
Append markdown content to the end of an existing page.
Parameter | Type | Required | Description |
| string | yes | The page to append to |
| string | yes | Markdown text to append |
Content is parsed into blocks and appended. Automatically batches in groups of 100 if the content produces more than 100 blocks (Notion API limit).
Notion API: PATCH /blocks/{id}/children
Editing Page Content
notion_update_page
Update a page's title, icon, or database properties. Does not modify page body content.
Parameter | Type | Required | Default | Description |
| string | yes | The page to update | |
| string | no |
| New title |
| string | no |
| JSON of properties to update |
| string | no |
| Emoji, or |
For database row pages, properties follow the Notion property value format. Omitted properties are left unchanged.
Notion API: PATCH /pages/{id}
notion_update_page_content
Edit page body content using search-and-replace on the page's markdown. Use notion_read_page_markdown first to see the exact content, then provide the text to find and replace.
Parameter | Type | Required | Description |
| string | yes | The page to edit |
| string | yes | Exact text to find |
| string | yes | Replacement text (empty string to delete) |
Notion API: PATCH /pages/{id}/markdown with
type: "replace_content_range"(API 2025-09-03+)
notion_replace_page_content
Replace a page's entire body content with new markdown. Destructive — all existing content is overwritten.
Parameter | Type | Required | Description |
| string | yes | The page to overwrite |
| string | yes | New page content |
Notion API: PATCH /pages/{id}/markdown with
type: "replace_content"(API 2025-09-03+)
Page Lifecycle
notion_archive_page
Archive (soft-delete) a page. It moves to the Notion trash and can be restored within 30 days.
Parameter | Type | Required | Description |
| string | yes | The page to archive |
Notion API: PATCH /pages/{id} with
{"archived": true}
notion_restore_page
Restore an archived page from the Notion trash.
Parameter | Type | Required | Description |
| string | yes | The archived page to restore |
Notion API: PATCH /pages/{id} with
{"archived": false}
notion_move_page
Move a page to a new parent page or into a database.
Parameter | Type | Required | Default | Description |
| string | yes | The page to move | |
| string | no |
| Move under this page |
| string | no |
| Move into this database |
Provide exactly one of the parent parameters. When moving into a database, the server automatically resolves the data_source_id.
Notion API: POST /pages/{id}/move (API 2025-09-03+)
Block Operations
Use notion_read_page with include_block_ids=true to get block IDs for these tools.
notion_update_block
Edit an existing block's text content in place.
Parameter | Type | Required | Default | Description |
| string | yes | The block to edit | |
| string | yes | New text (supports inline markdown) | |
| string | no | auto-detect | Block type hint |
If block_type is omitted, the server fetches the block to detect its type. Supported types: paragraph, heading_1, heading_2, heading_3, bulleted_list_item, numbered_list_item, to_do, quote, callout, toggle, code.
Notion API: PATCH /blocks/{id}
notion_delete_block
Permanently delete a block and all its children.
Parameter | Type | Required | Description |
| string | yes | The block to delete |
Notion API: DELETE /blocks/{id}
Database Schema
notion_describe_database
Get a database's full property schema (column names and types).
Parameter | Type | Required | Description |
| string | yes | The database to describe |
Returns the database_id, data_source_id, and all properties with their types. Use this to discover exact property names (case-sensitive) before querying or creating rows.
Notion API: GET /databases/{id} + GET /data_sources/{id}
notion_create_database
Create a new inline database under a page.
Parameter | Type | Required | Description |
| string | yes | Page to create the database under |
| string | yes | Database title |
| string | yes | JSON property schema |
The schema_json maps property names to Notion property schema objects. A title property is required:
{
"Name": {"title": {}},
"Status": {"select": {"options": [
{"name": "To Do", "color": "red"},
{"name": "In Progress", "color": "yellow"},
{"name": "Done", "color": "green"}
]}},
"Due Date": {"date": {}},
"Priority": {"number": {"format": "number"}},
"Tags": {"multi_select": {"options": [
{"name": "bug", "color": "red"},
{"name": "feature", "color": "blue"}
]}},
"Assignee": {"people": {}},
"Done": {"checkbox": {}},
"Notes": {"rich_text": {}},
"Link": {"url": {}}
}Notion API: POST /databases
notion_update_database
Modify a database's title, description, or property schema.
Parameter | Type | Required | Default | Description |
| string | yes | The database to update | |
| string | no |
| New title |
| string | no |
| New description |
| string | no |
| JSON of property changes |
Property changes use Notion's property schema format:
// Add a column
{"New Column": {"rich_text": {}}}
// Remove a column
{"Old Column": null}
// Rename a column
{"Old Column": {"name": "New Name"}}
// Add select options
{"Status": {"select": {"options": [{"name": "Blocked", "color": "red"}]}}}Multiple changes can be combined in one call.
Notion API: PATCH /data_sources/{id} (routed through data source in API 2025-09-03)
Database Queries
notion_query_database
Query database rows with optional filter and sort.
Parameter | Type | Required | Default | Description |
| string | yes | The database to query | |
| string | no |
| Notion filter object as JSON |
| string | no |
| Notion sort array as JSON |
| int | no | 50 | Page size (1-100 — Notion's hard cap) |
| string | no |
| Opaque cursor from a previous call. Pass it back to fetch the next page. |
| string | no |
| Comma-separated property names to include in the output (e.g. |
Filter examples:
// Simple property filter
{"property": "Status", "select": {"equals": "Done"}}
// Number comparison
{"property": "Priority", "number": {"greater_than": 3}}
// Date filter
{"property": "Due", "date": {"before": "2026-04-01"}}
// Checkbox
{"property": "Done", "checkbox": {"equals": true}}
// Text contains
{"property": "Name", "title": {"contains": "meeting"}}
// Compound filter (AND)
{"and": [
{"property": "Status", "select": {"equals": "Active"}},
{"property": "Priority", "number": {"greater_than": 3}}
]}
// Compound filter (OR)
{"or": [
{"property": "Status", "select": {"equals": "To Do"}},
{"property": "Status", "select": {"equals": "In Progress"}}
]}Sort examples:
// Single sort
[{"property": "Due", "direction": "ascending"}]
// Multiple sorts
[
{"property": "Priority", "direction": "descending"},
{"property": "Name", "direction": "ascending"}
]
// Sort by timestamp
[{"timestamp": "last_edited_time", "direction": "descending"}]Results are returned one page at a time. Each response ends with a
has_more: <bool> next_cursor: <token-or-(end)> line; when
has_more is true, pass the next_cursor value back as start_cursor
on the next call to walk the next page. This gives the LLM bounded-
context pagination — walk a 10 000-row database 100 rows at a time
without ever materialising the whole thing in the tool output.
When properties is set, only the listed columns are included in the
per-row output (the title column is always shown). This is the fix
for "the query returns the full schema for every row and blows the
context budget" — set properties="Gmail Message ID,Invoice" and
the response shrinks to just those columns per row.
Notion API: POST /data_sources/{id}/query (API 2025-09-03+; the server resolves
database_idtodata_source_idautomatically)
notion_get_property
Retrieve a single property value with full pagination. Useful for large relation, rollup, or rich_text properties that get truncated in normal page responses.
Parameter | Type | Required | Default | Description |
| string | yes | The page (row) to read from | |
| string | no |
| Human-readable property name |
| string | no |
| Notion property ID (takes precedence) |
Notion API: GET /pages/{id}/properties/{property_id}
Database Rows & Files
notion_upload_file
Upload a file and attach it to a page as a new block.
Parameter | Type | Required | Default | Description |
| string | yes | File source (see below) | |
| string | yes | Page — or any block that supports children (toggle, column, callout, ...) — to attach the file to | |
| string | no |
| Override the source filename |
| string | no |
| Caption shown below the file in Notion |
| string | no |
| Where the new block lands: |
The source parameter accepts four schemes:
local:<path>— file from the server's local store (/data/files)shared:<filename>— file from the cross-MCP shared mount (/shared). Populated bygoogle-accounts-mcp download_attachment(destination='shared'). Preferred path for gmail → notion attachment handoffs; no base64, no size limit.drive:<name-or-id>— file from the shared Google Drive folderbase64:<data>— raw base64-encoded content (requiresfilename). Subject to MCP parameter size limits; prefershared:ordrive:for anything over ~20 KB.
The block type (image, pdf, video, audio, file) is auto-detected from the MIME type. Files over 20 MB are uploaded via Notion's multi-part protocol automatically (10 MiB parts + complete). The response includes the new block's ID and the sha256 of the uploaded bytes.
Notion API: POST /file_uploads (single-part or multi-part) + PATCH /blocks/{id}/children (with
position)
notion_replace_file
Replace the file inside an existing file/image/pdf/video/audio block, in place — the block keeps its position on the page. Use this to update a document without re-arranging anything.
Parameter | Type | Required | Default | Description |
| string | yes | The file block to update (from | |
| string | yes | Same schemes as | |
| string | no |
| Override the source filename |
| string | no |
| Non-empty replaces the caption; empty leaves it untouched |
The new file must map to the same block type as the existing block (you cannot replace an image block's content with a PDF — delete and re-upload instead).
Notion API: PATCH /blocks/{id} with a
file_uploadreference
notion_import_file_from_url
Import a file into Notion directly from a public HTTPS URL — the bytes go Notion-side, never through this server or MCP parameters. The import is asynchronous; the tool polls until done or wait_seconds elapses.
Parameter | Type | Required | Default | Description |
| string | yes | Public HTTPS URL | |
| string | yes | Page (or child-bearing block) to attach to | |
| string | yes | Must carry an extension Notion accepts; determines block type | |
| string | no |
| Caption |
| string | no |
| As in |
| int | no |
| Max time to poll for the async import |
Size limits are plan-dependent (5 MiB free / 5 GiB paid workspaces).
Notion API: POST /file_uploads with
mode=external_url+ GET /file_uploads/{id} polling
notion_set_page_visual
Set or remove a page's icon or cover image.
Parameter | Type | Required | Default | Description |
| string | yes | Target page | |
| string | yes |
| |
| string | no |
| An image via the usual schemes |
| string | no |
| Single emoji character (icon only) |
| string | no |
| Override for |
| bool | no |
| Clear the icon/cover entirely |
Provide exactly one of source, emoji, or remove=True. Covers/icons from source must be images.
Notion API: PATCH /pages/{id} with
icon/cover
notion_upload_file_to_database
Create a new database row with a file attached.
Parameter | Type | Required | Default | Description |
| string | yes | Target database | |
| string | yes | File source (same schemes as above) | |
| string | yes | Exact name of the files column (case-sensitive) | |
| string | yes | Title for the new row | |
| string | no | auto-detect | Override the title column name |
| string | no |
| Override the source filename |
Use notion_describe_database first to find the exact files_property name.
Notion API: POST /file_uploads + POST /pages
notion_add_file_to_row
Add a file to an existing database row's files column.
Parameter | Type | Required | Default | Description |
| string | yes | The row (page) ID | |
| string | yes | File source | |
| string | yes | Exact name of the files column | |
| string | no |
|
|
| string | no |
| Override the source filename |
Notion API: POST /file_uploads + PATCH /pages/{id}
notion_batch_add_file_to_row
Attach files to many existing rows in one call.
Parameter | Type | Required | Default | Description |
| string | yes | JSON array of item objects (see below) | |
| string | no |
| Default |
| string | no |
| Default |
Each item in items_json takes the same fields as the single-shot
tool: page_id, source, optional filename, optional
files_property, optional mode. Defaults fill in any field left
off at the item level.
[
{"page_id": "p1", "source": "shared:m1_invoice.pdf"},
{"page_id": "p2", "source": "shared:m2_invoice.pdf", "filename": "Renamed.pdf"},
{"page_id": "p3", "source": "drive:<file_id>",
"files_property": "Contracts", "mode": "replace"}
]Items are processed with bounded concurrency — Notion's file upload API
is not pipelined and rejects rapid parallel stage-2 calls. Per-item
failures are reported in the output summary ([i] FAIL page=... : ...)
but do not abort the batch, so you can retry individual failing
items without re-running the whole set.
Typical pattern: stage N attachments via
google-accounts-mcp/download_attachment(destination='shared', prefix=f"{msg}_"),
call this tool once, then call notion_purge_file or
notion_purge_shared_files to free the shared slots.
Notion API: same as
notion_add_file_to_row, called N times under the hood.
notion_purge_file
Delete a single file from the cross-MCP shared mount by bare filename.
Parameter | Type | Required | Description |
| string | yes | Bare filename (no path components) |
Use after a successful upload to free the shared slot instead of
waiting for the daily TTL sweep (or calling notion_purge_shared_files
with max_age_hours=0, which would wipe any unrelated in-flight
handoffs). Rejects any filename containing path separators.
File Downloads
notion_download_file
Download a file from a Notion file/image/pdf/video/audio block.
Parameter | Type | Required | Default | Description |
| string | yes | File block ID (from | |
| string | no |
|
|
| string | no |
| Override the inferred filename (bare filename only for |
Destinations:
local— saves to the server's local file storeshared— saves to the cross-MCP mount (/shared), immediately attachable by google-accounts-mcp asattachments=['shared:<name>']ondraft_email/send_email. Collisions auto-rename atomically; 24h TTL.drive— uploads to the shared Google Drive folderbase64— returns the file content as base64 in the response
Every destination reports the sha256 of the downloaded bytes for
end-to-end integrity verification.
Notion API: GET /blocks/{id} to get the signed S3 URL, then direct download
PDF Reading & OCR
Read PDFs in place — no download hop needed. Both tools accept any file
source: notion:<block_id> (a file/pdf block on a page), shared:<name>,
local:<path>, or drive:<name-or-id>. Semantics are identical to
google-accounts-mcp's PDF tools (the pdf_read module is duplicated verbatim across
the two repos — edit both copies together).
notion_extract_file_text
Extract text from a PDF, with OCR for scanned/image-only pages.
Parameter | Type | Required | Default | Description |
| string | yes |
| |
| string | no | all |
|
| string | no |
|
|
| string | no |
|
|
Returns JSON {text, page_count, pages_returned, mode, truncated, filename, source} plus ocr_used/ocr_pages/ocr_engine when OCR ran (and
ocr_error if auto-mode OCR was needed but the local stack failed —
native text still returns). Response ceiling 200 KB, truncated on a page
boundary with a marker naming the pages to fetch next.
notion_render_file_page
Render one PDF page as a viewable MCP image content block — the calling model sees the page directly (scans, charts, stamps — often no OCR needed).
Parameter | Type | Required | Default | Description |
| string | yes | Same schemes as | |
| int | no |
| 1-indexed page number |
| int | no |
| Target pixel width, 200..4000 |
| string | no |
|
|
| int | no |
| JPEG quality 1..100 |
| bool | no |
|
|
OCR is delegated to an xberg
server — no OCR wheels or OS libs needed here. See google-accounts-mcp's README
§ PDF OCR for the full tier/env table (shared pdf_read module).
Comments
notion_get_comments
List all comments on a page.
Parameter | Type | Required | Description |
| string | yes | The page to read comments from |
Returns comment text, author name, timestamp, and discussion_id for threading.
Notion API: GET /comments with
block_idparameter
notion_add_comment
Add a comment to a page, or reply to an existing discussion thread.
Parameter | Type | Required | Default | Description |
| string | yes | The page to comment on | |
| string | yes | Comment text (supports inline markdown) | |
| string | no |
| Reply to this thread (from |
text is sent as native API markdown (2026-04 addition): inline
formatting, inline equations, and @mentions all work.
Notion API: POST /comments
notion_update_comment
Edit a comment this integration created (the API returns 404 for comments created by anyone else).
Parameter | Type | Required | Description |
| string | yes | From |
| string | yes | Replacement text (native API markdown) |
Notion API: PATCH /comments/{id}
notion_delete_comment
Delete a comment this integration created (404 for anyone else's).
Parameter | Type | Required | Description |
| string | yes | From |
Notion API: DELETE /comments/{id}
Views
The Views API (2026-03) exposes the saved views you see as tabs on a database — each carries its own filter, sorts, and layout.
notion_list_views
List a database's views: name, type, id, and whether each carries a saved filter/sorts. (The API's list endpoint returns identity-only objects, so each view is hydrated with an extra retrieve.)
Parameter | Type | Required | Description |
| string | yes | The database whose views to list |
notion_query_view
Run a view's saved filter and sorts — no filter JSON needed. Use
this instead of notion_query_database when a view already encodes the
question ("Open bugs", "This week").
Parameter | Type | Required | Default | Description |
| string | yes | From | |
| int | no |
| Max rows (≤ 100) |
Implementation note: the API's view queries are cached objects with a ~15-minute TTL; the client creates one, reads a page, and best-effort deletes it.
notion_create_view / notion_update_view / notion_delete_view
Parameter | Type | Required | Default | Description |
| string | create | Parent database | |
| string | update/delete | Target view | |
| string | create |
| Display name |
| string | no |
| table / board / list / calendar / timeline / gallery / chart |
| string | no |
| Notion filter object (same shape as |
| string | no |
| JSON array of sort objects |
Gotcha (verified live): view creation requires both database_id
and data_source_id — the client resolves the data source through the
same cache the query path uses. Deleting a view never touches rows.
Users
notion_list_users
List all workspace users (people and bots).
Returns names, IDs, emails, and types. User IDs are needed for people properties and @mentions in comments.
Notion API: GET /users (paginated)
notion_get_user
Get details for a specific user.
Parameter | Type | Required | Description |
| string | yes | Notion user UUID |
Returns name, email, avatar URL, type (person/bot), and owner info for bots.
Notion API: GET /users/{id}
Markdown Format
Writing (markdown to blocks)
When you pass content to notion_create_page or notion_append_content, the markdown is parsed into Notion blocks. Supported syntax:
Markdown | Notion Block |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Inline formatting within any block:
Markdown | Rendering |
| Bold |
| Italic |
| Bold + Italic |
| Inline code |
| Strikethrough |
| Link |
Reading (blocks to markdown)
notion_read_page renders all common Notion block types:
Paragraphs, headings (1-3), bullet/numbered lists, to-do items
Quotes, callouts (with emoji icons), toggles
Code blocks (with language), dividers, equations
Images (
), files, bookmarks, embedsTables (rendered as markdown tables)
Child pages and databases (shown as
[Page: Title]/[Database: Title])Nested blocks (indented, recursive up to
max_depth)
Working with Databases
API 2025-09-03 Data Source Model
In the 2025-09-03 API, database properties and queries operate through data sources rather than directly on databases. This server handles the mapping transparently:
You pass a
database_id(from search results or a Notion URL)The server calls
GET /databases/{id}to find thedata_source_idSchema/query/update operations go through
/data_sources/{data_source_id}The mapping is cached per session for performance
You never need to know or pass data source IDs directly.
Typical Database Workflow
1. notion_search_databases("project") → find the database ID
2. notion_describe_database(db_id) → see property names and types
3. notion_query_database(db_id, filter) → read rows
4. notion_create_page(database_id=db_id) → add a row
5. notion_update_page(row_id, props) → update a row's propertiesProperty Types Reference
The Notion property value format for common types:
// Title (every database has exactly one)
{"Title Column": {"title": [{"text": {"content": "My Title"}}]}}
// Select
{"Status": {"select": {"name": "Done"}}}
// Multi-select
{"Tags": {"multi_select": [{"name": "bug"}, {"name": "urgent"}]}}
// Number
{"Priority": {"number": 5}}
// Date (single)
{"Due": {"date": {"start": "2026-03-15"}}}
// Date (range)
{"Sprint": {"date": {"start": "2026-03-01", "end": "2026-03-15"}}}
// Checkbox
{"Done": {"checkbox": true}}
// URL
{"Link": {"url": "https://example.com"}}
// Email
{"Contact": {"email": "user@example.com"}}
// Rich text
{"Notes": {"rich_text": [{"text": {"content": "Some notes"}}]}}
// People (requires user IDs from notion_list_users)
{"Assignee": {"people": [{"id": "user-uuid-here"}]}}
// Relation (requires page IDs)
{"Related": {"relation": [{"id": "page-uuid-here"}]}}Working with Files
File Source Schemes
All upload tools accept a source parameter with one of five schemes:
Scheme | Format | Example | Notes |
|
|
| A file/image/pdf/video/audio block already in the workspace (block IDs from |
|
|
| Relative to |
|
|
| Relative to |
|
|
| From the shared Google Drive folder |
|
|
| Requires |
File Upload Protocol
Notion uses a 3-stage upload protocol:
Create —
POST /file_uploadsreturns anupload_idSend —
POST /file_uploads/{id}/sendwith multipart file dataReference — attach the
upload_idin a block or page property (must be used within 1 hour)
This is handled automatically by all upload tools.
Cross-MCP File Handoff (shared: scheme)
Shared-store invariants: the mount is read/write from both MCP
servers. Filename clashes during google-accounts-mcp download_attachment are
resolved by auto-renaming (invoice.pdf → invoice-2.pdf), and the
return value always reports the actual saved name to reference. Files
are swept 24 hours after last modification by the
host-side TTL sweep (if you run one) — stage to Notion
within that window. For immediate cleanup after a workflow, call the
notion_purge_shared_files tool (see the "Files" tool table).
notion-mcp and google-accounts-mcp share a host volume
(~/.local/share/containers/data/mcp-shared/) mounted into both
containers at /shared. Files dropped there by
google-accounts-mcp download_attachment(destination='shared') are immediately
readable via the shared: source scheme:
# From google-accounts-mcp:
download_attachment(message_id="...", filename="invoice.pdf",
destination="shared")
# From notion-mcp:
notion_add_file_to_row(page_id="...", source="shared:invoice.pdf",
files_property="Attachments")The pipeline is bidirectional — the reverse direction stages a Notion file for google-accounts-mcp to attach:
# From notion-mcp:
notion_download_file(block_id="...", destination="shared")
# From google-accounts-mcp:
draft_email(to=["..."], subject="...", body="...",
attachments=["shared:contract.pdf"])The file bytes never traverse MCP tool parameters, so there is no size
limit and the 2026-04 "Energy Locals 1.57 MB invoice" pipeline failure
no longer applies. Use this path by default for file transfers between
the two servers in either direction. All transfer tools report sha256
so the agent can verify integrity at each hop ( notion_list_local_files
and gmail's list_shared_files include it per file too).
Google Drive Integration
The Drive integration is an optional companion feature: it reuses OAuth refresh tokens from google-accounts-mcp (mounted read-only at /google-data/tokens.db) using the same Google client ID. Without that companion server, skip the Drive env vars — every other file source keeps working, and drive: sources return a clear setup error. Use drive: when you want the file to persist in Drive; use shared: when you just need a one-shot handoff between the two MCP servers.
Common Workflows
Read a page and make a targeted edit
1. notion_read_page_markdown(page_id) → see current content
2. notion_update_page_content(page_id,
old_text="Draft version",
new_text="**Final** version") → search-replace editCreate a meeting notes page
1. notion_create_page(
title="Sprint Planning 2026-03-15",
parent_page_id="meetings-page-id",
icon="📋",
content="# Agenda\n\n- [ ] Review backlog\n- [ ] Assign tasks\n\n# Notes\n\n")Query a database and update a row
1. notion_query_database(db_id,
filter_json='{"property": "Status", "select": {"equals": "In Progress"}}')
2. notion_update_page(row_id,
properties_json='{"Status": {"select": {"name": "Done"}}}')Move a page into a database
1. notion_move_page(page_id, new_parent_database_id=db_id)Download a file from Notion to Drive
1. notion_list_files_on_page(page_id) → get block_id
2. notion_download_file(block_id, destination="drive")Email a file stored in Notion
1. notion_list_files_on_page(page_id) → get block_id
2. notion_download_file(block_id, destination="shared")
3. google-accounts-mcp/draft_email(..., attachments=["shared:<filename>"])Edit a specific block on a page
1. notion_read_page(page_id, include_block_ids=true) → find block UUID
2. notion_update_block(block_id, "New **content**") → edit in placeConfiguration
All config is via environment variables. For container deployment, put secrets in .secrets.env:
Variable | Required | Default | Description |
| Yes | Internal integration token (starts with | |
| Yes | Bearer token for authenticating MCP clients | |
| No |
| Notion API version header |
| No |
| Server listen port |
| No |
| Local file store path |
| For Drive | OAuth client ID (same as google-accounts-mcp) | |
| For Drive | OAuth client secret | |
| For Drive |
| Path to google-accounts-mcp's SQLite token DB (read-only; the legacy |
| For Drive | Google account email for Drive access | |
| For Drive |
| Shared Drive folder name |
Architecture
src/notion_mcp/
server.py # FastMCP tool definitions, HTTP server, bearer auth middleware
notion_client.py # Notion REST client — all API calls, pagination, caching
blocks.py # Bidirectional Notion blocks <-> markdown conversion
drive_client.py # Google Drive client (reuses google-accounts-mcp OAuth tokens)
config.py # Environment variable configurationKey design decisions:
notion_client.pyhandles all HTTP, pagination, and the database → data_source mapping. Tools inserver.pynever call the Notion API directly.blocks.pyis a pure-function module with zero side effects — easy to test and reuse.Data source IDs are cached in memory per
NotionClientinstance to avoid redundant lookups.Block appends are auto-batched at 100 (Notion API limit).
The bearer auth middleware is pure ASGI, compatible with streamed responses.
Threadpool tool offload (
server.py): the MCP SDK runs synchronous@mcp.tool()handlers inline on the event loop, so one blockinghttpxcall would freeze every other request (the cause of the "server unresponsive after a burst" stalls).mcp.toolis wrapped so each sync tool runs its body in a worker thread (anyio.to_thread.run_sync); the loop stays free. The wrapper preserves the tool signature (client schemas unchanged — no restart) and returns the original sync function as the module name (tool-to-tool calls and tests still work). Each call logstool=… outcome=… duration_ms=…for Loki.Rate-limit backoff (
notion_client._request): retries429/502/503/504up to 4 attempts honouringRetry-After(capped 30s/attempt). The backoff sleep runs in the offload thread, never blocking the loop.send_file_uploadtimeout is capped at 180s — below the MCP client's 240s ceiling — so the server fails before the client does.Container healthcheck:
python -m notion_mcp.healthcheckdoes a full HTTP round-trip to/mcp; a wedged loop fails the probe andHealthOnFailure=kill+Restart=alwaysrestart the container.
Development
Requires Python 3.12+ and uv.
# Install all dependencies including test extras
uv sync --extra test
# Run the server locally
NOTION_TOKEN=ntn_... uv run notion-mcp
# Run unit tests (fast, no API calls needed)
uv run --extra test pytest tests/ --ignore=tests/test_integration.py -v
# Run all tests including live API
NOTION_TEST_TOKEN=ntn_... uv run --extra test pytest -vTesting
Unit Tests (203 tests, ~2s)
No API access required. Seven test files (the PDF-tool tests mock the xberg HTTP calls — no network):
test_blocks.py (77 tests) — markdown conversion:
rich_text_to_md/md_to_rich_text: all inline formatting variantsblocks_to_markdown: every block type, nesting,include_block_ids, tablesmarkdown_to_blocks: headings, lists, quotes, code, dividers, mixed contentformat_property_value: all 20+ Notion property typesformat_page_properties: multi-property formatting
test_notion_client.py (50 tests) — client logic with mocked HTTP:
Pagination for
list_children,query_data_source,list_comments,list_usersresolve_data_source_idcaching and error handlingcreate_pagechild batching (>100 blocks)Request body construction for markdown, move, comment endpoints
pick_block_typeMIME mappingfind_title_property/get_page_titleedge cases
test_server_tools.py (38 tests) — tool-layer logic with a mocked client
(file source resolution, positional inserts, replace flows, purge tools).
test_sources.py (13 tests) — _read_source scheme parsing for
local:/shared:/base64: (the drive: scheme lives in test_drive_client.py).
test_purge.py (6 tests) — notion_purge_shared_files filters.
test_pdf_tools.py (16 tests) — notion_extract_file_text /
notion_render_file_page wiring, the notion: source scheme, image vs
base64 return modes, OCR plumbing (xberg calls mocked; full OCR-tier
semantics are covered in google-accounts-mcp's test_pdf_read.py, since
pdf_read.py is duplicated verbatim across the two repos).
test_drive_client.py (3 tests) — Drive client; guards the read-only
tokens-DB regression (sqlite must open with immutable=1).
uv run --extra test pytest tests/ --ignore=tests/test_integration.py -vIntegration Tests (17 tests, ~60s)
Hit the live Notion API against a sandbox page you provide. Require:
NOTION_TEST_TOKEN— an integration token with access to the sandboxNOTION_TEST_PAGE_ID— a scratch page the tests may write toNOTION_TEST_DB_ID— an inline database on that page
Tests create pages, exercise all endpoints, and clean up after themselves:
Connectivity (search, list users, retrieve page)
Page CRUD (create, read, archive, restore)
Blocks (append, read, update, delete)
Markdown API (read, replace, search-replace, insert)
Data sources (resolve, get schema, query, search)
Move page (create parent A/B, move child, verify)
Comments (create, list)
NOTION_TEST_TOKEN=ntn_... uv run --extra test pytest tests/test_integration.py -vRun integration tests after:
Upgrading
NOTION_API_VERSIONinconfig.pyChanging endpoint paths or request body formats
Modifying pagination or error handling
Local stdio Mode
--stdio starts FastMCP's stdio transport: no uvicorn, no bearer token
(the client owns the spawned process; there is no network surface). This
is what most interactive MCP clients should use:
// e.g. Claude Desktop claude_desktop_config.json / Claude Code .mcp.json
{
"mcpServers": {
"notion": {
"command": "uv",
"args": ["run", "--project", "/path/to/notion-mcp",
"notion-mcp", "--stdio"],
"env": {
"NOTION_TOKEN": "ntn_...",
"FILES_DIR": "/home/you/.local/share/notion-mcp/files"
}
}
}
}Prefer an env file over inline values where your client supports it
(uv run --env-file ...).
Container Deployment (HTTP)
podman build -t notion-mcp . # or: docker build -t notion-mcp .
podman run -d --name notion-mcp -p 8322:8322 -v notion-data:/data \
-e NOTION_TOKEN=ntn_... \
-e MCP_BEARER_TOKEN=some-long-random-token \
notion-mcpHTTP mode refuses to start without MCP_BEARER_TOKEN; clients
register with:
{
"mcpServers": {
"notion": {
"url": "https://your-host:8322/mcp",
"headers": {"Authorization": "Bearer <MCP_BEARER_TOKEN>"}
}
}
}notion_mcp.healthcheck does a full HTTP round-trip to /mcp (the 401
counts as alive); wire it to your container healthcheck. Terminate TLS at
a reverse proxy — the server itself speaks plain HTTP. For the optional
Drive/shared-mount features, add the /google-data (read-only) and
/shared mounts shared with a google-accounts-mcp container.
Notion API Version Notes
This server uses Notion API 2026-03-11. Version history:
2025-09-03 (from 2022-06-28)
Feature | Old (2022-06-28) | New (2025-09-03) |
Database properties | On | Moved to |
Database query |
|
|
Database search |
|
|
Markdown read | Not available |
|
Markdown write | Not available |
|
Move pages | Not available |
|
2026-03-11 (from 2025-09-03)
Feature | Old (2025-09-03) | New (2026-03-11) |
Trash status field |
|
|
Block append positioning |
|
|
Transcription block type |
|
|
The position object also supports {"type": "start"} and {"type": "end"} for inserting at the beginning or end of a parent block.
The server handles the data source migration transparently — you always pass database_id and the server resolves the data_source_id internally (with caching).
If upgrading from an older version, run the integration test suite to verify nothing breaks:
NOTION_TEST_TOKEN=ntn_... uv run --extra test pytest tests/test_integration.py -vLicense
Available Tools
44 toolsnotion_add_commentA
Add a comment to a Notion page or reply to a discussion thread.
page_id: the page to comment on. text: comment text. Sent as native API markdown — inline formatting, inline equations, and @mentions all work. discussion_id: if provided, the comment is a reply to this existing discussion thread. Get discussion IDs from notion_get_comments.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| page_id | Yes | ||
| discussion_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses that text is sent as native API markdown, supporting inline formatting, equations, and @mentions, and explains the behavior of discussion_id (turns the comment into a reply). It doesn't mention permissions or errors, but given the output schema exists, return values are covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured, with the purpose front-loaded in the first sentence. The parameter list is clear and each line earns its place, including the practical pointer to notion_get_comments. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description is complete: purpose, all parameter semantics, and a helpful cross-reference to a sibling tool. The presence of an output schema covers return values. No critical information is missing for an agent to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description fully compensates by explaining each parameter explicitly: page_id (the page to comment on), text (with markdown details), and discussion_id (reply semantics). This adds significant meaning beyond the schema's bare names and types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: 'Add a comment to a Notion page or reply to a discussion thread.' It specifies the verb (add) and resource (page or discussion thread), and distinguishes it from sibling tools like notion_update_comment and notion_delete_comment by focusing on creation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: to add a new comment or reply to an existing discussion thread. It also points to a sibling tool (notion_get_comments) for obtaining discussion IDs, which is useful. It doesn't explicitly exclude alternatives, but the context is clear enough for a simple create operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_add_file_to_rowA
Upload a file and attach it to an EXISTING database row's files & media column.
page_id: the row (page) ID — paste from the row's "Copy link"
or obtain via notion_search_pages.
source: same schemes as notion_upload_file: local:<path>,
shared:<filename>, drive:<name-or-id>, or
base64:<bytes>.
files_property: exact name of the files & media column.
mode: append (default) keeps existing files and adds the
new one. replace overwrites the column with just the
new file.
filename: override the source filename.
Cross-MCP file transfer
To attach a Gmail attachment to an existing Notion row:
google-accounts-mcp download_attachment(msg_id, name, destination='shared')
notion_add_file_to_row(page_id, source='shared:', files_property='')
Files never traverse MCP parameters — no size limits. Alternative via Drive: download_attachment → drive_upload(local_filename=...) → notion_add_file_to_row(source='drive:', ...).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | append | |
| source | Yes | ||
| page_id | Yes | ||
| filename | No | ||
| files_property | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses key behavioral traits: the append/replace mode semantics (what happens to existing files), the fact that files never traverse MCP parameters (implying side-channel transfer and no size limits), and the exact source schemes. This goes far beyond typical descriptions and informs the agent of important operational details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main purpose, followed by a cleanly formatted parameter list and a practical workflow example. Every sentence contributes valuable information—no fluff. The structure makes it easy to scan and understand.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (5 params, 3 required) and lack of annotations, the description is remarkably complete: it covers all parameters, provides usage workflows, and even explains cross-MCP file transfer mechanics. It also references sibling tools for context. No critical information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description compensates excellently by defining every parameter: page_id with how to obtain it, source with all supported schemes, files_property as exact column name, mode with concrete append/replace behavior, and filename as override. This provides complete semantics beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource+target: 'Upload a file and attach it to an EXISTING database row's files & media column.' The emphasis on 'EXISTING' distinguishes it from sibling tools like notion_upload_file_to_database and notion_batch_add_file_to_row. It clearly states what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Cross-MCP file transfer' section provides a concrete step-by-step workflow for using this tool with a Gmail attachment, including prerequisites (download_attachment) and an alternative route via Drive. This gives explicit context for when to use this tool and how it fits into a larger process, effectively covering usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_append_contentA
Append markdown content to an existing Notion page.
Parses the markdown into blocks and appends them to the end of the page.
Supports: headings (# ## ###), bullet/numbered/to-do lists, quotes,
fenced code blocks, dividers (---), paragraphs with inline formatting
(bold, italic, code, strike, links).
page_id: the page to append to. content: markdown text to append.
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | ||
| page_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that markdown is parsed into blocks and appended to the end of the page, and lists supported markdown elements. It doesn't discuss error cases or permissions, but the core behavioral traits are transparent and complete for a simple append operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: a one-sentence purpose, a brief explanation of parsing behavior, a list of supported markdown features, and clear parameter definitions. Every sentence provides useful information with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers both required parameters, explains the input format, and describes the append operation. It doesn't address edge cases like empty content or invalid page_id, but the tool is relatively simple and the output schema is present, so the description is sufficiently complete for an agent to use it correctly in most scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only names and types with no property descriptions (0% coverage). The description fully compensates by explicitly defining page_id as 'the page to append to' and content as 'markdown text to append,' and it elaborates on the content format. This adds substantial meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool appends markdown content to an existing Notion page, with a specific verb (append), resource (existing page), and scope (end of page). This distinguishes it from siblings like notion_replace_page_content or notion_update_page_content, which replace or update content rather than append.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool: when you want to add content to the end of an existing page. It doesn't explicitly mention alternatives or exclusions, but the append semantics and 'existing page' phrasing imply the appropriate use case and distinguish from creation or replacement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_archive_pageA
Archive (soft-delete) a Notion page. The page can be restored from the Notion trash within 30 days using notion_restore_page.
page_id: the page to archive.
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, the description discloses that the operation is a soft-delete and the page remains in trash for 30 days. This is valuable behavioral context beyond the basic operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact: one sentence for the operation, one for restoration, and one for the parameter. It is front-loaded with the core purpose and contains no redundant text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one required parameter, and the description covers purpose, soft-delete behavior, restore path, and parameter semantics. The presence of an output schema means return values don't need explanation. Slight gap: no mention of permissions or side effects, but not essential.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage for page_id, but the description adds 'the page to archive,' providing clear meaning for the sole parameter. This compensates for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool archives (soft-deletes) a Notion page, distinguishing it from delete_block or update_page. It also mentions restoration, further clarifying the specific operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly references notion_restore_page as the path for undoing the archival, giving context on when to use this tool vs. that alternative. However, it does not explicitly state when not to use it (e.g., for permanent deletion).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_batch_add_file_to_rowA
Attach files to many existing Notion rows in one call.
items_json is a JSON array of objects. Each item takes the same shape as the single-shot tool's parameters::
[
{"page_id": "...", "source": "shared:invoice1.pdf"},
{"page_id": "...", "source": "shared:invoice2.pdf",
"filename": "Renamed.pdf"},
{"page_id": "...", "source": "drive:<id>",
"files_property": "Attachments", "mode": "replace"}
]default_files_property and default_mode fill in any item that omits those fields — pass them once at the batch level instead of repeating per item.
Items are uploaded with bounded concurrency (NOTION_BATCH_CONCURRENCY, default 3) so a batch of N finishes in roughly ceil(N/concurrency) waves rather than serially — a batch of ~8 used to exceed the client's 4-minute timeout when serial. Concurrent items targeting the SAME row are still serialised (the 'append' path is a read-modify-write). The 429/5xx backoff in the client absorbs any rate-limit bursts. Per-item failures are reported in the output (in input order) but do NOT abort the batch — use the per-item status to retry individual items.
Files are staged in the shared mount; the typical pattern is to stage N files via google-accounts-mcp download_attachment, call this tool once, then call notion_purge_file to remove each staged file.
| Name | Required | Description | Default |
|---|---|---|---|
| items_json | Yes | ||
| default_mode | No | append | |
| default_files_property | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses key behaviors: bounded concurrency with default 3, serialization for same-row items, 429/5xx backoff, per-item failures reported but not aborting the batch, and the read-modify-write nature of the append path. This is rich, non-obvious context that goes far beyond what annotations or schema provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but genuinely information-dense: each paragraph covers a distinct aspect (usage example, defaults, concurrency, error handling, staging workflow) and the first sentence states the purpose. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (batch concurrency, per-item errors, default inheritance), the description covers all critical operational aspects, including a recommended workflow involving sibling tools. An output schema exists, so return-value details are not required, but the description still covers per-item status reporting.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It does so by giving a full JSON example for items_json, explaining default_mode and default_files_property as batch-level fill-ins, and showing mode values like 'append' and 'replace'. This makes the parameters meaningful beyond their bare schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Attach files to many existing Notion rows in one call,' which is a specific verb+resource+scope. It clearly contrasts with the singular notion_add_file_to_row sibling and the batch nature is explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a concrete usage pattern ('stage N files via google-accounts-mcp download_attachment, call this tool once, then call notion_purge_file') and explains why batch is preferable to serial ('a batch of ~8 used to exceed the client's 4-minute timeout when serial'). This gives clear when-to-use context and implies the singular tool for one-off operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_create_databaseA
Create a new Notion database under a page.
parent_page_id: page to create the database under (it appears as an inline database on that page). title: database title. schema_json: JSON object mapping property names to their type config in Notion API format. A title property is required. Example: { "Name": {"title": {}}, "Status": {"select": {"options": [ {"name": "To Do", "color": "red"}, {"name": "Done", "color": "green"} ]}}, "Due Date": {"date": {}}, "Priority": {"number": {"format": "number"}}, "Tags": {"multi_select": {"options": [ {"name": "bug"}, {"name": "feature"} ]}}, "Assignee": {"people": {}}, "Done": {"checkbox": {}}, "Notes": {"rich_text": {}}, "Link": {"url": {}} }
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| schema_json | Yes | ||
| parent_page_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It does disclose that the database appears as an inline database on the page and that a title property is required, which adds behavioral context. However, it does not state permissions needed, reversibility, or what happens on failure. For a mutation tool, this is a moderate level of transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening sentence, parameter breakdown, and a compact example. The example is lengthy but necessary for explaining the schema_json format. Every part serves a purpose, though the overall length is above minimal.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the essential aspects of the create operation, including the target page, title, and schema structure. It does not mention return values, but an output schema is present, so that gap is acceptable. Missing prerequisites like page existence or permissions are not stated, but the description is fairly complete given its complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides no descriptions for its parameters, so the description must compensate. It does so thoroughly by explaining each parameter (parent_page_id, title, schema_json) and providing a detailed example for schema_json, including property types and structure. This adds significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Create a new Notion database under a page,' which is a specific verb and resource. It distinguishes this from sibling tools like notion_update_database (updating existing) and notion_query_database (querying) by focusing on creation. The scope of where the database is created is also specified.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context of use is clear: this tool creates a database and places it under a specified page. While it doesn't explicitly mention alternatives or exclusions, the description provides enough context for an agent to know when to select this tool over siblings (e.g., not for updating or querying). The 'under a page' detail adds important usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_create_pageA
Create a new Notion page with optional markdown content.
For a standalone page under another page, provide parent_page_id. For a database row, provide database_id and properties_json.
title: the page title. content: markdown text that becomes the page body. Supports headings, lists, quotes, code blocks, inline formatting. parent_page_id: ID of the parent page. database_id: ID of a database to add the row to. properties_json: JSON object of extra Notion properties (for database rows). Keys are property names, values are Notion API property value objects. icon: emoji character for the page icon (e.g. "🚀").
| Name | Required | Description | Default |
|---|---|---|---|
| icon | No | ||
| title | Yes | ||
| content | No | ||
| database_id | No | ||
| parent_page_id | No | ||
| properties_json | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains that the tool behaves differently depending on which ID is provided (parent_page_id vs database_id), and it details that content supports markdown elements like headings, lists, quotes, code blocks, and inline formatting. While it does not mention permissions or rate limits, the main creation behavior is well-covered for a non-destructive write operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficiently structured with a lead sentence, two usage lines, and a clean parameter list. It is longer than minimal, but given 6 parameters and two modes, every line earns its place. The purpose is front-loaded, and the list format improves readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 6 parameters, no schema descriptions, and an output schema (so return values are presumably covered elsewhere). The description covers all parameters and the key mode distinction, making it complete enough for an agent to invoke correctly. It does not explain error scenarios, but that is not required for completeness here.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description must fully compensate. It explains every parameter: title, content, parent_page_id, database_id, properties_json, and icon. It also clarifies the format of properties_json as 'keys are property names, values are Notion API property value objects' and gives an example for icon. This is excellent compensation for the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Create a new Notion page with optional markdown content.' It clearly differentiates from sibling tools like notion_create_database and notion_update_page by focusing on page creation, and it further specifies two distinct modes (standalone page under another page vs database row). This makes the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: 'For a standalone page under another page, provide parent_page_id. For a database row, provide database_id and properties_json.' It effectively explains the two main use cases, though it does not explicitly name alternatives or state when not to use this tool. Still, the mode distinction gives actionable guidelines.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_create_viewA
Create a view on a Notion database.
database_id: the database to add the view to. name: display name for the view. view_type: table | board | list | calendar | timeline | gallery | chart (default table). filter_json: optional Notion filter object as JSON (same shape as notion_query_database's filter_json). sorts_json: optional JSON array of sort objects.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| view_type | No | table | |
| sorts_json | No | ||
| database_id | Yes | ||
| filter_json | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It adds useful behavioral context by documenting parameters, including the default view_type and the cross-reference to notion_query_database's filter_json, but it does not disclose side effects, permissions, or failure modes. It only implies mutation through the verb 'create'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads the purpose in a single sentence, then uses a clear list format for parameter documentation. Every line provides necessary information with no filler, making it both concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 5-parameter complexity and the existence of an output schema, the description covers all parameters effectively and provides a helpful cross-reference for filter_json. It does not mention prerequisites like the database existing, but this is relatively minor for a create operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description fully compensates by documenting every parameter: database_id, name, view_type with allowed values, filter_json with a reference to another tool's format, and sorts_json as an optional JSON array. This adds significant meaning beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Create a view on a Notion database' with a specific verb and resource. It clearly distinguishes from sibling tools like notion_list_views, notion_update_view, and notion_delete_view by the action 'create'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context is clear that this tool is used to create a view on a database, but there is no explicit guidance on when to use it versus alternatives. No exclusions or alternative tool mentions are provided, so the usage is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_delete_blockA
Delete a block from a Notion page. This removes the block and all its children. The deletion is permanent (blocks cannot be restored).
block_id: ID of the block to delete.
| Name | Required | Description | Default |
|---|---|---|---|
| block_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It explicitly discloses that the deletion removes the block and all children, and that deletion is permanent and cannot be restored. This fully informs the agent of destructive side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is only two sentences plus a parameter line, with the main action and critical caveats front-loaded. Every sentence adds value with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple deletion tool with one parameter and an output schema, the description covers the essential behavioral context: what is deleted, cascading effect, and irreversibility. No further explanation of return values is necessary given the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema only provides a title ('Block Id') with no description. The description adds 'ID of the block to delete,' clarifying that this is the target block. For a single-parameter tool with 0% schema coverage, this is adequate compensation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Delete'), the resource ('a block from a Notion page'), and adds key scope ('all its children') and irreversibility. This distinguishes it from sibling tools like update_block or archive_page.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The first sentence provides clear context: use this tool to delete a block from a Notion page. It does not explicitly name alternatives or exclusions, but the purpose is unambiguous and distinct from related block/page operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_delete_commentA
Delete a comment previously created by this integration (Notion returns 404 for comments created by anyone else).
comment_id: from notion_get_comments or notion_add_comment.
| Name | Required | Description | Default |
|---|---|---|---|
| comment_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals the ownership constraint and the 404 error for non-owned comments, which is useful behavioral context. However, it does not explicitly mention permanence or reversibility of the deletion, though this is a typical implication of a delete operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, with two clearly separated sentences: one for the purpose/behavior and one for parameter sourcing. No redundant information or filler text exists, making it easy to parse and act on.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one parameter, an output schema (though not shown), and no annotations. The description covers the core purpose, a key behavioral constraint, and parameter sourcing. It could mention what the response looks like or explicitly note that deletion is permanent, but given the simplicity and presence of an output schema, the description is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has no description for the single parameter, and coverage is 0%. The description compensates by telling the agent where to source the comment_id (from notion_get_comments or notion_add_comment). This adds practical meaning beyond the raw schema type, but it does not elaborate on the expected format or validation of the ID.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool deletes a comment, with the specific constraint that it must have been created by this integration. This distinguishes it from sibling comment tools like notion_add_comment and notion_update_comment. The mention of Notion returning 404 for others further clarifies the exact scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (only for comments created by this integration) and when not to (for comments created by anyone else, as they will 404). It also guides the agent on where to obtain a valid comment_id (from notion_get_comments or notion_add_comment). Explicit alternatives are not listed, but no other delete-comment tool exists among the siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_delete_viewA
Delete a view from its database. The database and its rows are untouched — only the saved view configuration is removed.
| Name | Required | Description | Default |
|---|---|---|---|
| view_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses a key behavioral trait: deletion only affects the view configuration, not the database or its rows. This helps set expectations about the tool's impact, though it does not mention permanence or permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that front-loads the action and includes a valuable clarification about what is not affected. No unnecessary words or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity of the tool (one param, no annotations) and the presence of an output schema, the description is largely complete. It explains both the action and the non-destructive scope, leaving little ambiguity for an agent invoking the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage for its single parameter, and the description does not explicitly explain 'view_id'. While the parameter name and context imply it is the ID of the view to delete, the description does not add meaningful detail (e.g., how to obtain it or whether it must be a view ID rather than a database ID).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Delete a view from its database', which identifies the specific action (delete) and resource (view). It distinguishes from sibling tools like notion_create_view and notion_update_view by indicating the destructive action, and from notion_delete_block by clarifying the scope is limited to a view configuration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides implicit context by noting 'The database and its rows are untouched', implying this tool is for removing only a saved view without affecting data. However, it does not explicitly state when to use this tool versus alternatives or mention any exclusions, so the guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_describe_databaseA
Retrieve a Notion database's schema. Returns each property name and type — use this to find the exact files & media column name to pass to notion_upload_file_to_database / notion_add_file_to_row.
database_id can be found by calling notion_list_files_on_page on the page that holds the inline database (child_database blocks will show), or pasted from the database URL.
| Name | Required | Description | Default |
|---|---|---|---|
| database_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It states the core behavior (retrieves schema, returns property names/types) and adds context about how to find database_id. However, it does not disclose potential error conditions, rate limits, or any prerequisites beyond knowing the database_id. For a simple read-only operation this is adequate but not deeply transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured. The first sentence states the purpose and return value, while the second provides crucial parameter guidance. No unnecessary words or redundant information are present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (one parameter, no nested objects), and an output schema is present. The description explains what the tool does, what it returns, and how to get the input parameter. It also ties the tool into a broader workflow with related tools. This is sufficient for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides only the parameter name 'database_id' with no description. The tool description compensates fully by explaining what database_id is and exactly how to obtain it: 'calling notion_list_files_on_page on the page that holds the inline database (child_database blocks will show), or pasted from the database URL.' This adds significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Retrieve' and clearly identifies the resource ('Notion database's schema'). It states what is returned ('each property name and type') and distinguishes this from siblings by focusing on schema retrieval rather than querying or modifying data. The additional note about finding exact column names for upload tools clarifies its intended niche.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an explicit use case: 'use this to find the exact files & media column name to pass to notion_upload_file_to_database / notion_add_file_to_row.' It also explains how to obtain the database_id via a sibling tool or URL. However, it does not explicitly mention when not to use this tool or compare it to alternatives like notion_query_database, so it lacks full exclusionary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_download_fileA
Download a file from a Notion file/image/pdf/video/audio block.
destination is one of: local, shared, drive, base64.
• local — the notion-mcp private store (FILES_DIR).
• shared — the cross-MCP shared mount, immediately attachable by
google-accounts-mcp as attachments=['shared:'] on
draft_email / send_email. 24h TTL applies.
• drive — upload to the shared Drive folder (DRIVE_FOLDER_NAME).
• base64 — inline; subject to MCP response size limits.
filename overrides the inferred name. When destination=local, filename
may include subdirectories (e.g. reports/q3.pdf); they are created
under the local store. Use notion_list_files_on_page to find block IDs.
Cross-MCP file transfer (Notion → Gmail)
To email a file stored in Notion:
notion_download_file(block_id, destination='shared')
google-accounts-mcp draft_email(..., attachments=['shared:']) Bytes never traverse MCP parameters — no size limits.
| Name | Required | Description | Default |
|---|---|---|---|
| block_id | Yes | ||
| filename | No | ||
| destination | No | local |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does so effectively by explaining storage locations (FILES_DIR, shared mount), the 24h TTL for shared, Drive upload behavior, and MCP response size limits for base64. It also notes that bytes never traverse MCP parameters in the shared flow, which is valuable operational context. It omits specifics like authentication or error semantics, but given the richness of what is disclosed, this is above average.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but well-structured with a bulleted list and a clearly separated cross-MCP workflow. Each sentence adds necessary information, and the most important purpose is front-loaded. It could be slightly tighter by moving the cross-MCP example into a 'Use cases' subsection, but it remains efficient and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no annotations and minimal schema, the description covers all essential operational aspects: destinations, filename handling, storage paths, TTL, size constraints, and an end-to-end email attachment flow. It also gives a pointer to the sibling tool needed to locate block IDs. With an output schema present, return-value details are not needed from the description, and nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully document parameters. It explains destination as an enum with per-value behavior, filename as an override, and that local filenames may include subdirectories that are auto-created. block_id is implied by the opening sentence and the pointer to notion_list_files_on_page. This fully compensates for the sparse schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource+scope: 'Download a file from a Notion file/image/pdf/video/audio block.' This clearly distinguishes the tool from siblings like notion_extract_file_text or notion_render_file_page, and the destination options are enumerated. It also cross-references notion_list_files_on_page for finding block IDs, reinforcing its unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides detailed guidance on when to use each destination option (local, shared, drive, base64), including TTL and size constraints. It also includes a step-by-step cross-MCP transfer example to Gmail. However, it does not explicitly contrast this tool with sibling tools that might also retrieve file content (e.g., notion_extract_file_text or notion_render_file_page), so exclusionary guidance is implicit rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_extract_file_textA
Extract text from a PDF anywhere notion-mcp can reach — a file stored in Notion, the shared cross-MCP mount, the private store, or the Drive folder — without moving the bytes over MCP.
source schemes: 'notion:' (file/pdf block on a page — get block IDs from notion_list_files_on_page), 'shared:', 'local:', 'drive:'.
Returns JSON: {"text", "page_count", "pages_returned", "mode", "truncated", "filename"} (+ "ocr_used"/"ocr_pages"/"ocr_engine" when OCR ran). Response ceiling 200 KB — truncation happens on a page boundary with a trailing marker naming the pages to fetch next.
pages: pdftotext-style spec — None/"" (all), "3", "1-5", "1,3,5", "1-3,7". Out-of-range pages are silently dropped. mode: 'text' (flowing), 'layout' (preserve columns), 'tables' (extract_tables → markdown). Applies to native extraction only.
OCR (scanned / image-only PDFs) — delegated to the fleet xberg service (XBERG_BASE_URL env; pages rasterised locally, sent as PNGs): ocr='auto' (default) — pages whose native text is < 20 chars are OCR'd (tesseract backend, seconds/page). "ocr_error" in the response means OCR was needed but xberg was unreachable/failed. ocr='off' — native extraction only. ocr='force' — OCR every requested page (garbled font encodings). ocr='llm' — transcribe pages with a vision model (xberg vlm backend → LiteLLM; env: XBERG_VLM_API_KEY, optional XBERG_VLM_MODEL / XBERG_VLM_BASE_URL). Best for handwriting and messy tables; slower and metered.
| Name | Required | Description | Default |
|---|---|---|---|
| ocr | No | auto | |
| mode | No | text | |
| pages | No | ||
| source | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure. It excels by detailing response truncation (200 KB ceiling, page-boundary truncation, trailing marker), silent dropping of out-of-range pages, OCR auto behavior with a 20-char threshold, error conditions ('ocr_error'), and the distinction between native and OCR extraction. These details go far beyond what the schema or annotations reveal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but densely informative, with every section providing necessary operational detail. It is front-loaded with the core purpose and then structured into paragraphs and enumerations for source schemes, return format, page specs, mode, and OCR, making it navigable despite its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the presence of an output schema, the description goes beyond it by explicitly listing the returned JSON fields and explaining truncation behavior. It covers all four parameters, source access, mode semantics, OCR fallback conditions, and error signaling, leaving no material gap for an agent to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Since schema description coverage is 0%, each parameter is thoroughly explained in prose: source includes scheme-specific examples, pages uses a pdftotext-style grammar with concrete examples, mode enumerates 'text', 'layout', and 'tables' with explanations, and ocr documents 'auto', 'off', 'force', and 'llm' with detailed behavior. This fully compensates for the absent schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: "Extract text from a PDF anywhere notion-mcp can reach" and distinguishes it by noting it does so "without moving the bytes over MCP." It also specifies supported source schemes and references companion tool notion_list_files_on_page, making the resource and scope unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear contextual guidance: it explains the acceptable source schemes, how to obtain block IDs (via notion_list_files_on_page), and when to use different modes and OCR settings. However, it does not explicitly contrast with alternative sibling tools (e.g., notion_download_file) or state when not to use this tool, so it falls short of full alternative-based guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_get_commentsA
Get all comments on a Notion page.
Returns comment text, author, and timestamps. Use this to read discussion threads on a page.
page_id: the page to get comments from.
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the transparency burden. It discloses that the tool returns comment text, author, and timestamps, and implies a read-only operation. However, it doesn't mention pagination, error behavior, or permissions. For a simple read tool this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded. The first sentence states the main action, followed by a useful detail about returned fields, a usage guideline, and a parameter explanation. Every sentence contributes value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and an output schema, the description is complete. It explains what the tool does, what it returns, when to use it, and what the parameter means. Given the low complexity, no additional details are needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has one parameter (page_id) with no description, and schema coverage is 0%. The description compensates by explicitly explaining 'page_id: the page to get comments from.' This adds clear meaning beyond the bare parameter name, which is valuable for correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Get all comments on a Notion page.' It specifies a precise verb (Get), resource (comments on a Notion page), and scope (all comments). The addition 'Use this to read discussion threads' reinforces the purpose and differentiates it from sibling tools that add, update, or delete comments.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear context for use: 'Use this to read discussion threads on a page.' While it doesn't explicitly name alternatives or exclusions, the read-focused language makes it obvious that this is for reading rather than modifying comments. The context is sufficient for selecting this tool over its mutating siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_get_propertyA
Retrieve a single property from a Notion page with full pagination.
Useful for large properties (relations, rollups, long rich_text) that get truncated in the normal page response. Provide either property_name or property_id.
page_id: the page to read from. property_name: human-readable property name (looked up from page metadata). property_id: Notion property ID (from notion_describe_database schema). Takes precedence over property_name if both given.
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes | ||
| property_id | No | ||
| property_name | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It reveals that the tool returns a single property with full pagination, handles large properties gracefully, and gives precedence to property_id over property_name. This goes beyond a simple 'get' but could mention error handling or auth implications.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: a clear one-sentence purpose, followed by a targeted use case, then a neatly formatted parameter list. Every sentence earns its place, with no unnecessary fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, usage, and parameters well. However, it says 'Provide either property_name or property_id' but does not specify what happens if neither is given, especially since both are optional in the schema. This minor ambiguity prevents a perfect score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. It thoroughly documents all three parameters: page_id (page to read), property_name (looked up from metadata), and property_id (from notion_describe_database schema, with precedence). This adds significant meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Retrieve a single property from a Notion page with full pagination,' clearly stating the verb, resource, and scope. It distinguishes itself from sibling tools like notion_read_page by specifying 'single property' and addressing truncation, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The tool says it is 'Useful for large properties (relations, rollups, long rich_text) that get truncated in the normal page response,' providing clear context on when to use it. However, it does not explicitly name alternative tools or state when not to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_get_userA
Get details for a specific Notion user by ID.
Returns the user's name, email, avatar URL, and type. Use notion_list_users to find user IDs first.
user_id: Notion user UUID.
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of disclosing behavior. It states the tool 'Get details' (implying non-mutating) and lists the return fields. It also specifies the user_id format as a 'Notion user UUID.' However, it does not mention error conditions (e.g., 404 if not found) or any authentication requirements, but for a simple read tool this is reasonably transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three concise sentences: purpose, return values, and usage guidance. It is front-loaded with the primary action. No filler or redundant information; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-id tool with one parameter and an output schema, the description is complete. It states what the tool returns, how to find the ID (via list_users), and the parameter format. No additional behavior or caveats are needed for this straightforward read operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description compensates by defining user_id as 'Notion user UUID,' which adds meaning beyond the bare schema (type string, title 'User Id'). It also includes the context that the ID is for a specific user. This is sufficient for a single parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb+resource+scope: 'Get details for a specific Notion user by ID.' It also lists the returned fields (name, email, avatar URL, type), distinguishing it from sibling tools like notion_list_users which list users rather than fetching one. The phrase 'by ID' further clarifies the exact operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly guides usage: 'Use notion_list_users to find user IDs first.' This provides a clear alternative and prerequisite, telling the agent when to use this tool vs. listing users. It also implies this tool is for a known user ID, which is good contextual guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_import_file_from_urlA
Import a file into Notion directly from a public HTTPS URL — the bytes go Notion-side, never through this server or MCP parameters.
url must be publicly accessible over HTTPS. filename must carry an extension Notion accepts (it determines the block type). The import is asynchronous: this tool polls until the upload reaches a terminal status or wait_seconds elapses. parent_page_id and position behave as in notion_upload_file.
Size limits are plan-dependent (5 MiB free / 5 GiB paid). No sha256 is reported — the bytes never pass through this server; verify via notion_download_file if integrity matters.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| caption | No | ||
| filename | Yes | ||
| position | No | end | |
| wait_seconds | No | ||
| parent_page_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full responsibility. It discloses async polling behavior, plan-dependent size limits, the absence of sha256 reporting, and the server-side transfer path without sending bytes through this server. This is exemplary transparency for a tool with no annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact—four sentences—with the core purpose front-loaded. Every sentence adds essential context: constraints, async behavior, size limits, and integrity caveat. It is dense but not bloated, and each statement earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (async import, size limits, integrity concerns) and the presence of an output schema, the description covers all necessary operational aspects. It explains the critical behaviors without needing to describe return values, which are already handled by the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description compensates well by explaining url requirements, filename semantics (determines block type), wait_seconds as polling timeout, and referencing notion_upload_file for parent_page_id and position. However, the caption parameter is not mentioned, leaving a gap for a minor field.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action: 'Import a file into Notion directly from a public HTTPS URL' and clearly distinguishes this tool from notion_upload_file by noting the bytes go Notion-side, never through the server. It also references notion_upload_file for parameter behavior, making the scope and differentiation explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear usage context: url must be publicly accessible, filename must have an acceptable extension, and the import is asynchronous with wait_seconds timeout. It recommends notion_download_file for integrity checks, offering an alternative for a related need, but does not explicitly state when to prefer this over notion_upload_file for local files.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_list_files_on_pageA
List all file/image/pdf/video/audio blocks on a Notion page. Returns block IDs and filenames — use block IDs with notion_download_file.
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that the tool returns block IDs and filenames, and implies it does not download files (by directing to another tool). It does not mention any side effects, permissions, pagination, or failure modes, but for a read-only listing operation, the core behavior is adequately covered. The score reflects that it adds some context but lacks deeper behavioral details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no fluff. The first sentence states the action and scope, the second sentence explains the return value and next step. It is front-loaded with the key information and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity (1 parameter, simple listing) and the presence of an output schema, the description is mostly complete. It tells what is listed, what is returned, and how to use the result. The main gap is the lack of parameter format details, but for a tool this simple, the description covers the essential context well.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has zero description coverage, and the description does not compensate by explaining the page_id format (e.g., UUID vs URL). The only param is page_id, and the description merely says 'on a Notion page', which is redundant with the tool's name. The description adds no meaningful semantic information beyond what the schema field name implies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'List' and clearly identifies the resource: all file/image/pdf/video/audio blocks on a Notion page. It distinguishes from siblings by mentioning the return of block IDs and filenames for use with notion_download_file, setting it apart from search or upload tools. This is a precise, unambiguous statement of purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool: to identify files on a page for subsequent download. It explicitly directs the user to use the returned block IDs with notion_download_file, which is a concrete usage guideline. However, it does not mention explicit alternatives or exclusions (e.g., when not to use it), but the context is sufficient for a simple listing tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_list_local_filesA
List files available to notion-mcp by scheme, so the agent can verify a handoff before attaching it to Notion.
location: • 'files' (default) — the notion-mcp private store under FILES_DIR. These are addressable as source='local:'. • 'shared' — the cross-MCP shared mount under SHARED_DIR. Files placed here by google-accounts-mcp (download_attachment with destination='shared') are addressable as source='shared:'.
Optional substring filter on the filename.
| Name | Required | Description | Default |
|---|---|---|---|
| filter | No | ||
| location | No | files |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the tool lists files in two specific stores and describes the source addressing forms. It does not mention side effects or edge cases, but as a read-only listing action the core behavior is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a purpose statement, then uses a bulleted list for the location options, and ends with a short sentence about the filter. It is well-structured and every sentence contributes value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has only two optional parameters with defaults and an output schema, and the description covers its purpose, both locations, and the filter. The cross-MCP context about google-accounts-mcp adds completeness, making the description sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has zero descriptions, but the description fully explains the 'location' parameter with its two possible values and their meanings, and the 'filter' parameter as an optional substring filter. This adds significant meaning beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists files available to notion-mcp by scheme, and explains the purpose of verifying a handoff before attaching to Notion. It distinguishes between 'files' and 'shared' locations, which sets it apart from sibling tools like notion_list_files_on_page.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool—verifying a handoff before attaching—and explains the two location schemes including which files are in each. However, it does not explicitly mention alternatives or when not to use this tool versus other listing tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_list_usersA
List all users in the Notion workspace.
Returns user names, IDs, emails, and types (person or bot). User IDs are needed for people properties and @mentions in comments.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the disclosure burden. It states the returned data (names, IDs, emails, types) and the typical use of user IDs. However, it does not disclose potential pagination behavior or permission requirements, leaving some behavioral gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the main purpose. The second sentence adds valuable details about return data and use case. No unnecessary words or repetition; it is highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is low complexity with an output schema, and the description covers the core purpose and returned data. It lacks explicit notes on pagination or permissions, but with an output schema in place and the simplicity of a zero-parameter list, the description is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter information to add. The baseline of 4 is appropriate given that the schema is trivially empty and the description doesn't need to explain any arguments.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and resource ('all users in the Notion workspace'), clearly distinguishing this from sibling notion_get_user which fetches a single user. The scope is explicit, and the purpose is immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context for when to use the tool by explaining that user IDs are needed for people properties and @mentions, implying the use case for obtaining a complete user list. It does not explicitly mention exclusions or alternative tools, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_list_viewsA
List the views defined on a Notion database — name, type, id, and whether each carries a saved filter/sorts. Use the view id with notion_query_view to run a view's saved filter, or with notion_update_view / notion_delete_view to manage it.
| Name | Required | Description | Default |
|---|---|---|---|
| database_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the nature of the operation ('List') and the specific output fields, which is behavioral context. It does not mention side effects or permissions, but for a read-only listing operation, 'List' and the output description give sufficient transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The first sentence states the purpose and output; the second provides actionable integration with other tools. Every part earns its place, and it is front-loaded with the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a single required parameter, an output schema present, and a clear description of what the tool returns and how to use it with sibling tools, the description is complete. It covers purpose, usage, and follow-up actions without needing to explain return values (which the output schema handles).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has a single parameter (database_id) with 0% schema description coverage, so the description must compensate. The description implies that database_id identifies the Notion database whose views are listed, but it does not provide format, validation, or any additional meaning beyond the schema itself. Given the simplicity of the parameter, this is adequate but not exceptional.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') with a clear resource ('views defined on a Notion database') and enumerates the output fields (name, type, id, saved filter/sorts). It clearly distinguishes this tool from siblings like notion_query_database or notion_describe_database by focusing specifically on views.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool and how to chain it with related tools ('Use the view id with notion_query_view... or with notion_update_view / notion_delete_view'). This provides clear guidance on the tool's role and alternatives, making it easy for an agent to decide when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_move_pageA
Move a Notion page to a new parent page or database.
page_id: the page to move. new_parent_page_id: move under this page. new_parent_database_id: move into this database (as a new row). Only one of the two parent args should be set.
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes | ||
| new_parent_page_id | No | ||
| new_parent_database_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must carry the full burden. It outlines the mechanics (new row for database) but does not disclose side effects such as whether the page is removed from its original location, permission requirements, or whether the operation is reversible. This is a significant gap for a mutation tool, similar to the update_drive example.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, using a single-purpose sentence followed by a clean parameter list. Every line earns its place; there is no fluff. The formatting makes the parameter semantics easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description covers the core action and parameters adequately. However, it omits potential edge cases (e.g., circular moves, self-parenting) and does not describe the output or failure modes, though an output schema exists. More detail on side effects would make it more complete, but it's minimally viable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds substantial meaning beyond the raw schema by explaining each parameter: page_id identifies the page, new_parent_page_id specifies the target page, and new_parent_database_id specifies the target database. It also clarifies the 'as a new row' behavior and the exclusivity constraint, which are not present in the schema. Schema description coverage is 0%, so this compensation is essential.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb+resource: 'Move a Notion page to a new parent page or database.' This distinguishes it from sibling tools like create/update/archive. It leaves no ambiguity about the tool's core function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides specific guidance on how to use the two parent parameters, noting that only one should be set. While it doesn't explicitly mention alternatives, the unique 'move' operation makes alternatives unnecessary. It gives clear context on the condition for using each parent argument.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_purge_fileA
Delete a single file from the cross-MCP shared mount by bare filename. Use this after a successful upload to free the shared slot instead of waiting for the daily TTL sweep (or calling notion_purge_shared_files with max_age_hours=0, which would wipe any unrelated in-flight handoffs). Rejects any filename containing path separators.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosing behavior. It reveals a key constraint ('Rejects any filename containing path separators') and provides context about the daily TTL sweep and shared-slot semantics. However, it does not explicitly state return values, error handling on missing files, or permanence of deletion, which would be useful for a destructive operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: the first states the operation, the second provides usage context and alternatives, the third adds a critical constraint. It is front-loaded with the primary action and avoids any filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, single file deletion) and the presence of an output schema, the description covers the key behavioral and usage aspects. It explains the shared-mount context, the TTL sweep, and the exclusion of path separators. It is sufficiently complete for an agent to select and invoke the tool correctly, though it could mention side effects or idempotency.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only defines a 'filename' string with no description (0% coverage). The description compensates by specifying that it must be a 'bare filename' and that path separators are rejected, adding crucial meaning beyond the schema. Still, it could offer examples or clarify what happens if the file doesn't exist, but the essential semantics are covered.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Delete a single file'), the resource ('from the cross-MCP shared mount'), and the method ('by bare filename'). It also distinguishes itself from sibling tools by explicitly naming the alternative (notion_purge_shared_files) and explaining why this tool is safer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit when-to-use guidance: 'Use this after a successful upload to free the shared slot' and contrasts with the alternative tool 'notion_purge_shared_files with max_age_hours=0' which could wipe unrelated handoffs. This gives clear usage direction and warns against misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_query_databaseA
Query a Notion database with optional filter, sort, and pagination.
Returns matching rows with their properties. Use notion_describe_database first to see the schema and property names.
database_id: the database to query.
filter_json: Notion API filter object as JSON. Example:
{"property": "Status", "select": {"equals": "Done"}}
Compound example:
{"and": [
{"property": "Status", "select": {"equals": "Active"}},
{"property": "Priority", "number": {"greater_than": 3}}
]}
sorts_json: JSON array of sort objects. Example:
[{"property": "Due", "direction": "ascending"}]
Use "ascending" or "descending".
limit: page size (default 50, max 100 — Notion's hard cap).
start_cursor: opaque cursor returned by a previous call. Pass it
to fetch the next page. When the output shows
next_cursor: <token> the result set has more rows; when it
shows next_cursor: (end) you have reached the end.
properties: optional comma-separated list of property names to
include (e.g. "Gmail Message ID, Invoice, Status"). Slims
the output dramatically when you only need a few columns. The
title column is always shown. Unknown names are ignored silently
so a caller can ask for a union across a few databases.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| properties | No | ||
| sorts_json | No | ||
| database_id | Yes | ||
| filter_json | No | ||
| start_cursor | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses important behaviors: pagination via opaque cursor with next_cursor token/end marker, the hard cap of 100, silent ignoring of unknown property names, and the always-shown title column. It does not mention error handling or rate limits, but the disclosed behaviors are substantial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but appropriately so for a tool with six parameters and JSON syntax. It is well-structured, alternating usage guidance with parameter definitions. Every sentence adds value—there is no fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of pagination, filters, and property selection, the description covers all invocation essentials: pagination semantics, default/max limits, property filtering behavior, and JSON formatting. It also notes an output schema exists, so return values need not be fully described in text. This is complete for an agent to select and call the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must fully compensate. It does: every parameter (database_id, filter_json, sorts_json, limit, start_cursor, properties) is explained with JSON examples, defaults, constraints, and usage nuances. The examples for filter and sort are especially valuable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'Query a Notion database with optional filter, sort, and pagination' and explains it returns matching rows with their properties. This provides a specific verb and resource, and the mention of pagination and filtering distinguishes it from simple search or read tools. The sibling reference to notion_describe_database further clarifies its role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs to 'Use notion_describe_database first to see the schema and property names', establishing a clear prerequisite workflow. However, it does not explicitly discuss alternatives or when not to use this tool (e.g., full-text search vs. structured query), so it earns a 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_query_viewA
Run a database view's saved filter and sorts, returning the matching rows (title + id + url). Use this instead of notion_query_database when the view already encodes the filter you want — no filter JSON needed.
view_id: from notion_list_views. limit: max rows to return (max 100).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| view_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses the return shape ('title + id + url') and the limit constraint ('max 100'). However, it does not mention error behavior or permissions, which is a minor gap for a read-only query.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with purpose, then usage, then parameters. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (2 params, one required), has an output schema, and is well-differentiated from siblings. The description covers purpose, usage, and parameters adequately for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description compensates by explaining view_id's provenance ('from notion_list_views') and limit's semantics ('max rows to return (max 100)'). This adds real meaning beyond the schema's type/default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Run' and identifies the resource as 'a database view's saved filter and sorts'. It explicitly differentiates from sibling notion_query_database by stating 'Use this instead of... when the view already encodes the filter you want'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'Use this instead of notion_query_database when the view already encodes the filter you want'. Also implies when not to use (when custom filter JSON is needed), and directs users to notion_list_views for obtaining view_id.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_read_pageA
Read a Notion page's properties and content as markdown.
Returns the page title, properties, and full block content rendered as readable markdown. Nested blocks (toggles, list children, columns) are fetched recursively up to max_depth levels.
page_id: Notion page ID (from notion_search_pages or a URL). max_depth: how many levels of nested blocks to fetch (1-5, default 3). include_block_ids: if True, each block line is suffixed with an HTML comment containing the block UUID, e.g. . Use these IDs with notion_update_block / notion_delete_block.
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes | ||
| max_depth | No | ||
| include_block_ids | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It explains recursive fetching of nested blocks, the max_depth limit, and the behavior of include_block_ids, including how to use the resulting block IDs with other tools. This is more than a basic read operation, though it does not mention rate limits or potential large page considerations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loaded with the main purpose, and uses a clear structure separating the core function from parameter explanations. Every sentence earns its place with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers full functionality, return format, parameter details, and even points to related operations for block IDs. It is complete for a read tool with three parameters and an output schema, though it could optionally mention read-only safety or error scenarios, but these are not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, but the description fully compensates by explaining each parameter: what page_id is and where to get it, the range and default for max_depth, and the effect and purpose of include_block_ids. This provides complete semantic meaning beyond raw schema types and defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads a Notion page's properties and content as markdown, which is a specific verb+resource. It distinguishes from mutation and search siblings, but does not differentiate from the similarly named sibling notion_read_page_markdown, so it falls short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool should be used to read page content, such as the title, properties, and blocks, and mentions using block IDs for updates/deletes. However, it does not explicitly state when to use this tool over alternatives like notion_read_page_markdown or when not to use it, leaving usage guidance mostly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_read_page_markdownA
Read a Notion page's content as native Notion-flavored markdown.
Uses the direct markdown API endpoint — faster than block-by-block fetching and returns Notion's own markdown representation including special tags for databases, files, and embeds.
For block-level editing (update/delete individual blocks), use notion_read_page with include_block_ids=True instead.
page_id: Notion page ID.
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosing behavior. It reveals that the tool 'uses the direct markdown API endpoint', is 'faster than block-by-block fetching', and 'returns Notion's own markdown representation including special tags'. This adds meaningful context about performance and output format, though it doesn't explicitly state read-only safety or error behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: three sentences cover purpose, implementation benefit, and an explicit alternative. Every sentence adds value, with no redundant or irrelevant content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with a single parameter, clear purpose, and an existing output schema, the description is complete. It covers what the tool does, why it's useful, when not to use it (with a named alternative), and the parameter meaning. There are no significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description must compensate. It adds 'page_id: Notion page ID,' which is minimal and essentially repeats the schema title 'Page Id'. This provides only basic meaning and no additional format or context details, so the compensation is weak.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: reading a Notion page's content as markdown. It distinguishes itself from sibling tools, particularly notion_read_page, by explicitly naming the alternative for block-level editing, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance by saying 'For block-level editing (update/delete individual blocks), use notion_read_page with include_block_ids=True instead.' This names the alternative and gives a clear exclusion, along with a performance rationale for using this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_render_file_pageA
Render one page of a PDF (from Notion, shared, local, or Drive) as a viewable image. The default return is a real MCP image content block, so you SEE the page directly — for a scanned document this is often all you need. Use when notion_extract_file_text isn't enough: charts, stamps, layouts, visual validation.
source schemes as in notion_extract_file_text ('notion:', 'shared:', 'local:', 'drive:').
Set return_base64=True for a JSON envelope {"image_base64", "mime_type", "width", "height", "page", "page_count", "filename"} instead (for relaying bytes programmatically). Errors return a JSON string with an "error" key in both modes.
page: 1-indexed. max_width: 200..4000 px (default 1200). format: 'jpeg' (default) or 'png'. quality: JPEG 1..100 (default 75).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| format | No | jpeg | |
| source | Yes | ||
| quality | No | ||
| max_width | No | ||
| return_base64 | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses key behaviors: default return is an MCP image content block, optional base64 JSON envelope, error handling in both modes, page indexing, and parameter ranges. It does not explicitly state read-only behavior, but rendering implies no mutation, and the error description adds transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening, usage context, and parameter breakdown. Each sentence adds essential information, and the layout is easy to scan. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 6 parameters and no output schema, the description covers return values in both modes (image block and JSON envelope), error format, parameter constraints, and source schemes. It provides sufficient context for an agent to invoke the tool correctly without additional lookups.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% parameter coverage, so the description fully compensates by explaining each parameter: source schemes, page indexing, max_width range, format options, quality range, and return_base64 envelope structure. Every parameter is given meaningful context beyond its type/default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool renders one page of a PDF as a viewable image, specifying the supported sources (Notion, shared, local, Drive). It distinguishes itself from sibling notion_extract_file_text by targeting visual content like charts, stamps, and layouts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides when-to-use guidance: 'Use when notion_extract_file_text isn't enough' with concrete examples (charts, stamps, layouts, visual validation). It also explains that the default image return is sufficient for scanned documents.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_replace_fileA
Replace the file inside an EXISTING file/image/pdf/video/audio block, in place — the block keeps its position on the page. Use this to update a document without re-arranging anything; use notion_upload_file(position=...) to add a new block instead.
block_id: the file block to update (from notion_list_files_on_page or
notion_read_page(include_block_ids=True)).
source: same schemes as notion_upload_file (local:, shared:,
drive:, base64:).
caption: when non-empty, replaces the caption; when empty, the
existing caption is left untouched.
The new file must map to the same block type as the existing block (e.g. you cannot replace an image block's content with a PDF — Notion blocks are typed). In that case delete the block and upload anew.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | ||
| caption | No | ||
| block_id | Yes | ||
| filename | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full disclosure burden. It transparently states that the replacement happens in-place, that the block position is preserved, and that the caption is only replaced when non-empty. It does not explicitly state reversibility/permissions, but the core destructive behavior is clearly communicated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: the main behavior, usage direction, parameter details, and a caveat about type constraints. It is front-loaded with the key action and remains compact without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the essential context: what the tool does, when to use it, where to obtain block_id, how to specify the source, caption behavior, and a fallback action for type mismatch. An output schema exists, so not detailing return values is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains block_id, source (with scheme examples), and caption semantics thoroughly, but the 'filename' parameter is not mentioned at all. The source reference to notion_upload_file assumes the agent already knows those schemes, which slightly weakens self-containedness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action: 'Replace the file inside an EXISTING file/image/pdf/video/audio block, in place — the block keeps its position on the page.' It clearly distinguishes itself from the sibling notion_upload_file by contrasting updating an existing block versus adding a new one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use guidance is provided: 'Use this to update a document without re-arranging anything; use notion_upload_file(position=...) to add a new block instead.' It also covers the edge case of block type mismatch and instructs to delete and upload anew.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_replace_page_contentA
Replace a page's entire content with new markdown.
Overwrites all existing content. Use notion_read_page_markdown first to see what's there. For targeted edits, use notion_update_page_content instead.
page_id: the page to replace content on. markdown: new page content in markdown format.
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes | ||
| markdown | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It explicitly discloses the destructive behavior: 'Overwrites all existing content.' This tells the agent the operation is destructive, though it does not discuss permissions, reversibility, or edge cases like clearing the page with empty markdown.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core action in the first sentence. Supporting details (overwrite warning, read-first advice, alternative tool) are provided in a crisp, scannable structure without excess.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a destructive mutation with no annotations, yet the description covers what it does, when to use it, what to do first, and how to avoid unintended edits. Parameter semantics are also covered, and since an output schema exists, return values need not be explained. It is complete for the task.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description adds per-parameter definitions: 'page_id: the page to replace content on' and 'markdown: new page content in markdown format.' These are clear and add meaning beyond the parameter names, though they could include format constraints or examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Replace a page's entire content with new markdown.' It clearly distinguishes from siblings by explicitly mentioning that targeted edits should use notion_update_page_content instead. The scope ('entire content') is precise.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit guidance: 'Use notion_read_page_markdown first to see what's there' and 'For targeted edits, use notion_update_page_content instead.' This explains when to use the tool and names a concrete alternative, which is exemplary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_restore_pageA
Restore an archived page from the Notion trash.
page_id: the archived page to restore.
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full burden of behavioral disclosure. It states the action but does not disclose what happens if the page is not archived, whether permissions are required, what the response contains, or whether the operation is reversible. This is a minimal description for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short, direct sentences with the action front-loaded and a single parameter clarification. Every word earns its place; there is no redundancy or wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one parameter and an output schema, so the description covers the basic purpose and parameter adequately. However, the lack of behavioral caveats (e.g., error conditions, prerequisites, or effects on page state) leaves some gaps, especially given there are no annotations to supplement it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema description coverage at 0%, the description compensates by explaining that 'page_id' is 'the archived page to restore,' adding meaning beyond the schema's generic 'Page Id' title. While it does not specify a format or additional constraints, the single parameter is clearly interpreted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Restore') and a clear resource ('an archived page from the Notion trash'), which directly distinguishes it from sibling tools like notion_archive_page. The purpose is immediately obvious and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context that this tool is for restoring pages that are in the Notion trash, but it does not explicitly mention when not to use it or point to alternatives such as notion_archive_page for the inverse operation. No exclusions or alternative tool references are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_search_databasesA
Search Notion for databases the integration has access to. Returns titles, IDs, and property schemas. Use the database ID with notion_query_database, notion_describe_database, or notion_create_page (with database_id).
The integration only sees databases explicitly shared with it in Notion.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses the integration's access limitation ('only sees databases explicitly shared with it') and return content. No annotations exist, so the description carries the full burden; it gives useful context but doesn't mention rate limits or pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences with front-loaded purpose; the access-scope note is useful and not redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple tool and presence of an output schema, the description covers the key workflow and access limitation. Missing parameter details prevent a 5, but overall it's adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description never explains the 'limit' parameter and only implies 'query' is a search term. With 0% schema description coverage, this is a significant gap; the agent cannot know how limit behaves or what query matches.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Search Notion for databases the integration has access to' with a specific verb and resource, and distinguishes from notion_search_pages by focusing on databases. It also lists the return content (titles, IDs, property schemas).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent to use the returned database ID with notion_query_database, notion_describe_database, or notion_create_page, providing a clear usage workflow. However, it doesn't explicitly contrast with notion_search_pages or state when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_search_pagesA
Search Notion for pages the integration has access to. Returns titles and page IDs — use these IDs with notion_upload_file / list_files_on_page. The integration only sees pages explicitly shared with it in Notion. in_trash=True searches trashed pages instead of active ones (restore matches with notion_restore_page).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| in_trash | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses a key limitation (integration only sees explicitly shared pages) and explains the in_trash behavior. While it does not explicitly state it is read-only, 'search' implies non-mutating and it adds useful context beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each contributing value: main function and return, access scope limitation, and in_trash behavior with related tool. It is front-loaded and contains no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema is present, the description adequately covers access limitations, return type, and trash behavior. It does not mention pagination or rate limits, which are not critical for a search tool. Overall, it provides sufficient context for an agent to select and use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains the non-obvious in_trash parameter in detail, including the restore workflow. Query and limit are self-explanatory by name and default, so the lack of explicit explanations is acceptable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it searches Notion for pages the integration can access, distinguishing it from searching databases (a sibling tool). It also specifies the return type (titles and page IDs) and links to related tools, providing a clear and specific purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit downstream usage guidance by instructing to use returned IDs with notion_upload_file / list_files_on_page, and notes that in_trash=True can pair with notion_restore_page. However, it does not explicitly mention when to use this tool instead of notion_search_databases, though the 'pages' scope implies it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_set_page_visualA
Set or remove a Notion page's icon or cover image.
target: 'icon' or 'cover'.
Provide exactly one of:
• emoji — a single emoji character (icon only), e.g. '📊'.
• source — an image via the usual schemes (local:, shared:,
drive:, base64:); uploaded and attached as the icon/cover.
• remove=True — clear the icon/cover entirely.
| Name | Required | Description | Default |
|---|---|---|---|
| emoji | No | ||
| remove | No | ||
| source | No | ||
| target | Yes | ||
| page_id | Yes | ||
| filename | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses that images are 'uploaded and attached,' that emoji applies to icons only, that remove clears the visual entirely, and lists valid source schemes. This goes beyond the bare schema, though it does not explain failure modes or effects on existing visuals beyond removal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured with a short opening sentence and a clear bulleted list for the exactly-one-of options. Every sentence carries semantic weight; there is no padding or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter tool with no annotations and no schema descriptions, the description covers the core behavior, valid source schemes, target options, and removal semantics. It omits filename and alternative-tool guidance, but an output schema exists, so return values don't need to be spelled out.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions are absent (0% coverage), so the description must compensate. It explains target, emoji, source, and remove in detail, but never mentions the filename parameter and leaves page_id implicit. Thus it provides substantial but incomplete parameter coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a crisp verb-resource statement: 'Set or remove a Notion page's icon or cover image.' It immediately tells the agent both the action and the target resource, and it is distinct from sibling tools that upload/replace files or update page content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is implied by the purpose statement ('set or remove icon/cover') and the operational note that exactly one of emoji, source, or remove must be supplied, but there is no explicit guidance on when to choose this tool over alternatives or any exclusions/when-not-to-use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_update_blockA
Update an existing block's text content.
block_id: ID of the block to update (from notion_read_page output). content: new text for the block (supports inline markdown). block_type: the block type (paragraph, heading_1, heading_2, heading_3, bulleted_list_item, numbered_list_item, to_do, quote, callout, toggle, code). If omitted, the block is fetched to detect it.
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | ||
| block_id | Yes | ||
| block_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that block_type can be omitted and the block is fetched to detect it, and that content supports inline markdown. However, it does not clarify whether content fully replaces existing text, whether other block properties are preserved, or any permission requirements. This is partial transparency but lacks depth for a mutating tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is efficient and front-loaded with the primary action. The parameter list is clearly formatted and avoids unnecessary fluff. It is slightly longer than strictly necessary but every sentence contributes useful information, so it earns a 4 rather than a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists and no annotations, the description adequately covers the tool's purpose, parameters, and a key behavioral option (auto-detecting block type). It lacks details on error cases or explicit confirmation that content replaces existing text, but overall it is complete enough for an agent to invoke correctly. A 4 is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does so excellently: block_id is anchored to notion_read_page output, content is explained with 'supports inline markdown', and block_type includes a full list of allowed values plus behavior when omitted. This adds substantial meaning beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Update an existing block's text content.' The verb 'update' is specific, the resource is a block, and the scope is text content, which distinguishes it from siblings like notion_append_content and notion_delete_block. The parameter details further elaborate on the operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context by noting block_id comes from notion_read_page output and listing allowed block types, but it does not explicitly state when to use this tool versus alternatives like notion_append_content or notion_update_page. No exclusions or alternative tool references are provided, so it only meets the 'implied usage' level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_update_commentA
Edit a comment previously created by this integration (Notion returns 404 for comments created by anyone else).
comment_id: from notion_get_comments or notion_add_comment. text: replacement text (native API markdown — inline formatting, equations, @mentions).
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| comment_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the transparency burden. It discloses a key behavioral trait: comments created by others are not editable and return a 404. It also specifies that the text parameter supports native API markdown, which is essential for correct formatting. This goes beyond typical descriptions and sufficiently informs the agent of limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely compact, delivering purpose, a critical caveat, and parameter details in just three sentences. Each element earns its place without redundancy, and the structured parameter explanations are easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter mutation tool, the description covers purpose, limitation, parameter sources, and text formatting expectations. Since an output schema exists, there is no need to describe return values, making the description contextually complete for selecting and invoking this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has no property descriptions (0% coverage), so the description is the primary source of parameter meaning. It explains comment_id is obtained from specific sibling tools and text is the replacement text with markdown support. This gives the agent the necessary semantic understanding to populate both parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool edits a comment with the specific action verb 'Edit' and resource 'comment'. It also includes a crucial constraint ('previously created by this integration') that distinguishes it from sibling tools like notion_add_comment, notion_get_comments, and notion_delete_comment.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: the tool is for editing comments created by this integration, with a warning that others will cause a 404. It also tells the user where to find the comment_id (from notion_get_comments or notion_add_comment). However, it does not explicitly list exclusions or alternative tools for updating comments, so it stops short of full prescriptive guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_update_databaseA
Update a Notion database's title, description, or property schema.
database_id: the database to update. title: new database title (leave empty to keep current). description: new description (leave empty to keep current). properties_json: JSON object of property changes. Notion API format:
Add property: {"New Column": {"rich_text": {}}}
Remove property: {"Old Column": null}
Rename property: {"Old Column": {"name": "New Column"}}
Change type: {"Column": {"number": {"format": "percent"}}}
Add select opts: {"Status": {"select": {"options": [ {"name": "New Option", "color": "blue"} ]}}}
Multiple changes can be combined in one call. Use notion_describe_database first to see current schema.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| database_id | Yes | ||
| description | No | ||
| properties_json | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It explains property schema operations in detail (add, remove, rename, change type, add options) and that empty title/description keeps current values. However, it does not disclose potentially destructive effects such as data loss when removing a property or changing its type, which is a significant gap for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized for the complexity, opening with a one-line summary and using structured bullet examples for property changes. Every line adds value, and the formatting makes it easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers prerequisites, parameter semantics, and multiple operation types with examples. It does not explain return values, but an output schema exists, so that burden is reduced. The main gap is the absence of warnings about irreversible or destructive changes, which is important for an update tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 0% schema description coverage, the description fully documents all four parameters inline. It provides detailed syntax and concrete JSON examples for properties_json, covering add, remove, rename, type change, and select options. This far exceeds what the bare schema offers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb and resource: 'Update a Notion database's title, description, or property schema.' This clearly distinguishes it from sibling tools like notion_update_page, notion_update_block, and notion_create_database. The scope is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly instructs to 'Use notion_describe_database first to see current schema,' providing a clear prerequisite. It also states that multiple changes can be combined. While it doesn't name alternatives, the database-specific context makes the intended use apparent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_update_pageA
Update a Notion page's title, icon, or other properties.
page_id: the page to update. title: new title (leave empty to keep current). properties_json: JSON object of properties to update. Keys are property names, values are Notion API property value objects. Omitted properties are left unchanged. icon: emoji for page icon, or "remove" to clear it.
| Name | Required | Description | Default |
|---|---|---|---|
| icon | No | ||
| title | No | ||
| page_id | Yes | ||
| properties_json | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important behavioral details: omitted properties are left unchanged, empty title keeps current, and icon can be set to 'remove' to clear it. These go beyond basic semantics. However, it does not mention error behavior, permission requirements, or side effects like partial failures, and annotations are absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a one-sentence purpose, followed by a clear bullet-like list of parameters. Every sentence earns its place, and there is no redundant or extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all parameters and core behavior, and the output schema likely explains return values. However, it lacks formatting details for properties_json (e.g., the structure of property value objects) and doesn't mention error cases for invalid page_id or JSON, leaving some gaps for first-time users.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description provides detailed, inline documentation for every parameter, adding significant meaning beyond the schema's opaque names. It explains the purpose and valid values (e.g., 'remove' for icon), which is especially valuable given the 0% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool updates a Notion page's title, icon, or properties, using a specific verb and resource. It distinguishes itself from sibling tools like notion_update_block or notion_set_page_visual by specifying exactly what it modifies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives. It does not mention exclusions, prerequisites, or which specific scenario this tool is best suited for. The user must infer usage from the purpose statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_update_page_contentA
Edit page content using search-and-replace on the page's markdown.
Finds old_text in the page content and replaces it with new_text. Use notion_read_page_markdown first to see the current content and copy the exact text to replace.
page_id: the page to edit. old_text: exact text to find in the page content. new_text: replacement text (use empty string to delete).
| Name | Required | Description | Default |
|---|---|---|---|
| page_id | Yes | ||
| new_text | Yes | ||
| old_text | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must disclose behavior itself. It explains the search-and-replace operation and the delete-via-empty-string behavior, but does not specify whether all occurrences or only the first are replaced, case sensitivity, or the behavior when old_text is not found. This ambiguity for a mutation tool is a gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a clear one-line summary, a brief usage workflow, and a compact parameter list. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a simple signature and an output schema, so return values need no explanation. The description covers the core behavior and usage flow, but omits edge cases like multiple occurrences or not-found handling, leaving some ambiguity for a production editing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description adds meaningful semantics for all three parameters: page_id identifies the page, old_text must be exact, and new_text can be empty to delete. This compensates well for the bare schema, though format details are not provided.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the verb 'Edit' with resource 'page content' and the specific method 'search-and-replace', clearly distinguishing it from sibling tools like notion_replace_page_content and notion_append_content. It also explicitly explains the find-replace mechanism.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It instructs users to first use notion_read_page_markdown to view current content and copy exact text, which is a clear usage prerequisite. It does not explicitly exclude alternatives or state when not to use, but the context is clear enough for a targeted edit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_update_viewA
Update a view's name, saved filter, and/or sorts. Only provided fields change (fields left empty are preserved).
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| view_id | Yes | ||
| sorts_json | No | ||
| filter_json | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the transparency burden. It discloses that only provided fields change and empty fields are preserved, preventing accidental overwrites. However, it does not mention permission requirements, behavior on invalid JSON, or any side effects beyond the update itself.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, immediately stating the purpose and the key behavioral rule. No filler or redundant repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core update behavior and partial preservation but leaves a critical gap: it does not explain how to construct the sorts_json and filter_json strings. Given the output schema exists, the return format is covered, but the parameter formats are not.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has no descriptions for its 4 parameters, and the description names three of them (name, filter, sorts) in prose, mapping to name, filter_json, and sorts_json. It also clarifies that empty string values preserve the current setting, which is essential for partial updates. However, the JSON format for sorts_json and filter_json is not explained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (update), the resource (a view), and the specific fields affected (name, saved filter, sorts). This distinguishes it from sibling tools like create_view, delete_view, and query_view.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for modifying existing view settings but does not explicitly reference alternatives or provide when/why guidance. Users must infer from the word 'update' that this is for existing views, not creation or deletion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_upload_fileA
Upload a file to Notion and attach it as a new block.
source accepts one of:
• local:<relative-path> — a file under the notion-mcp private
store (FILES_DIR). List with notion_list_local_files.
• shared:<filename> — a file on the shared cross-MCP mount,
written there by google-accounts-mcp download_attachment with
destination='shared'. List with
notion_list_local_files(location='shared').
• drive:<name-or-id> — a file in the shared Drive folder (DRIVE_FOLDER_NAME)
Google Drive folder (read from google-accounts-mcp's credentials, read-only).
• base64:<bytes> — raw base64 content; requires filename.
Subject to MCP parameter size limits — prefer shared: or drive:
for anything over ~20KB.
parent_page_id is a Notion page ID (find via notion_search_pages) OR any block ID that supports children (toggle, column, callout, ...) to attach the file inside that block.
position controls where the new block lands among the parent's children: 'end' (default), 'start', or a block ID to insert directly AFTER that block (get block IDs from notion_read_page(include_block_ids=True) or notion_list_files_on_page).
filename overrides the source filename when provided. caption is shown below the file block in Notion. Files larger than 20 MB are uploaded via Notion's multi-part protocol automatically. To swap the file in an existing block without moving it, use notion_replace_file instead.
Cross-MCP file transfer
To upload a Gmail attachment to a Notion page:
google-accounts-mcp download_attachment(..., destination='shared')
notion_upload_file(source='shared:', parent_page_id=...) Files never traverse MCP parameters — no size limits.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | ||
| caption | No | ||
| filename | No | ||
| position | No | end | |
| parent_page_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full behavioral burden. It discloses source types, size limits (~20KB parameter limit, >20MB multipart), position behavior, filename override, and the read-only nature of the Drive source. This goes well beyond the basic 'upload' implication and provides substantial operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with bullets and a dedicated cross-MCP workflow section. Most sentences add essential information, though there is minor redundancy (e.g., repeating 'Google Drive folder' and restating that files don't traverse MCP parameters). It is appropriately sized for the tool's complexity, but not as tight as it could be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, absent schema descriptions, and no annotations, the description is remarkably complete. It covers all source alternatives, target placement, positioning, size limits, automatic multipart handling, and a multi-step usage example. An output schema exists, so not explaining return values is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, so the description must compensate for all parameter meaning. It thoroughly explains the source format variants, parent_page_id as a page or block ID, position values ('end', 'start', block ID), filename override, and caption behavior. Every parameter is given practical semantic context far beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the primary action: 'Upload a file to Notion and attach it as a new block.' It defines the resource (file upload into a Notion page/block) and differentiates from the sibling tool by explicitly directing users to notion_replace_file for swapping files in existing blocks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance and alternatives: it names notion_replace_file for existing blocks, explains which source type to prefer for large files, and offers a cross-MCP usage workflow. It also clarifies where parent_page_id can point, covering page vs. block use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notion_upload_file_to_databaseA
Upload a file and create a NEW row in a Notion database with the file attached to the given files & media column.
source: local:<path>, shared:<filename>,
drive:<name-or-id>, or base64:<bytes> — see
notion_upload_file for scheme details and the
cross-MCP handoff pattern.
files_property: exact name of the files & media column
(e.g. "Files & media"). Use notion_describe_database
to confirm the name — it is case-sensitive.
title: text value for the row's title column.
title_property: override the auto-detected title column name.
filename: override the source filename.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| source | Yes | ||
| filename | No | ||
| database_id | Yes | ||
| files_property | Yes | ||
| title_property | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description is the sole source of behavioral context. It adds useful details about accepted source schemes, case-sensitivity of the files_property, and the need to verify column names with notion_describe_database. However, it does not disclose failure modes, idempotency, permissions, or side effects beyond creating a row, leaving some gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description starts with a clear one-sentence purpose and then lists parameters in a structured, scannable format. It is concise (about 120 words) with no filler, and each line adds essential information. The only minor issue is that it could be slightly tighter in wording, but it remains effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter create-operation tool, the description covers the main workflow, required inputs, and source scheme details, and it references the cross-MCP handoff pattern. It does not discuss return values or edge cases, but an output schema exists to cover return format. The description is sufficiently complete for accurate invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description provides rich semantic detail for most parameters: source scheme syntax, files_property case-sensitivity and verification, title behavior, and override purposes. This goes well beyond the bare schema and compensates for the 0% schema description coverage. Even database_id is self-evident from the tool name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: uploading a file and creating a new row in a Notion database with the file attached to a specified files & media column. It uses a specific verb ('upload') and resource ('database row'), and explicitly says 'NEW row' to distinguish from tools like notion_add_file_to_row that add files to existing rows.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for creating a new row with a file attachment, while siblings like notion_add_file_to_row serve existing rows. It references notion_upload_file for source scheme details, which guides the user on prerequisite knowledge, but it does not explicitly say when not to use this tool or name alternatives. The purpose is clear enough for the agent to select correctly in most cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
44 tool updates
v0.1.0- First observed
notion_add_comment - First observed
notion_add_file_to_row - First observed
notion_append_content - First observed
notion_archive_page - First observed
notion_batch_add_file_to_row - First observed
notion_create_database - First observed
notion_create_page - First observed
notion_create_view - First observed
notion_delete_block - First observed
notion_delete_comment - First observed
notion_delete_view - First observed
notion_describe_database - First observed
notion_download_file - First observed
notion_extract_file_text - First observed
notion_get_comments - First observed
notion_get_property - First observed
notion_get_user - First observed
notion_import_file_from_url - First observed
notion_list_files_on_page - First observed
notion_list_local_files - First observed
notion_list_users - First observed
notion_list_views - First observed
notion_move_page - First observed
notion_purge_file - First observed
notion_purge_shared_files - First observed
notion_query_database - First observed
notion_query_view - First observed
notion_read_page - First observed
notion_read_page_markdown - First observed
notion_render_file_page - First observed
notion_replace_file - First observed
notion_replace_page_content - First observed
notion_restore_page - First observed
notion_search_databases - First observed
notion_search_pages - First observed
notion_set_page_visual - First observed
notion_update_block - First observed
notion_update_comment - First observed
notion_update_database - First observed
notion_update_page - First observed
notion_update_page_content - First observed
notion_update_view - First observed
notion_upload_file - First observed
notion_upload_file_to_database
TDQS
Scored across 44 tools
Most tools target a distinct Notion resource/action, but a few close pairs (e.g., notion_read_page vs notion_read_page_markdown, notion_update_page vs notion_update_page_content vs notion_replace_page_content) could cause misselection without careful reading of descriptions. Overall, descriptions are detailed enough to disambiguate, so the overlap is manageable.
All tools share the 'notion_' prefix and generally follow verb_noun naming, but the verbs are inconsistent across similar actions (add vs upload, get vs read/list/query, update vs replace/append). This inconsistency creates some friction, though the pattern is still predictable overall.
44 tools is far beyond the typical well-scoped range and feels heavy for a single server, even for a broad API like Notion. Several tools could be consolidated (e.g., three ways to modify page content, multiple file-purge variants), and the sheer number increases cognitive load and misselection risk.
The tool set provides thorough coverage of Notion's core surface: CRUD for pages, databases, blocks, comments, views, and users, plus rich file operations (upload, download, replace, extract, render, batch attach). There are few obvious gaps—the domain appears fully supported for common workflows.
Maintenance
Related MCP Connectors
MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.
A MCP server built for developers enabling Git based project management with project and personal…
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
Related MCP Servers
- -licenseNot gradedqualityNot gradedmaintenanceAn MCP server that enables natural language interaction with the Notion API, allowing users to search, comment, create pages, and access content within their Notion workspace.122,532 npm-
- AlicenseCqualityDmaintenanceAn MCP server that converts Markdown content to Notion API-compatible formats, suitable for content management and development integration.11Apache 2.0
- AlicenseAqualityCmaintenanceAn MCP server for Notion API with optimized token efficiency and full database property filtering, enabling AI assistants to manage pages, databases, and blocks.3210 npm1MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for the Notion API, enabling management of pages, blocks, databases, data sources, comments, and users through natural language.4 npm3MIT