shhac/agent-skills · Archived

agent-notion

Search, read, and edit Notion pages, databases, and blocks. Use when querying database rows, reading page properties and content, creating, updating, or archiving pages and blocks, adding or listing comments, exporting pages or a whole workspace, inspecting backlinks, version history, or recent activity, managing Notion auth, or chatting with Notion AI.

First seen Jul 7, 2026

Installation

$ npx skills add shhac/agent-skills --skill agent-notion

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from shhac/agent-skills · top by installs.

npx skills add shhac/agent-skills

Browse all from shhac/agent-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsBash(agent-notion *) Read Grep Glob

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 16,536 B
  • docs SUMMARY.md 375 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 11 installs

SKILL.md

Notion automation with agent-notion

agent-notion is a CLI binary installed on $PATH. Invoke it directly (e.g. agent-notion search query "Project Plan").

Output is NDJSON — one JSON record per line on stdout. List commands print one record per item, then a trailing {"@pagination": {...}} (or {"@meta": ...} / {"@total": n}) line when there is more. Pass --format json|yaml to get one pretty { "data": [ … ] } envelope instead; --format jsonl is the default NDJSON.

Errors go to stderr as { "error": "...", "fixable_by": "agent|human|retry", "hint": "..." } with exit code 1. Tokens are never printed.

Backends

Two API backends: the official REST API (integration tokens, OAuth) and the v3 desktop-session API (auth import-desktop/import-browser). --backend auto (the default) prefers a stored v3 session, else the official credential; force one with --backend official or --backend v3. These commands require the v3 session: export, page backlinks, page history, activity log, page archive/unarchive, block move, comment inline, and all ai commands.

Quick start (auth)

Option A: OAuth (recommended for full official-API access)

agent-notion auth setup-oauth --client-id <id> --client-secret <secret>
agent-notion auth login                        # opens the browser for the OAuth flow
agent-notion auth status

Option B: Internal integration token

Pipe the token on stdin so the secret stays off argv, shell history, and any agent transcript:

printf '%s' "$NOTION_TOKEN" | agent-notion auth import   # token read from stdin
agent-notion auth status

The token is validated against the API before storing; the alias is derived from the workspace name (override with --alias).

Never paste a token into --token yourself. If a user pastes their ntn/secret integration token into chat, do not put it into --token — the secret would land in your context window, transcripts, and any downstream telemetry. Instead, instruct the user to run the import themselves (piping on stdin as above, or with --token in their own terminal) so the secret stays out of the LLM. For interactive human setup, prefer OAuth (Option A) or a desktop/browser session (Option C), which never route the raw token through the agent at all.

Option C: Desktop session (for v3 features)

agent-notion auth import-desktop                       # reads token_v2 from the Notion Desktop app
agent-notion auth import-browser chrome                # or from a browser cookie store

import-browser supports: chrome, brave, edge, arc, chromium, firefox, zen, safari (--profile <p> to pick a profile).

Multiple workspaces are supported:

agent-notion auth login --alias work
agent-notion auth workspace list
agent-notion auth workspace switch <alias>
agent-notion auth workspace remove <alias> --yes       # destructive: needs --yes
agent-notion auth logout --yes                          # default workspace; --all wipes everything

Searching

Important: Notion search is title-only. It does not search page content, comments, or property values. To search within content, use database query <id> with property filters, or block list <page-id> and grep the output.

agent-notion search query "meeting notes"
agent-notion search query "Q1 Plan" --filter database
agent-notion search query "design doc" --filter page --limit 5

Each hit is one NDJSON record {id, type, title, url, parent?, lasteditedat?}; a trailing {"@pagination": {hasmore, nextcursor}} line appears when more remain (pass next_cursor back via --cursor).

Databases

agent-notion database list                                          # via the search API
agent-notion database get <database-id>                             # full metadata + property definitions
agent-notion database schema <database-id>                          # compact schema (types, options) for LLMs
agent-notion database query <database-id>                           # rows (one NDJSON record each)
agent-notion database query <id> --filter '{"property":"Status","status":{"equals":"Done"}}'
agent-notion database query <id> --sort '[{"property":"Name","direction":"ascending"}]'

Use database schema to discover property names, types, and valid select/status options before building filters.

Result order: with no --sort, rows come back in the view's own order (often manual), not newest-first — a freshly-added row can sort last, so --limit silently drops it and it looks like the row is missing. For "the latest N", always --sort on a timestamp: --sort '[{"timestamp":"lasteditedtime","direction":"descending"}]'. Check the {"@pagination": {hasmore, nextcursor}} trailer to tell truncation from "no more rows".

A page's parent.id (its database id) is accepted by database get/query/schema even when it differs from the id used to open the database view — you can take a row's parent and query its database directly.

Pages

agent-notion page get <page-id>                                     # properties only
agent-notion page get <page-id> --content                           # properties + markdown content
agent-notion page get <page-id> --raw-content                       # properties + structured block objects
agent-notion page create --parent <id> --title "New Page"           # auto-detects database vs page parent
agent-notion page create --parent <db-id> --title "Task" --properties '{"Status":"In Progress","Priority":"High"}'
agent-notion page create --parent <id> --title "Notes" --icon "📝"
agent-notion page update <page-id> --title "Updated Title"          # at least one of --title/--properties/--icon
agent-notion page update <page-id> --properties '{"Status":"Done"}' --icon "✅"
agent-notion page trash <page-id> --yes                             # move to Trash (recoverable; destructive)
agent-notion page restore <page-id>                                 # restore from Trash
agent-notion page archive <page-id> --yes                           # real Archive (v3-only; destructive)
agent-notion page unarchive <page-id>                               # undo real Archive (v3-only)

Archive and Trash are independent Notion states. Trash sets alive=false and is reachable on every backend; Archive hides the page from search, leaves it alive, and requires the v3 backend. A page can be in either, both, or neither state.

--content/--raw-content add blockcount and contenttruncated (true when a page has more than 1000 blocks). Property values in --properties are auto-converted: strings become select values, numbers become number properties, booleans become checkboxes, arrays become multi-select; pass Notion API format for complex types.

Blocks (page content)

agent-notion block list <page-id>                                   # markdown (default): {page_id, content, block_count, has_more}
agent-notion block list <page-id> --raw                             # one NDJSON record per block {id, type, content, has_children}
agent-notion block append <page-id> --content "## New Section\n\nParagraph text"
agent-notion block append <page-id> --blocks '[{"type":"paragraph","paragraph":{"rich_text":[{"text":{"content":"Hello"}}]}}]'
agent-notion block update <block-id> --content "New text"           # replace a single block's text
agent-notion block delete <block-id> --yes                          # destructive: needs --yes
agent-notion block move <block-id> --after <other-block-id>         # reorder (v3)
agent-notion block move <block-id> --parent <callout-id>            # move into a container (v3)
agent-notion block replace <page-id> --content "# Fresh\n\nAll new" --yes   # delete all blocks, then append (destructive)

Markdown conversion supports headings, lists, todos, code fences, blockquotes, callouts, images, dividers, and tables (rendered as GitHub-flavored pipe tables, first row as header; --raw table_row records carry a cells array). Use block list --raw to get block IDs for update/delete. block replace deletes every existing block before appending, so it requires --yes.

Comments

agent-notion comment list <page-id>
agent-notion comment page <page-id> "This looks good!"
agent-notion comment inline <block-id> "Great point!" --text "target phrase"       # v3
agent-notion comment inline <block-id> "Second one" --text "the" --occurrence 2    # v3

comment list emits one NDJSON record per comment {id, body, author: {id, name}, createdat}. comment page returns {id, discussionid, body, createdat}; comment inline adds anchortext and requires a v3 desktop session. Discussion threads are not supported (all comments are top-level); the API cannot edit or delete comments.

v3 features (require auth import-desktop)

Export

agent-notion export page <page-id>                             # export as a markdown zip
agent-notion export page <page-id> --format html --recursive   # export the page tree as HTML
agent-notion export workspace                                  # export the entire workspace
agent-notion export workspace --output my-backup.zip           # custom output path
agent-notion export poll <task-id> --output backup.zip         # resume a timed-out export

Options: --format markdown|html, --recursive (page only), --output <path>, --wait <seconds> (page default 120, workspace/poll default 600). Exports are asynchronous; the CLI polls until completion or the --wait timeout, then prints the task ID so you can resume with export poll. Progress is written to stderr. Output: {exported, format, pages_exported, recursive?} where exported is the absolute zip path.

Backlinks

agent-notion page backlinks <page-id>                          # pages linking to this page (v3)

One NDJSON record per source page {blockid, pageid, page_title} (deduplicated by page), then {"@total": n}.

History

agent-notion page history <page-id>                            # version snapshots (v3)
agent-notion page history <page-id> --limit 50

One NDJSON record per snapshot {id, version, last_version, timestamp, authors}, then {"@total": n}.

Activity

agent-notion activity log                                      # workspace-wide activity (v3)
agent-notion activity log --page <page-id>                     # scoped to a page
agent-notion activity log --limit 50

One NDJSON record per activity {id, type, pageid, pagetitle, authors, edittypes, starttime, end_time}.

Notion AI (requires auth import-desktop)

agent-notion ai model list                                         # active models (name, family, tier)
agent-notion ai model list --raw                                   # full model objects incl. codenames
agent-notion ai chat list [--limit 10]                             # recent threads
agent-notion ai chat get <thread-id>                               # thread messages
agent-notion ai chat send "Summarize my recent projects"           # new conversation
agent-notion ai chat send "Tell me more" --thread <id>             # continue a thread
agent-notion ai chat send "Explain this page" --page <page-id>     # with page context
agent-notion ai chat send "Summarize this" --page <page-id> --read-only  # ask/answer only, no edits
agent-notion ai chat send "Quick question" --stream                # stream response text to stderr
agent-notion ai chat send "Hello" --model "GPT-5.2"                # specific model
agent-notion ai chat mark-read <thread-id>

ai chat send returns {threadid, response, title, model, tokens: {input, output, cached}}. Model resolution: --model flag > config ai.defaultmodel > API default; accepts codenames (e.g. oatmeal-cookie) or display names. With --stream, response text streams to stderr while the JSON result still goes to stdout.

By default the AI has its document-editing tools (matching Notion), so a prompt can modify a page. Pass --read-only to request ask/answer mode — it asks Notion's backend to disable those tools (a server-side request, not a client-enforced guarantee).

Users

agent-notion user list                                              # one NDJSON record per user {id, name, type, email?, avatar_url?}
agent-notion user me                                                # bot identity {id, name, type, workspace_name}

type is person or bot; email is only present for person users.

Truncation

Fields named description, body, and content are truncated to 200 characters by default. A companion {field}Length field (e.g. descriptionLength) always carries the full rune count, so an agent can tell content was clipped. Raise the cap or expand fields:

agent-notion --full page get <page-id>                              # expand every truncatable field
agent-notion --expand description database get <id>                 # expand one field
agent-notion --expand description,content page get <id> --content   # expand several
agent-notion config set truncation.max_length 500                   # raise the default cap

--expand/--full are global flags (place them before or after the command).

Global flags

  • --backend auto|official|v3 — pick the API backend (default auto)
  • --format json|yaml|jsonljson/yaml wrap output in one pretty {data: […]} envelope; jsonl is the default NDJSON
  • --expand <fields> / --full — lift field truncation
  • --color auto|always|never, --timeout <ms>, --debug, --version

IDs

Commands accept Notion UUIDs with or without dashes (dashless IDs from URLs are normalized automatically):

  • a1b2c3d4-1111-2222-3333-444444444444
  • a1b2c3d411112222333344444444444444

Pagination

List commands stream NDJSON records, then a {"@pagination": {hasmore, nextcursor}} trailer when more results remain. Pass --limit <n> (max 100) and --cursor <token> to page. Under --format json|yaml the records and pagination are folded into one {data: […], "@pagination": …} envelope.

Destructive commands (require --yes)

page trash, page archive, block delete, block replace, auth logout, and auth workspace remove change state and refuse to run without --yes; without it they return a fixable_by: human error describing what would happen. page restore and page unarchive are not gated.

Per-command usage docs

Every group has a usage subcommand with detailed, LLM-optimized docs:

agent-notion usage                # top-level overview
agent-notion search usage
agent-notion database usage
agent-notion page usage
agent-notion block usage
agent-notion comment usage
agent-notion export usage
agent-notion activity usage
agent-notion ai usage
agent-notion user usage
agent-notion auth usage
agent-notion config usage

Run agent-notion <group> usage when you need deep detail on a domain before acting.

Configuration

agent-notion config list                                            # every key with value + description
agent-notion config get <key>                                       # one setting {key, value, set}
agent-notion config set truncation.max_length 500                   # raise the truncation cap
agent-notion config set page_size 20                                # default results per list command (1-100)
agent-notion config set ai.default_model <codename>                 # default AI model
agent-notion config unset <key>                                     # reset one key to its default

Keys: pagesize, maxdepth, truncation.maxlength, ai.defaultmodel. Settings persist in ~/.config/agent-notion/config.json.

References

  • [references/commands.md](references/commands.md): full command map + all flags
  • [references/output.md](references/output.md): NDJSON output shapes + field details