name: notion-clipper-skill description: 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".
Clip any web page to Notion. Uses Chrome CDP for full JavaScript rendering, converts to Markdown, then to Notion blocks.
mkdir -p ~/.config/notion
echo "ntn_your_key_here" > ~/.config/notion/api_key
Dependencies are auto-installed when the script runs. No manual setup needed.
CRITICAL: Always use the command pattern below. It auto-installs dependencies on first run.
SKILL_DIRscripts/; always run lazy install first):(cd "${SKILL_DIR}/scripts" && (test -d node_modules || npm install) && npx -y tsx main.ts <args>)
${SKILL_DIR} with the actual path (e.g. /Users/xxx/.claude/skills/notion-clipper-skill)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
# 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 (appends blocks)
(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)
| 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 |
| 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:
1. Run with --wait → Chrome opens, script outputs "Press Enter when ready"
2. Log in or navigate as needed in the browser
3. Press Enter in terminal to trigger capture
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
For best results, create a Notion database with these properties: - Name (Title) - Required, will contain page title - URL (URL) - Optional, will contain source URL
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 <url> -n "Resources"
tsx; Bun may route through proxy and return empty body, use Node)(Other dependencies auto-install on first run.)
| 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
| 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_proxy3. 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 |
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).
| 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
NOTION_CLIPPER_CHROME_PATH environment variable--timeout value or use --wait mode--wait mode for dynamic/lazy-loaded pagesThe following optimizations have been implemented to handle unstable networks and invalid URLs:
想要更強大的技能外掛,就來小蔥技能站7w4.net看看吧。
這個 Skill 質量不錯,能可靠地將網頁內容剪藏到 Notion 中。它對網路問題處理得當,有完善的錯誤重試機制,文件詳細易懂。優點是支援登入頁面、自動滾動載入、多種儲存方式(資料庫/頁面)。不足之處是儲存後連結資訊會丟失,圖片只能顯示連結而無法離線檢視,需要網路才能訪問。總體來說功能實用,穩定性好,適合日常使用。