React to the documents Claude Code writes. Pin a note on any passage, right in your browser — the notes flow back to the session that wrote the document, and it fixes it.
A long answer from Claude Code is hard to read in a terminal and awkward to answer. With docpin, the session writes a document instead; you read it in your browser, Alt+click the sentence that is wrong, type what you want, and click Send to session. The session that wrote the document gets your notes, each with the passage it points at, corrects the document, and waits for the next round.
- Your notes go back to the same conversation, not to a new one.
- Nothing to install in the browser, any browser works.
- Your projects stay clean: your notes are kept on your machine, never next to the document.
- After a correction, the page shows what changed since you sent your notes, and folds what you already read.
| What it does | Needed? | |
|---|---|---|
| docpin | the loop above: your sessions write documents you can annotate, and your notes come back to them | yes |
| eli | sessions explain one level at a time, plain words and a diagram first, and every document they write is checked: a Markdown file or a page without a visual is sent back to the session | optional, recommended, a separate plugin: /plugin install eli --marketplace elphono/eli |
| epic-infographics | richer poster-like figures, as images | optional, another author's plugin: /plugin install epic-infographics --marketplace OrRon/EpicInfographics |
That is exactly the author's setup, minus his own preferences (he writes in French).
| Your machine | Works? |
|---|---|
| Windows, with Claude Code running in WSL2 | ✓ developed and used every day |
| Linux | ✓ should work: built for it, not yet tried on a desktop |
| macOS | ⚠ written for it, never tested |
| Windows without WSL | ✗ not supported |
- Claude Code 2.1.275 or later.
- Python 3.12 or newer, available as
python3. Ubuntu 24.04 and recent distributions have it; on Ubuntu 22.04 or macOS, install a newer Python first. docpin installs no Python package. - A browser.
-
In a Claude Code session, type:
/plugin install docpin --marketplace elphono/docpin -
Optional, recommended: install eli, which draws before it writes and checks every document a session writes (it asks docpin which pages are documents):
/plugin install eli --marketplace elphono/eli, then pick eli:eli in/output-style. If you had docpin's former visual-first plugin, eli replaces it: run/plugin uninstall visual-first@docpinfirst, or every document is checked twice. -
Start a new session. That is all: there is nothing to configure.
To try it, ask that new session for something to review, for instance "write up how our login works, as a document I can comment on". It answers with a link: open it, Alt+click a sentence, write a note, click Send to session. The session receives the note and fixes the document.
The first time, Claude Code asks your permission to run annotate wait: that is the session waiting
for your notes. Allow it.
| What | Where |
|---|---|
| the two plugins | in Claude Code's own plugin folder, like any plugin |
| your notes, and a copy of docpin's code | ~/.local/share/annotate |
| docpin's daemon: the small background program that serves the pages and carries your notes | included in the docpin plugin, nothing else to install; it only answers your own machine (http://127.0.0.1:8765) |
Nothing is written into your projects, nothing is installed system-wide, nothing goes to the network.
When the daemon runs. It is not started with Claude Code: the first time a session writes a document, docpin sees that no daemon answers and starts it in the background. It then keeps running until the machine (or WSL) restarts, and the next document starts it again. The only thing it does not do on its own is start at login, so that the home page answers before any session wrote anything.
This uses systemd, which recent Linux distributions and WSL Ubuntu have switched on (not macOS).
-
In a Claude Code session, type
! annotate service. (annotateis on the PATH of Claude Code's sessions, not of an ordinary terminal; the!runs it from the session.) It writes the service file. -
In any terminal:
loginctl enable-linger $USER # keep it running when no terminal is open systemctl --user daemon-reload systemctl --user enable annotate.service
-
The service takes over at the next start of your machine (on Windows: the next start of WSL, for instance after
wsl --shutdown). If docpin has not started its daemon yet, start the service right away instead:systemctl --user start annotate.service. Do not start it while docpin's own daemon runs: both would want the same port.
To check: systemctl --user status annotate.service. To undo:
systemctl --user disable --now annotate.service.
Type them in a Claude Code session:
| You want | Type |
|---|---|
| the list of your documents | ! annotate open, or open http://127.0.0.1:8765/ |
| an icon in the Windows notification area | ! annotate tray --start |
Start a conversation on one computer, pick it up on another, where you left it. Off by default, set up once per machine in the Sync between machines panel of the home page:
- Where it travels: your Google Drive (a hidden folder only docpin sees; you create a free OAuth client once, the panel says how) or a folder another program already syncs.
- A passphrase, the same on both machines. What travels is encrypted with it before it leaves: Google never reads your conversations.
- The folders whose conversations may leave this machine. Nothing else can be sent.
Then Send a session… on the home page, or ! annotate sync send inside the conversation. Within a
minute the other machine lists it under Arrived here; Resume here opens it in its own clone of the
repository. The code travels by git as usual: the panel warns about what is not committed or pushed.
Both machines should run the same Claude Code version.
- Ask a session for a document (a spec, a report, a plan to review). It gives you the link.
- Alt+click to pin a note; select text first to quote exactly that.
- Send to session. If the session is still open, the notes arrive there (Claude Code may show an Approve / Deny dialog first); if you closed it, a terminal tab reopens it.
- Reopen the document after the correction: the changes are marked. Mark as read when you are done.
Which documents? Out of the box, the HTML files a session writes in a docs/ folder. To follow
another folder, add it on the home page (! annotate open in a session). Documents also show up when
a script or a helper agent wrote them, within 30 seconds.
In a terminal:
- Update:
claude plugin update docpin@docpin, then start a new session. If the home page says Restart daemon, click it. - Uninstall:
claude plugin uninstall docpin@docpin. Your notes stay in~/.local/share/annotate; delete that folder to remove them too.
v0.3, used every day by its author. Installing from this page, updating, and the whole loop up to a note sent from Chrome on Windows were checked on 2026-10-12. Not yet checked: a Linux or macOS desktop, and the tray icon on screen. What comes next is in ROADMAP.md.
Configuration is optional: ~/.config/annotate/config.toml takes port, claude_bin (how to start
Claude Code) and terminal (which terminal reopens a closed session, for instance
["kitty", "bash", "-l", "{script}"]). The command line does what the pages do; type each command in a
Claude Code session with a leading !:
annotate list # one line per document
annotate open [<id>] # a document, or the home page
annotate send <id> # same as the button
annotate resend <id> # the last batch again, if it never reached the session
annotate new-session <id> # the unsent notes go to a NEW session
annotate forget <id> [--delete]
annotate attach <id> <session> # tie a document to another conversation (or: detach)
annotate folders [add|remove <dir>] # the followed folders
annotate rescan [--days 7] # take what was written recently
annotate statusThe daemon listens on 127.0.0.1 only, and send starts a session that is allowed to edit files, so a
web page you merely visit must not be able to trigger it: every request that changes anything needs the
custom X-Annotate header (which forces a CORS preflight the daemon never grants), a local Origin,
and a Host that names localhost (DNS rebinding). /docs/<id>/files/ serves nothing outside the
document's folder, symbolic links included. A conversation sent to your other machine is compressed and
encrypted on this one (AES-256 through openssl, with an HMAC checked before anything is decrypted),
only from the folders you allowed; the passphrase and Google's token stay in a file only you can read.
From a clone (git clone https://github.com/elphono/docpin.git && cd docpin && uv sync),
claude --plugin-dir . starts a session that uses the clone instead of the installed plugin.
uv run pytest -q # default suite
uv run ruff check src tests tools hooks bin/annotate plugins
uv run mypy
uv run python tools/mutate.py # directed mutation campaign, run on a copy of the repo
claude plugin validate --json . > report.json && python3 tools/check_plugin_report.py report.json
claude plugin eval . --runs 1 --allow-tools Write Edit # the skill, with and without the pluginThe invariants and the lessons behind them are in CLAUDE.md (in French). The design study that fixed the main choices is docs/etude-reutilisation.html (French; GitHub shows HTML as source, so open it from a clone).
MIT.
docpin: pin a note on a doc. The command line is still annotate, and so is the Python package, so that nothing you have set up breaks.