Clip the article, not the furniture. A Firefox extension that extracts the readable part of a page and files it into Notion as Markdown.
Website Β· Install on Firefox Β· Extension Β· Privacy Β· Quick start
- One-click clip: URL + title + selection or full readable article as Markdown.
- Smart extraction: articles, YouTube/video pages, index/listing pages, or plain links β picked from JSON-LD /
og:type. - Sign in with Notion, nothing to paste β OAuth 2.1 + PKCE via Notion's hosted MCP server, no backend or secret.
- Save as new page/row or append to an existing page; inline databases discovered automatically.
- Database rows come filled in: URL, tags, and author / site / published date / note when the database has columns named for them. Pages get the site's preview image as cover and its icon.
- Notes, pinned destinations, an "Already clipped" warning with a link to the earlier page, and an Open in Notion link after every clip.
- Quick clip:
Alt+Shift+Cor Clip to Notion in the context menu clips straight to the last destination. - Highlights: save passages from the context menu or
Alt+Shift+H, keep them locally, sync them into a Notion database β or append them to an existing page β when the popup opens. - No build step, no dependencies. Just load
manifest.json.
- Firefox:
about:debugging#/runtime/this-firefoxβ Load Temporary Add-on β picknotion-clipper-source/manifest.json. Chrome:chrome://extensionsβ Developer mode β Load unpacked β picknotion-clipper-source/. - Click the add-on β Connect Notion β choose which pages to share.
- Pick a destination β Clip.
How picks what happens at the destination: New page inside creates a child page (or a row, if the destination is a database), Append to the end adds the clip to the bottom via notion-update-page / insert_content. Appending is disabled for databases, which cannot hold loose blocks.
The dropdown loads recent pages on open (notion-list-recent-pages); typing searches the workspace (notion-search). Selecting a page also lists inline databases inside it, indented with β³. Both only ever see pages shared during consent. Pasting a link still works for anything the list misses.
A database destination is read once when you pick it, so the popup can offer its tags as chips (type new ones comma-separated; they are added to the database's tag column for you) and the clip can fill the matching columns. β pins the current destination to the top of the list.
Quick clip (Alt+Shift+C, or Clip to Notion in the context menu) skips the popup and clips to wherever you last clipped from it β no note, tags or custom title. The badge shows β¦, then β or !; a failure is explained the next time you open the popup. With no destination yet, it opens the popup instead.
Highlights accumulate instead of being clipped one at a time. Select text, then use the context menu or Alt+Shift+H; the badge counts what is waiting. Nothing is sent while you read β the queue drains into Notion the next time the popup opens, from the Highlights disclosure at the bottom of the popup. Pick the destination in Open Settings: a database gets one row per passage, a page gets them appended as quotes grouped by source, or let it create a database for you. The same passage saved twice, or from two URLs of one article, is one highlight. Context menu and shortcut are desktop-only; Firefox for Android has neither API.
Save as resets to A new page inside every popup open β appending is a per-clip decision, never sticky.
A text selection outranks everything: highlight something and the clip is that quote alone. Article bodies cap at 60,000 characters and are marked when truncated.
- Auth talks to Notion's hosted MCP server (
https://mcp.notion.com) with dynamic client registration (RFC 7591,token_endpoint_auth_method: "none") β designed for public clients. Each install registers as its own OAuth client. Notion's REST OAuth is intentionally avoided: it needs aclient_secreta public extension cannot hold. - Sign-in runs in the background page (
auth.js), not the popup β Firefox destroys popups when focus moves to the auth window, killing the exchange mid-flight. - Pages are created with the
notion-create-pagesMCP tool (Markdown in, no block JSON). - Extraction is @mozilla/readability 0.6.0 + turndown 7.2.0 + turndown-plugin-gfm 1.0.2, vendored unmodified in
vendor/. A page counts as an index when Readability finds under 600 characters of prose (link text excluded).
See notion-clipper-source/README.md for the full technical notes.
- notion-clipper-source/ β the extension. No build step; load
manifest.jsondirectly. - notion-clipper-site/ β landing page + privacy policy, served at slipclip.todorx.dev.
cd notion-clipper-source && node test.mjsBare Node 18+, no dependencies. .github/workflows/test.yml runs it on every push touching the extension.
The extension is the zip of notion-clipper-source/, with manifest.json at the archive root:
npx -y web-ext build --source-dir notion-clipper-source --artifacts-dir dist --overwrite-destRelease Firefox needs a signed package, so the file on a GitHub release must come back from addons.mozilla.org. Upload dist/*.zip by hand, or sign with AMO API credentials:
npx -y web-ext sign --source-dir notion-clipper-source --channel unlisted --api-key "$AMO_JWT_ISSUER" --api-secret "$AMO_JWT_SECRET"--channel unlisted returns a self-distributable .xpi; --channel listed submits for review. The site's download button points at releases, so publish the signed file there first.
Firefox 140 is the floor (MV3 service workers); Chrome 120+ for DNR modifyHeaders. (strict_min_version): host permissions grant-at-install needs 127+, data_collection_permissions needs 140. Firefox for Android reads that key only from 142, so leave the Android listing off on AMO.
.github/workflows/deploy.yml publishes notion-clipper-site/ to GitHub Pages on pushes to main touching it (or by hand from Actions). One-time setup:
- Settings β Pages β Source: GitHub Actions (not branch deploy).
- Settings β Pages β Custom domain:
slipclip.todorx.dev, Enforce HTTPS once issued.
DNS on todorx.dev: CNAME slipclip β todorx.github.io. notion-clipper-site/CNAME pins the hostname so redeploys keep it. og.png is rendered from og.svg (scrapers don't read SVG):
cd notion-clipper-site && npx -y @resvg/resvg-js-cli og.svg og.png --font-serif-family GeorgiaTokens live in storage.local (~8h access, ~180d refresh, rotated on use). The manifest declares data_collection_permissions (websiteContent, searchTerms) β shown on the AMO install prompt. Full policy: privacy.html.
vendor/ holds unmodified release builds; licenses in THIRD-PARTY-NOTICES.md (ships inside the extension). SlipClip's own code is MIT β see LICENSE.
MIT β see LICENSE.
Not affiliated with Notion Labs, Inc.
