A browser extension for Karakeep. One click on the toolbar button:
- saves the tab to Karakeep (automatically, or after you confirm), then shows its tags, lists and note for editing, and the copy Karakeep scraped;
- captures the page as Markdown, using the same engine as Obsidian Web Clipper (Defuddle);
- on YouTube, captures the transcript already shown on the page, with timestamps, chapters, language, title, canonical URL and video id. Keepsake itself makes no requests to YouTube: no caption fetch, no API fallback. If the transcript panel is closed, it clicks YouTube's own Show transcript button (setting Open YouTube transcript automatically, on by default), so YouTube loads it exactly as after a manual click, and closes it again after the capture. With the setting off, it asks you to open the panel and retry;
- optionally classifies the bookmark with Jev right after saving and files it into Karakeep lists and a topic tag (see Jev tagging).
Captures can be copied, downloaded as Markdown or JSON, sent to Obsidian, or attached to the Karakeep bookmark. Karakeep is the single store: a Hermes agent reads the transcripts and page Markdown from there for its triage, and uploads its own transcript fallback there too. Why this exists instead of the official Karakeep extension: docs/MOTIVATION.md.
Needs Node 24 and pnpm.
pnpm install
pnpm build # Chrome/Chromium/Edge → .output/chrome-mv3
pnpm build:firefox # Firefox → .output/firefox-mv3- Chrome: open
chrome://extensions, enable Developer mode, Load unpacked, pick.output/chrome-mv3. - Firefox: install
keepsake-<version>.xpifrom the latest release once. Firefox then updates it itself (it checks about once a day; Check for Updates inabout:addonsforces it). To ship a version, publish a GitHub Release taggedvX.Y.Z(higher than the last one, e.g.gh release create v0.3.0 --generate-notes).release-firefox.ymlthen has Mozilla sign it as an unlisted add-on and attaches the.xpiandupdates.jsonto that release. It needs the repository secretsAMO_JWT_ISSUERandAMO_JWT_SECRET(addons.mozilla.org → Developer Hub → Manage API Keys). For local testing:about:debugging#/runtime/this-firefox→ Load Temporary Add-on →.output/firefox-mv3/manifest.json.
Click the gear in the popup (or the extension's Options):
| setting | meaning |
|---|---|
| Server address | Your Karakeep URL. HTTPS, or HTTP only for localhost/LAN addresses. The browser asks once for permission to reach exactly that origin. |
| Email & password / API key | Password sign-in exchanges your credentials for an API key, as the official Karakeep extension does. The key is kept in this browser profile's local extension storage. It is never synced, exported or logged. |
| Logged in as / Sign out | Shows the Karakeep account. Sign out forgets the key; revoke it in Karakeep under Settings → API Keys. |
| Auto-save on open | On: the tab is saved when the popup opens. Off: you confirm before saving. |
| Auto-attach transcripts | On (default): a captured YouTube transcript is attached to the bookmark when the popup opens. Replacing a different transcript still asks first. Off: click Attach. |
| Tag transcripts | Optional tag added when a transcript is attached. |
| Jev API key / Endpoint / Model | Key empty = off; stored locally only. Endpoint (full URL of a Jev systemone endpoint) and model select the provider; neither has a default. Save requests permission for the endpoint's origin; saved bookmarks are then classified using page text/transcripts. |
| Theme | System, light or dark. |
| Obsidian vault / folder | Shows an Obsidian button that copies the Markdown and opens obsidian://new…&clipboard, the same way Obsidian Web Clipper does. |
- Open the video. (With Open YouTube transcript automatically off, also click …more under it, then Show transcript.)
- Click the Keepsake button. The Capture tab says Transcript captured with the segment count and language.
- With Auto-attach on it is attached right away; otherwise Attach transcript to Karakeep stores it on the bookmark as an attachment named
keepsake-transcript-<videoId>-<lang>-<hash>.html. Clicking again does nothing: the same transcript is already attached. A different transcript in the same language is only replaced after you confirm.
Other states you can see: Open the transcript first, No captions on this video, The page is still switching videos (the transcript belongs to the previous video in YouTube's single-page navigation), Too large to capture, Nothing to capture here. If Karakeep rejects an upload after 3 attempts, the capture goes to an outbox shown in the popup with Retry now. Nothing is dropped silently.
Off until you set an API key, endpoint and model. Then, when a bookmark is saved (or opened and not yet classified), Keepsake:
- attaches the page Markdown as
keepsake-page-<hash>.html(YouTube: the transcript is attached as described above); - sends the title, URL, description (up to 600 characters) and page text or transcript (up
to 3,000 characters) to your Jev endpoint, with your existing
topic-*tags as choices; - tags the bookmark with the best topic (probability at least 0.5) and
jev-tagged, then adds it toResearch > Tech|Business|IdeasandLibrary > Articles|Tools|Videos|Reposwhen those lists exist.
This runs in the extension's background worker, so you can close the popup right away.
Bookmarks that already have jev-tagged or any topic-* tag are skipped. On YouTube, Jev runs only when the transcript was captured.
Checked against the deployed Karakeep 0.32.0, both in its source and on a local
0.32.0 instance. The API refuses to attach anything as linkHtmlContent (HTTP 400), so
the scraped copy can't be overwritten. Keepsake uploads the transcript as a text/html
asset and attaches it as userUploaded. It shows up under Attachments, and the note,
tags, metadata and scraped content stay unchanged. Karakeep serves the file with
Content-Security-Policy: sandbox; default-src 'none'. The full reasoning is in
docs/ARCHITECTURE.md.
activeTab, scripting, storage, plus runtime access to your Karakeep origin and, optionally, your Jev endpoint's origin.
There are no content scripts, no background polling (the background worker only runs Jev when the popup asks), and no access to cookies, history
or other tabs. Page reading happens only when you open the popup.
pnpm test # unit tests (vitest)
scripts/karakeep-local.sh up && pnpm test:e2e # Playwright + local Karakeep 0.32.0The e2e suite loads the built extension in Chromium and serves a fixture page at a real
https://www.youtube.com/watch?v=… URL through request interception. Every other request
is blocked and recorded, and the Chrome DevTools Protocol logs all traffic from the
YouTube tab and the popup. It asserts:
- zero YouTube/caption requests while capturing;
- the unopened-panel instruction appears and no transcript is created;
- the exact segments, timestamps and chapters arrive in Karakeep;
- a duplicate click leaves one bookmark, one attachment, and the original note and tags.
The local Karakeep runs with its crawler disabled and a dead proxy, so bookmarking test YouTube URLs never contacts YouTube.
- Extension: remove or disable it in
chrome://extensions/about:addons. It stores nothing outside its own extension storage. - Karakeep: Delete
keepsake-transcript-*.htmlandkeepsake-page-*.htmlfrom Attachments as needed. Remove optional transcript/Jev tags and Jev list memberships manually. Bookmarks it created are ordinary link bookmarks. - Hermes: see the rollback notes in the private
MatCer/hermes-setuprepo. Attachments stay in Karakeep and are harmless.
MIT

