Notion Clipper
Clip any web page to Notion. Uses Chrome CDP for full JavaScript rendering, converts to Markdown, then uploads via Notion's 2026-03-11 markdown API.
Prerequisites
- Notion API Key: Create an integration at https://notion.so/my-integrations
- Store the key:
mkdir -p ~/.config/notion
echo "ntn_your_key_here" > ~/.config/notion/api_key
- Share target database/page with your integration (click "..." → "Connect to" → your integration name)
First Time Setup
Dependencies are auto-installed when the script runs. No manual setup needed.
Agent Execution Instructions
CRITICAL: Always use the command pattern below. It auto-installs dependencies on first run.
- Determine this SKILL.md file's directory path as
SKILL_DIR - Command pattern (package.json in
scripts/; always run lazy install first):
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && npx -y tsx main.ts <args>)
- Replace
${SKILL_DIR}with the actual path
Usage
IMPORTANT - Use this command pattern for best results:
# Recommended: Clear proxy env vars and use tsx runtime
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && unset http_proxy https_proxy all_proxy && npx -y tsx main.ts <url> --database-name "Resources")
# Clip to a Notion database by NAME (recommended - searches for database)
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && npx -y tsx main.ts <url> --database-name "Resource")
# Clip to a Notion database by ID
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && npx -y tsx main.ts <url> --database <database_id>)
# Clip to an existing page (creates child page)
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && npx -y tsx main.ts <url> --page <page_id>)
# List all accessible databases
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && npx -y tsx main.ts --list-databases)
# For pages requiring login (wait mode)
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && npx -y tsx main.ts <url> --database-name "Resource" --wait)
Options
| Option | Description |
|---|---|
<url> | URL to clip |
--database-name, -n <name> | Target database by name (searches for match) |
--database, -d <id> | Target Notion database by ID |
--page, -p <id> | Target Notion page ID (creates child page) |
--list-databases, -l | List all accessible databases and exit |
--wait, -w | Wait for user signal before capturing |
--timeout, -t <ms> | Page load timeout (default: 30000) |
--no-bookmark | Don't include source link at top |
Capture Modes
| Mode | Behavior | Use When |
|---|---|---|
| Auto (default) | Capture on network idle | Public pages, static content |
Wait (--wait) | User signals when ready | Login-required, lazy loading, paywalls |
Wait mode workflow:
- Run with
--wait→ Chrome opens, script outputs "Press Enter when ready" - Log in or navigate as needed in the browser
- Press Enter in terminal to trigger capture
Output Structure
When saving to a database, creates a new page with:
- Name: Page title
- Content: Source link + converted markdown content
When saving to a page, creates a child page with:
- Source link
- Converted markdown content
Database Setup
For best results, create a Notion database with these properties:
- Name (Title) - Required, will contain page title
How It Works
- Fetch: Launch Chrome via CDP, navigate to URL
- Render: Wait for JavaScript to execute, scroll to trigger lazy loading
- Extract: Run cleanup script to remove ads/nav, extract main content
- Convert: HTML → Markdown
- Save: Upload markdown directly via Notion's 2026-03-11 markdown API
Dependencies
- Chrome/Chromium browser (installed locally)
- Node.js (script runs with
tsx) - Notion API key configured
(Other dependencies auto-install on first run.)
Environment Variables
| Variable | Description |
|---|---|
NOTION_CLIPPER_CHROME_PATH | Custom Chrome executable path |
NOTION_CLIPPER_CHROME_PROFILE_DIR | Custom Chrome profile directory |
Troubleshooting
| Error | Solution |
|---|---|
ECONNREFUSED | Run unset http_proxy https_proxy all_proxy first |
empty body | Use tsx runtime (NOT bun) |
| Chrome not found | Set NOTION_CLIPPER_CHROME_PATH |
| Content missing | Try --wait mode for dynamic/lazy-loaded pages |
| Notion API error | Ensure integration has access to target database/page |