{
  "schema": "snappy-card/1",
  "skill": "snappy-notion",
  "tier": "public",
  "origin_tier": "base",
  "purpose": "You are operating the Notion workspace automation skill. Create, update, and enrich Notion pages with structured blocks and generated diagrams. Prefer `snappy-docs` for pure page/database ops; this skill is kept for its Charlotte MCP image generation integration.",
  "verbs": [
    {
      "name": "me",
      "args": [],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-notion/api.ts me"
    },
    {
      "name": "page",
      "args": [
        "page-id"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-notion/api.ts page <page-id>"
    },
    {
      "name": "get",
      "args": [
        "page-id"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-notion/api.ts get <page-id>"
    },
    {
      "name": "search",
      "args": [
        "query"
      ],
      "effect": "read",
      "firstCall": "npx tsx ~/.claude/skills/snappy-notion/api.ts search \"<query>\""
    }
  ],
  "faces": [],
  "agents": [],
  "uses": [],
  "used_by": [],
  "checks": {
    "pass": 41,
    "fail": 8,
    "defer": 12,
    "line": "41 of 49 checks pass",
    "failing": [
      {
        "id": 4,
        "rule": "Near-neighbour descriptions cross-reference each other",
        "says": "near neighbours not named: snappy-specwatch"
      },
      {
        "id": 9,
        "rule": "Time-sensitive prose is isolated under Old patterns",
        "says": "7 time-sensitive instruction line(s) outside Old patterns"
      },
      {
        "id": 10,
        "rule": "One term names each concept",
        "says": "mixed synonym sets: endpoint/url/route/path, field/box/element"
      },
      {
        "id": 11,
        "rule": "Each task presents one default, not a menu",
        "says": "1 line(s) present three-way alternative menus"
      },
      {
        "id": 54,
        "rule": "At least three eval scenarios precede ready status",
        "says": "0 eval scenario(s); ready=true"
      },
      {
        "id": 55,
        "rule": "Eval scenarios are multi-call with ground truth",
        "says": "eval manifest missing"
      },
      {
        "id": 57,
        "rule": "Eval manifest contains a disjoint holdout",
        "says": "0 disjoint holdout scenario(s)"
      },
      {
        "id": 60,
        "rule": "Loader publishes the contract's derived first call, current",
        "says": "generated block is stale against HAND_CONTRACT; run fix-loader"
      }
    ]
  },
  "coverage": null,
  "spec": null,
  "evals": null,
  "files": [
    "AGENTS.md",
    "SKILL.md",
    "api-reference.md",
    "api.ts",
    "block-types.md",
    "face.test.ts",
    "faces/components/notion-faces.css",
    "faces/components/notion-faces.tsx",
    "faces/family.tsx",
    "faces/fixtures/notion-append.json",
    "faces/fixtures/notion-blocks.json",
    "faces/fixtures/notion-page.json",
    "faces/fixtures/notion-pages.json",
    "image-workflows.md",
    "page-recipes.md",
    "refusals.test.ts"
  ],
  "total_size": 136912,
  "checksum": "sha256:2ae2e6a51c6e08a3eedc184550b0008d6b8e8c9d4211886775107391797df62a",
  "built_at": "2026-09-09T22:09:57.112Z",
  "openapi": {
    "openapi": "3.1.0",
    "info": {
      "title": "snappy-notion",
      "version": "0.0.0",
      "description": "NARROW -- generating whiteboard and diagram IMAGES via Charlotte MCP image_generate and inserting them into Notion pages at the right position. Use ONLY when a page needs generated visuals. NOT the general Notion primitive: creating pages, appending blocks, querying databases, and the document recipes all belong to snappy-docs, which is the default for writing to Notion. Triggers: notion diagram, notion whiteboard, insert image notion, generate diagram notion, snappy notion, visual for notion page"
    },
    "x-snappy-transport": "cli",
    "servers": [
      {
        "url": "npx tsx ~/.claude/skills/snappy-notion/api.ts",
        "description": "The hand itself. Every path is a verb word, every query or body key an argument."
      }
    ],
    "paths": {
      "/me": {
        "get": {
          "operationId": "snappy_notion_me",
          "summary": "snappy-notion me",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/page": {
        "get": {
          "operationId": "snappy_notion_page",
          "summary": "snappy-notion page",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "page-id",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "The Notion page id — the 32-character UUID at the end of the page's URL, with or without dashes",
                "x-snappy-position": 0
              }
            },
            {
              "name": "json",
              "in": "query",
              "required": false,
              "schema": {
                "x-snappy-flag": "--json"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/get": {
        "get": {
          "operationId": "snappy_notion_get",
          "summary": "snappy-notion get",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "page-id",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "The Notion page id — the 32-character UUID at the end of the page's URL, with or without dashes",
                "x-snappy-position": 0
              }
            },
            {
              "name": "json",
              "in": "query",
              "required": false,
              "schema": {
                "x-snappy-flag": "--json"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/append": {
        "post": {
          "operationId": "snappy_notion_append",
          "summary": "snappy-notion append",
          "x-snappy-effect": "write-reversible",
          "x-snappy-annotations": {
            "readOnlyHint": false,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "page-id": {
                      "type": "string",
                      "description": "The Notion page id — the 32-character UUID at the end of the page's URL, or a `search` row's `id`",
                      "x-snappy-position": 0
                    },
                    "text": {
                      "type": "string",
                      "description": "The paragraph's words, verbatim; they are added at the END of the page and nothing already there is touched",
                      "x-snappy-position": 1
                    },
                    "json": {
                      "x-snappy-flag": "--json"
                    }
                  },
                  "required": [
                    "page-id",
                    "text"
                  ]
                }
              }
            }
          },
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      },
      "/search": {
        "get": {
          "operationId": "snappy_notion_search",
          "summary": "snappy-notion search",
          "x-snappy-effect": "read",
          "x-snappy-annotations": {
            "readOnlyHint": true,
            "destructiveHint": false,
            "idempotentHint": false,
            "openWorldHint": true
          },
          "parameters": [
            {
              "name": "query",
              "in": "query",
              "required": true,
              "schema": {
                "type": "string",
                "description": "Search text matched against page and database titles in the workspace",
                "x-snappy-position": 0
              }
            },
            {
              "name": "limit",
              "in": "query",
              "required": false,
              "schema": {
                "type": "integer",
                "description": "How many results to return. The count is the FLAG --limit, never a positional word; default 20, ceiling 100",
                "default": 20,
                "minimum": 1,
                "maximum": 100,
                "x-snappy-flag": "--limit"
              }
            },
            {
              "name": "json",
              "in": "query",
              "required": false,
              "schema": {
                "x-snappy-flag": "--json"
              }
            }
          ],
          "responses": {
            "200": {
              "description": "The verb's own answer, as printed by `--json`."
            }
          }
        }
      }
    },
    "components": {
      "schemas": {
        "SnappyRefusal": {
          "type": "object",
          "required": [
            "outcome",
            "code",
            "message"
          ],
          "properties": {
            "outcome": {
              "type": "string",
              "const": "refused"
            },
            "code": {
              "type": "string",
              "description": "A row of the closed refusal table."
            },
            "message": {
              "type": "string"
            },
            "fix": {
              "type": "string"
            }
          }
        }
      }
    },
    "x-snappy-requires": [
      "NOTION_TOKEN"
    ]
  }
}