Agent skill

Notion Connector

by ericrisco in ericrisco/rsc-harness

A skill your agent uses when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an…

MITAuto-check passedBackend & APIs

Install Notion Connector

skills CLI
$ npx skills add ericrisco/rsc-harness --skill notion-connector -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ericrisco/rsc-harness notion-connector --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/notion-connector .claude/skills/notion-connector && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
notion-connector
GitHub stars
174
Token cost
~2.4k tokens
SKILL.md length
878 words
Files
7 (incl. scripts, references)
Skills in repo
233
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an…

  • Works in 4 steps: Create an internal integration in Notion… → Put the token in an env var, never in… → Share the target database/page with the… → …
  • Wiring server code
  • SKILL.md covers Route elsewhere, Setup (4 steps), The database → data source… and Query a data source, plus 7 more sections
  • Runs Shell scripts from its folder; needs NOTION_TOKEN

What it does

Notion Connector is an agent skill from ericrisco/rsc-harness. Use when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an integration broken by the 2025-09-03 data-source split. NOT generic REST wiring (that is api-connector-builder), NOT inbound Notion webhook events (that is webhooks).

Its SKILL.md is about 2.4k tokens, which your agent loads only when the skill is triggered. The skill folder holds 9 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/api-versions.md`).

It sits in Backend & APIs, covering Webhooks, REST APIs and Scheduled and recurring tasks. It works with Notion. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.

When your agent uses it

  • Wiring server code
  • A cron job to Notion as an ops backend over its HTTP API: pushing
  • Mirroring database rows
  • Two-way sync without duplicates

Example prompts

  • “/notion-connector”

Requirements

  • A Bash shell
  • A credential in NOTION_TOKEN

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. Create an internal integration in Notion → Settings → Integrations. Copy
  2. Put the token in an env var, never in client-side JS, never committed. It
  3. Share the target database/page with the integration in the Notion UI
  4. Construct the SDK client with a pinned Notion-Version. Official JS SDK

What it can do on your machine

Read from SKILL.md and the folder at commit e3d5b33. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Shell), which the agent can run.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • NOTION_TOKEN

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Notion Connector loads about 2.4k tokens when it runs, and up to ~5.1k if it reads all its reference files. Until then it costs about 91 tokens; SKILL.md has 878 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~91
When it runs · the whole SKILL.md, loaded when a task matches
~2.4k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~5.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from ericrisco/rsc-harness at commit e3d5b33, republished under its MIT licence (© ericrisco). 878 words, ~2,432 tokens.

Download SKILL.mdSave it as .claude/skills/notion-connector/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.
name
notion-connector
description
Use when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an integration broken by the 2025-09-03 data-source split. NOT generic REST wiring (that is `api-connector-builder`), NOT inbound Notion webhook events (that is `webhooks`).
tags
notion, ops-backend, api-integration, databases, sync
recommends
api-connector-builder, webhooks, automation-flows, spreadsheet-ops, secure-coding
origin
risco

Notion connector — Notion as a code-backed ops store

Wire server code to the Notion HTTP API so a database behaves like a small operational store: push rows, pull rows, sync both ways idempotently, read and write page blocks. This skill owns the outbound Notion API surface only — the database/data-source data model, property-type write shapes, and the rate-limit/pagination discipline that the API forces on you.

Route elsewhere

SituationRoute to
Generic "call any REST API", nothing Notion-specific../api-connector-builder/SKILL.md
Receiving + verifying inbound Notion webhook events../webhooks/SKILL.md
Notion is one node in a multi-tool sequence../automation-flows/SKILL.md
CSV/tabular bulk transforms, column mechanics../spreadsheet-ops/SKILL.md
Token handling, secret rotation, never-client-side rules../secure-coding/SKILL.md

Setup (4 steps)

  1. Create an internal integration in Notion → Settings → Integrations. Copy the secret — it looks like ntn_... (older ones secret_...).
  2. Put the token in an env var, never in client-side JS, never committed. It is a bearer secret; treat it like a password. See ../secure-coding/SKILL.md.
  3. Share the target database/page with the integration in the Notion UI (the page ••• menu → Connections). Skip this and every call 404s or returns empty — the integration sees nothing it was not explicitly granted.
  4. Construct the SDK client with a pinned Notion-Version. Official JS SDK is @notionhq/client v5.12.0+ (latest 5.22.0, 2026-05-19); its default notionVersion is the current major 2025-09-03, and it supports the latest 2026-03-11 if you opt in. The default and method names below are stable across the whole 5.x line. Behavior differs across versions, so pin it per client (or per request) — an unpinned client drifts when the default moves.
ts
import { Client } from "@notionhq/client"; // v5.12.0+ (latest 5.22.0)

const notion = new Client({
  auth: process.env.NOTION_TOKEN,          // ntn_... — env only, never inlined
  notionVersion: "2025-09-03",             // pin it; do not ride the default
});

The database → data source model (biggest gotcha)

Post 2025-09-03 a database is a container of one or more data sources, not a queryable table: it holds a data_sources array and each data source has its own schema. Resolve the data source before you query — query and read schema against it, not against the database, or code that worked last year 404s silently.

You have…Do this
A database_idGET /v1/databases/:id → read data_sources[] ({id,name}) → use that id
Already a data_source_idUse it directly for query/schema/pages
A DB with >1 data sourcePick the right one by name; never assume index 0

Endpoints moved to /v1/data_sources:

diff
- POST /v1/databases/:database_id/query        # 2022-06-28 — 404s on 2025-09-03+
+ POST /v1/data_sources/:data_source_id/query  # query rows
+ GET  /v1/data_sources/:data_source_id         # schema (properties)
+ PATCH /v1/data_sources/:data_source_id        # update schema / title
ts
// Resolve once, then reuse the data_source_id everywhere downstream.
const db = await notion.databases.retrieve({ database_id: DATABASE_ID });
const dataSourceId = db.data_sources[0].id; // verify by name if >1 exists

Query a data source

Send filter + sorts in the body. Page size maxes at 100; results are cursor-based. Always loop on has_more + next_cursor or you silently drop every row past the first 100. Filter operand shapes per property type live in references/property-shapes.md.

ts
async function queryAll(dataSourceId: string, filter?: object) {
  const rows: any[] = [];
  let cursor: string | undefined = undefined;
  do {
    const res = await notion.dataSources.query({
      data_source_id: dataSourceId,
      filter,
      page_size: 100,                 // hard max
      start_cursor: cursor,
    });
    rows.push(...res.results);
    cursor = res.has_more ? res.next_cursor ?? undefined : undefined;
  } while (cursor);
  return rows;
}

Property write shapes

Most write failures (HTTP 400) are a wrong property envelope. Each type has its own JSON shape. The high-frequency ones:

TypeWrite shape (abridged)
title{ title: [{ text: { content } }] }
rich_text{ rich_text: [{ text: { content } }] }
number{ number: 42 }
select{ select: { name } }
multi_select{ multi_select: [{ name }] }
status{ status: { name } }
date{ date: { start, end? } } (ISO 8601)
checkbox{ checkbox: true }
relation{ relation: [{ id }] }
people{ people: [{ id }] }
url{ url: "https://…" }

Full write + read-parse JSON for every type → references/property-shapes.md.

Create / update pages (rows)

A page's parent is the data source, not the database:

ts
// CREATE a row
await notion.pages.create({
  parent: { type: "data_source_id", data_source_id: dataSourceId },
  properties: {
    Name: { title: [{ text: { content: "Ship invoice export" } }] },
    Status: { status: { name: "In progress" } },
    ExternalId: { rich_text: [{ text: { content: extId } }] },
  },
});

// UPDATE a row: PATCH the page by id; send only changed properties
await notion.pages.update({
  page_id,
  properties: { Status: { status: { name: "Done" } } },
});

To soft-delete: on 2025-09-03 set { archived: true }; on 2026-03-11 that field is renamed { in_trash: true }. Match the field to the version you pinned (see references/api-versions.md).

Show full SKILL.md (363 more words)Show less

Sync patterns

Idempotency is the whole game. Store the Notion page_id keyed by your external id (a column in your DB, or a rich_text "ExternalId" property in Notion). An upsert is: query-by-external-key → if a row exists, pages.update; else pages.create. Never blind-create on a re-run — that is how you get duplicate rows.

  • One-way (app → Notion): upsert on every sync; the app is source of truth.
  • Two-way: track a last_edited_time watermark on each side; last-writer wins, or flag conflicts for review. Cursor-checkpoint large pulls.

Dedupe, two-way reconcile, and checkpointing → references/sync-patterns.md.

Rate limits & resilience

The integration is capped at ~3 requests/second average. Over-limit calls return HTTP 429 with a Retry-After header (seconds) — honor it, do not guess a fixed sleep. Cap concurrency, batch reads, back off on 429.

ts
async function withRetry<T>(fn: () => Promise<T>, tries = 5): Promise<T> {
  for (let i = 0; ; i++) {
    try {
      return await fn();
    } catch (e: any) {
      const after = Number(e?.headers?.["retry-after"]);
      if (e?.status === 429 && i < tries) {
        const wait = Number.isFinite(after) ? after * 1000 : 2 ** i * 500;
        await new Promise((r) => setTimeout(r, wait));
        continue;
      }
      throw e;
    }
  }
}

Version migration

From → ToWhat changed
2022-06-28 → 2025-09-03DB is a container; query/schema move to /v1/data_sources; page parent is data_source_id; search filter value "database" → "data_source"
2025-09-03 → 2026-03-11block after param → position object (after_block/start/end); archived → in_trash (pages/dbs/blocks/data sources); block type transcription → meeting_notes

Exact field/endpoint diffs → references/api-versions.md.

Anti-patterns

Anti-patternWhy it bitesDo instead
Unpinned Notion-VersionBehavior shifts when the default movesPin per request/client
POST /v1/databases/:id/query on 2025-09-03+404 — that path is goneResolve data source → /v1/data_sources/:id/query
Forgetting to share the DB with the integration404 / empty results, looks like an auth bugShare in the UI (step 3)
No pagination loopSilently drops every row past 100Loop on has_more + next_cursor
Ignoring 429 / fixed sleepHammers the 3 req/s ceiling, gets bannedHonor Retry-After, exponential backoff
Blind pages.create on every syncDuplicate rows on re-runUpsert: query-by-external-key first
Token in client-side JS or committedLeaked bearer secret = full workspace accessEnv var + secret manager
Assuming one DB = one schemaBreaks on multi-data-source DBsResolve and select by data-source name
Using database_id as a page parentRejected on 2025-09-03+{ type: "data_source_id", data_source_id }
archived on 2026-03-11Field renamedUse in_trash for that version

verify.sh

scripts/verify.sh <file-or-dir> statically lints a connector you (or the agent) wrote: it flags a missing pinned Notion-Version/notionVersion, a deprecated databases/:id/query query path, a query without a has_more/next_cursor loop, and missing 429/Retry-After handling. Read-only; exits 0 on a clean or empty target. It does not call Notion.

© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 6 other files (scripts, references) in skills/notion-connector of ericrisco/rsc-harness.

  • SKILL.md
  • evals/README.md
  • evals/cases.yaml
  • references/api-versions.md
  • references/property-shapes.md
  • references/sync-patterns.md
  • scripts/verify.sh

Open the folder on GitHubat commit e3d5b33

Compare with similar skills

Notion Connector next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Notion Connector compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Notion Connector this skillericrisco/rsc-harness174—~2.4kAutomated safety check: PassMIT
Workspace APIfriday-platform/friday-studio104—~9.3kAutomated safety check: NotesCustom licence
Function Devbutterbase-ai/butterbase-skills534—~2.8kAutomated safety check: PassMIT
Nextclaw Self ManagePeiiii/nextclaw260—~3.5kAutomated safety check: PassMIT
Wp Performancegambitph/Stackable3513 repos~1.5kAutomated safety check: PassGPL-3.0
API Patternsdilolabs/nosia2131 repos~2.5kAutomated safety check: PassMIT

Similar skills

  • Workspace API

    friday-platform/friday-studio

    Create, list, update, delete, and clean up workspaces via the daemon HTTP API at $FRIDAYDURL.

    104 GitHub stars~9.3k tokensUpdated 1 mo ago
    Backend & APIsAuto-check: notes
  • Function Dev

    butterbase-ai/butterbase-skills

    A skill your agent uses when developing, deploying, or debugging Butterbase serverless functions, or when the user needs to add backend logic like webhooks, scheduled jobs, or custom API endpoints

    534 GitHub stars~2.8k tokensUpdated 4 days ago
    Backend & APIsAuto-check passed
  • Nextclaw Self Manage

    Peiiii/nextclaw

    Self-manage NextClaw runtime via CLI guide. An agent skill from Peiiii/nextclaw.

    260 GitHub stars~3.5k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Wp Performance

    gambitph/Stackable

    A skill your agent uses when investigating or improving WordPress performance (backend-only agent): profiling and measurement (WP-CLI profile/doctor, Server-Timing, Query Monitor via REST headers)…

    351 GitHub starsUsed in 3 repos~1.5k tokens
    Backend & APIsAuto-check passed
  • API Patterns

    dilolabs/nosia

    Builds REST APIs using respondto blocks with Jbuilder templates following the 37signals same-controllers-different-formats philosophy.

    213 GitHub starsUsed in 1 repo~2.5k tokens
    Backend & APIsAuto-check passed
  • Loops API

    openinary/openinary

    A skill your agent uses whenever the user wants to integrate Loops from application code, backend services, webhook handlers, or server-side automation.

    412 GitHub stars~1.1k tokensUpdated 5 days ago
    Backend & APIsAuto-check passed

More from ericrisco/rsc-harness

All 233 skills in this repo
  • Ab Testing

    ericrisco/rsc-harness

    A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…

    174 GitHub stars~2.4k tokensUpdated 2 days ago
    Auto-check passed
  • Accessibility

    ericrisco/rsc-harness

    A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…

    174 GitHub stars~3.4k tokensUpdated 2 days ago
    Auto-check passed
  • Ads

    ericrisco/rsc-harness

    A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…

    174 GitHub stars~2.2k tokensUpdated 2 days ago
    Auto-check passed
  • Agent Eval

    ericrisco/rsc-harness

    A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…

    174 GitHub stars~3.2k tokensUpdated 2 days ago
    Auto-check passed
  • AI Media

    ericrisco/rsc-harness

    A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…

    174 GitHub stars~3.3k tokensUpdated 2 days ago
    Auto-check passed
  • Analytics

    ericrisco/rsc-harness

    A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.

    174 GitHub stars~2.8k tokensUpdated 2 days ago
    Auto-check passed

Works with

Categories

Questions about Notion Connector

What does Notion Connector do?

A skill your agent uses when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an…. Notion Connector is an agent skill from ericrisco/rsc-harness. Use when wiring server code or a cron job to Notion as an ops backend over its HTTP API: pushing or mirroring database rows, two-way sync without duplicates, page blocks, or an integration broken by the 2025-09-03 data-source split.

When should I use Notion Connector?

Notion Connector fits situations like: wiring server code; A cron job to Notion as an ops backend over its HTTP API: pushing; mirroring database rows; two-way sync without duplicates.

How do I install Notion Connector in Claude Code?

Run `npx skills add ericrisco/rsc-harness --skill notion-connector -a claude-code`. Or copy the skill folder (skills/notion-connector in ericrisco/rsc-harness) into .claude/skills/notion-connector in your project. Claude Code loads it when a task matches its description.

How do I install Notion Connector in Codex?

Run `npx skills add ericrisco/rsc-harness --skill notion-connector -a codex`. Or copy the skill folder (skills/notion-connector in ericrisco/rsc-harness) into .agents/skills/notion-connector in your project. Codex loads it when a task matches its description.

Can I use Notion Connector in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill notion-connector -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/notion-connector, .gemini/skills/notion-connector, .github/skills/notion-connector and .opencode/skills/notion-connector in your project.

What does Notion Connector need to run?

Going by SKILL.md and its folder, Notion Connector needs a shell for the scripts in its folder and credentials named NOTION_TOKEN. Our summary lists: A Bash shell; A credential in NOTION_TOKEN.

Does Notion Connector access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Notion Connector safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Notion Connector use?

Notion Connector is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Notion Connector use?

About 2.4k tokens (SKILL.md is roughly 9.7k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.6k tokens, read only when the agent opens those files.

What are the alternatives to Notion Connector?

Skills that share tags, products or a category with Notion Connector: Workspace API (friday-platform/friday-studio, 104 stars), Function Dev (butterbase-ai/butterbase-skills, 534 stars), Nextclaw Self Manage (Peiiii/nextclaw, 260 stars) and Wp Performance (gambitph/Stackable, 351 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Notion Connector?

ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 174 GitHub stars. The repository holds 233 skills in this directory. The repository was last updated on October 7, 2026.

Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.