Organize your Chrome bookmarks with help from a Claude agent.
A small local web app that reads your Chrome bookmarks, asks Claude to propose
a folder taxonomy, lets you refine it through a chat (the agent edits the tree
via tool calls), and exports a bookmarks.html file you can import back into
Chrome.
- macOS with Google Chrome installed (the bookmarks file is read from
~/Library/Application Support/Google/Chrome/Default/Bookmarks) - Python 3.11+
- uv (
brew install uv) - An Anthropic API key
git clone <this-repo> bkmk
cd bkmk
uv sync
export ANTHROPIC_API_KEY=sk-ant-...Tip: copy .env.example to .env and source it from your shell, or paste the
export line into your ~/.zshrc. The repo's .gitignore excludes .env so
your key won't be committed.
uv run python -m bkmkOpen http://127.0.0.1:8000 in your browser.
The UI has three buttons across the top — work through them in order:
-
Load Chrome bookmarks. Reads your Chrome bookmarks file and shows them under a single
Unsortedfolder. -
Propose organization. Sends the bookmarks to Claude, which returns a folder taxonomy with each bookmark assigned. Takes 20–40 seconds. The rationale appears in the chat panel.
-
Chat to refine. Talk to the agent in the right pane. Examples:
- "Rename AI Tools to AI."
- "Move Rust and Go out of Dev Resources, then delete Dev Resources."
- "Where did you put the Factorio wiki?" (questions don't trigger edits)
The agent edits the tree directly via tool calls; each call shows up in the chat as a small grey row so you can see what changed.
-
Export bookmarks.html. Downloads a Netscape-format file.
- Chrome → ⋮ menu → Bookmarks and lists → Bookmark manager
- In the manager, click ⋮ → Import bookmarks
- Select the
bookmarks.htmlyou downloaded
Chrome adds the imported tree alongside your existing bookmarks (under a
folder named Imported or similar) — it does not replace them. To do a clean
swap, delete your existing bookmarks first, or move the imported folders to
where you want them.
bkmk/chrome.py— Chrome bookmarks JSON readerbkmk/state.py— in-memory folder/bookmark model + mutation opsbkmk/agent.py— Claude calls (initial proposal + chat agent loop with edit tools)bkmk/export.py— Netscape HTML emitterbkmk/server.py— FastAPI serverbkmk/static/— single-page UI (vanilla JS, no build step)
- State is held in memory in the server process; restarting the server resets everything. Re-run "Load" then "Propose" to start fresh.
- Single-user, single-session — no auth, only listens on
127.0.0.1. - Costs a few cents in API spend per session at 26 bookmarks; scales with
bookmark count and chat length. Uses
claude-opus-4-7.