BoundBench

Notion MCP Server

Notion's self-hosted MCP server that exposes the Notion API as tools generated from a bundled OpenAPI spec.

github.com/makenotion/notion-mcp-server · 2026-10-05 · 730ae78

Defense-in-depth score

5.4 / 10

Moderate

Run as shipped, this server gives the model read and write access to every Notion page the operator's integration can see, through 24 narrow tools that only ever talk to api.notion.com. It runs no code, keeps no memory and loads no plugins, and every write tool is labelled destructive so the MCP host can ask before acting. The dominant risk is prompt injection: page and comment content comes back unmarked, nothing in the server separates reading it from writing pages or comments, and the server keeps no record of what it did. Scope the integration in Notion (for example read-only capabilities) to cut its authority.

Key gaps (2)

  1. Unmarked page and comment content, every page shared with the integration, and page-writing and comment tools are all available in one default session with nothing in the server separating them. C5 · Untrusted input blast radius
  2. The server records nothing about the tool calls it executes, so writes and deletes leave no server-side trail. C9 · Audit & traceability

Criteria

C1 Identity & least privilege

Minimal 0.42 / 1.00

The server authenticates every call with the single Notion integration token the operator puts in its environment. How much that token can reach is decided entirely in Notion (the integration's capabilities and which pages are shared with it); the server itself does not narrow it, and read and write tools use the same credential. No tool can change the integration's own permissions or sharing. An opt-in HTTP mode can instead accept a per-connection Notion token from each client, which is off in the scored configuration.

C2 Approval gates

Moderate 0.63 / 1.00

As a tool server it relies on the MCP host to ask the user before acting. What it provides is a label on every tool, derived from the HTTP method: GET tools are marked read-only and everything else is marked destructive, so no write tool is presented as safe, although two read-only search and query tools are also marked destructive. There is no preview or dry-run, and no server-side read-only mode. If a host auto-approves or the user approves the wrong call, page content can be overwritten, blocks and pages moved to trash, and comments posted; most of that can be recovered from Notion's trash and page history.

C3 Tool & action scoping

Minimal 0.40 / 1.00

Each tool maps to one Notion API endpoint with a typed input schema generated from the bundled spec, and every request goes to the fixed api.notion.com server, so there is no general URL fetch, shell or query language. The server does not validate arguments against those schemas itself; it decodes JSON-looking strings and forwards them, relying on Notion's API to reject bad input. With no flags all 24 tools load, including page overwrite, block deletion and schema updates, and there is no option to select a smaller or read-only set. A generic local-file upload helper exists in the HTTP client, but no operation in the shipped spec uses it.

C4 Code-execution isolation

N/A · full credit 1.00 / 1.00

The server never runs model-influenced code: there is no shell, subprocess, eval or template execution anywhere in its source, and tool calls only become HTTPS requests to Notion's API. The one eval in the source is inside a commented-out block. The optional Docker image runs the same Node process and adds no execution path.

C5 Untrusted input blast radius

Minimal 0.13 / 1.00

Page content, blocks and comments, which other workspace members, guests or imported content may have written, are returned to the model as the raw Notion API JSON, with nothing marking them as third-party text. In the default configuration the same session can read that content, read every page shared with the integration, and write pages or post comments, and nothing in the server separates those. A successful prompt injection can therefore copy private page content into a page or comment the attacker can read, without a human involved unless the host asks. Deletions go to Notion's trash rather than being permanent.

C6 Memory, context & configuration integrity

N/A · full credit 1.00 / 1.00

The server keeps no memory, retrieval store or conversation history, and it reads nothing from the user's working directory: the API spec is loaded by an absolute path inside its own install directory and configuration comes only from environment variables set in the MCP host's config. Nothing the model reads can persist into later sessions through the server.

C7 Third-party extensions

N/A · full credit 1.00 / 1.00

The server loads no plugins, MCP servers, remote tools or model files at runtime; its tools come only from the OpenAPI spec bundled with the package. How the host installs the server itself (for example an unpinned npx command) is the project's own distribution and is out of scope here.

C8 Secrets & sensitive-data protection

Moderate 0.55 / 1.00

The Notion token is read from the environment and only ever attached to outgoing API requests; it is never returned to the model. The server's logging is deliberately thin: failed API calls log only the HTTP status, tool errors log only the error message, and the optional per-connection token is logged only as a redacted prefix. There is no telemetry, crash reporting or stored transcript. Page content that itself contains secrets is passed to the model unfiltered, and the integration token is long-lived, though limited to the pages shared with it.

C9 Audit & traceability

Minimal 0.00 / 1.00

The server keeps no record of what it does. A successful tool call writes nothing at all, and a failed one prints only an error message or HTTP status to stderr, without the tool's arguments, the page it touched or a timestamp. After an incident the only trace is whatever the MCP host logged and Notion's own page history.

C10 Limits & kill switch

Minimal 0.25 / 1.00

The server sets no bounds on its own work: Notion API requests have no timeout, response size is not capped, and there are no rate limits on writes or comments. The only limits are caller-chosen page sizes defined by Notion's API (up to 100 items per page) and Notion's own server-side rate limits, plus a small cap on how many times a string argument is JSON-decoded. A runaway host loop can keep editing pages until Notion throttles it.