Building an outbound sales agent as a Claude Code plugin (and open-sourcing it) A developer in Tokyo built LeadAce, an outbound sales agent that runs as a Claude Code plugin and is open-sourced. The agent finds companies matching an ideal customer profile, writes personalized emails, sends them via Gmail, and categorizes rejections by reason. The architecture separates model decisions from code, with validation and data access enforced server-side, and supports both cloud and self-hosted editions. I run a small software company in Tokyo. I am an engineer, not a salesperson. Cold outbound was the part of my job I kept avoiding. So I built an agent that does it for me. It runs as a Claude Code plugin, and the whole stack is open source. This post is about the architecture decisions that mattered. The product is LeadAce leadace.ai https://leadace.ai , source https://github.com/aitit-inc/leadace . It is in Public Beta. It finds companies that match your ICP, reads each company's site, writes one email per company, and sends from your own Gmail. Then it collects the replies. And it turns every rejection into a structured reason: budget, timing, wrong buyer, or missing feature. That data changes the next round's targeting. The honest reason: I already spend all day in Claude Code. I did not want to build one more web app with a chat box in it. Later I found a better reason. A Claude Code plugin runs on the user's own Anthropic plan, on their machine. I do not proxy the LLM calls. So I do not have to charge for them. The price only covers send volume and infrastructure. That is why the entry plan can be $29/mo. My users are developers who already pay for Claude Pro or Max. For them, "bring your own agent runtime" is a feature, not a limitation. The plugin is only the UX layer. Everything stateful is a normal SaaS backend behind it. If you have not built one: a plugin is a directory with skills markdown instructions that become slash commands , an optional MCP server declaration, and scripts. Distribution is a git repo: claude plugin marketplace add aitit-inc/leadace claude plugin install leadace@leadace LeadAce ships skills like /leadace onboarding: point it at your homepage , daily-cycle , build-list , outbound , check-responses , and evaluate . Each skill is a prompt that works like a program. It contains instructions, guardrails, and references to MCP tools and local scripts. ${CLAUDE PLUGIN ROOT} resolves file paths inside the installed plugin. That sounds like a small thing. But you need it the first time a helper script inside your plugin has to run on someone else's machine. The main design question for any agent product is this: what does the model decide, and what is code? Our split: record outreach . It does not see the twelve validation rules behind it. The validation runs on the server. So a prompt injection hidden in some company's website cannot turn it off.The rule I ended up with: if a mistake causes a compliance or data problem, it must be code. If a mistake causes a quality problem, the model can do it, with review gates around it. There is one more point I understood too late. This split is also the trust boundary. The agent reads random websites all day. A prospect's site is untrusted input by definition. So anything that touches the database or sends email has to be a fixed contract in code. It must not be something the model can be talked into. Every table has a tenant id . Every request runs in a Postgres transaction that starts with: SET LOCAL ROLE app rls SET LOCAL app.tenant id = '