AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL unreviewed MIT Self-run

Notion

skill-atlasomnia-donna-starter-notion · by AtlasOmnia

Notion API + ntn CLI: pages, databases, markdown, Workers.

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-atlasomnia-donna-starter-notion

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Pipes remote content directly into a shell (remote code execution).

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

Not yet reviewed
0 installs to date
no reviews yet
5d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Notion? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Notion

Talk to Notion two ways. Same integration token works for both — pick by what's available.

ntn CLI — Notion's official CLI. Shorter syntax, one-line file uploads, required for Workers. macOS + Linux only as of May 2026 (Windows support "coming soon"). Default when installed.HTTP + curl — works everywhere including Windows. Default fallback when ntn isn't installed.

Setup

1. Get an integration token (required for both paths)

  1. Create an integration at https://notion.so/my-integrations
  2. Copy the API key (starts with ntn_ or secret_)
  3. Store in ${HERMES_HOME:-~/.hermes}/.env:

`` NOTION_API_KEY=ntn_yo...re ``

  1. Ensure the integration is connected to the workspace — before sharing any pages, verify the integration appears in your workspace's connection list:
  • Open any page in Notion → click Share (top-right) → ⚙️ SettingsConnections tab
  • The integration should appear under Connected apps. If NOT listed, the API key is valid but the integration has no workspace linkage — every API call will return 404 object_not_found regardless of page sharing.
  • To connect: go to https://notion.so/my-integrations → click your integration → in the Connected pages section, enable "Full workspace access" (or connect individual top-level pages manually).
  • After connecting, verify it shows up in the Connections panel before proceeding.
  1. Share target pages/databases with the integration in Notion: page menu ...Connect to → your integration name. Without this, the API returns 404 for that page even though it exists.

1b. Grant workspace-wide access (optional, recommended for single-user workspaces)

To avoid connecting pages one by one, grant the integration full workspace access:

  1. Open https://notion.so/my-integrations
  2. Find your integration → click it
  3. Change access from Selected pages to Full workspace access (exact label may vary — look for a toggle or dropdown)
  4. This makes all existing and future pages visible to the integration by default

Tip: For single-user workspaces, Option 1b is the cleanest approach. For shared workspaces, connect individual top-level pages instead — child pages inherit access from their parent.

  1. For full workspace access (single-user workspaces): Open https://notion.so/my-integrations → click your integration → enable "Full workspace access" in the Connected pages section. This avoids having to manually connect every page. Child pages inherit access from their parent, so connecting top-level pages is sufficient if you prefer granular control.

2. Install ntn (preferred path on macOS / Linux)

### 2. Install `ntn` (preferred path on macOS / Linux)

```bash
# Recommended — use custom install dir if /usr/local/bin needs sudo
curl -fsSL https://ntn.dev | bash

# Or to a user-writable location (fallback when /usr/local/bin is locked):
curl -fsSL "https://ntn.dev" | NTN_INSTALL_DIR="$HOME/.local/bin" bash

# Or via npm (needs Node 22+, npm 10+)
npm install --global ntn

ntn --version # verify

macOS note: On recent macOS, /usr/local/bin may require sudo. Use NTN_INSTALL_DIR="$HOME/.local/bin" as a fallback — just ensure $HOME/.local/bin is on your PATH.

Skip ntn login — use the integration token instead. This works headlessly, no browser needed:

export NOTION_API_TOKEN=*** # ntn reads NOTION_API_TOKEN (not NOTION_API_KEY)
export NOTION_KEYRING=0 # don't try to use the OS keychain

Add those exports to your shell profile (or to ${HERMES_HOME:-~/.hermes}/.env) so every session inherits them.

> Pitfall: On macOS, curl -fsSL https://ntn.dev | bash fails with "Could not install to /usr/local/bin" — use NTN_INSTALL_DIR="$HOME/.local/bin" instead. Ensure $HOME/.local/bin is on your PATH.

3. Choose path at runtime

if command -v ntn >/dev/null 2>&1; then
 # use ntn
else
 # fall back to curl
fi

Windows users: skip step 2 entirely until native ntn ships — Path B works fine. If you want CLI ergonomics now, install ntn inside WSL2.

API Basics

Notion-Version: 2025-09-03 is required on all HTTP requests. ntn handles this for you. In this version, what users call "databases" are called data sources in the API.

Path A — ntn CLI (preferred, macOS / Linux)

Raw API calls (shorthand for curl)

ntn api v1/users # GET
ntn api v1/pages parent[page_id]=abc123 \ # POST with inline body
 properties[title][0][text][content]="Notes"
ntn api v1/pages/abc123 -X PATCH archived:=true # PATCH; := is non-string (bool/num/null)

Syntax notes:

  • key=value — string fields
  • key[nested]=value — nested object fields
  • key:=value — typed assignment (booleans, numbers, null, arrays)

Search

ntn api v1/search query="page title"

Read page metadata

ntn api v1/pages/{page_id}

Read page as Markdown (agent-friendly)

ntn api v1/pages/{page_id}/markdown

Read page content as blocks

ntn api v1/blocks/{page_id}/children

Create page from Markdown

ntn api v1/pages \
 parent[page_id]=xxx \
 properties[title][0][text][content]="Notes from meeting" \
 markdown="# Agenda

- Q3 roadmap
- Hiring"

Patch a page with Markdown

The current endpoint uses a command-style discriminated union. For a full replacement:

ntn api v1/pages/{page_id}/markdown -X PATCH \
 type=replace_content \
 replace_content[new_str]="## Update

Shipped the prototype."

For pages containing child pages or databases, prefer insert_content or update_content; replace_content refuses to delete protected child content unless allow_deleting_content=true.

Query a database (data source)

ntn api v1/data_sources/{data_source_id}/query -X POST \
 filter[property]=Status filter[select][equals]=Active

For complex queries with sorts, multiple filter clauses, or compound logic, pipe JSON in:

echo '{"filter": {"property": "Status", "select": {"equals": "Active"}}, "sorts": [{"property": "Date", "direction": "descending"}]}' | \
 ntn api v1/data_sources/{data_source_id}/query -X POST --json -

File uploads (one-liner — biggest CLI win)

ntn files create  `Hello, ${name}!`,
});

Webhook capability

worker.webhook("onGithubPush", {
 title: "GitHub Push Handler",
 execute: async (events, { notion }) => {
 for (const event of events) {
 // event.body, event.rawBody (for signature verification), event.headers
 console.log("got delivery", event.deliveryId);
 }
 },
});

After deploy: ntn workers webhooks list shows the URL Notion generates. Treat that URL as a secret — anyone with it can POST events unless you add signature verification.

Worker lifecycle commands

ntn workers deploy
ntn workers list
ntn workers exec  -d '{"name": "world"}'
ntn workers sync trigger  # run a sync now
ntn workers sync pause 
ntn workers env set GITHUB_WEBHOOK_SECRET=...
ntn workers runs list # recent invocations
ntn workers runs logs 
ntn workers webhooks list

When asked to build a Worker, scaffold with ntn workers new, write the code in src/index.ts, set any secrets with ntn workers env set, and deploy. Notion's docs at https://developers.notion.com/workers cover the full API surface.

Notion-Flavored Markdown (used by /markdown endpoints)

Standard CommonMark plus XML-like tags for Notion-specific blocks. Use tabs for indentation.

Blocks beyond CommonMark:


	Ship the MVP by **Friday**.

Toggle title
	Children indented one tab

	Left side
	Right side

Inline:

  • Mentions: `, Title, `
  • Underline: text
  • Color: text or block-level {color="blue"} on the first line
  • Math: inline $x^2$, block $$ ... $$
  • Citations: [^https://example.com]

Colors: gray brown orange yellow green blue purple pink red, plus *_bg variants for backgrounds.

Headings 5/6 collapse to H4. Multiple > lines render as separate quote blocks — use ` inside a single >` for multi-line quotes.

Choosing the Right Path

| Task | mac / Linux | Windows | |---|---|---| | Read/write pages, search, query databases | ntn api ... | curl | | Read a page for an agent to summarize | ntn api v1/pages/{id}/markdown | curl /markdown endpoint | | Upload a file | ntn files create /) and proceed with API calls. The CUA path is useful for diagnosing why the integration isn't visible — it reveals whether the issue is page sharing vs. workspace connection.

  • Bot integrations cannot create workspace-root pages OR databases: The API v2025-09-03 requires parent.page_id or parent.database_id for all page AND database creation. Bot integrations (internal, not public) have no member_page. To create top-level content, you MUST first have a manually-created parent page shared with the integration — then nest everything under it. The workspace-parent shortcut ("parent": {"type": "workspace"}) works for neither pages nor databases on bot integrations — both return validation_error asking for parent.page_id.
  • ntn CLI headless auth requires TWO env vars: NOTION_API_TOKEN (the integration key) AND NOTION_WORKSPACE_ID (from /v1/users/mebot.workspace_id). Without NOTION_WORKSPACE_ID, ntn errors with "No workspace selected." Set both:

``bash export NOTION_API_TOKEN=*** export NOTION_WORKSPACE_ID= ``

  • Archived datasources are stuck: Once a database (datasource) is archived via PATCH /v1/data_sources/{id}, it cannot be unarchived through any endpoint — /v1/pages/, /v1/databases/, and /v1/data_sources/ all return 400 or 404. Recreate instead of trying to restore.
  • Bulk archiving hits type mismatches: When searching for items to archive, database rows appear in search results but their IDs may not resolve on /v1/pages/ (404) nor on /v1/data_sources/ (wrong type). The reliable path: collect unique parent database IDs from search results and archive the parent databases — their rows disappear with them.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.