npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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

  1. Go to Notion Integrations
  2. Click "Create new integration"
  3. Set workspace and name your integration
  4. Grant required capabilities:
    • ✅ Read content
    • ✅ Update content
    • ✅ Insert content
    • ✅ Read user information
    • ✅ Insert comments
  5. Copy your "Internal Integration Secret" (token)
  6. Set environment variable:
    export NOTION_API_KEY=secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Share Resources with Your Integration

For each database/page you want to access:

  1. Click the ••• menu (top-right)
  2. Scroll to "Add connections"
  3. 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 database
  • filter (optional): JSON filter object (e.g., {"property": "Status", "status": {"equals": "Done"}})
  • sort (optional): Array of sort objects
  • page_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 schema
  • markdown (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 parent object (for example { "database_id": "..." } or { "page_id": "...") — do not pass separate parent_id / parent_type parameters. 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 update
  • properties (optional): JSON properties to update
  • icon (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 trash
  • is_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 (use discussion_id parameter)
  • discussion_id (optional): Discussion thread to reply to (alternative to parent)
  • rich_text (required): Array of rich text objects representing the comment content
  • attachments (optional): Array of file objects to attach to the comment
  • Formatting/annotations should be provided within the rich_text objects (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:

  1. Check integration has "Read/Update/Insert content" capabilities in Notion dashboard
  2. Share the database/page with your integration (••• → Add connections → select integration)
  3. 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:

  1. Verify database ID from Notion URL: https://www.notion.so/{database_id}
  2. Ensure resource is shared with integration
  3. 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

🤝 Contributing

Found a bug or want to suggest a feature? See CONTRIBUTING.md.


Part of the Matimo ecosystem — Write YAML once, use everywhere.