@matimo/notion
v0.1.0-alpha.13
Published
Notion workspace tools for Matimo
Readme
@matimo/notion — Notion Tools for Matimo
Notion workspace integration tools for Matimo's universal AI tools ecosystem. Query databases, create pages, manage content, search workspaces, add comments, and retrieve user information through YAML-defined tools that work with any AI framework.
📦 Installation
npm install @matimo/notion
# or
pnpm add @matimo/notion🛠️ Available Tools (7 Total)
| Tool | Method | Description | |------|--------|-------------| | notion_list_databases | POST | List all databases (data sources) in workspace | | notion_query_database | POST | Query pages from database with filters and sorting | | notion_create_page | POST | Create new page in database or as child page | | notion_update_page | PATCH | Update page properties, icon, status, archive | | notion_search | POST | Search workspace pages and databases by title | | notion_create_comment | POST | Add comments to pages, blocks, or discussions | | notion_get_user | GET | Retrieve user information and profile details |
🚀 Quick Start
import { MatimoInstance } from '@matimo/core';
const matimo = await MatimoInstance.init({ autoDiscover: true });
// Query a database
const results = await matimo.execute('notion_query_database', {
database_id: 'a1d8501e-1ac1-43e9-a6bd-ea9fe6c8822b'
});
console.log('Found pages:', results.results.length);🔐 Authentication Setup
Get Your Notion API Token
- Go to Notion Integrations
- Click "Create new integration"
- Set workspace and name your integration
- Grant required capabilities:
- ✅ Read content
- ✅ Update content
- ✅ Insert content
- ✅ Read user information
- ✅ Insert comments
- Copy your "Internal Integration Secret" (token)
- Set environment variable:
export NOTION_API_KEY=secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Share Resources with Your Integration
For each database/page you want to access:
- Click the ••• menu (top-right)
- Scroll to "Add connections"
- Search for and select your integration
🤖 How AI Agents Use These Tools
AI agents (Claude, ChatGPT, etc.) don't need to know internal API details. They discover tools automatically:
// AI agent discovers all available tools
const tools = matimo.listTools();
// Each tool has:
// - name: "notion_list_databases" ← Tool identifier
// - description: "List all databases..." ← What it does
// - parameters: { ← What inputs it accepts
// database_id: { type: "string", description: "Get from notion_list_databases..." }
// }
// - examples: [...] ← How to use it
// AI agent reads descriptions and automatically knows:
// 1. Use notion_list_databases() first to get database IDs
// 2. Pass those IDs to notion_query_database() for queries
// 3. Use returned page IDs with notion_create_page(), etc.No memorization needed. Tools are self-describing through their schemas, descriptions, and examples.
📖 Integration Examples
Factory Pattern (Simple)
import { MatimoInstance } from '@matimo/core';
const matimo = await MatimoInstance.init({ autoDiscover: true });
// AI agent autonomously discovers and uses tools
// Step 1: List databases
const databases = await matimo.execute('notion_list_databases', { page_size: 10 });
const myDb = databases.data.results[0];
// Step 2: Query the database
const pages = await matimo.execute('notion_query_database', {
database_id: myDb.id,
page_size: 5
});
// Step 3: Create a new page
const newPage = await matimo.execute('notion_create_page', {
parent: { database_id: myDb.id },
markdown: '# New Page\n\nContent here'
});
console.log('Created:', newPage.data.url);Decorator Pattern (Class-Based)
import { MatimoInstance, setGlobalMatimoInstance, tool } from '@matimo/core';
const matimo = await MatimoInstance.init('./tools');
setGlobalMatimoInstance(matimo);
class NotionManager {
@tool('notion_query_database')
async queryDatabase(database_id: string, filter?: Record<string, any>) {
// Auto-executed by decorator
}
@tool('notion_create_page')
async createPage(
parent: Record<string, string>, // e.g., { database_id: '...' } or { page_id: '...' }
markdown?: string,
icon?: Record<string, string>
) {
// Auto-executed by decorator
}
@tool('notion_search')
async search(query: string, sort_by?: string) {
// Auto-executed by decorator
}
}
const manager = new NotionManager();
const results = await manager.queryDatabase('db-id');LangChain Integration (AI Framework)
import { MatimoInstance } from '@matimo/core';
const matimo = await MatimoInstance.init('./tools');
// Get tool schemas for LangChain
const notionTools = matimo.listTools()
.filter(t => t.name.startsWith('notion_'))
.map(tool => ({
type: 'function',
function: {
name: tool.name,
description: tool.description,
parameters: {
type: 'object',
properties: tool.parameters || {},
required: Object.entries(tool.parameters || {})
.filter(([_, p]: [string, any]) => p.required)
.map(([name]) => name),
},
},
}));
// Use with your LLM/agent
console.log('Available tools for LangChain:', notionTools.map(t => t.function.name));📚 API Reference
notion_query_database
Query pages in a Notion database with optional filtering and sorting.
Parameters:
database_id(required): UUID of the databasefilter(optional): JSON filter object (e.g.,{"property": "Status", "status": {"equals": "Done"}})sort(optional): Array of sort objectspage_size(optional): Results per page (1-100, default 100)start_cursor(optional): Pagination cursor
Returns: Paginated list of pages with results, has_more, next_cursor
notion_create_page
Create a new page, optionally with properties and content.
Parameters:
parent(required): Object describing where to create the page. Provide ONE of:{ "database_id": "..." }to create inside a database{ "page_id": "..." }to create as a child page
properties(optional): JSON properties matching parent schemamarkdown(optional): String content using Markdown (easiest way to add content)icon(optional): Object for page icon, e.g.{ type: 'emoji', emoji: '✅' }children(optional): Array of Notion block objects to add to the page
Note: This tool accepts a single
parentobject (for example{ "database_id": "..." }or{ "page_id": "...") — do not pass separateparent_id/parent_typeparameters. This matches the tool's YAML definition (packages/notion/tools/notion_create_page/definition.yaml).
Returns: Created page object with id, url, and properties
notion_update_page
Update page properties, status, archive status, or icon.
Parameters:
page_id(required): UUID of page to updateproperties(optional): JSON properties to updateicon(optional): Object for page icon (e.g., { "type": "emoji", "emoji": "✅" } or { "type": "external", "external": { "url": "https://..." } })archived(optional): Archive/unarchive page (boolean)in_trash(optional): Move to/restore from trashis_locked(optional): Lock/unlock page editing
Returns: Updated page object
notion_search
Search workspace pages and databases by title.
Parameters:
query(optional): Search text (omit to return all items)filter_object(optional): 'page' or 'data_source'sort_timestamp(optional): 'last_edited_time' or 'created_time'sort_direction(optional): 'ascending' or 'descending'page_size(optional): Results per page (1-100)start_cursor(optional): Pagination cursor
Returns: Paginated list of pages/databases matching search
notion_create_comment
Add a comment to a page, block, or discussion thread.
Parameters:
parent(optional): Object describing the comment target. Provide ONE of:{ "page_id": "..." }— comment on a page{ "block_id": "..." }— comment on a block- omit to reply to a
discussion_id(usediscussion_idparameter)
discussion_id(optional): Discussion thread to reply to (alternative toparent)rich_text(required): Array of rich text objects representing the comment contentattachments(optional): Array of file objects to attach to the comment- Formatting/annotations should be provided within the
rich_textobjects (bold/italic/code via annotations)
Returns: Created comment object with id and created_time
notion_get_user
Retrieve user information including name, avatar, and email.
Parameters:
user_id(required): UUID of user to retrieve
Returns: User object with id, name, avatar_url, email
⚙️ Environment Variables
# Required
NOTION_API_KEY=secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional (for OAuth2 - Phase 2)
NOTION_OAUTH_CLIENT_ID=your_client_id
NOTION_OAUTH_CLIENT_SECRET=your_client_secret
NOTION_OAUTH_REDIRECT_URI=https://yourdomain.com/callback🔧 Troubleshooting
"403 Forbidden" Error
Cause: Integration lacks required capability or resource not shared.
Solutions:
- Check integration has "Read/Update/Insert content" capabilities in Notion dashboard
- Share the database/page with your integration (••• → Add connections → select integration)
- Verify token is current (refresh in Notion integrations dashboard)
"404 Not Found" Error
Cause: Database/page ID is incorrect or integration doesn't have access.
Solutions:
- Verify database ID from Notion URL:
https://www.notion.so/{database_id} - Ensure resource is shared with integration
- Check API key is correct
Filters Not Working
Cause: Incorrect filter syntax for property type.
Solutions:
- Use Notion's property filtering UI as reference
- Filters depend on property type (status, checkbox, date, etc.)
- See Notion Filter Reference
Rate Limiting
Info: Notion API has rate limits (~3-4 requests/second per integration). Implement exponential backoff for production systems.
📖 Learning Resources
- Notion API Docs
- Notion Integrations Dashboard
- Working with Databases
- Creating Pages
- Notion Developers Slack
🤝 Contributing
Found a bug or want to suggest a feature? See CONTRIBUTING.md.
Part of the Matimo ecosystem — Write YAML once, use everywhere.
