Notion MCP server tool surface audit

B86/100composite score
Token footprint
~17,476
Tools
24
Findings
95
Scanned

Engine mcp-surface-lint@0.3.3 · reported as Notion API v1.0.0

The Notion MCP server exposes 24 tools whose definitions cost approximately 17,476 tokens in every single conversation, whether or not any of them is ever called. Against the 19 static rules in the catalogue it scores 86 out of 100 — grade B — raising 95 scored findings in 3 of the six categories.

Its strongest category is naming at 100/100; the weakest is schemas at 68/100. It is catalogued here under Productivity and Docs, alongside other servers agents reach for in the same kind of work.

Token footprint

At 17,476 tokens the surface takes about 9% of a 200,000-token context window, and it takes it on every turn — this is rent, not a one-off cost. That averages 728 tokens per tool definition, counted with the o200k_base encoding.

Against a category median of 2,360 tokens, this surface runs about 641% above the middle of the pack.

surface70
naming100
descriptions100
schemas68
annotations100
design75

Findings

The findings below are grouped by severity, and each links to the rule that produced it.

`schemas/loose` accounts for 40 findings. Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes. On this surface it fires on `API-get-self`, `API-post-search` and `API-patch-block-children`, among 8 others.

37 findings come from `schemas/param-desc-missing`. Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes. On this surface it fires on `API-get-user`, `API-post-search` and `API-update-a-block`, among 9 others.

`schemas/complexity-budget` contributes 8 findings. Deeply nested inputs, very wide property lists, and stacked oneOf/anyOf force the model to solve a constraint puzzle before every call. Flatter, narrower inputs get filled correctly more often. On this surface it fires on `API-patch-page`, `API-post-page` and `API-create-a-comment`, among 4 others.

Notion's surface raises 4 further rules — `design/overlap-cluster`, `design/enum-in-prose`, `surface/token-budget` and `surface/tool-budget` — listed in full below.

warn 95 findings

Findings that measurably degrade tool selection.

design/enum-in-proseAPI-post-search
Parameter "direction" enumerates its values in prose but declares no enum.

Values enumerated in prose ('one of: a, b, c') are invisible to schema validation: the model can misspell them and the server only finds out at call time. If the value set is closed, encode it as an enum.

The direction to sort. Possible values include `ascending` and `descending`.

design/enum-in-proseAPI-post-search
Parameter "timestamp" enumerates its values in prose but declares no enum.

Values enumerated in prose ('one of: a, b, c') are invisible to schema validation: the model can misspell them and the server only finds out at call time. If the value set is closed, encode it as an enum.

The name of the timestamp to sort against. Possible values include `last_edited_time`.

design/enum-in-proseAPI-post-search
Parameter "property" enumerates its values in prose but declares no enum.

Values enumerated in prose ('one of: a, b, c') are invisible to schema validation: the model can misspell them and the server only finds out at call time. If the value set is closed, encode it as an enum.

The name of the property to filter by. Currently the only property you can filter by is the object type. Possible values include `object`. Limitation: Currently the only filter allowed is `object` which will filter by type of object (either `page` or `data_source`)

4 tools share the name prefix "api_get" — likely one tool with include-flags or a mode parameter.

Tools whose descriptions substantially overlap force the model to pick between near-synonyms — the classic cause of wrong-tool calls. Clusters are usually one tool wearing several names; consolidate with include-flags or a mode parameter.

API-get-user, API-get-users, API-get-self, API-get-block-children

7 tools share the name prefix "api_retrieve" — likely one tool with include-flags or a mode parameter.

Tools whose descriptions substantially overlap force the model to pick between near-synonyms — the classic cause of wrong-tool calls. Clusters are usually one tool wearing several names; consolidate with include-flags or a mode parameter.

API-retrieve-a-block, API-retrieve-a-page, API-retrieve-a-page-property, API-retrieve-a-comment, API-retrieve-a-data-source, API-retrieve-a-database, API-retrieve-page-markdown

3 tools share the name prefix "api_update" — likely one tool with include-flags or a mode parameter.

Tools whose descriptions substantially overlap force the model to pick between near-synonyms — the classic cause of wrong-tool calls. Clusters are usually one tool wearing several names; consolidate with include-flags or a mode parameter.

API-update-a-block, API-update-a-data-source, API-update-page-markdown

21 tools have overlapping descriptions (trigram Jaccard up to 0.85) — consolidation candidates.

Tools whose descriptions substantially overlap force the model to pick between near-synonyms — the classic cause of wrong-tool calls. Clusters are usually one tool wearing several names; consolidate with include-flags or a mode parameter.

API-get-user, API-get-self, API-post-search, API-get-block-children, API-patch-block-children, API-retrieve-a-block, API-update-a-block, API-delete-a-block, API-retrieve-a-page, API-patch-page, API-post-page, API-retrieve-a-page-property, API-retrieve-a-comment, API-create-a-comment, API-query-data-source, API-retrieve-a-data-source, API-update-a-data-source, API-create-a-data-source, API-list-data-source-templates, API-retrieve-a-database, API-move-page

2 tools have overlapping descriptions (trigram Jaccard up to 0.80) — consolidation candidates.

Tools whose descriptions substantially overlap force the model to pick between near-synonyms — the classic cause of wrong-tool calls. Clusters are usually one tool wearing several names; consolidate with include-flags or a mode parameter.

API-retrieve-page-markdown, API-update-page-markdown

Input schema uses oneOf/anyOf 3 times (budget 2).

Deeply nested inputs, very wide property lists, and stacked oneOf/anyOf force the model to solve a constraint puzzle before every call. Flatter, narrower inputs get filled correctly more often.

Input schema uses oneOf/anyOf 3 times (budget 2).

Deeply nested inputs, very wide property lists, and stacked oneOf/anyOf force the model to solve a constraint puzzle before every call. Flatter, narrower inputs get filled correctly more often.

schemas/complexity-budgetAPI-create-a-comment
Input schema nests 4 levels deep (budget 3).

Deeply nested inputs, very wide property lists, and stacked oneOf/anyOf force the model to solve a constraint puzzle before every call. Flatter, narrower inputs get filled correctly more often.

schemas/complexity-budgetAPI-query-data-source
Input schema uses oneOf/anyOf 3 times (budget 2).

Deeply nested inputs, very wide property lists, and stacked oneOf/anyOf force the model to solve a constraint puzzle before every call. Flatter, narrower inputs get filled correctly more often.

schemas/complexity-budgetAPI-update-a-data-source
Input schema uses oneOf/anyOf 3 times (budget 2).

Deeply nested inputs, very wide property lists, and stacked oneOf/anyOf force the model to solve a constraint puzzle before every call. Flatter, narrower inputs get filled correctly more often.

schemas/complexity-budgetAPI-create-a-data-source
Input schema uses oneOf/anyOf 3 times (budget 2).

Deeply nested inputs, very wide property lists, and stacked oneOf/anyOf force the model to solve a constraint puzzle before every call. Flatter, narrower inputs get filled correctly more often.

schemas/complexity-budgetAPI-update-page-markdown
Input schema nests 4 levels deep (budget 3).

Deeply nested inputs, very wide property lists, and stacked oneOf/anyOf force the model to solve a constraint puzzle before every call. Flatter, narrower inputs get filled correctly more often.

schemas/complexity-budgetAPI-update-page-markdown
Input schema uses oneOf/anyOf 4 times (budget 2).

Deeply nested inputs, very wide property lists, and stacked oneOf/anyOf force the model to solve a constraint puzzle before every call. Flatter, narrower inputs get filled correctly more often.

schemas/looseAPI-get-self
Bare "type: object" with no properties at /inputSchema — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-post-search
"additionalProperties: true" at /inputSchema/properties/sort/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-post-search
"additionalProperties: true" at /inputSchema/properties/filter/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-patch-block-children
Bare "type: object" with no properties at /inputSchema/properties/children/items/anyOf/2 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-patch-block-children
"additionalProperties: true" at /inputSchema/properties/children/items/anyOf/2 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-a-block
Bare "type: object" with no properties at /inputSchema/properties/type/anyOf/0 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-a-block
"additionalProperties: true" at /inputSchema/properties/type/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-patch-page
Bare "type: object" with no properties at /inputSchema/properties/properties/anyOf/0 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-patch-page
"additionalProperties: true" at /inputSchema/properties/properties/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-post-page
Bare "type: object" with no properties at /inputSchema/properties/properties/anyOf/0 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-post-page
"additionalProperties: true" at /inputSchema/properties/properties/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-post-page
Bare "type: object" with no properties at /inputSchema/properties/children/items/anyOf/2 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-post-page
"additionalProperties: true" at /inputSchema/properties/children/items/anyOf/2 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-create-a-comment
"additionalProperties: true" at /inputSchema/properties/parent/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-create-a-comment
"additionalProperties: true" at /inputSchema/properties/rich_text/items/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-create-a-comment
"additionalProperties: true" at /inputSchema/properties/rich_text/items/anyOf/0/properties/text — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-create-a-comment
Bare "type: object" with no properties at /inputSchema/properties/rich_text/items/anyOf/2 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-create-a-comment
"additionalProperties: true" at /inputSchema/properties/rich_text/items/anyOf/2 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-query-data-source
Bare "type: object" with no properties at /inputSchema/properties/filter_properties/items/anyOf/2 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-query-data-source
"additionalProperties: true" at /inputSchema/properties/filter_properties/items/anyOf/2 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-query-data-source
Bare "type: object" with no properties at /inputSchema/properties/filter/anyOf/0 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-query-data-source
"additionalProperties: true" at /inputSchema/properties/filter/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-query-data-source
Bare "type: object" with no properties at /inputSchema/properties/sorts/items/anyOf/2 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-query-data-source
"additionalProperties: true" at /inputSchema/properties/sorts/items/anyOf/2 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-a-data-source
Bare "type: object" with no properties at /inputSchema/properties/title/items/anyOf/2 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-a-data-source
"additionalProperties: true" at /inputSchema/properties/title/items/anyOf/2 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-a-data-source
Bare "type: object" with no properties at /inputSchema/properties/description/items/anyOf/2 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-a-data-source
"additionalProperties: true" at /inputSchema/properties/description/items/anyOf/2 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-a-data-source
Bare "type: object" with no properties at /inputSchema/properties/properties/anyOf/0 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-a-data-source
"additionalProperties: true" at /inputSchema/properties/properties/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-create-a-data-source
Bare "type: object" with no properties at /inputSchema/properties/properties/anyOf/0 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-create-a-data-source
"additionalProperties: true" at /inputSchema/properties/properties/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-create-a-data-source
Bare "type: object" with no properties at /inputSchema/properties/title/items/anyOf/2 — the model has nothing to go on.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-create-a-data-source
"additionalProperties: true" at /inputSchema/properties/title/items/anyOf/2 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-page-markdown
"additionalProperties: true" at /inputSchema/properties/replace_content/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-page-markdown
"additionalProperties: true" at /inputSchema/properties/update_content/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-page-markdown
"additionalProperties: true" at /inputSchema/properties/update_content/anyOf/0/properties/content_updates/items — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-page-markdown
"additionalProperties: true" at /inputSchema/properties/insert_content/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-page-markdown
"additionalProperties: true" at /inputSchema/properties/insert_content/anyOf/0/properties/position — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

schemas/looseAPI-update-page-markdown
"additionalProperties: true" at /inputSchema/properties/replace_content_range/anyOf/0 — accepts arbitrary keys silently.

Loose schemas (bare objects, untyped arrays, open additionalProperties) turn schema validation off exactly where the model is most likely to hallucinate argument shapes.

Parameter "user_id" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "sort" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "filter" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-update-a-block
Parameter "type" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "properties" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "archived" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "icon" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "cover" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "emoji" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "external" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "type" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "url" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "parent" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "properties" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-create-a-comment
Parameter "parent" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-create-a-comment
Parameter "rich_text" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-create-a-comment
Parameter "text" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-query-data-source
Parameter "filter" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-query-data-source
Parameter "sorts" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-query-data-source
Parameter "start_cursor" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-query-data-source
Parameter "page_size" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-query-data-source
Parameter "archived" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-query-data-source
Parameter "in_trash" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-update-a-data-source
Parameter "title" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-update-a-data-source
Parameter "description" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-update-a-data-source
Parameter "properties" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-create-a-data-source
Parameter "parent" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-create-a-data-source
Parameter "properties" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-create-a-data-source
Parameter "title" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-list-data-source-templates
Parameter "start_cursor" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-list-data-source-templates
Parameter "page_size" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

Parameter "parent" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-update-page-markdown
Parameter "replace_content" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-update-page-markdown
Parameter "update_content" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-update-page-markdown
Parameter "insert_content" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-update-page-markdown
Parameter "replace_content_range" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

schemas/param-desc-missingAPI-update-page-markdown
Parameter "type" has no description.

Undescribed parameters get filled by guesswork. Every property the model must populate deserves a sentence saying what it means and what shape it takes.

tools/list footprint is ~17476 tokens (o200k_base, approximate) — above the 10000-token budget. Every conversation pays this before the first user message.

The serialized tools/list payload is injected into every conversation that connects the server, before any work happens. Its token cost is a per-message tax.

Server exposes 24 tools (warn threshold 20 exceeded). Consider consolidating into fewer intent-shaped tools.

Tool selection accuracy degrades as the surface grows: more near-neighbours to confuse, more tokens spent before the first user message. Fewer, intent-shaped tools outperform one-tool-per-endpoint surfaces.

What this surface does well

3 of the six categories come through clean: naming, descriptions and annotations. In practice that means the tool names follow one convention end to end, every tool carries a description long enough to disambiguate it and read and write operations are machine-distinguishable before a client runs them.

Tool inventory

The heaviest definition is `API-update-page-markdown` at 1,281 tokens, roughly 7% of the total; the lightest, `API-get-self`, costs 594. Every tool carries a description, ranging from 49 to 280 characters.

All 24 declare annotations, so a client can tell a read from a write before running one. Input schemas average 3 top-level parameters and nest 4 levels deep at their worst, with 1 tool taking no input at all.

All 24 tools as published, heaviest first. Token counts use the o200k_base encoding and are approximate.

Every tool on this surface with its token cost and schema shape.
ToolTokensDescriptionParamsRequiredDepthAnnotations
API-update-page-markdown1,281280 chars624yes
API-post-search1,09658 chars502yes
API-patch-page88865 chars613yes
API-post-page81856 chars522yes
API-query-data-source76962 chars812yes
API-update-a-block72657 chars311yes
API-create-a-comment72457 chars224yes
API-update-a-data-source72063 chars412yes
API-patch-block-children71264 chars322yes
API-retrieve-page-markdown705231 chars211yes
API-retrieve-a-page-property70372 chars421yes
API-get-block-children69266 chars311yes
API-create-a-data-source68763 chars322yes
API-retrieve-a-comment68660 chars311yes
API-retrieve-a-page67958 chars211yes
API-get-users66249 chars201yes
API-move-page64054 chars221yes
API-list-data-source-templates63974 chars311yes
API-retrieve-a-data-source61765 chars111yes
API-retrieve-a-database61262 chars111yes
API-retrieve-a-block61159 chars111yes
API-delete-a-block61057 chars111yes
API-get-user60350 chars111yes
API-get-self59473 chars000yes

How this compares

Notion ranks 3 of 3 scanned Productivity and Docs servers, 10 points below the category median of 96.

The closest comparisons in this directory are Memory, Microsoft Learn and MongoDB, which sit nearest on score and face the same kind of surface-design pressure.

Category
Productivity and Docs
Rank in category
3
Category median score
96
Category median tokens
2,360
Want this surface fixed, not just measured?

A fix plan turns these findings into an ordered set of changes with the token saving of each one.

Get a fix plan

This page is a static analysis of Notion's published tools/list surface on the date shown. It is not a security review, a performance benchmark, or a judgement of the product behind the surface. Read how the score is computed, or browse every audited server.