Notion Workspace
Productivity
Puts a Notion workspace behind an MCP endpoint: an agent can search it, read a page, query a database, and append blocks — without ever holding your integration token.
What you get
notion.search— full-text search across everything the integration has been shared with.notion.page.get— one page's properties by id.notion.db.query— a filter-and-sort against a Notion database.notion.block.append— the one write, and it only appends.notion://page/{page_id}— the same page as an MCP resource, for clients that prefer to attach rather than call.
Every binding sits at the verified trust floor, so a caller whose identity is merely asserted in a header sees an empty tools/list rather than a permission error.
What you need
- Notion integration token — an internal integration's secret, from Settings → Connections. Notion grants access per page, so share each page or database you want reachable with that integration; anything you do not share is invisible to these tools, which is the containment you want.
- JWKS endpoint — the host where your identity provider publishes its signing keys, without a scheme. A managed gateway answers on the public internet, so it verifies a bearer token on every call.
- Token audience — the
audclaim your callers' tokens carry. - Notion API version — optional; it is already set to the version these bindings were written against.
How it works
Notion authenticates with a bearer token that is equivalent to whatever the integration can reach. That token belongs in the config, not in a prompt and not in an argument, so every binding sets the Authorization header itself and the caller has no way to supply, read or override it.
On a managed gateway the token becomes a dev.mcpg.credential.static target and is resolved per request. Running it yourself, the same value is written as ${env.NOTION_TOKEN} and never enters the file at all.
The write tool is deliberately narrow. notion.block.append adds children to a page; there is no update and no delete binding, so the worst an agent can do to your workspace is add to it.
Notes
Notion-Version is pinned on every request. Notion keeps old versions working indefinitely, and an unpinned client is one that changes behaviour on a day nobody deployed anything.
notion.db.query takes the caller's filter object verbatim but never the database id from anywhere but its own argument — a filter cannot widen the query to a database the integration was not shared with.