Verified MCP server: Notion

The Notion MCP server, its live tool list captured on a real Mac.

  • Tools enumerated2026-08-03macOS 14.4.1
  • Package@notionhq/notion-mcp-server 2.5.1
  • Self-reportedNotion API 1.0.0
  • MCP protocol2025-06-18
  • Runtimev25.8.1

The tool list below is a live capture from the running server; an authenticated tool call is still pending credentials.

The short answer

Last verified 2026-08-03

The Notion MCP server is Notion's own bridge between an AI assistant and your workspace: search, read pages as Markdown, edit them, query databases, and leave comments, all through the Notion API. It runs on your Mac over stdio and it needs one credential, an internal integration secret you create yourself. We ran it and kept the raw output. The interesting part is what happened without a token: the server started, spoke the protocol, and listed all 24 tools before it ever asked for a credential. Only the first real call came back with Notion's 401, and that reply is printed further down. Notion also runs a hosted version at mcp.notion.com that uses OAuth instead of a pasted token, and it now recommends that one; both configs are on this page. [1][3][5][6]

  • Tools

    24, enumerated live

  • Credentials

    Notion integration secret [5]

  • Transport

    stdio, runs on your Mac [5]

  • Maintainer

    Notion Labs (makenotion) [1][3]

  • Downloads

    209k last week [2]

  • License

    MIT [4]

Verification

How this MCP server was verified.

Method

We spawned the server with npx over stdio with no environment variables set at all: no NOTION_TOKEN, no OPENAPI_MCP_HEADERS. It started anyway, completed the MCP initialize handshake, and answered tools/list with 24 tools. The tool table below is that capture, word for word. We then ran one read-only call, API-post-search, and the server passed it to Notion and returned the real reply: a 401 saying the API token is invalid, which is printed below exactly as it came back. A tool call that actually reaches a workspace is still pending credentials, so this page carries the enumerated badge and not the verified one. The server prints nothing to stderr on startup, so the banner below is the raw initialize response it wrote on the wire.

Startup banner

{"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{}},"serverInfo":{"name":"Notion API","version":"1.0.0"}},"jsonrpc":"2.0","id":1}

One real tool call

tools/call API-post-search {"query": "Getting started", "page_size": 1}
{"status":401,"object":"error","code":"unauthorized","message":"API token is invalid.","request_id":"ede4937b-fa79-4222-8515-b404299d6f82"}

Real lines from the captured result: enough to prove the call answered.

Tools

Every tool, enumerated from the running server.

The server answered tools/list with 24 tools on 2026-08-03. The names, descriptions and parameters below are its own words, copied from that response and never edited.

ToolWhat it does
API-get-useruser_id*

Notion | Retrieve a user Error Responses: 400: 400

API-get-usersstart_cursorpage_size

Notion | List all users Error Responses: 400: 400

API-get-self

Notion | Retrieve your token's bot user Error Responses: 400: Bad request

API-post-searchquerysortfilterstart_cursorpage_size

Notion | Search by title Error Responses: 400: Bad request

API-get-block-childrenblock_id*start_cursorpage_size

Notion | Retrieve block children Error Responses: 400: Bad request

API-patch-block-childrenblock_id*children*after

Notion | Append block children Error Responses: 400: Bad request

API-retrieve-a-blockblock_id*

Notion | Retrieve a block Error Responses: 400: Bad request

API-update-a-blockblock_id*typearchived

Notion | Update a block Error Responses: 400: Bad request

API-delete-a-blockblock_id*

Notion | Delete a block Error Responses: 400: Bad request

API-retrieve-a-pagepage_id*filter_properties

Notion | Retrieve a page Error Responses: 400: Bad request

API-patch-pagepage_id*propertiesin_trasharchivediconcover

Notion | Update page properties Error Responses: 400: Bad request

API-post-pageparent*properties*childreniconcover

Notion | Create a page Error Responses: 400: Bad request

API-retrieve-a-page-propertypage_id*property_id*page_sizestart_cursor

Notion | Retrieve a page property item Error Responses: 400: Bad request

API-retrieve-a-commentblock_id*start_cursorpage_size

Notion | Retrieve comments Error Responses: 400: Bad request

API-create-a-commentparent*rich_text*

Notion | Create comment Error Responses: 400: Bad request

API-query-data-sourcedata_source_id*filter_propertiesfiltersortsstart_cursorpage_sizearchivedin_trash

Notion | Query a data source Error Responses: 400: Bad request

API-retrieve-a-data-sourcedata_source_id*

Notion | Retrieve a data source Error Responses: 400: Bad request

API-update-a-data-sourcedata_source_id*titledescriptionproperties

Notion | Update a data source Error Responses: 400: Bad request

API-create-a-data-sourceparent*properties*title

Notion | Create a data source Error Responses: 400: Bad request

API-list-data-source-templatesdata_source_id*start_cursorpage_size

Notion | List templates in a data source Error Responses: 400: Bad request

API-retrieve-a-databasedatabase_id*

Notion | Retrieve a database Error Responses: 400: Bad request

API-move-pagepage_id*parent*

Notion | Move a page Error Responses: 400: Bad request

API-retrieve-page-markdownpage_id*include_transcript

Notion | Retrieve a page as Markdown Error Responses: 400: Bad request 403: The integration lacks the read/update content capability required for this page. 404: Page not found or not shared with the integration. 429: Rate limited.

API-update-page-markdownpage_id*type*replace_contentupdate_contentinsert_contentreplace_content_range

Notion | Update a page's content as Markdown Error Responses: 400: Bad request 403: The integration lacks the read/update content capability required for this page. 404: Page not found or not shared with the integration. 409: Conflict (e.g. row limit exceeded). 429: Rate limited.

Parameters marked with * are required.

Setup

Working configs, one per app.

Copy the block for the app you use. Each one is the configuration this server was verified with.

Claude Desktop

Open the file ~/Library/Application Support/Claude/claude_desktop_config.json (in Claude Desktop: Settings, then Developer, then Edit Config) and add:

{
  "mcpServers": {
    "notion": {
      "command": "npx",
      "args": [
        "-y",
        "@notionhq/notion-mcp-server"
      ],
      "env": {
        "NOTION_TOKEN": "ntn_your_integration_secret"
      }
    }
  }
}

Replace the placeholder with the secret from your own integration, then quit and reopen Claude Desktop. If you would rather not paste a token, Notion's hosted server is added under Settings, then Connectors, using the address https://mcp.notion.com/mcp and an OAuth sign-in. [7][5][6]

Claude Code

One command in your terminal:

claude mcp add --env NOTION_TOKEN=ntn_your_integration_secret --transport stdio notion -- npx -y @notionhq/notion-mcp-server

Everything after the double dash is the exact command Claude Code will run. For the hosted server instead, Notion documents claude mcp add --transport http notion https://mcp.notion.com/mcp, then run /mcp to finish the OAuth sign-in. [8][6]

Cursor

Add to ~/.cursor/mcp.json for every project, or to .cursor/mcp.json inside one project:

{
  "mcpServers": {
    "notion": {
      "command": "npx",
      "args": [
        "-y",
        "@notionhq/notion-mcp-server"
      ],
      "env": {
        "NOTION_TOKEN": "ntn_your_integration_secret"
      }
    }
  }
}

Cursor picks the file up on restart. The hosted server uses the same file with a single url line, {"url": "https://mcp.notion.com/mcp"}, and signs you in with OAuth on first use. [9][6]

Routines

No JSON file and no terminal. In Routines: Settings, then Assistant, then Connections, then Add MCP Server. Switch the form to Command (stdio) and enter:

Name                   Notion
Command                npx
Arguments              -y @notionhq/notion-mcp-server
Environment Variables  NOTION_TOKEN = ntn_your_integration_secret

The Arguments field splits on spaces, so leave it exactly as shown. Put the secret in Environment Variables, not in Arguments. Click Test Connection first: a working server answers with its tool count, twenty-four for this one. [10]

No terminal needed

Set the Notion MCP server up without the terminal.

If you have never opened Terminal and never want to, this is your path. Routines is a Mac app that runs MCP servers for you: fill in four fields once, and this server's tools are available to your AI in chat and in scheduled routines. The only preparation happens inside Notion, and it takes about two minutes.

  1. 01

    Create the integration in Notion

    Go to notion.so/profile/integrations and create a new internal integration. Copy the secret it shows you: it starts with ntn_. On the Configuration tab you can tick Read content only, which gives you a token that can look but never write.

  2. 02

    Share the pages you want it to see

    An integration starts with access to nothing. In the integration settings, open the Access tab and pick the pages and databases it may use. Anything you do not share stays invisible to the server.

  3. 03

    Install Routines and open the MCP settings

    Download the app from getroutines.ai/download, drag it to Applications, and sign in. Click your account at the bottom of the sidebar and choose Settings. Open the Assistant section, then the Connections tab, scroll to MCP Servers, and click Add MCP Server.

  4. 04

    Choose Command (stdio)

    The form opens in URL (SSE/HTTP) mode. Switch it to Command (stdio): this server is a command, not a web address. Name: Notion. Command: npx. Arguments: -y @notionhq/notion-mcp-server, with nothing after it.

  5. 05

    Paste the secret as an environment variable

    In Environment Variables add one entry, NOTION_TOKEN, with the ntn_ secret as its value. Do not put it in Arguments: that field splits on spaces and is not the place for a credential.

  6. 06

    Test, add, then use it

    Click Test Connection: Routines starts the server and reports how many tools it found, twenty-four for this one. Then click Add Server. The tools work in chat right away. To let a scheduled routine use them, open the routine, find the Tools & connections card, and tick the server under Apps.

Routine ideas

Routines worth scheduling.

Once the server is connected, a scheduled routine can use its tools while you are away. Copy a prompt, paste it into Routines, and pick a time.

A Monday standup brief

Prompt

Every Monday at 8:30, search my Notion workspace for pages updated in the last seven days, group them by project, and write me a short standup brief with one line per project and anything that looks blocked.

A stale-page sweep

Prompt

Every first day of the month at 9:00, query my Notion project database for pages with a status of In progress that have not been edited in 30 days, and list them with their owner and last edited date so I can chase or close them.

A meeting notes filer

Prompt

Every weekday at 19:00, read today's meeting notes from my Notion Meetings database, pull out every decision and action item, and append them as a dated section to my Notion page called Running Log.

Troubleshooting

The errors we hit, and what fixed them.

Real errors captured during the verification run, printed exactly as the server returned them.

The tool list looks fine but every call comes back unauthorized

What you see

{"status":401,"object":"error","code":"unauthorized","message":"API token is invalid.","request_id":"ede4937b-fa79-4222-8515-b404299d6f82"}

The fix

This is the exact reply we captured with no token set. The server does not check your credential at startup: it starts, lists all 24 tools, and only fails when a tool call reaches Notion. So a green connection test proves nothing about the token. Set NOTION_TOKEN to a real internal integration secret (it starts with ntn_) and restart the client. If the token is real and you still see this, it was revoked or you copied the integration ID instead of the secret.

You used OPENAPI_MCP_HEADERS and the server ignored it

What you see

Failed to parse OPENAPI_MCP_HEADERS environment variable: SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)

The fix

We triggered this on purpose with a header string that was not valid JSON. The variable must hold a complete JSON object with every key and value in double quotes, and inside a JSON config file each of those quotes has to be escaped again. The server prints this line to stderr, then carries on with no credential at all, which is why the next thing you see is the 401 above. Use NOTION_TOKEN instead unless you specifically need to pin a Notion-Version header. What you see above is the first line of that stderr; the stack frames printed under it are withheld here because they carry local paths from our Mac.

The hosted server at mcp.notion.com rejects you

What you see

{"error":"invalid_token","error_description":"Missing or invalid access token"}

The fix

That is the body we got back from https://mcp.notion.com/mcp when we called it without signing in, alongside a WWW-Authenticate header advertising Bearer realm="OAuth". The hosted server does not take a pasted ntn_ secret: it expects an OAuth sign-in that your client completes in a browser. In Claude Code that is the /mcp command; in Cursor and Claude Desktop it happens the first time a Notion tool is used. If your client cannot do OAuth, use the local npx setup on this page instead.

Your MCP client cannot start the server at all

The fix

The npx command belongs to Node.js. If Node is not installed on your Mac, every client on this page fails at the spawn step before the server can say anything. Install Node from nodejs.org, restart your MCP client, and try again.

FAQ

Questions people ask.

What is the Notion MCP server?

It is Notion's own Model Context Protocol server, published as @notionhq/notion-mcp-server. Once connected, an AI assistant such as Claude can search your workspace, read and edit pages, query databases, move pages and leave comments, through the same public API a Notion app would use. It runs as a local process on your Mac and talks to your AI app over stdio. [1][5]

What tools does the Notion MCP server include?

The running server answered tools/list with 24 tools: search (API-post-search), pages (API-retrieve-a-page, API-post-page, API-patch-page, API-move-page, API-retrieve-a-page-property), page content as Markdown (API-retrieve-page-markdown, API-update-page-markdown), blocks (API-get-block-children, API-patch-block-children, API-retrieve-a-block, API-update-a-block, API-delete-a-block), data sources and databases (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), comments (API-retrieve-a-comment, API-create-a-comment) and users (API-get-user, API-get-users, API-get-self). The table above is that response, word for word.

Why does the README say 22 tools when you counted 24?

Because the count in the README is older than the package. The 22 figure belongs to the version 2.0.0 notes; the release we ran, 2.5.1, also ships API-retrieve-page-markdown and API-update-page-markdown, the two tools that read and write a page as Markdown instead of block JSON. A README is a claim, a tools/list response is a fact, and 24 is what the running server said. [5][1]

Should I use this server or the hosted Notion MCP?

Notion now recommends the hosted one. Its docs describe Notion MCP at https://mcp.notion.com/mcp as the actively maintained server, authenticated with OAuth and needing no token to paste, and describe this open-source package as no longer actively maintained. The local package is still the better fit when you want a credential you control, a read-only integration, or a server that runs from your own machine, which is why both configs are on this page. [6][5]

Does it need an API key or an account?

Yes. You create an internal integration at notion.so/profile/integrations and copy its secret, a string beginning with ntn_, into NOTION_TOKEN. The integration also starts with access to nothing: you choose which pages and databases it may touch on the Access tab, so its reach is exactly what you grant it and nothing more. [5]

Can I give it read-only access to my workspace?

Yes, and it is the setting worth knowing about. On the integration's Configuration tab you can grant Read content only, which produces a token that cannot write. The tool list will still show the writing tools, because the list is fixed by the server, but Notion refuses the write on its side. Pair that with sharing only the pages a task needs. [5]

Which apps can use the Notion MCP server?

Any MCP client that can launch a local stdio server: Claude Desktop, Claude Code, Cursor, and Routines all can, and the exact config for each is above. The server itself is the same in every client; only the place you paste the config differs. Clients that can complete an OAuth sign-in can use the hosted server instead. [7][8][9][10]

Sources

Every external claim, receipted.

Anything on this page we did not observe in the run is linked here, with the date we read it. The run itself is the receipt for the rest.

  1. [1]

    npm registry: @notionhq/notion-mcp-serveraccessed 2026-08-03

    Latest version 2.5.1, published 2026-07-25; described as the official MCP server for the Notion API; every publishing maintainer is a Notion address.

  2. [2]

    npm downloads API: last weekaccessed 2026-08-03

    209,337 downloads for the week ending 2026-08-01.

  3. [3]

    GitHub: makenotion/notion-mcp-serveraccessed 2026-08-03

    4,566 stars and a push dated 2026-07-25 at access time, per the GitHub API; owned by the makenotion organisation.

  4. [4]

    makenotion/notion-mcp-server LICENSE fileaccessed 2026-08-03

    We read the file: it is the MIT License text, copyright 2025 Notion Labs, Inc.

  5. [5]

    Notion MCP Server READMEaccessed 2026-08-03

    The NOTION_TOKEN and OPENAPI_MCP_HEADERS contract, stdio as the default transport, the integration and Access tab steps, and the 22-tool figure from the 2.0.0 notes.

  6. [6]

    Notion developers: Connecting to Notion MCPaccessed 2026-08-03

    The hosted server at https://mcp.notion.com/mcp, its OAuth flow, per-client config, and the note that the open-source server is no longer actively maintained.

  7. [7]

    modelcontextprotocol.io: Connect to local MCP serversaccessed 2026-08-03

    The claude_desktop_config.json location and shape for a local stdio server.

  8. [8]

    Claude Code docs: MCPaccessed 2026-08-03

    The claude mcp add syntax for stdio servers with --env, and for remote servers with --transport http.

  9. [9]

    Cursor docs: Model Context Protocolaccessed 2026-08-03

    The mcp.json shape and file locations.

  10. [10]

    Routines: Connectorsaccessed 2026-08-03

    How Routines runs one-click OAuth connectors and any MCP server.

This page describes Notion as it behaved in one dated run on one Mac. Versions move: if something here no longer matches what you see, the capture date at the top says how old the reading is.

Behind this directory

Routines, the app behind this directory, runs MCP servers like this one without a terminal: see how connectors work. Whatever it writes for you stays as markdown files on your Mac, and there is no cloud bill. Download Routines