SkillAgentSearch skills...

Notionary

Notion API made simple. Write Markdown, get Notion pages. Built for Python developers and AI automation. Async, typed, battle-tested.

Install / Use

/learn @mathisarends/Notionary

README

<picture> <source media="(prefers-color-scheme: dark)" srcset="./static/notionary-dark.png"> <source media="(prefers-color-scheme: light)" srcset="./static/notionary-light.png"> <img alt="Notionary logo: dark mode shows a white logo, light mode shows a black logo." src="./static/browser-use.png" width="full"> </picture> <h1 align="center">The Modern Notion API for Python & AI Agents</h1> <div align="center">

PyPI version Python Version License: MIT Downloads Documentation Notion API

Transform complex Notion API interactions into simple, Pythonic code. Perfect for developers building AI agents, automation workflows, and dynamic content systems.

</div>

Why Notionary?

  • AI-friendly – Composable APIs that drop cleanly into agent workflows
  • Smart discovery – Find pages/databases by title with fuzzy matching (no ID spelunking)
  • Markdown content – Read & write page content as Markdown via the Notion Markdown API
  • Async-first – Modern Python with full async / await
  • Round-trip content – Read a page as Markdown, transform, write back
  • Full coverage – Pages, databases, data sources, file uploads, users, workspace search

Installation

pip install notionary

Set up your Notion integration and configure your token:

export NOTION_API_KEY=your_integration_key

Quick Start

All access goes through the Notionary client:

import asyncio
from notionary import Notionary

async def main():
    async with Notionary() as notion:
        # Find a page by title (fuzzy matching)
        page = await notion.pages.find("Meeting Notes")
        print(page.title, page.url)

        # Read content as Markdown
        md = await page.get_markdown()
        print(md)

        # Append content
        await page.append("## Action Items\n- [ ] Review proposal")

        # Replace all content
        await page.replace("# Fresh Start\nThis page was rewritten.")

asyncio.run(main())

Architecture Overview

flowchart TD
  N[Notionary] --> PG[pages]
  N --> DB[databases]
  N --> DS[data_sources]
  N --> FU[file_uploads]
  N --> USR[users]
  N --> WS[workspace]

  PG --> P[Page]
  DB --> D[Database]
  DS --> S[DataSource]
  S --> P

The Notionary client exposes namespace objects – each mapping to a Notion API area. Content operations use the Notion Markdown API directly.


Core Concepts

Pages

async with Notionary() as notion:
    # Lookup
    page = await notion.pages.find("Sprint Board")
    page = await notion.pages.from_id(page_uuid)

    # List & search
    pages = await notion.pages.list(query="roadmap")

    # Content (Markdown API)
    md = await page.get_markdown()
    await page.append("## New Section")
    await page.replace("# Replaced content")
    await page.clear()

    # Metadata
    await page.rename("New Title")
    await page.set_icon("🚀")
    await page.set_cover("https://example.com/cover.png")
    await page.random_cover()

    # Properties
    await page.properties.set_property("Status", "Done")

    # Comments
    await page.comment("Review completed")

    # Lifecycle
    await page.lock()
    await page.trash()

Notion API Reference: Pages · Markdown

Databases

async with Notionary() as notion:
    db = await notion.databases.find("Tasks")
    db = await notion.databases.from_id(db_uuid)

    # Create
    db = await notion.databases.create(
        parent_page_id=page_uuid,
        title="New Database",
        icon_emoji="📊",
    )

    # Metadata
    await db.set_title("Project Tracker")
    await db.set_description("All current projects")
    await db.set_icon("📊")
    await db.lock()

Notion API Reference: Databases

Data Sources

async with Notionary() as notion:
    ds = await notion.data_sources.find("Engineering Backlog")

    # Create a page inside the data source
    page = await ds.create_page(title="New Feature")

    # Metadata
    await ds.set_title("Sprint Board")
    await ds.set_icon("🧭")

Notion API Reference: Data Sources

File Uploads

from pathlib import Path

async with Notionary() as notion:
    # Upload from disk
    result = await notion.file_uploads.upload(Path("./report.pdf"))

    # Upload from bytes
    result = await notion.file_uploads.upload_from_bytes(
        content=image_bytes,
        filename="chart.png",
    )

    # List uploads
    uploads = await notion.file_uploads.list()

Users

async with Notionary() as notion:
    all_users = await notion.users.list()
    people = await notion.users.list(filter="person")
    bots = await notion.users.list(filter="bot")
    me = await notion.users.me()

    matches = await notion.users.search("alex")

Workspace Search

async with Notionary() as notion:
    results = await notion.workspace.search(query="roadmap")
    for r in results:
        print(type(r).__name__, r.title)

Key Features

<table> <tr> <td width="50%">

Smart Discovery

  • Find pages/databases by name
  • Fuzzy matching for approximate searches
  • No more hunting for IDs or URLs

Markdown Content API

  • Read page content as Markdown
  • Append, replace, or clear content
  • Powered by the official Notion Markdown API

Modern Python

  • Full async/await support
  • Type hints throughout
  • Pydantic models for API responses
</td> <td width="50%">

Round-Trip Editing

  • Read existing content as Markdown
  • Edit and modify
  • Write back to Notion seamlessly

AI-Ready Architecture

  • Predictable models enable prompt chaining
  • Ideal for autonomous content generation
  • Clean namespace-based API

Complete Coverage

  • Pages, databases, data sources
  • File uploads with automatic handling
  • Users and workspace search
</td> </tr> </table>

MCP Server

Notionary ships a built-in Model Context Protocol server so AI agents can manage your Notion workspace out of the box.

pip install notionary[mcp]

Use with the OpenAI Agents SDK

import asyncio
import sys

from agents import Agent, Runner
from agents.mcp import MCPServerStdio


async def main():
    async with MCPServerStdio(
        name="Notionary",
        params={
            "command": sys.executable,
            "args": ["-m", "notionary.mcp.server"],
        },
    ) as server:
        agent = Agent(
            name="Notion Assistant",
            instructions="You help users manage their Notion workspace.",
            mcp_servers=[server],
        )

        result = await Runner.run(agent, "Search my workspace and list what you find.")
        print(result.final_output)

asyncio.run(main())

Use with Claude Desktop / Claude Code

Add to your MCP config:

{
  "mcpServers": {
    "notionary": {
      "command": "notionary-mcp",
      "env": {
        "NOTION_API_KEY": "your_integration_key"
      }
    }
  }
}

Available Tools

| Area | Tools | |------|-------| | Workspace | search_workspace | | Pages | list_pages, find_page, get_page_content, get_page_comments, update_page, append_to_page, replace_page_content, clear_page, comment_on_page, rename_page, set_page_property, trash_page, restore_page, lock_page, unlock_page | | Data Sources | list_data_sources, find_data_source, get_data_source_schema, create_page_in_data_source, update_data_source, list_data_source_templates, trash_data_source, restore_data_source | | Databases | list_databases, find_database, create_database, update_database, trash_database, restore_database | | Users | list_users, search_users, get_me |


Full Documentation

mathisarends.github.io/notionary – Complete API reference with auto-generated docs from source code


Contributing

We welcome contributions from the community! Whether you're:

  • Fixing bugs - Help improve stability and reliability
  • Adding features - Extend functionality for new use cases
  • Improving docs - Make the library more accessible
  • Sharing examples - Show creative applications and patterns

Check our Contributing Guide to get started.


<div align="center">

Ready to revolutionize your Notion workflows?

📖 Read the Docs · 💻 Browse Examples

Built with ❤️ for Python developers and AI agents

</div>

Related Skills

View on GitHub
GitHub Stars16
CategoryDevelopment
Updated7d ago
Forks5

Languages

Python

Security Score

95/100

Audited on Mar 30, 2026

No findings