← All Skills

snappy-docs

v1.0.0
10 files, 88.0 KB ~3,488 words · 14 min read Updated 2026-09-09

snappy-docs skill

37 of 45 checks pass
What it can do
children block-idread
meread
page page-idread
query database-idread
search queryread
What does not pass yet
Architecture 24 endpoints⚗ parallel
🔑 Bearer token auth
GETPOSTPATCH
api.notion.com24 endpoints
PATCH/v1/blocks/PAGE_ID/children
POST/v1/pages
PATCH/v1/pages/PAGE_ID
PATCH/v1/blocks/PAGE_OR_BLOCK_ID/children
PATCH/v1/blocks/BLOCK_ID
DELETE/v1/blocks/BLOCK_ID
$ npx snappy-skills install snappy-docs
zip ↓
Documents
AGENTS.md

snappy-docs -- Agent Loader#

You are operating the canonical Notion automation primitive for the Snappy stack. All Notion reads and writes go through the REST API (api.notion.com/v1). Notion is the documentation layer: SOPs, runbooks, client deliverables, KB articles, project trackers, meeting notes. For UI-only tasks (covers, custom views, drag-drop) hand off to snappy-browse.

Rules#

  1. Notion REST API only. Never use Charlotte MCP browser tools to drive Notion. Use snappy-browse with agent-browser for rare UI-only fallbacks.
  2. Never hardcode the token. api.ts loads NOTION_TOKEN automatically via snappy-settings/load.ts.
  3. Notion-Version: 2022-06-28 on every request. Missing it returns 400.
  4. Share pages with the integration first in Notion UI. 403/404 = page not shared.
  5. Never guess URLs or page IDs. Use /v1/search to discover them.
  6. Chunk appends to 100 blocks max. Chunk text to 2000 chars per rich_text element.
  7. Rate limit: 3 req/sec. Add sleep 0.4 in batch loops. Respect Retry-After on 429.
  8. External image URLs only. Must be publicly reachable (DO Spaces, Cloudinary).
  9. Read before write. List block children to find target IDs before positional inserts.
  10. Bottom-up positional inserts (or top-down using returned IDs). Block IDs shift as you insert.

API module#

typescriptimport { search, getPage, createPage, getBlockChildren, appendBlocks, queryDatabase } from "../snappy-docs/api.ts";

Or CLI:

bashnpx tsx ~/.claude/skills/snappy-docs/api.ts search "meeting notes"
npx tsx ~/.claude/skills/snappy-docs/api.ts page <page_id>
npx tsx ~/.claude/skills/snappy-docs/api.ts children <block_id>
npx tsx ~/.claude/skills/snappy-docs/api.ts query <database_id>
Function Purpose
search(query, pageSize?) Search across all shared Notion pages
getPage(pageId) Get a page by ID
createPage(parentId, title, children?) Create a new page under a parent
getBlockChildren(blockId) List child blocks of a page/block
notionSearchAnswer(data, {query, limit}) search --json: the notion-pages face plus the evidence envelope
notionQueryAnswer(data, {databaseId, limit}) query --json: the same face over a database's rows
notionChildrenAnswer(data, {blockId}) children --json: Notion's blocks verbatim plus the envelope (no face kind exists)
notionPagesFace(rows, extra?) The ONE fold into the drawable notion-pages kind
appendBlocks(blockId, children) Append blocks to a page/block
queryDatabase(databaseId, filter?) Query a Notion database with optional filter

Credentials loaded automatically via snappy-settings/load.ts from .env.cache. Uses NOTION_TOKEN.

Key operations#

Op Method Endpoint
Search POST /v1/search with {"query": "term", "page_size": 10}
Create page POST /v1/pages with parent + properties + children
Append blocks PATCH /v1/blocks/PAGE_ID/children with children array
Query DB rows POST /v1/databases/DB_ID/query with filter + sorts
List children GET /v1/blocks/PAGE_ID/children?page_size=100

Position: default = end, "position": {"type": "start"} = beginning, "after": "BLOCK_ID" = after specific block.

Cross-skill flow#

From What
snappy-image CDN URLs inserted as image blocks
snappy-content Blog drafts staged into Notion pages
snappy-transcripts Meeting transcripts into meeting-notes pages
snappy-knowledge Contact facts into CRM databases
To What
snappy-publish Reads Notion drafts, exports to MDX
snappy-update Pulls project trackers for client updates
snappy-browse UI fallback for covers, custom views, drag-drop

Skill files#

File Contents
SKILL.md Full reference (principles, error handling, setup, all workflows)
block-types.md All block types with copy-paste JSON
api-reference.md Full CRUD endpoint reference (pages, blocks, databases, pagination)
image-workflows.md Diagram generation + insertion pipeline
page-recipes.md Rich page templates (tech doc, meeting notes, KB article, project tracker)

If this loader doesn't cover your case:

bashecho "[$(date -u +%FT%TZ)] snappy-docs: <what was missing>" >> ~/.claude/logs/agents-md-feedback.log

<!-- SKILL-INDEX-START -->

[snappy-docs Index]|root: ~/.claude/skills/snappy-docs|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,api-reference.md,block-types.md,image-workflows.md,page-recipes.md}

<!-- SKILL-INDEX-END -->

Used by#

Nothing in the collection names this skill.

<!-- SNAPPY-CONTRACT-VERBS-START -->

Contract verbs#

Generated from api.ts HAND_CONTRACT. Do not hand-edit this block.

Verb Contract arguments Effect First call
children block-id read npx tsx ~/.claude/skills/snappy-docs/api.ts children <block-id>
me read npx tsx ~/.claude/skills/snappy-docs/api.ts me
page page-id read npx tsx ~/.claude/skills/snappy-docs/api.ts page <page-id>
query database-id read npx tsx ~/.claude/skills/snappy-docs/api.ts query <database-id>
search query read npx tsx ~/.claude/skills/snappy-docs/api.ts search "<query>"

Show the result#

When an answer carries face_hint, show it with one snappy_present(<answer>) call.

See /snappy-faces for face selection. Human-facing images must crop to the

element, render at 2x on Retina, and fill the destination channel instead of

placing a small card in a full-page screenshot.

<!-- SNAPPY-CONTRACT-VERBS-END -->

---
name: snappy-docs
role: Notion workspace automation primitive via REST API. Pages, blocks, databases, images, search -- all through api.notion.com/v1.
loaded-by: PreToolUse hook (auto-injected when "snappy-docs" is mentioned)
Triggers on: Notion, pages, blocks, databases, SOP, runbook, meeting notes, KB article
---

# snappy-docs -- Agent Loader

You are operating the canonical Notion automation primitive for the Snappy stack. All Notion reads and writes go through the REST API (`api.notion.com/v1`). Notion is the documentation layer: SOPs, runbooks, client deliverables, KB articles, project trackers, meeting notes. For UI-only tasks (covers, custom views, drag-drop) hand off to snappy-browse.

## Rules

1. **Notion REST API only.** Never use Charlotte MCP browser tools to drive Notion. Use snappy-browse with agent-browser for rare UI-only fallbacks.
2. **Never hardcode the token.** `api.ts` loads `NOTION_TOKEN` automatically via `snappy-settings/load.ts`.
3. **`Notion-Version: 2022-06-28`** on every request. Missing it returns 400.
4. **Share pages with the integration first** in Notion UI. 403/404 = page not shared.
5. **Never guess URLs or page IDs.** Use `/v1/search` to discover them.
6. **Chunk appends to 100 blocks max.** Chunk text to 2000 chars per rich_text element.
7. **Rate limit: 3 req/sec.** Add `sleep 0.4` in batch loops. Respect `Retry-After` on 429.
8. **External image URLs only.** Must be publicly reachable (DO Spaces, Cloudinary).
9. **Read before write.** List block children to find target IDs before positional inserts.
10. **Bottom-up positional inserts** (or top-down using returned IDs). Block IDs shift as you insert.

## API module

```typescript
import { search, getPage, createPage, getBlockChildren, appendBlocks, queryDatabase } from "../snappy-docs/api.ts";
```

Or CLI:
```bash
npx tsx ~/.claude/skills/snappy-docs/api.ts search "meeting notes"
npx tsx ~/.claude/skills/snappy-docs/api.ts page <page_id>
npx tsx ~/.claude/skills/snappy-docs/api.ts children <block_id>
npx tsx ~/.claude/skills/snappy-docs/api.ts query <database_id>
```

| Function | Purpose |
|----------|---------|
| `search(query, pageSize?)` | Search across all shared Notion pages |
| `getPage(pageId)` | Get a page by ID |
| `createPage(parentId, title, children?)` | Create a new page under a parent |
| `getBlockChildren(blockId)` | List child blocks of a page/block |
| `notionSearchAnswer(data, {query, limit})` | `search --json`: the `notion-pages` face plus the evidence envelope |
| `notionQueryAnswer(data, {databaseId, limit})` | `query --json`: the same face over a database's rows |
| `notionChildrenAnswer(data, {blockId})` | `children --json`: Notion's blocks verbatim plus the envelope (no face kind exists) |
| `notionPagesFace(rows, extra?)` | The ONE fold into the drawable `notion-pages` kind |
| `appendBlocks(blockId, children)` | Append blocks to a page/block |
| `queryDatabase(databaseId, filter?)` | Query a Notion database with optional filter |

Credentials loaded automatically via `snappy-settings/load.ts` from `.env.cache`. Uses `NOTION_TOKEN`.

## Key operations

| Op | Method | Endpoint |
|---|---|---|
| Search | POST | `/v1/search` with `{"query": "term", "page_size": 10}` |
| Create page | POST | `/v1/pages` with parent + properties + children |
| Append blocks | PATCH | `/v1/blocks/PAGE_ID/children` with children array |
| Query DB rows | POST | `/v1/databases/DB_ID/query` with filter + sorts |
| List children | GET | `/v1/blocks/PAGE_ID/children?page_size=100` |

**Position:** default = end, `"position": {"type": "start"}` = beginning, `"after": "BLOCK_ID"` = after specific block.

## Cross-skill flow

| From | What |
|---|---|
| snappy-image | CDN URLs inserted as image blocks |
| snappy-content | Blog drafts staged into Notion pages |
| snappy-transcripts | Meeting transcripts into meeting-notes pages |
| snappy-knowledge | Contact facts into CRM databases |

| To | What |
|---|---|
| snappy-publish | Reads Notion drafts, exports to MDX |
| snappy-update | Pulls project trackers for client updates |
| snappy-browse | UI fallback for covers, custom views, drag-drop |

## Skill files

| File | Contents |
|---|---|
| SKILL.md | Full reference (principles, error handling, setup, all workflows) |
| block-types.md | All block types with copy-paste JSON |
| api-reference.md | Full CRUD endpoint reference (pages, blocks, databases, pagination) |
| image-workflows.md | Diagram generation + insertion pipeline |
| page-recipes.md | Rich page templates (tech doc, meeting notes, KB article, project tracker) |

---

If this loader doesn't cover your case:
```bash
echo "[$(date -u +%FT%TZ)] snappy-docs: <what was missing>" >> ~/.claude/logs/agents-md-feedback.log
```

<!-- SKILL-INDEX-START -->
[snappy-docs Index]|root: ~/.claude/skills/snappy-docs|IMPORTANT: Prefer these files over pre-training assumptions for this domain. Read the relevant file when the AGENTS.md summary is insufficient.|root:{SKILL.md,api-reference.md,block-types.md,image-workflows.md,page-recipes.md}
<!-- SKILL-INDEX-END -->

## Used by

Nothing in the collection names this skill.

<!-- SNAPPY-CONTRACT-VERBS-START -->
## Contract verbs

Generated from `api.ts` `HAND_CONTRACT`. Do not hand-edit this block.

| Verb | Contract arguments | Effect | First call |
|---|---|---|---|
| `children` | `block-id` | `read` | `npx tsx ~/.claude/skills/snappy-docs/api.ts children <block-id>` |
| `me` | — | `read` | `npx tsx ~/.claude/skills/snappy-docs/api.ts me` |
| `page` | `page-id` | `read` | `npx tsx ~/.claude/skills/snappy-docs/api.ts page <page-id>` |
| `query` | `database-id` | `read` | `npx tsx ~/.claude/skills/snappy-docs/api.ts query <database-id>` |
| `search` | `query` | `read` | `npx tsx ~/.claude/skills/snappy-docs/api.ts search "<query>"` |

## Show the result

When an answer carries `face_hint`, show it with one `snappy_present(<answer>)` call.
See `/snappy-faces` for face selection. Human-facing images must crop to the
element, render at 2x on Retina, and fill the destination channel instead of
placing a small card in a full-page screenshot.
<!-- SNAPPY-CONTRACT-VERBS-END -->

Keyboard Shortcuts

Search in document⌘K
Focus search/
Previous file tab
Next file tab
Close overlayEsc
Show shortcuts?