Devour a sprawling tab list. Close duplicates, file the keepers into Obsidian — or hand the whole backlog to a coding agent and let it triage.
For Firefox based browsers like Zen Browser and Chromium browsers like Helium.
Too much content, so little time! Tabglutton is for those voracious consumers of information who open dozens of blog posts, X posts, and articles every day out of interest where discovery outpaces ingestion. Tabglutton helps manage the feast of tabs you may or may not want to imbibe, acting as a curator, deduplicator, and dashboard. It even connects to your Obsidian vault to automate second brain extension, acting as a batch ingest version of Obsidian Web Clipper. Connect to your agent of choice to triage high signal content, determined by your existing interests and pursuits.
The toolbar badge counts duplicate tabs in scope. Open the popup to see them grouped by
canonical URL, then close them all in one action — the keeper is chosen by lastAccessed,
then active, then pinned. A toast offers Undo for ~6 seconds and restores tabs to
their original positions.
URLs are canonicalized first (src/normalize.ts): lowercased host, www. and trailing
slash stripped, tracking params (utm_*, fbclid, gclid, si, …) dropped, remaining
params sorted, and optionally the #fragment removed.
Select tabs and hit Devour. Each one is read through
Defuddle — the same extractor behind Obsidian's own
Web Clipper — formatted as markdown with frontmatter (title, source URL, author, site,
published date), filed into your vault under Clippings/, and closed.
Note
You can include the Clippings directory in your main vault, or put it in a secondary agent managed vault (LLM-wiki style), where you can do additional agent-driven synthesis to avoid polluting your primary vault with noise.
The full-screen Devour cockpit (Alt+Shift+D) is the workspace for this: tabs grouped
by host, an inspector previewing exactly where each note will land, and keyboard triage
throughout — j/k to move, space to toggle, d to devour, x to close, / to filter.
This is the part that isn't like other tab extensions.
Tabglutton ships Gullet, a local MCP server. Turn the bridge on in settings, run its
one-time token setup command, and point Claude Code or Codex at
bunx tabglutton-gullet; your agent can then work your actual open tabs:
| Tool | What it does |
|---|---|
tabs_list |
Metadata for every tab in scope — cheap across hundreds |
tab_read |
Full Defuddle extraction of one page |
tabs_load |
Wake tabs the browser unloaded, so they become readable |
tab_clip |
File a tab into Obsidian, optionally closing it |
tabs_close |
Close a batch, returning a batchId |
undo_close |
Reverse any batch |
So "go through my 400 tabs, tell me what's worth keeping, clip the good ones and close the noise" becomes a thing you can actually ask for. The agent triages on metadata first, reads only the survivors, and every close is reversible.
It is deliberately hard to make this dangerous. The bridge is off until you enable it. It binds loopback only, authenticates with a shared token that never crosses the wire (both ends prove knowledge of it against a nonce the other side chose), and checks the extension origin. Waking tabs is a second, separate opt-in, because it's the only method that acts on a page rather than reading one. Nothing is ever closed that the undo log couldn't put back — if a tab can't be recorded, it's left open and reported as skipped.
Setup lives in gullet/README.md; the design rationale, wire protocol,
and a long list of hard-won browser quirks are in docs/BRIDGE.md.
Not in the add-on stores yet. Two ways to run it today:
From source (either browser):
bun install
bun run build # → dist-firefox/ and dist-chrome/- Firefox / Zen —
about:debugging→ This Firefox → Load Temporary Add-on → pick any file indist-firefox/. For an install that survives restarts, see signing. - Chrome —
chrome://extensions→ enable Developer mode → Load unpacked →dist-chrome/. Chrome ignores the manifest's suggested shortcuts, so bindAlt+Shift+G(popup) andAlt+Shift+D(cockpit) yourself atchrome://extensions/shortcuts.
Dev loop:
bun start # build + launch Zen with the extension loaded
bun run start:firefox # same, against regular Firefox
bun run start:chrome # same, against Chromium
bun run check # typecheck + format + lint + test — run before committingZen has no workspace API for extensions, so "active workspace" is a heuristic:
tab.hidden === false. If it looks broken (every tab in the window reads as visible) the
popup warns you and you can fall back to "current window only" in settings. Regular Firefox
and Chrome have no workspaces, so they use current-window scope directly.
No analytics, no telemetry, no remote server, no account. Page content is extracted in-page and goes exactly two places: your Obsidian vault, and — only if you turn the bridge on — a loopback socket to an MCP server running on your own machine. The extension requests no permissions beyond what dedup and clipping need.
Right-click the toolbar icon → Manage Extension → Preferences.
- Strip URL fragment (default on) — treat
page#aandpage#bas the same URL. - Extra params to strip — additional query params beyond the built-in tracking list.
- Scope — active workspace (Zen heuristic) or current window only.
- Obsidian vault — required for Devour; ignored by dedup.
- Agent bridge — off by default. Enable, generate a token, optionally allow tab loading.
To run on your real profile so it survives restarts, sign through Mozilla AMO's unlisted channel (signed, not publicly listed). Create an AMO account, generate JWT credentials, then:
cp .env.sample .env # fill in WEB_EXT_API_KEY / WEB_EXT_API_SECRET
bun run sign # builds, uploads, signs → web-ext-artifacts/*.xpiDrag the .xpi onto about:addons. Upgrades are in-place and preserve extension storage.
Versions are major.minor.patch.build; bump the release triple normally and let
bun run sign:dev own the fourth part.
TypeScript compiled by Bun into dist-firefox/ and dist-chrome/ from one shared source
tree. manifest.json describes the Firefox shape and is patched in memory for Chrome;
src/target.ts is the single compile-time switch. Chrome additionally gets
webextension-polyfill inlined into a bundled service worker.
| Path | Role |
|---|---|
src/background.ts |
Event wiring, badge, tab readiness |
src/dedup.ts · src/normalize.ts |
Duplicate planning and URL canonicalization |
src/clip-current.ts · src/clip-format.ts |
Defuddle extraction → markdown → obsidian:// |
src/bridge-*.ts · src/undo-log.ts |
Agent bridge client, wire protocol, reversible closes |
gullet/ |
MCP server + loopback WebSocket hub (zero dependencies) |
popup/ · options/ · onboarding/ |
UI surfaces, sharing one token system |
Contributor notes are in AGENTS.md — including a fairly brutal catalogue of
cross-browser behaviours that cost real debugging time (Chrome minting new tab ids on
discard, Gecko's failed-WebSocket reconnect penalty, CSP silently upgrading ws:// to
wss://, and more).
Page extraction is powered by Defuddle by Steph Ango
(@kepano), MIT licensed. Type is
Vollkorn by Friedrich Althausen and
Geist by Vercel, both under the SIL Open Font
License. All three licenses ship with the packaged extension under THIRD_PARTY_LICENSES/.
MIT © Michael Simon