# Notion MCP server

Point Notion's own MCP server, @notionhq/notion-mcp-server, at the simulator so an agent's Notion tools act on the simulated workspace.

Notion's MCP server turns the Notion API into tools an agent calls, and it takes its API address from the environment, so one setting sends every tool to the simulator. Add the server to your agent's MCP configuration with `BASE_URL` set to `$RYSTIC_URL` and the token in its headers; the server's own `Notion-Version` needs no override:

```json
{
  "mcpServers": {
    "notion": {
      "command": "npx",
      "args": ["-y", "@notionhq/notion-mcp-server"],
      "env": {
        "BASE_URL": "http://localhost:8080",
        "OPENAPI_MCP_HEADERS": "{\"Authorization\":\"Bearer secret_placeholder\"}"
      }
    }
  }
}
```

Use the address `rystic run` printed in place of `localhost:8080`. To see the server work without an agent, send it the MCP handshake, list its tools and call `API-get-self` over stdio:

<!-- example: skip network -->
```bash
(printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"docs","version":"0"}}}' '{"jsonrpc":"2.0","method":"notifications/initialized"}' '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"API-get-self","arguments":{}}}'; sleep 5) | BASE_URL="$RYSTIC_URL" OPENAPI_MCP_HEADERS='{"Authorization":"Bearer secret_placeholder"}' npx -y @notionhq/notion-mcp-server | jq -c 'select(.id == 2 or .id == 3) | if .id == 2 then {tools: (.result.tools | length)} else (.result.content[0].text | fromjson | {name, type}) end'
# -> {"tools":24}
# -> {"name":"Wiki Reader","type":"bot"}
```

### What the tools reach

All 24 of the server's tools reach a served route, and the main page's Coverage section lists those routes. The main page's known clients table shows the server version that was last run against the simulator.

### Where the server and the simulator differ

- **One comment.** `API-retrieve-a-comment` lists a page's or block's comments (`GET /v1/comments`), and the server has no tool for reading, editing or deleting one comment. The SDKs and plain HTTP reach `GET`, `PATCH` and `DELETE /v1/comments/{comment_id}` ([Comments](https://www.rystic.ai/docs/simulators/notion/features/comments.md)).
- **Comment input.** `API-create-a-comment`'s input schema takes a page parent and plain rich text only.
- **Data source parent.** `API-create-a-data-source` declares a `page_id` parent, but `POST /v1/data_sources` takes `{"database_id": …}`, on Notion as on the simulator: pass the database's id.

---

Source: https://www.rystic.ai/docs/simulators/notion/features/mcp-server · Markdown: https://www.rystic.ai/docs/simulators/notion/features/mcp-server.md
