Repository navigation
Releases: KevinChu1110/driftnet
Release list
driftnet 0.10.2
driftnet 0.10.2
- Edit tags. Change a card's tags from the card view or over MCP (
tagsondriftnet_update_item, which replaces the whole list). Tags are checked like any other text, and the change is recorded in the card's history. - Delete for good. Cards in the trash can be deleted permanently: Delete forever per card, Empty trash for all, and the new MCP tool
driftnet_delete_item, which is marked destructive, only works on trashed cards and is not available to read-only sessions. It removes the card's shares, votes, history and search entries. MCP now has 15 tools. - Clearer MCP tool descriptions for folder ids, what
update_itemreturns, and when to skiplist_folders. - The update-check timeout now also fires on Node 22, which fixes CI.
- A new SECURITY.md explains how to report a vulnerability privately.
Upgrade: npx driftnet@latest.
driftnet 0.10.1
driftnet 0.10.1
Finishes #11: videos that say which tool they are about but have no captions.
DRIFTNET_VIDEO=watch: when captions, on-screen text and speech left a video thin and your model is Gemini or Vertex, the model watches it. YouTube links are passed directly, with no download; other reels go inline if 14 MB or smaller. Checked live: Gemini Flash read a YouTube Short correctly in about 3,100 prompt tokens.DRIFTNET_VIDEO_FRAMES=vision: up to 8 deduplicated frames, 768 px wide at most, sent to your vision-capable model. This works with Ollama vision models (Qwen-VL, Gemma) through the OpenAI-compatible endpoint, Claude and Gemini.- One request: frames and the video go in the same summary request, never one call per frame.
needs-transcript: a video nothing could read skips the model call. It waits in the agent queue withhint: "video: needs a transcript", so an agent with its own video tools can take it.- Both modes are off by default and only run after the cheaper steps found too little. Media goes only to the provider you configured.
Upgrade: npx driftnet@latest.
driftnet 0.10.0
driftnet 0.10.0
Find things by what they mean, see what's related, undo any change, and keep a backup, while keeping driftnet's three priorities: security first, then speed, then saving tokens.
New
- Search by meaning (optional). With a local embedding model (
ollama pull nomic-embed-text), driftnet turns on by itself: "login" finds OAuth Kit, and "transcribe a meeting" finds Whisper.cpp. Results blend keyword and meaning ranks. With no model, search works exactly as before. A cloud embedder (OpenAI, Gemini) is only used when you name it. - Related cards. The card view and
driftnet_get_itemlist up to 5 related cards. - History for every card. Changes to the note, summary, title, folder, star and trash are recorded and can be restored. A restore can itself be undone. 20 versions per card, kept 180 days. Forget history clears one card.
- Backup and restore. One click in ⚙ Settings, or
driftnet backup/driftnet restore. A backup is a zip with a consistent snapshot. API keys, chat tokens and signing secrets are left out unless you ask, with your password again. Restore checks the file thoroughly and swaps the database on the next start, keeping the old one. - Reader profile. A few lines about you (
DRIFTNET_PROFILE, at most 600 characters) shape what is worth a look and the why line. It is added once to the system prompt, so prompt caching still applies. - Update notice (opt-in).
DRIFTNET_UPDATE_CHECK=1checks npm once a day and shows a small notice. It is off by default. DRIFTNET_VIDEO=captions. Reads a reel's captions and description only: no download, no OCR, no speech model. Easy on a laptop battery.
Security, speed, tokens
A separate review against the three priorities found 13 issues; all are fixed:
- Private notes: they are only embedded by a model on this machine, and
127.0.0.1.evil.comno longer passes as local. - Query embeddings: they are rate-limited (30 a minute) and time-boxed (1.5 s), then fall back to keyword search. Nobody can drain your embedding quota through public search.
- Restore: it refuses backups that carry triggers or views, or that lack tables or columns. A failed swap never crash-loops the server, and old leftovers are pruned.
- History: read-only callers don't see the old notes.
- Speed at 50k cards: hybrid search went from 63 to 40 ms, related cards from 51 to 26 ms, and memory from 504 to 223 MB. Backup snapshots and checks run off the main thread.
- Agent brief: it carries the reader profile only when there is work, once per session. MCP is still 14 tools.
Upgrade
npx driftnet@latest. The database upgrades itself on first start (schema 5), with a backup next to it.
Tests: 427 unit, browser e2e (web, extension, demo site).
driftnet 0.9.0
driftnet 0.9.0
Try the demo: the real page with sample cards, no install. Your changes stay in your browser.
New
- Reels and shorts. For thin video posts (Instagram, Facebook, Threads, TikTok, YouTube Shorts, X…), driftnet reads captions with
yt-dlp, then on-screen text withtesseract, then speech withwhisper, using whichever local tools are installed (DRIFTNET_VIDEO=auto). One video at a time, hard time limits, temp files always removed, private addresses refused. Cards say 🎬 read from video. - Rich chat replies. Discord embeds, Slack Block Kit, LINE Flex, Telegram HTML with buttons (
DRIFTNET_REPLY_STYLE=rich, the default;textkeeps the old plain replies). Vote by reaction: 👍/👎 on Discord, Slack and Telegram, buttons on Telegram and LINE. - More models. Native
gemini,bedrock(SigV4, no AWS SDK) andvertex(service account) providers. - Pluggable judges.
DRIFTNET_JUDGE=rulesis a zero-cost judge from your folder descriptions and an optional rules file. Plugins can register providers and judges (examples/plugins/rainbow-judge.mjs). - Chrome extension. Dedicated capture for Threads (post + replies), X (tweet, quote, card, self-thread, real links behind t.co) and Instagram (caption + comments). There is a store-ready build (
pnpm build:extension), and the Chrome Web Store listing is coming. driftnet init. Connects Claude Code (MCP + skill), Claude Desktop, Cursor, Windsurf and Codex in one command, locally or to a remote server with a token. It merges existing configs, backs them up and is safe to re-run.- Let your agent set it up. Paste one sentence pointing at
docs/llms-install.txt. - Folder packs. Share a folder as a
.jsonpack or a signed link that opens only that folder. Importing a pack recreates its folders and cards without any model call. Notes, chat text and votes never leave.
Fixes
- An unreadable key file no longer stops driftnet from starting.
driftnet initno longer claims the local MCP server needs the page running.
Upgrade
npx driftnet@latest. No database change. Discord reaction votes need Add Reactions and Embed Links in the channel, and Slack needs the reactions:read scope and the reaction_added event.
Tests: 358 unit, browser e2e (web, extension, demo site).
driftnet 0.8.0
driftnet 0.8.0
Bring your old bookmarks, find things faster, and let driftnet tell you what's new and what broke.
New
- Full-text search. SQLite FTS5 with a trigram index: every word must match, best matches first (a name match beats a chat-note match), and Chinese substrings work. One- and two-character terms fall back to a plain match.
- Import bookmarks. ⚙ Settings → Import: Chrome / Firefox / Safari / Edge bookmark HTML, Pocket (HTML or CSV), Raindrop CSV, a JSON list of items, or any text with links. You see how many are new before anything starts, since each new link is one model call when a model is set up. "Keep my bookmark folders" rebuilds them under Imported as your own placement. Up to 5,000 links per import. API:
POST /api/import,GET /api/import/:job. - Command line.
driftnet add | search | open | export | import | status | completion.searchandexportstill work when the server is not running (they read the database directly).--jsonfor scripts. - Scheduled digest.
DRIFTNET_DIGEST=daily|weeklyposts a short summary of new cards (top picks, most shared, inbox count) into Telegram, Discord, Slack or LINE (DRIFTNET_DIGEST_TO). Links never carry the share key. It also sends adigest.sentwebhook.POST /api/digest/send {"dryRun": true}previews it. - Link health.
DRIFTNET_HEALTH=weeklychecks a few cards at a time: repos that are archived, gone, moved or untouched for 18 months, and pages that return 404. Badges on cards (☠ 🗄 💤 ↪, ★ stars for repos), a Needs review view, andview: "needs_review"plushealth/starsfields over MCP. It is off by default. - Paging. The card list loads 60 at a time and keeps going as you scroll (or Show more). Cards past 300 are reachable again.
GET /api/itemsacceptsoffsetand returnsX-Total-Count.
Under the hood
- Versioned database migrations. Each schema change runs once, inside a transaction. Before migrating, driftnet copies the database to
driftnet.db.bak-v<N>, and it refuses to open a database written by a newer version. - Central route access. Every HTTP route declares who may call it; a route without that does not compile, and a test checks every write route refuses anonymous callers.
createApp()builds the server without starting it.
Upgrade
npx driftnet@latest. The database upgrades itself on first start, with a backup next to it. MCP tools are unchanged: still 14, same names as 0.7.
Tests: 273 unit, browser e2e (web and extension).
driftnet 0.7.1
driftnet 0.7.1
MCP tool descriptions only; no behaviour change.
Every tool now says when to use it and which sibling to use instead, and explains what its parameters mean beyond the schema: that a note replaces the whole note, how votes and the trash differ, that folder ids survive a rename, how lease size relates to the 30-minute lease, and that enrich makes network calls. Ranges and defaults are left to the schema.
Upgrade: npx driftnet@latest.
driftnet 0.7.0
driftnet 0.7.0
Clearer MCP tools, and fixes from a two-round audit (architecture, features, details, security, performance, usability).
⚠️ MCP tools renamed (breaking)
14 tools instead of 19, every name verb_noun, every parameter explained with its format and an example.
| Before | Now |
|---|---|
driftnet_search, driftnet_list_recent |
driftnet_search_items (days for what's new; view: inbox, favorites, trash; kind) |
driftnet_vote, driftnet_favorite_item, driftnet_set_note, driftnet_trash_item, driftnet_restore_item |
driftnet_update_item |
driftnet_save |
driftnet_save_link (only the URL is saved; links inside the note are not) |
driftnet_lease_pending, driftnet_enrich |
driftnet_lease_items, driftnet_enrich_item |
driftnet_move_item (id or ids) |
driftnet_move_items (ids) |
driftnet_undo |
driftnet_undo_move |
Agents pick tools up from the server, so most need nothing; prompts that name the old tools need updating. Also: folder ids are checked when a tool runs, so a long-running stdio session accepts folders you add on the page later; driftnet_get_item shows trashed items and never returns ones flagged for prompt injection; a read-only session says so.
Security
- No password, no outside requests. Without
DRIFTNET_TOKEN, driftnet only answers requests addressed to this machine orDRIFTNET_PUBLIC_URL, so a web page can't reach a local install through DNS rebinding (DRIFTNET_ALLOWED_HOSTSadds names). A non-local listen address without a password prints a warning. - The page sends a Content-Security-Policy,
frame-ancestors 'none'and related headers. - Votes over HTTP: only
up/down, and the voter is whoever is signed in, not a field anyone can fill in. - No http retry for a request that carries a token (GitHub), and none after a timeout; tokens and signatures are dropped on a cross-site redirect.
- The prompt-injection check also reads titles, page metadata and image text.
- Webhooks: signed over
timestamp.bodywithX-Driftnet-Timestamp/X-Driftnet-Delivery, so receivers can refuse replays; redirects are not followed. - The wrong-password counter uses the real client address, and its memory is capped.
- Vault export and folder names can't contain
..paths. - Chrome extension: https required for a remote server; settings are saved only after the connection test passes.
Data safety and correctness
- Refreshing a card with no model, or while the model fails, keeps its summary instead of clearing it.
- A link shared again while it still has no summary is summarised again (once a model works).
- Search matches every word (
markdown pdffinds "Convert PDF to Markdown"), only in the summary's text, and treats%/_literally. - Link cleanup no longer merges different pages:
?t=,?s=,?ref=… are only stripped on the social and video sites that add them;#/routelinks stay distinct. - Chat:
+1 for thisis not a vote, and a message with a link is never one (👍12,👎12 reason,+#12,-#12still are). - Telegram: links behind text are read; a message that fails is not skipped for good; optional
DRIFTNET_TELEGRAM_CHATSallow-list. - Discord: catch-up reads up to 1000 missed messages per channel, and forwarded messages.
item.trashedanditem.restoredwebhook events.- Settings:
xhighreasoning effort, and an unexpected value already in.envno longer blocks saving other settings.
Performance
- Picture proxy: at most 4 downloads at a time, failed pictures remembered for 10 minutes, no blocking disk reads, cache trimmed to 90% instead of rescanning on every picture.
llms.txt, the feed and exports read the folder list once instead of per card;llms.txtsays when it shows only part of the catalogue.- Faster link lookup on every share; a one-off database repair no longer runs on every start.
Smaller
npx driftneton an old Node says which version it needs;--helplists the useful settings; unknown commands say so.- README: stdio setup for Claude Code and Claude Desktop, a "Not working?" list, new settings.
- The agent queue brief is the same over HTTP (
/api/pending→brief) and MCP.
Upgrade
npx driftnet@latest. The database updates itself. If you open driftnet from another device without a password, set one or add the host to DRIFTNET_ALLOWED_HOSTS.
Tests: 194 unit, browser e2e (web and extension).
driftnet 0.6.0
driftnet 0.6.0
Cards you can understand at a glance.
New
- Card pictures — driftnet finds the pictures a link already has (README images and GIFs, YouTube thumbnails, og:image) and shows them as thumbnails, with a
+Nbadge when there are more. Pictures go through the server's own SSRF-guarded proxy with per-picture signed paths, so they work on a private catalogue without a key in the URL, and are cached on disk (DRIFTNET_MEDIA_CACHE_MB). MCP and the API expose them as itemmedia. - What you'll see / why it's here — summaries now carry a demo line (what you will actually see when you open it), a why line grounded in the chat text it was shared with or your note, and a try it step.
DRIFTNET_SUMMARY_DEPTH=brief/standard/detailed. - Detail modal — list cards are now a thumbnail, one-liner and demo line; click for a gallery, why, highlights, try it and actions, with ←/→ and
#item-<id>links. The mind map opens the same modal. - Refresh a card — re-fetch and re-summarise one card; your note, favourite, share count and chosen folder are kept. MCP:
driftnet_refresh_item. - Atom feed —
/feed.xml(newest 50,?folder=to narrow) for any feed reader. - Outgoing webhook —
DRIFTNET_WEBHOOK_URLgets a POST for each new card, HMAC-signed withDRIFTNET_WEBHOOK_SECRET. - Starter folder templates —
DRIFTNET_FOLDERS=ai|research|everyday, or pick one in the first-run chooser.
Fixes
- Xiaohongshu links keep
xsec_token(a note will not load without login otherwise); Xiaohongshu / Douyin / TikTok share parameters are stripped. zundoes only while the Undo toast is visible.- A zero list limit returns nothing instead of everything.
- From a second Gemini audit: the picture cache keeps a running total instead of rescanning, trash sits at the far end of the modal,
+Non thumbnails, map tooltip layout.
Docs
README rewritten demo-first: what it does in one screen, core features at a glance, numbered quick start.
Upgrade
npx driftnet@latest — the database migrates itself (new media column). Existing cards get pictures, demo and why when you refresh them (POST /api/items/:id/media/refresh backfills pictures only).
Tests: 167 unit, browser e2e in English and Traditional Chinese.
driftnet 0.5.0
driftnet 0.5.0
Every open feature issue in one release.
New
- Inbox (#2) — links the AI filed on its own wait in Inbox (N), each with two or three suggested folders. One tap or
1–3files it,sskips,mopens the full picker; Undo brings it back. No extra model call: suggestions come with the classification, with a keyword fallback when there is no model. - AI tidy-up plan (#4) — ✨ in the folders header asks the model for a plan (create, rename, merge, move), each line with its reason. Nothing changes until you tick lines and press Apply selected. Cards you placed and folders you made are never touched; one Undo reverts the whole plan. MCP:
driftnet_suggest_folders(proposes only). - Command palette (#3) —
⌘K/Ctrl+K: jump to a folder or card, switch view, export, settings, dark mode… - Split view (#6) — on wide screens, the card list and the mind map side by side; drag cards (or a selection) from the list onto a folder.
- Mind map focus (#5) — double-click a folder or press
zto see only its branch; a breadcrumb andEscgo back up, and the focus is kept in the URL. - Keyboard tree (#7) — the mind map is an ARIA tree: arrows, → / ← to expand and collapse, Home / End, type-ahead, one tab stop.
- Unlock a phone with a QR code (#9) — scan a one-time, five-minute code and the phone gets its own revocable device token. No password typed on the phone.
Upgrade
npx driftnet@latest — the database migrates itself (new suggestions column, folder builtin marker, pair_codes table).
Tests: 129 unit, browser e2e in English and Traditional Chinese.
driftnet 0.4.1
Select many cards, file with number keys, and one key per agent
Multi-select and bulk actions (#1). x, Shift-click or a long press selects cards; a bar offers Move to…, ★, Trash / Restore, Select all, Clear. The whole batch is one transaction and one Undo; the undo snapshot is kept on the server. On the mind map, Shift-click (phone: hold, then tap more cards) collects several and dropping one moves them all. MCP: driftnet_move_item accepts ids, and driftnet_undo reverts a batch.
Number keys (#10). 1–9 file the focused card (or the selection) into your nine most-used folders. The counter is stored on the server, so it's the same on every device and undo counts it back down; agents get it as uses on driftnet_list_folders. ? now opens a full shortcut dialog.
Agent tokens (#8). Settings → Access → Agent tokens: one named key per agent, read or write, shown once, revocable. The Connect-an-AI cards mint one for that agent so the copied config never carries the admin password. A write token can do everything except settings and token management. Queue leases and moves record which token acted.
Fixes: the create-token row no longer collapses, token times show in local time.
npx driftnet@0.4.1 · MCP: npx -y driftnet mcp