TypeScriptADK-TS

MCP Notion

Interact with Notion pages, databases, and workspaces using Notion's official MCP server

  • Name: MCP Notion
  • Package: @notionhq/notion-mcp-server
  • Provider: Notion

Overview

MCP Notion is the official MCP server from Notion. It lets agents read and write pages, query databases, search content, and manage comments and blocks across a Notion workspace.

Integration Token Required

You need a Notion internal integration token (NOTION_TOKEN) to use this server. Create one at notion.so/my-integrations and share the relevant pages with it.

Usage with ADK TypeScript

import { McpNotion } from "@iqai/adk";

const toolset = McpNotion({
  env: {
    NOTION_TOKEN: process.env.NOTION_TOKEN,
  },
});

const tools = await toolset.getTools();
import { McpToolset } from "@iqai/adk";

const toolset = new McpToolset({
  name: "Notion MCP Client",
  description: "Client for Notion workspace operations",
  transport: {
    mode: "stdio",
    command: "npx",
    args: ["-y", "@notionhq/notion-mcp-server"],
    env: {
      NOTION_TOKEN: process.env.NOTION_TOKEN || "",
      PATH: process.env.PATH || "",
    },
  },
});

const tools = await toolset.getTools();

Add this to your Claude Desktop configuration file:

MacOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Windows: %APPDATA%\Claude\claude_desktop_config.json

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

Environment Variables

VariableTypeDescription
NOTION_TOKENRequiredYour Notion integration secret (starts with ntn_)

Configuration Options

All MCP servers support these configuration options:

OptionTypeDescription
envobjectEnvironment variables (see table above)
debugbooleanEnable debug logging
descriptionstringCustom description
retryOptions.maxRetriesnumberMax retry attempts (default: 2)
retryOptions.initialDelaynumberInitial retry delay in ms (default: 200)
samplingHandlerSamplingHandlerHandler for MCP sampling requests

Available Tools

Hyphenated Tool Names

Notion's tool names use hyphens (e.g. retrieve-a-page). ADK-TS automatically maps these to underscore equivalents (retrieve_a_page) for the LLM, and maps them back when calling the server.

API-get-user
user_id:stringNotion-Version:string

Description

Notion | Retrieve a user Error Responses: 400: 400

API-get-users
start_cursor:stringpage_size:integerNotion-Version:string

Description

Notion | List all users Error Responses: 400: 400

API-get-self
Notion-Version:string

Description

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

API-post-search
Notion-Version:stringquery:stringsort:objectfilter:objectstart_cursor:stringpage_size:integer

Description

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

API-get-block-children
block_id:stringstart_cursor:stringpage_size:integerNotion-Version:string

Description

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

API-patch-block-children
block_id:stringNotion-Version:stringchildren:arrayafter:string

Description

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

API-retrieve-a-block
block_id:stringNotion-Version:string

Description

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

API-update-a-block
block_id:stringNotion-Version:stringtype:objectarchived:boolean

Description

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

API-delete-a-block
block_id:stringNotion-Version:string

Description

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

API-retrieve-a-page
page_id:stringfilter_properties:stringNotion-Version:string

Description

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

API-patch-page
page_id:stringNotion-Version:stringproperties:objectin_trash:booleanarchived:booleanicon:objectcover:object

Description

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

API-post-page
Notion-Version:stringparent:anyproperties:objectchildren:arrayicon:stringcover:string

Description

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

API-retrieve-a-page-property
page_id:stringproperty_id:stringpage_size:integerstart_cursor:stringNotion-Version:string

Description

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

API-retrieve-a-comment
block_id:stringstart_cursor:stringpage_size:integerNotion-Version:string

Description

Notion | Retrieve comments Error Responses: 400: Bad request

API-create-a-comment
parent:objectrich_text:array

Description

Notion | Create comment Error Responses: 400: Bad request

API-query-data-source
data_source_id:stringfilter_properties:arrayNotion-Version:stringfilter:objectsorts:arraystart_cursor:stringpage_size:integerarchived:booleanin_trash:boolean

Description

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

API-retrieve-a-data-source
data_source_id:stringNotion-Version:string

Description

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

API-update-a-data-source
data_source_id:stringNotion-Version:stringtitle:arraydescription:arrayproperties:object

Description

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

API-create-a-data-source
Notion-Version:stringparent:anyproperties:objecttitle:array

Description

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

API-list-data-source-templates
data_source_id:stringstart_cursor:stringpage_size:integerNotion-Version:string

Description

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

API-retrieve-a-database
database_id:stringNotion-Version:string

Description

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

API-move-page
page_id:stringNotion-Version:stringparent:any

Description

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

Complete Example

import { McpNotion, LlmAgent } from "@iqai/adk";

async function main() {
  const notionToolset = McpNotion({
    env: {
      NOTION_TOKEN: process.env.NOTION_TOKEN,
    },
  });

  try {
    const tools = await notionToolset.getTools();

    const agent = new LlmAgent({
      name: "notion_agent",
      model: "gemini-2.5-flash",
      description: "An agent that reads and writes Notion content",
      instruction: `You have access to a Notion workspace.
        Use the available tools to search pages, read content, and create or update pages.
        Always confirm before making destructive changes.`,
      tools,
    });

    const response = await agent.ask(
      "Search for pages about project planning and summarize what you find",
    );
    console.log(response);
  } finally {
    await notionToolset.close();
  }
}

main();

Setting Up a Notion Integration

  1. Go to notion.so/my-integrations and create a new integration
  2. Copy the integration secret (starts with ntn_) and set it as NOTION_TOKEN
  3. Open the Notion pages or databases you want the agent to access
  4. Click ... > Connect to > select your integration to grant access

The integration can only access pages it has been explicitly connected to.

Use Cases

  • Search and summarize: Find pages across a workspace and extract key information
  • Page creation: Create structured notes, meeting summaries, or documentation pages
  • Database queries: Read rows from Notion databases and filter by properties
  • Content updates: Edit existing pages or append blocks to them
  • Comment threads: Post and retrieve comments on pages

Best Practices

  • Only share the specific pages and databases the integration needs access to
  • Use read-only integrations where write access is not needed
  • Always call toolset.close() when done

Troubleshooting

IssueSolution
Unauthorized errorCheck that NOTION_TOKEN is correct and starts with ntn_
Page not foundEnsure the integration has been connected to that page in Notion
Tools not loadingVerify @notionhq/notion-mcp-server can be resolved via npx
Connection timeoutCheck if npm/npx is installed and in PATH