notion-clipper-skill
/install notion-clipper-skill
Notion Clipper
Clip any web page to Notion. Uses Chrome CDP for full JavaScript rendering, converts to Markdown, then to Notion blocks.
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 \x3Cargs>)
- 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 \x3Curl> --database-name "Resources")
Why this pattern?
unset http_proxy https_proxy all_proxy- Avoids ECONNREFUSED from proxy conflictstsxruntime - 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:
- Close any VPN/proxy software
- Switch to a stable network (mobile hotspot often works)
- Use the recommended command pattern above
# 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 \x3Curl> --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 \x3Curl> --database \x3Cdatabase_id>)
# Clip to an existing page (appends blocks)
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && npx -y tsx main.ts \x3Curl> --page \x3Cpage_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 \x3Curl> --database-name "Resource" --wait)
Options
| Option | Description |
|---|---|
\x3Curl> |
URL to clip |
--database-name, -n \x3Cname> |
Target database by name (searches for match) |
--database, -d \x3Cid> |
Target Notion database by ID |
--page, -p \x3Cid> |
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 \x3Cms> |
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 |
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
- 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
Examples
Clip a tweet to "Resource" database (by name):
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && unset http_proxy https_proxy all_proxy && npx -y tsx main.ts "https://x.com/dotey/status/123456" -n "Resource")
List all databases first:
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && unset http_proxy https_proxy all_proxy && npx -y tsx main.ts --list-databases)
Clip article requiring login:
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && unset http_proxy https_proxy all_proxy && npx -y tsx main.ts "https://medium.com/article" -n "Reading" --wait)
Append to reading notes page:
(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && unset http_proxy https_proxy all_proxy && npx -y tsx main.ts "https://blog.example.com/post" -p xyz789)
Quick alias (add to your ~/.bashrc or ~/.zshrc):
alias notion-clip='(cd "${SKILL_DIR}/scripts" && unset http_proxy https_proxy all_proxy && npx -y tsx main.ts)'
# Usage: notion-clip \x3Curl> -n "Resources"
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 → Notion blocks
- 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
(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 |
https_proxy / HTTP_PROXY |
Proxy for Notion API (e.g. http://127.0.0.1:7890) |
http_proxy / HTTPS_PROXY |
Same as above |
all_proxy |
Optional, e.g. socks5://127.0.0.1:7890 |
Example (proxy on port 7890):
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890
Troubleshooting
Network Issues
| Error | Cause | Solution |
|---|---|---|
ECONNREFUSED 208.103.161.1:443 |
DNS returns blocked IP; proxy conflict | 1. Close VPN/proxy software\x3Cbr>2. Use unset http_proxy https_proxy all_proxy\x3Cbr>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:\x3Cbr>1. Use network without proxy (unset env vars)\x3Cbr>2. Ensure proxy allows HTTPS traffic |
CloudFlare 403 |
Direct IP access triggers security protection | Use hostname instead of IP; ensure proper Authorization header |
| Mixed: Sometimes works, sometimes fails | Unstable network or DNS returns different IPs | Script now has 6 retries with exponential backoff (1s, 2s, 4s, 4s...) |
Best Practice: For reliable Notion API access, use a stable network (mobile hotspot often works better than corporate VPN).
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_PATHenvironment variable - Timeout errors: Increase
--timeoutvalue or use--waitmode - Content missing: Try
--waitmode 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
Code Optimizations Applied
The following optimizations have been implemented to handle unstable networks and invalid URLs:
- Auto-retry mechanism: Up to 6 retries with exponential backoff (1s → 2s → 4s → 4s...)
- Increased timeout: 30s for Notion API requests (was 25s)
- URL cleaning: Removes invalid URLs before Notion API submission
- Using tsx: Node.js runtime that properly handles direct connections (unlike Bun)
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install notion-clipper-skill - 安装完成后,直接呼叫该 Skill 的名称或使用
/notion-clipper-skill触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
notion-clipper-skill 是什么?
Clip web pages to Notion. Fetches any URL via Chrome CDP, converts HTML to Markdown, then to Notion blocks, and saves to user-specified Notion database or page. Use when user wants to save/clip a webpage to Notion, or mentions "clip to notion", "save page to notion", "网页剪藏到Notion". 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 966 次。
如何安装 notion-clipper-skill?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install notion-clipper-skill」即可一键安装,无需额外配置。
notion-clipper-skill 是免费的吗?
是的,notion-clipper-skill 完全免费(开源免费),可自由下载、安装和使用。
notion-clipper-skill 支持哪些平台?
notion-clipper-skill 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 notion-clipper-skill?
由 EwingYangs(@ewingyangs)开发并维护,当前版本 v1.0.0。