A dev team of one human and three AI agents
- .NET 10 Native AOT
- PostgreSQL
- MCP
- OAuth
- Claude Code
- Telegram
Each agent is its own long-running Claude session on its own machine. They share a memory, hand work to each other, review each other's code, and talk to me (and each other) in one Telegram group. I set the direction and approve every merge.
The crew
Snoopy
the home serverLives next to Home Assistant and the GPU. Operations, databases, the voice of the house, and code review.
Linus
my Windows workstationLead developer on Snowcap Studio: features, Native AOT builds, UI automation tests.
Lucy
my laptopProject manager and keeper of the to-do lists, and a full developer on Studio as well.
Why "Lucy"?
Lucy came first, and her name comes from 50 First Dates. Drew Barrymore's character, Lucy, has short-term memory loss: she wakes up every morning with no memory of the day before. That's exactly how an AI agent works. Every session starts from zero.
In the movie, Henry makes Lucy a videotape that she watches each morning to catch up on her life. LucyAPI is that videotape. At the start of every session, an agent pulls its memories, projects, hints, handoffs and standing context from it, so nobody begins from scratch. I built it for Lucy first, which is why it carries her name, and it grew into the platform the whole team runs on.
The Peanuts theme came later. With a Lucy already on the team, Vince Guaraldi's "Linus and Lucy" suggested the rest: Linus, then Snoopy, the beagle who gets into everything. So "Lucy" has two meanings: the amnesiac who needs her tape, and the bossy big sister who runs the show. Fitting for the team's project manager.
LucyAPI: the shared brain
A small .NET 10 service, compiled with Native AOT over PostgreSQL, that every agent connects to over MCP, signed in with OAuth. It's where the team's knowledge lives (the videotape), so a fresh session picks up exactly where the last one left off.
Projects
Hints
Handoffs
Memories, nudges, secrets
Load the index, not the library
The design choice I'm proudest of: most of what LucyAPI stores is a tree, and every node has a short title that works as a manifest entry, with the details one call away.
An agent's context window is its working memory, and it fills up fast. So when a session starts, the agent doesn't receive hundreds of hints and memories in full. It receives their titles: a table of contents, arranged as a tree. When the work calls for something ("how do I deploy this app?", "what did we decide about the cutoff?"), it opens that one node and reads its details and children. Then it can drill down further, or stop.
- session starts: titles only
- the task needs one topic
- open that node
- read its children if needed
- everything else stays closed
It's how a person uses a reference manual: skim the table of contents, open the right chapter, and never read the whole book. The agent knows everything the team has learned is available, but it only pays for the parts the current task needs. That leaves its context free for the actual work.
The data access is all PostgreSQL stored functions: the service never builds SQL strings. Every query goes through a function with typed parameters, which keeps the hot paths fast and the surface small.
RickAtSnowcap/lucyapi-v2The service: .NET 10 Native AOT, PostgreSQL stored functions, an MCP connector with OAuth.
Telegram: the team room
Every agent has its own Telegram bot. In the group, an agent wakes up only when it's @mentioned, and it answers routine pings with a thumbs-up reaction instead of a message, so agents can't talk themselves into a loop. I can send a voice note, and the agent answers in its own voice.
Linus: @Snoopy chore/third-party-notices is pushed and ready for your review. Details in handoff #643.
Snoopy: @Linus the review is in #644. Nothing blocks the merge once the license branch goes first. One must-fix before release, six should-fix.
Linus: @Snoopy fixed in 16dcfd0. Quick re-check, please.
Me: Looks good. Merge it.
How code actually gets written
- we agree the plan
- an agent builds on a branch
- another agent reviews it
- findings go back as a handoff
- fixes and a re-review
- I test and approve
- merge to main
- Reviews are adversarial on purpose. Studio's column-first SQL completion went through four review rounds and a 328-case probe harness before I merged it.
- Reviewers check their own findings. A reviewing agent fans out sub-agents for independent reads, then verifies every finding against the code before reporting it.
- House rules are enforced, not hoped for. Nothing reaches main without me, agents never push to each other's branches, and a content-check hook blocks secrets and internal names.
- Sessions hand off to themselves. When a session's context fills up, the agent writes a "self-handoff", so its next session resumes cleanly.