Skip to main content

Notion

Workspace integration for pages, databases, and content management.

Provider: Notion
Authentication: OAuth (Integration Token)
Category: Productivity & Workspace
Credit Cost: 1 credit per operation

Overview

Notion tools enable AI agents to search, create, read, and manage content in your Notion workspace. Perfect for knowledge management, content creation, task tracking, and building automated workflows with your Notion data.

Key Concepts

Databases and Data Sources

With Notion's API version 2025-09-03:

  • Database: A container that holds one or more data sources
  • Data Source: A table/view within a database with its own schema (properties)
  • Page: A document that can exist standalone or as a row in a data source

Typical workflow:

  1. Use get_database to get the list of data sources in a database
  2. Use retrieve_data_source to get the schema (properties) of a data source
  3. Use query_data_source to query pages or create_page to add entries

Setup

Get Notion Integration Token

  1. Go to Notion Integrations
  2. Click "New integration"
  3. Fill in:
    • Name: Reeva MCP
    • Associated workspace: Select your workspace
    • Capabilities: Enable needed permissions (Read, Update, Insert)
  4. Click Submit
  5. Copy the Internal Integration Token (starts with secret_)

Share Pages with Integration

Important: Your integration can only access pages you explicitly share with it.

  1. Open the Notion page or database you want to access
  2. Click Share in the top right
  3. Click "Invite"
  4. Search for your integration name and select it
  5. Click "Invite"

Add to Reeva

  1. Dashboard → AccountsAdd Account
  2. Select Notion
  3. Paste your Integration Token
  4. Click Save

Available Tools

Search Pages

Search for pages and data sources across your Notion workspace.

Tool ID: search_pages
Credit Cost: 1 credit

Parameters:

  • query (string, optional): Search query string
    • Default: "" (returns all accessible items)
  • object_filter (string, optional): Filter by object type
    • Options: "page", "data_source"
  • page_size (integer, optional): Number of results to return
    • Default: 10
    • Maximum: 100
  • start_cursor (string, optional): Pagination cursor from previous response

Response:

{
"results": [
{
"id": "abc123-def456",
"title": "Project Notes",
"url": "https://www.notion.so/Project-Notes-abc123",
"type": "page",
"created_time": "2025-11-22T10:30:00.000Z",
"last_edited_time": "2025-11-22T15:45:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}

Example Usage:

# Python - Search for pages
response = client.call_tool(
name="search_pages",
arguments={
"query": "meeting notes",
"page_size": 20
}
)

for result in response["results"]:
print(f"{result['title']}: {result['url']}")
// TypeScript - Find databases only
const response = await client.callTool({
name: "search_pages",
arguments: {
query: "tasks",
object_filter: "data_source",
page_size: 10
}
});

Use Cases:

  • Find specific pages by keyword
  • Discover databases in workspace
  • Build page navigation
  • Search before creating duplicates

Get Page

Retrieve page properties and metadata.

Tool ID: get_page
Credit Cost: 1 credit

Parameters:

  • page_id (string, required): The ID of the page to retrieve

Response:

{
"id": "abc123-def456",
"object": "page",
"created_time": "2025-11-22T10:30:00.000Z",
"last_edited_time": "2025-11-22T15:45:00.000Z",
"properties": {
"Name": {
"title": [{"plain_text": "My Page Title"}]
},
"Status": {
"status": {"name": "In Progress"}
}
},
"url": "https://www.notion.so/My-Page-abc123"
}

Example Usage:

# Python - Get page properties
response = client.call_tool(
name="get_page",
arguments={"page_id": "abc123-def456-ghi789"}
)

title = response["properties"]["Name"]["title"][0]["plain_text"]
print(f"Page: {title}")

Use Cases:

  • Read page properties
  • Check page status
  • Get page metadata
  • Validate page exists

Get Page Content

Retrieve complete page content including all blocks.

Tool ID: get_page_content
Credit Cost: 1 credit

Parameters:

  • page_id (string, required): The ID of the page to retrieve content from

Response:

{
"page_id": "abc123-def456",
"blocks": [
{
"type": "heading_1",
"heading_1": {
"rich_text": [{"plain_text": "Welcome"}]
}
},
{
"type": "paragraph",
"paragraph": {
"rich_text": [{"plain_text": "This is the content..."}]
}
}
],
"markdown": "# Welcome\n\nThis is the content...",
"block_count": 2
}

Example Usage:

# Python - Get page as markdown
response = client.call_tool(
name="get_page_content",
arguments={"page_id": "abc123-def456"}
)

# Use the markdown representation
markdown_content = response["markdown"]
print(f"Content ({response['block_count']} blocks):")
print(markdown_content)
// TypeScript - Read and process content
const response = await client.callTool({
name: "get_page_content",
arguments: {
page_id: "abc123-def456"
}
});

// Process individual blocks
response.blocks.forEach(block => {
console.log(`Block type: ${block.type}`);
});

Use Cases:

  • Read full page content
  • Extract text for analysis
  • Convert Notion to markdown
  • Build content pipelines

Create Page

Create a new page under a parent page or in a data source.

Tool ID: create_page
Credit Cost: 1 credit

Parameters:

  • title (string, required): Title for the new page
  • parent_page_id (string, optional): ID of parent page
  • parent_data_source_id (string, optional): ID of parent data source (for database entries)
  • content (string, optional): Markdown content for the page
  • properties (object, optional): Page properties (for data source entries)
  • template_type (string, optional): Template type
    • Options: "none", "default", "template_id"
    • Default: "none"
  • template_id (string, optional): Template ID (when template_type is "template_id")

Response:

{
"id": "new-page-id",
"url": "https://www.notion.so/New-Page-newpageid"
}

Example Usage:

# Python - Create a simple page under a parent
response = client.call_tool(
name="create_page",
arguments={
"title": "Meeting Notes - Nov 22",
"parent_page_id": "parent-page-id",
"content": "# Agenda\n\n- Review Q4 goals\n- Discuss roadmap\n\n# Action Items\n\n- [ ] Follow up with team"
}
)

print(f"Created: {response['url']}")
// TypeScript - Add entry to database
const response = await client.callTool({
name: "create_page",
arguments: {
title: "New Task",
parent_data_source_id: "data-source-id",
properties: {
"Status": {
"status": {"name": "To Do"}
},
"Priority": {
"select": {"name": "High"}
},
"Due Date": {
"date": {"start": "2025-11-30"}
}
}
}
});
# cURL - Create page with template
curl -X POST https://api.joinreeva.com/mcp/server_YOUR_ID \
-H "Authorization: Bearer mcpk_your_key" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_page",
"arguments": {
"title": "Weekly Report",
"parent_data_source_id": "reports-ds-id",
"template_type": "default"
}
},
"id": 1
}'

Use Cases:

  • Create documentation pages
  • Add tasks to databases
  • Store research findings
  • Log events and data

Get Database

Retrieve database metadata and list of data sources.

Tool ID: get_database
Credit Cost: 1 credit

Parameters:

  • database_id (string, required): ID of the database to retrieve

Response:

{
"id": "database-id",
"object": "database",
"title": [{"plain_text": "Project Tracker"}],
"data_sources": [
{
"id": "data-source-id-1",
"name": "Tasks"
},
{
"id": "data-source-id-2",
"name": "Milestones"
}
]
}

Example Usage:

# Python - Get database data sources
response = client.call_tool(
name="get_database",
arguments={"database_id": "your-database-id"}
)

print(f"Database: {response['title'][0]['plain_text']}")
print("Data Sources:")
for ds in response["data_sources"]:
print(f" - {ds['name']} ({ds['id']})")

Use Cases:

  • Discover data sources in a database
  • Get data source IDs for querying
  • Understand database structure

Retrieve Data Source

Get the full schema (properties) of a data source.

Tool ID: retrieve_data_source
Credit Cost: 1 credit

Parameters:

  • data_source_id (string, required): ID of the data source to retrieve

Response:

{
"id": "data-source-id",
"object": "data_source",
"properties": {
"Name": {
"id": "title",
"type": "title",
"title": {}
},
"Status": {
"id": "status",
"type": "status",
"status": {
"options": [
{"name": "To Do", "color": "gray"},
{"name": "In Progress", "color": "blue"},
{"name": "Done", "color": "green"}
]
}
},
"Priority": {
"id": "priority",
"type": "select",
"select": {
"options": [
{"name": "High", "color": "red"},
{"name": "Medium", "color": "yellow"},
{"name": "Low", "color": "green"}
]
}
}
}
}

Example Usage:

# Python - Get data source schema
response = client.call_tool(
name="retrieve_data_source",
arguments={"data_source_id": "data-source-id"}
)

print("Available properties:")
for prop_name, prop_info in response["properties"].items():
print(f" {prop_name}: {prop_info['type']}")

Use Cases:

  • Understand database schema before creating pages
  • Get available status/select options
  • Validate property names
  • Build dynamic forms

Query Data Source

Query pages from a data source with filtering and sorting.

Tool ID: query_data_source
Credit Cost: 1 credit

Parameters:

  • data_source_id (string, required): ID of the data source to query
  • filter (string, optional): JSON string representing filter criteria
  • sorts (string, optional): JSON string or array of sort objects
  • page_size (integer, optional): Number of results (1-100)
    • Default: 10
  • start_cursor (string, optional): Pagination cursor
  • filter_properties (array, optional): Property names to include in results

Response:

{
"results": [
{
"id": "page-id-1",
"properties": {
"Name": {"title": [{"plain_text": "Task 1"}]},
"Status": {"status": {"name": "In Progress"}}
}
}
],
"has_more": true,
"next_cursor": "cursor-string"
}

Example Usage:

# Python - Query with filter
response = client.call_tool(
name="query_data_source",
arguments={
"data_source_id": "tasks-ds-id",
"filter": '{"property": "Status", "status": {"equals": "In Progress"}}',
"page_size": 20
}
)

for page in response["results"]:
title = page["properties"]["Name"]["title"][0]["plain_text"]
print(f"Task: {title}")
// TypeScript - Query with sorting
const response = await client.callTool({
name: "query_data_source",
arguments: {
data_source_id: "tasks-ds-id",
filter: JSON.stringify({
"and": [
{"property": "Status", "status": {"does_not_equal": "Done"}},
{"property": "Priority", "select": {"equals": "High"}}
]
}),
sorts: JSON.stringify([
{"property": "Due Date", "direction": "ascending"}
]),
page_size: 50
}
});

Filter Examples:

// Equals
{"property": "Status", "status": {"equals": "Done"}}

// Contains text
{"property": "Name", "title": {"contains": "meeting"}}

// Date filter
{"property": "Due Date", "date": {"before": "2025-12-01"}}

// Checkbox
{"property": "Completed", "checkbox": {"equals": true}}

// AND condition
{
"and": [
{"property": "Status", "status": {"equals": "In Progress"}},
{"property": "Priority", "select": {"equals": "High"}}
]
}

// OR condition
{
"or": [
{"property": "Status", "status": {"equals": "To Do"}},
{"property": "Status", "status": {"equals": "In Progress"}}
]
}

Use Cases:

  • List tasks by status
  • Find overdue items
  • Search database entries
  • Build filtered views

Create Database

Create a new database with an initial data source.

Tool ID: create_database
Credit Cost: 1 credit

Parameters:

  • parent_page_id (string, optional): ID of parent page
  • parent_workspace (boolean, optional): Set to true for workspace-level
  • title (string, optional): Database title
  • description (string, optional): Database description
  • initial_data_source_properties (object, optional): Schema for initial data source
  • icon (object, optional): Icon object
  • cover (object, optional): Cover image object

Response:

{
"id": "new-database-id",
"object": "database",
"data_sources": [
{
"id": "initial-ds-id",
"name": "My Database"
}
]
}

Example Usage:

# Python - Create task database
response = client.call_tool(
name="create_database",
arguments={
"parent_page_id": "parent-page-id",
"title": "Project Tasks",
"initial_data_source_properties": {
"Task Name": {"title": {}},
"Status": {"status": {}},
"Priority": {
"select": {
"options": [
{"name": "High", "color": "red"},
{"name": "Medium", "color": "yellow"},
{"name": "Low", "color": "green"}
]
}
},
"Due Date": {"date": {}},
"Assignee": {"people": {}}
}
}
)

print(f"Created database: {response['id']}")

Use Cases:

  • Create project trackers
  • Set up content calendars
  • Build CRM databases
  • Create structured data stores

Update Database

Update database-level properties.

Tool ID: update_database
Credit Cost: 1 credit

Parameters:

  • database_id (string, required): ID of database to update
  • title (string, optional): New title
  • description (string, optional): New description
  • icon (object, optional): New icon
  • cover (object, optional): New cover image
  • parent_page_id (string, optional): Move to new parent
  • is_inline (boolean, optional): Toggle inline/full-page mode
  • in_trash (boolean, optional): Archive/unarchive

Example Usage:

# Python - Update database title
response = client.call_tool(
name="update_database",
arguments={
"database_id": "database-id",
"title": "Updated Project Tracker",
"description": "Tracking all Q4 projects"
}
)

Create Data Source

Add a new data source to an existing database.

Tool ID: create_data_source
Credit Cost: 1 credit

Parameters:

  • database_id (string, required): ID of parent database
  • properties (object, required): Schema for the data source
  • title (string, optional): Data source title
  • icon (object, optional): Icon object

Example Usage:

# Python - Add new data source
response = client.call_tool(
name="create_data_source",
arguments={
"database_id": "database-id",
"title": "Bug Tracker",
"properties": {
"Bug Title": {"title": {}},
"Severity": {
"select": {
"options": [
{"name": "Critical", "color": "red"},
{"name": "Major", "color": "orange"},
{"name": "Minor", "color": "yellow"}
]
}
},
"Reported Date": {"date": {}},
"Fixed": {"checkbox": {}}
}
}
)

Update Data Source

Update data source schema and properties.

Tool ID: update_data_source
Credit Cost: 1 credit

Parameters:

  • data_source_id (string, required): ID of data source to update
  • properties (object, optional): Property updates (set to null to remove)
  • title (string, optional): New title
  • icon (object, optional): New icon
  • in_trash (boolean, optional): Archive/unarchive
  • parent_database_id (string, optional): Move to different database

Example Usage:

# Python - Add and remove properties
response = client.call_tool(
name="update_data_source",
arguments={
"data_source_id": "data-source-id",
"properties": {
"New Field": {"rich_text": {}}, # Add new
"Old Field": None # Remove
}
}
)

List Data Source Templates

List available templates for a data source.

Tool ID: list_data_source_templates
Credit Cost: 1 credit

Parameters:

  • data_source_id (string, required): ID of the data source
  • name (string, optional): Filter templates by name
  • page_size (integer, optional): Number of results (default: 100)
  • start_cursor (string, optional): Pagination cursor

Response:

{
"templates": [
{
"id": "template-id",
"name": "Weekly Report Template",
"is_default": true
}
],
"has_more": false,
"next_cursor": null
}

Use Cases:

  • Discover available templates
  • Get template IDs for page creation
  • List custom templates

Common Patterns

Complete Database Query Workflow

# Step 1: Get database and find data source
database = client.call_tool(
name="get_database",
arguments={"database_id": "your-database-id"}
)

data_source_id = database["data_sources"][0]["id"]

# Step 2: Get schema to understand properties
schema = client.call_tool(
name="retrieve_data_source",
arguments={"data_source_id": data_source_id}
)

print("Available properties:", list(schema["properties"].keys()))

# Step 3: Query with filter
results = client.call_tool(
name="query_data_source",
arguments={
"data_source_id": data_source_id,
"filter": '{"property": "Status", "status": {"equals": "In Progress"}}',
"page_size": 50
}
)

print(f"Found {len(results['results'])} items")

Content Pipeline

# Scrape content and store in Notion
def save_to_notion(url, parent_page_id):
# Scrape the content
content = client.call_tool(
name="web_scraper_Get_Website_Markdown",
arguments={"url": url}
)

# Create Notion page
page = client.call_tool(
name="create_page",
arguments={
"title": content["title"],
"parent_page_id": parent_page_id,
"content": content["markdown"]
}
)

return page["url"]

Task Management

# Create task and track in database
def create_task(title, priority, due_date, data_source_id):
return client.call_tool(
name="create_page",
arguments={
"title": title,
"parent_data_source_id": data_source_id,
"properties": {
"Status": {"status": {"name": "To Do"}},
"Priority": {"select": {"name": priority}},
"Due Date": {"date": {"start": due_date}}
}
}
)

# Get overdue tasks
def get_overdue_tasks(data_source_id):
today = datetime.now().strftime("%Y-%m-%d")
return client.call_tool(
name="query_data_source",
arguments={
"data_source_id": data_source_id,
"filter": json.dumps({
"and": [
{"property": "Due Date", "date": {"before": today}},
{"property": "Status", "status": {"does_not_equal": "Done"}}
]
})
}
)

Property Types Reference

TypeDescriptionExample Value
titleMain title field{"title": [{"text": {"content": "Name"}}]}
rich_textText content{"rich_text": [{"text": {"content": "Text"}}]}
numberNumeric value{"number": 42}
selectSingle option{"select": {"name": "Option"}}
multi_selectMultiple options{"multi_select": [{"name": "A"}, {"name": "B"}]}
dateDate/time{"date": {"start": "2025-11-22"}}
checkboxBoolean{"checkbox": true}
statusStatus field{"status": {"name": "In Progress"}}
peopleUser references{"people": [{"id": "user-id"}]}
urlURL link{"url": "https://example.com"}
emailEmail address{"email": "user@example.com"}

Best Practices

Access Control

  • Only share specific pages/databases with your integration
  • Use least-privilege access
  • Regularly audit shared content

Performance

  • Use filter_properties to limit returned data
  • Implement pagination for large result sets
  • Cache data source schemas

Data Integrity

  • Validate property values match schema
  • Handle missing properties gracefully
  • Check status/select options exist before using

Error Handling

  • Handle "page not found" for deleted pages
  • Check for rate limiting
  • Validate IDs before operations

Troubleshooting

"Object not found" Error

Cause: Page/database not shared with integration

Solutions:

  • Share the page/database with your integration
  • Check the ID is correct
  • Verify integration has access

"Invalid property" Error

Cause: Property name doesn't exist or wrong type

Solutions:

  • Use retrieve_data_source to check schema
  • Verify property name spelling and case
  • Ensure property type matches expected format

"Validation error" Error

Cause: Property value format incorrect

Solutions:

  • Check property type requirements
  • Verify date formats (ISO 8601)
  • Ensure select options exist

See Also