Inspiration comes in batches. I’ll sit down on a Saturday and have four or five Note ideas arrive at once, none of which want to go up together. Post them all and they stomp on each other. Post one and save the rest, and the rest go stale in a scratch file. What I wanted was to catch the batch while it was fresh and trickle them out over the week.
Substack didn’t have scheduled Notes when I started building. It does now, but the feature sits inside Substack’s own UI, and I don’t want Substack open while I’m working. It’s a feed. Feeds aren’t a place I can spend time. The other piece was that most of my drafting already happened in Claude Code. If the queue lived inside Substack, Claude couldn’t see it. If it lived as markdown files on disk, Claude could read them, edit them, and reason about them the same way it reasons about everything else.
So StackCLI is a command line tool plus a small menubar app that watches a folder of markdown files and posts Notes at the times you set.
Getting Notes onto Substack
The CLI was the easy half. A queue folder, markdown files, a command that takes text and a time. The hard half was the other end of the pipe, because Substack doesn’t publish an API.
The first attempt was a Chrome extension. It worked, but for the extension to post, Substack had to be open in a Chrome tab, and the whole point was not having Substack open. What was left was a small native app hosting its own hidden webview.
macOS pushed back. Hidden webviews get throttled. Text posts snuck through, but image uploads would crash because Substack’s multi-step upload flow couldn’t finish before the webview got killed. The fix was to surface it enough that the system kept it running, which meant a menubar icon and a popover.
The menubar turned out to be more than a necessary evil. It became the glanceable status surface. I can look up from what I’m writing, see three Notes queued for the week, and feel quietly confident the thing is doing its job.
Why agent-first
Most of my drafting goes through Claude now, so the interesting surface is the one Claude can reach. A GUI for scheduling Notes is fine for a human, but it’s a terrible shape for Claude, which can’t see a textarea or drive one through simulated clicks. The CLI is the real interface, and the MCP server wrapping it lets Claude call stackcli add "..." the same way I can. The menubar is for me. The CLI is for both of us.
Why Rust
The question for me was never “can I write Rust”, it was “can Claude write Rust well enough that I’d rather ship native than ship Electron”. Eight months ago the answer wasn’t obviously yes. Now it is.
Rust has the single most useful property for AI-assisted coding, which is very good error messages. When Claude writes something wrong, the compiler tells it in detail what’s wrong and often how to fix it. That tight feedback loop is the difference between a language AI writes fluently and one it only struggles in.
Add Tauri on top, which handles the native Mac menubar without any Objective-C or Swift, and the old tradeoff vanishes. A small native app, almost no memory, launches instantly, behaves like a proper Mac citizen.
This note is a living document and will keep changing. It's not an article. It's a notebook page I'm letting you read over my shoulder. If you spot something I'm wrong about, or if you've worked through the same thing differently, reply to henrik@holenventures.com.