The diff against the v1.0.0 tag shows 17,238 deletions and 1,361 insertions. What replaced those 17,000 lines is a Claude Code plugin: four slash commands, three skills backed by Python helper scripts, and a flat-file state directory. The app is gone. The behavior mostly works.
Quick start
claude install mukitmomin/scribe
# edit ~/.scribe/interests.md: topics, depth level, avoid-list
/scribe:scan
No Docker, no database. You need Claude Code running and about 60 seconds.
scan fetches the last 7 days from arXiv, HN, and Hugging Face, scores each
paper against your interests file, and drops anything scoring 7 or above into
~/.scribe/inbox/. The rest of the commands are in the diagram above.
What v1 was
I built Scribe last December as a research assistant for keeping up with AI papers. arXiv publishes hundreds of papers a week; I wanted a system that filters them, teaches me the ones worth knowing, and drafts blog posts from what I've learned.
v1 was a proper web app. Next.js 15 frontend, FastAPI backend, PostgreSQL 15 for
persistence, LangGraph and LangChain for agent orchestration, Google Gemini as the
LLM. Three Docker containers. A dev.sh that set up a Python venv, installed pnpm
dependencies, started the database, started the backend, started the frontend. Five
steps just to run locally. 141 files. About 17,300 lines of code.
The UI had a paper discovery page, a trend discovery page that scraped HackerNews, an AI Teacher with LaTeX rendering via KaTeX so the math actually displayed, a draft generator, a publisher dashboard, and a public blog API so my site could serve posts. I built most of this between December 2025 and May 2026.
Then I started not using it.
Why it stopped making sense
At some point I had ./dev.sh running in one terminal, Docker spinning up three
containers, and Claude open in another window. I typed my question into Claude
directly. The app existed to do exactly that and I was routing around it.
What I actually needed from Scribe was: find relevant papers automatically, surface the good ones, let me learn them, help me write about them. A workflow, not a UI. The entire frontend, the ORM, the database migrations, the Docker networking, the API layer, all of it existed to orchestrate a model call and store some state. Claude Code was already doing both those things.
| v1 | v2 | |
|---|---|---|
| Runtime | 3 Docker containers | claude CLI |
| State | PostgreSQL | ~/.scribe/*.md + seen.json |
| Orchestration | LangGraph + LangChain | SKILL.md + Bash |
| LLM | Gemini Flash | Claude (Sonnet / Opus) |
| To start | ./dev.sh (5 steps) | already open |
| Files | 141 | 25 |
| Lines | ~17,300 | ~1,360 |
The v2 design
The rewrite took about two weeks and produced 25 files. The design principle is blunt: Python scripts handle anything deterministic (HTTP fetches, file I/O, state serialization, Slack notifications). The model handles everything that requires judgment (scoring papers against my interests, teaching, generating drafts). Files are the database.
The four commands map directly to the four things I actually do:
State lives in ~/.scribe/:
~/.scribe/
├── interests.md # my topic list in plain English
├── seen.json # arxiv IDs already processed
├── digests/ # one .md table per scan day
├── inbox/ # high-score papers awaiting study
├── notes/ # learned papers, spaced-rep source
└── drafts/ # generated posts
Each command is a short Markdown file that loads a skill. Each skill is a longer Markdown file that tells Claude what to do and in what order. The Python scripts are called via Bash from inside the skill when something needs fetching or structured disk writes.
The build
I wrote the spec first: three phases, each in a separate session with a /clear
between them. Phase 1 was the plugin scaffold. Phase 2 was gathering real numbers
(LOC counts, infra costs, real output examples). Phase 3 is this post. The whole
thing took about two hours. I used three models: Fable 5 for design and ideation
(it was Fable that surfaced the Proxmox LXC as the obvious deployment target, pulling
from context about my homelab that I hadn't explicitly mentioned in the prompt),
Opus 4.7 for spec review and architecture decisions, Sonnet 4.6 for the bulk of
implementation.
The hardest part was state synchronization. Each skill that modifies state needs to
push to a private GitHub repo so nothing is lost between sessions or machines. I
wrote a sync.py helper used by scan, learn, and review. Git push failures are
silent unless you add explicit error handling, and I got burned by this once: a
network timeout left the seen-state locally updated but unpushed, which caused the
next scan to re-score papers I'd already processed. I added a check that aborts the
run if the push fails rather than silently continuing.
The scoring prompt is the core of the scout skill. I give it my interests.md and a
batch of papers and ask for a 0–10 score with a one-line reason. This morning's scan
scored 40 papers, took a few minutes, and the results were sensible: a score-9 for an
LLM agent memory evaluation paper, two 8s for agent scaffolding benchmarks, a 0 for an
astronomy paper about a stellar explosion. The model is consistent enough that the
same paper scores within one point across runs. That's all the precision I need.
Cron and Slack
v2 runs nightly on a Proxmox LXC container (VMID 210, 2 vCPU, 2 GB RAM, 8 GB disk) that was already on my homelab for other things. The cron fires at 06:00 UTC:
0 6 * * * scribe bash -c 'source ~/scribe.env && claude -p "/scribe:scan" --permission-mode auto'
~/scribe.env sets SCRIBE_HOME and SLACK_WEBHOOK_URL. Each scan posts a digest
to Slack: score, clickable arXiv link, and a 2–3 sentence analysis per paper. I read
it on my phone, pick one or two papers, run /scribe:learn at a desk. Ten to fifteen
minutes of attention per day.
The cron now runs deploy.sh before the scan, which does a git pull --ff-only
from the plugin repo and posts a one-line Slack notice if new code landed. Push to
main on my Mac, the container picks it up at 06:00 UTC without an SSH session.
The incremental infra cost is zero. What this points to more broadly: a low-power device on a home network — a Proxmox node, a Raspberry Pi, a spare NUC — is sufficient to run Claude Code agents on a schedule. The model lives in Anthropic's infrastructure; the local machine just needs enough to fire a CLI call and manage files. Personal automation, fully under your own control, with no cloud bill for the compute.
What it cost to delete the UI
The web UI is gone. There is no public-facing component. If I want to show someone what Scribe does, I walk them through my terminal.
LaTeX rendering is gone. The Teacher can explain math, but it comes back as raw
notation. \nabla_\theta \mathcal{L} instead of rendered symbols. For most papers
this is fine. For anything heavy on linear algebra or probability theory, it is a
real degradation.
The publisher dashboard is gone. Drafts sit in ~/.scribe/drafts/ as Markdown
files. Publishing is manual. This post is one of those drafts: I wrote the spec,
the scan ran, and now I'm editing the output myself before putting it anywhere.
That's more friction per post than the v1 workflow, which had a one-click publish
button.
None of these losses stopped me from switching. But they're losses, not rounding errors. The architecture is wrong for you if you need a public UI, if your users aren't comfortable in a terminal, or if math rendering is a hard requirement. It's also wrong if you want to share the workflow with someone who doesn't have Claude Code installed.
I traded features for a tool I actually use.
Installing it
The repo is at github.com/mukitmomin/scribe. The install is:
claude install mukitmomin/scribe
mkdir -p ~/.scribe
# write your interests to ~/.scribe/interests.md
/scribe:scan
No Docker. No database. No dev.sh. You need an Anthropic API key and about 60
seconds.
The spec, the code, and the build notes are in the repo. If you want to see how
something like this gets built with the tools doing most of the implementation work,
the .claude/specs/ directory has the full phase breakdown. Nothing in there is
proprietary; it's just the way I've started structuring anything I build with Claude
Code that has more than two moving parts.