notion-clipper-skill

Summary

Notion Clipper automates saving web pages into Notion by using Chrome DevTools Protocol to fully render JavaScript-driven sites, converting the rendered HTML to Markdown, and importing it as native Notion blocks. Key features include CLI-driven clipping to a specific Notion database or page, auto-installation of Node dependencies on first run, and a recommended execution pattern that unsets proxy env vars and uses the tsx runtime to avoid common network/runtime issues. Use cases include archiving articles, saving research and reference pages, capturing dynamic single-page apps, and centralizing web-based notes for personal or team knowledge management. Core advantages are faithful rendering of dynamic content, structured Notion-native blocks for searchability and editing, secure use via your Notion integration key, and minimal setup for reproducible clipping workflows.

Notion Clipper

Clip any web page to Notion. Uses Chrome CDP for full JavaScript rendering, converts to Markdown, then to Notion blocks.

Prerequisites

  1. Notion API Key: Create an integration at https://notion.so/my-integrations

  2. Store the key:

    mkdir -p ~/.config/notion
    echo "ntn_your_key_here" > ~/.config/notion/api_key
    
  3. 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.

  1. Determine this SKILL.md file's directory path as SKILL_DIR

  2. 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>)
    
  3. Replace ${SKILL_DIR} with the actual path (e.g. /Users/xxx/.claude/skills/notion-clipper-skill)

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")

Why this pattern?

  • unset http_proxy https_proxy all_proxy - Avoids ECONNREFUSED from proxy conflicts
  • tsx runtime - Node.js runtime that properly handles direct connections (bun has proxy issues)
  • (test -d node_modules || npm install) - Auto-installs dependencies if missing

If you encounter network issues:

  1. Close any VPN/proxy software
  2. Switch to a stable network (mobile hotspot often works)
  3. Use the recommended command pattern above

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 (appends blocks)
--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 bookmark block 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

Output Structure

When saving to a database, creates a new page with:

  • Name: Page title
  • URL: Source URL (if database has URL property)
  • Content: Bookmark block + converted content blocks

When appending to a page, adds:

  • Bookmark block (link to source)
  • Divider
  • Converted content blocks

Database Setup

For best results, create a Notion database with these properties:

  • Name (Title) - Required, will contain page title
  • URL (URL) - Optional, will contain source URL

How It Works

  1. Fetch: Launch Chrome via CDP, navigate to URL
  2. Render: Wait for JavaScript to execute, scroll to trigger lazy loading
  3. Extract: Run cleanup script to remove ads/nav, extract main content
  4. Convert: HTML → Markdown → Notion blocks
  5. Save: Call Notion API to create page or append blocks

Dependencies

  • Chrome/Chromium browser (installed locally)
  • Node.js (script runs with tsx; Bun may route through proxy and return empty body, use Node)
  • Notion API key configured

Troubleshooting

Network Issues

Error Cause Solution
ECONNREFUSED 208.103.161.1:443 DNS returns blocked IP; proxy conflict 1. Close VPN/proxy software 2. Use unset http_proxy https_proxy all_proxy 3. Switch network (e.g., mobile hotspot)
Notion API returned empty body (status 200) Using bun which routes through proxy incorrectly Run with tsx: npx -y tsx main.ts ... (NOT bun)
fetch failed or ECONNREFUSED Proxy env vars set but Node.js https doesn't support them Either: 1. Use network without proxy (unset env vars) 2. Ensure proxy allows HTTPS traffic

Content Issues

Error Cause Solution
Invalid URL for link Notion API rejects non-http(s) URLs Script now removes all markdown links by default to avoid validation errors. Content is preserved, only links are stripped.

Note: The script automatically removes these invalid URL types:

  • javascript:, data:, file:, about: protocols
  • WeChat internal links (weixin:, wx://)
  • Relative paths (/path, ./path)
  • Hash-only links (#anchor)
  • Empty links

General Issues

  • Chrome not found: Set NOTION_CLIPPER_CHROME_PATH environment variable
  • Timeout errors: Increase --timeout value or use --wait mode
  • Content missing: Try --wait mode for dynamic/lazy-loaded pages
  • Notion API error (401/403): Check API key validity and integration permissions
  • Notion API error: Ensure integration has access to target database/page