Back to writing
AI Engineering

How I build local, open source agent software

The architecture I use for agent-powered tools that run on the user's own machine and credential, with the file system as the contract and no vendor lock, drawn from an open source tool called Marketing Ops.

Graham MorleyJuly 2, 20266 min read

I recently released an open source tool called Marketing Ops. It drafts the social content a business publishes and helps carry each piece from idea to posted, working through the user's own local agent rather than a model API the server calls. It handles text posts, blog posts, and carousels today, with images and short video built to slot into the same engine next. This is how I build that kind of software, and why.

The server holds no key

The dashboard has a small server, and that server never calls a model API. It holds no Anthropic key of its own. The brain is the user's local Claude Code, running on the user's own subscription or key, on the user's own machine. When the dashboard needs the agent to do something, it either hands the user an instruction to paste into Claude Code or shells out to the local claude command.

The reason is ownership. I do not want to run inference for other people, hold their keys, or sit in the billing path. The user's credential pays for the user's work, and the tool is something they run rather than a service I host. That choice has a real cost. There is no hosted version that works the moment you sign up, and you need Claude Code installed and authenticated first. For software people run on their own business, I think it is the right trade.

The file layer is the contract

The dashboard and the agent do not call each other. The dashboard writes what the user wants into files under a data/ directory. The agent reads those files, does the work, and writes the results back. A file watcher pushes every change into the UI as it lands.

This keeps the two sides independent. I can change the dashboard without touching the agent, and swap the agent without touching the dashboard, because neither one knows how the other is built. Every action the system takes is also a file on disk you can read, which makes the whole thing easy to inspect and to back up. The tradeoff is that you design around a queue of intent rather than a live request and response, so the system is eventually consistent by nature. For work with a human in the loop anyway, that fits.

Three ways to run, and no surprise bill

Agent work can run three ways, and the user picks per action. Chat mode hands over an instruction to paste into an interactive Claude Code session, which runs on the subscription allowance that refills. Headless subscription mode has the server run claude -p on the subscription token, with no copy and paste. Headless API key mode runs the same way but bills against the user's API key at metered rates, and it is used only when the user selects it on purpose.

The rule underneath is one credential per run, never both. An API key sitting in the environment counts as an automatic fallback that meters, so the tool always shows which credential a run will bill against and flags a stray key when it finds one. Chat mode is always available and never taken away, because it is the guaranteed fallback. Billing terms on agent subscriptions move, and I did not want a design that breaks when they do. Keeping the mode swappable and Chat always present means a billing change is absorbed by switching modes, with no rework.

Provider-agnostic to the backend

The tool recommends specific external services and depends on none of them. For media the agent cannot draw itself, an on-brand image or a video, it writes a ready-to-run generation package that names a suggested tool, such as Nano Banana, ChatGPT, or an AI video tool. The user runs it there and uploads the result. Swapping one image tool for another changes only which tool the package names. The engine does not move.

The agent backend is swappable too. Nothing in the data model, the routes, or the UI names Claude. Claude Code can be pointed at a local model like Ollama or LM Studio, or at Bedrock or Vertex, and the tool detects that posture and leaves the deliberately configured backend alone instead of overriding it. A different agent CLI, such as Codex, fits the same backend interface. The one cost that does not go away is that skills do not port between agent ecosystems, so moving to a different CLI means re-authoring the drafting skills. The file contract stays identical, so the dashboard and the data model do not change.

The human posts

The tool never publishes, sends, or schedules to an outside platform, and it never does outreach. It prepares the work and reminds the user, and the person posts. When it spots genuinely warm engagement, it writes a clean handoff note for PI6, my CRM, and stops there. It does not manage the relationship.

The same restraint runs through the part that learns. As the tool runs, it notices what performs and what the user keeps correcting, and it feeds that back into its own source material. Low-stakes tuning, like how often each topic comes up, it applies on its own and logs. Anything that touches identity or facts, like the voice or the canonical claims about a person or company, it drafts as a proposed edit and does not write until the user accepts it. The failure mode of an autonomous content tool is public and hard to walk back, and the part you least want a model rewriting on its own is who you say you are.

This design asks more of the user than a hosted tool does. They have to install Claude Code, authenticate it, and run the agent on their own machine against their own credential. In return, none of their business runs on infrastructure I control, the intent and the output are files they can read and back up, and nothing posts or bills without them choosing it. For a tool that touches a company's public voice and its customer relationships, that is the trade I want to make, and the one I would want made for me.

GM

About the author

Graham Morley , Software engineer and technical leader

I have built and delivered production software since 2011, including SOC 2 Type 1 and ISO 27001 certified platforms, DeFi systems that held more than 20 million dollars with zero exploits, and AI products that raised private equity funding. I build, review, and lead engineering across the stack, and I work with AI coding agents every day.

Get in touch

Related reading