{"slug": "the-agent-fleet-that-runs-my-business", "title": "The Agent Fleet That Runs My Business", "summary": "Applied AI engineer Zack Proser built a fleet of single-purpose AI agents to run his solo consulting business, with each bot owning one domain and coordinated by an orchestrator via Slack. The system, about 55% built, handles leads, writing, scheduling, contracts, email, and site ops using Claude Opus 4.8 on Vercel's eve framework, enabling him to manage business tasks from his phone without opening a laptop.", "body_md": "The Agent Fleet That Runs My Business\n\nI'm Zack Proser. I'm an applied AI engineer at WorkOS, and I run a solo business on the side: AI-transformation consulting, paid [workshops and trainings](/workshops), teaching, and the content you're reading now. The job is helping teams ship AI in production instead of demoing it once, and if that's what your team needs you can [get in touch here](/contact). That business has the workload of a small company and the headcount of one tired parent.\n\nSo I built a fleet of agents to run it. A team of single-purpose bots, each owning one domain, coordinated by an orchestrator, and I drive the whole thing from Slack on my phone.\n\nWhat I describe below is about 55% built. The bots in production already carry real weight every day; the rest are designed, partway coded, and coming online. I'm writing the whole vision down because the half that exists only makes sense as part of the half that's coming, and the shape of the finished thing is what I want you to see.\n\nWhen I say \"I use AI to run my business,\" that phrase hides the two things that matter. First, the architecture: a system I engineered to manage the irreducible complexity of running a business alone, covering leads, writing, scheduling, contracts, email, and site ops. Second, the limits: a hard boundary around what I will let a model do on its own. The framing carries the rest of this post.\n\nRunning a business is a complexity problem\n\nProgramming has always mostly been complexity management. Code is where the work shows up. A good program is one where you can hold a piece in your head without the rest of it leaking in. Decomposition, clean interfaces, separation of concerns, least privilege, failing closed: those are the moves you make so a system stays legible as it grows.\n\nA solo business has the same shape. The calendar fights the childcare schedule. The leads pile up in an inbox while the newsletter goes stale. The contracts need drafting, the books need reconciling, the posts need writing and then promoting, and the site needs to not quietly break. None of those are hard alone. Together, held in one head, they drown the person who tries to do all of it.\n\nI didn't reach for an agent because it's 2026 and that's what you do. I reached for the discipline I'd apply to any overgrown system: stop holding it in one place. Cut it into modules. Give each module one job, its own tools, and a boundary it can't reach past. Put a clean interface between them, then orchestrate the work through one place.\n\nThe bots are the modules. The message bus between them is the interface. The Chief of Staff is the orchestrator. The discipline that makes good software makes a good agent team. I pointed it at my own operation instead of a codebase.\n\nWhat the fleet is\n\nEvery bot is its own application built on [Vercel's eve](/blog/reviewing-vercels-eve-agent-framework), a filesystem-first TypeScript agent framework. One bot, one repo, one responsibility, one deployment. They share no codebase and no secret store. Each runs Claude Opus 4.8 through the Vercel AI Gateway, and each reaches me over Slack through Vercel Connect.\n\nDurability is what makes them useful. Each session runs on Vercel Workflow, so it survives a restart, a redeploy, or a cold start, and it can pause mid-task to wait for me to approve something, then pick up where it left off when I tap the button. The session outlives the chat window that started it. I can kick off a job from the school parking lot, lose signal, and find it finished or politely parked at a gate when I look again. The first time it earned its keep, the moment was almost boring. A lead came in while I was in the pickup line. I asked the fleet to read the thread and find a slot, and a draft reply with two proposed times was waiting for my thumb before the cars moved. I never opened a laptop, and the task never turned into one of those \"I'll get to it tonight\" jobs that slides into next week.\n\nThe roster runs in two tiers. The first six are in production today. The last three are designed and partway built, coming online now. Each one owns its domain, and only its domain holds its tools, its connectors, and its secrets. Least privilege, the same as you'd scope a service.\n\n**Margin** owns my calendar and wellbeing. It reads my Oura ring, protects rest and childcare time, and runs on tiered autonomy. Today it flags that in Slack; once the Chief of Staff is live, it becomes the signal the rest of the fleet schedules around, whatever the calendar says.**Inbox** triages Gmail. It reads, classifies, and drafts.**Resend** runs email marketing, with a hard outbound kill-switch so it physically cannot send a campaign without me.**Blog** is the writer. It drafted this post.**Social** handles X and LinkedIn, staged through Typefully.**Portfolio** owns site ops: SEO, analytics, the unglamorous maintenance that keeps the site from rotting.\n\nThe three coming online: **Chief of Staff**, the orchestrator that ties the fleet together; **Docs**, which drafts SOWs, MSAs, and NDAs; and **Bookkeeper**, which reconciles the bank against the books. Bookkeeper reads account activity through Plaid today, and it reads transactions rather than moving money. I'll likely move the banking workflow onto Mercury.\n\nEach of these is small enough that I can read it top to bottom in a sitting and know everything it can do, because everything it can do lives in one directory. A bot I can't fully reason about is a bot I can't safely leave running, and keeping each one that small is what lets me trust it.\n\nThe roles, as an org chart\n\nThe cleanest way to see the finished system is as reporting lines. I sit at the top, in Slack. The Chief of Staff is my one report, and every specialist reports to it. That's the target shape below. Today I can call the live specialists directly from Slack; the Chief of Staff is coming online as the single front door that makes the rest of this diagram true.\n\nRead it as a company. I give one instruction to the orchestrator, and it figures out which specialists to involve. I address one bot, and it fans the work out to the rest. That's the same reason you put an API gateway in front of a mess of services instead of making every client memorize the topology. The orchestrator absorbs the coordination so I don't have to hold it.\n\nWhere each specialist is headed\n\nThe roster above is a snapshot. The trajectory is the interesting part, so this section walks each specialist from what it does today to what it grows into once the fleet is complete.\n\nMargin: the one that protects me from myself\n\nMargin started as a calendar bot and became the most important one I own. Its job is guarding the two things I'm worst at protecting on my own: rest and time with my kid.\n\nToday Margin reads my Oura ring every morning and knows my readiness and sleep scores before I do. It already holds my childcare blocks as immovable. Where it's going is the part I care about most. I want to be able to message it \"I feel like shit\" from bed and have it act on that one sentence: pull my readiness data, find the meetings I can move, draft the reschedule notes, and propose a rearranged day with a real sleep block carved into it before I've finished my coffee. A bad night should reshape the day automatically, with me approving the changes rather than negotiating each one.\n\nThat means Margin owns the follow-ups too. When it moves a call, it drafts the \"something came up, can we do Thursday\" email, threads it to the right person, and waits for my tap to send. The reschedule and the apology and the new invite travel together as one approved action instead of three things I forget to do.\n\nThe scheduling itself gets sharper once Margin can see everything. I'm wiring it into Cal and Calendly so it reads my full picture and my business partner's: work calendars and personal calendars, mine and his, in one view. A bot that proposes times against only half the constraints proposes the wrong times. It reads my partner's calendars as free/busy only, not event details, which is the least-privilege version of \"can you two meet Thursday.\" Once Margin holds that availability plus my own work and personal calendars, my readiness data, and my childcare blocks, \"find a slot for the three of us next week\" becomes a question it can answer without me cross-checking four calendars on my phone.\n\nInbox: triage that clears the queue\n\nInbox reads Gmail, classifies what comes in, and drafts replies today. The direction is less about reading more mail and more about closing loops. A lead email should land as a structured summary, a suggested reply, and a proposed next action, so the work of answering it is one approval instead of a context-switch into my inbox. The follow-up that I always mean to send three days later is the kind of thing Inbox should own and schedule, with the draft waiting for my thumb.\n\nResend: marketing that can't fire by accident\n\nResend runs email marketing, and its defining feature is the hard outbound kill-switch. Nothing leaves without my approval. As it matures, the value is in drafting whole sequences from a single brief and staging them, so a launch I describe in two sentences in Slack comes back as a full campaign for review. The kill-switch stays exactly as load-bearing as it is now, because a marketing bot that can send on its own is a way to email my entire list a mistake.\n\nBookkeeper: invoicing and reconciliation from a Slack message\n\nBookkeeper already reads account activity through Plaid to reconcile the bank against the books. It reads transactions and does not move money. The invoicing is the part that's coming online.\n\nThe capability I'm building toward is invoicing from Slack. After a call, I want to message \"invoice Acme for the December workshop, net 30\" and have Bookkeeper draft the invoice, show it to me for approval, send it, and then track it against incoming transactions until it's paid, nudging me when it goes late. The reconciliation it already does and the invoicing it's growing into are two halves of the same job: knowing what's owed, what's paid, and what's overdue, without me keeping any of it in my head. When the banking workflow moves onto Mercury, the same approval gates ride along.\n\nDocs: minting uniform business artifacts\n\nDocs is the bot I'm most excited to finish. Running a consulting business means generating the same legal artifacts over and over: SOWs, MSAs, NDAs, order forms. Done by hand, each one is a chance to fat-finger a client name, a date, or a payment term.\n\nDocs mints these from uniform templates, so every contract that leaves looks the same and carries the same clauses. I'll describe the engagement in Slack, Docs assembles the right artifact, I approve it, and it goes out through DocuSign for signature. When the signed copy comes back, Docs files it in the right client folder in Google Drive, named consistently, where I can find it two years later. The pipeline runs from a Slack sentence to a signed, filed contract, and every outbound step still stops for my approval.\n\nThe orchestrator sees that pipeline as a single instruction that becomes a filed, signed document:\n\nBlog: the writer that drafted this\n\nBlog is the bot that wrote this post. I hand it a rough idea in Slack and it researches, drafts, generates the images and diagrams, runs its own voice and anti-slop passes, and opens a pull request against my portfolio repo for me to review. It owns the part of my content pipeline that used to stall: the blank page. Where it grows is into a tighter loop with Social, so a published piece becomes a staged thread without me copy-pasting between two tools. It writes; I edit and ship.\n\nSocial and Portfolio: the steady hands\n\nSocial stages posts to X and LinkedIn through Typefully, and Portfolio handles site ops, SEO, and analytics. Both run today and need the least from the vision. They're the proof that a bot doesn't have to be ambitious to be worth it. Some of the fleet exists to keep the lights on while the rest does the heavy lifting.\n\nMobility was a hard requirement\n\nOne constraint shaped every other decision: the control plane is Slack, and it has to give me identical power on my phone and my laptop. A full mobile control plane, with the same fleet, the same commands, and the same approvals as the desk.\n\nI'm a solo parent running a real business. The office is wherever I am, which is frequently a pickup line, a kitchen, or the ten minutes before a kid needs something. A system that only worked at my desk would only work when I'm least likely to be at it. So I made full capability from my phone a requirement at the start and designed backward from it.\n\nChat-as-interface is what makes that work, and the parts that matter are boring. It's ambient: Slack is already on my phone, so there's no app to open with intent and no context to reload. It's async: I drop an instruction and the durable session carries it whether I'm watching or not. It's durable: the work parks and resumes, so a flaky signal in a parking garage doesn't drop a task on the floor.\n\nI gave a talk at AI Engineering London called [Untethered Productivity](/blog/aie-london-untethered-productivity) about exactly this. Agents scale infinitely, but your nervous system doesn't. The win is getting unhooked from the desk while the work keeps moving. I built the fleet after that talk because I was tired of holding ideas until I got back to a keyboard. The keyboard stopped being where the work happens.\n\nHow the bots talk to each other, with the Chief of Staff in front\n\nThe Chief of Staff is the single front door. In the finished system I talk to it and almost nothing else, and it relays to the specialists on my behalf. That's the design eve is built for: a main agent that delegates focused subtasks to child agents, each with its own prompt, tools, and identity, and then combines the results. eve's own docs describe a subagent as a separate agent with fresh state that the main agent hands a narrow job to, which is exactly the role each specialist plays.\n\nThe Chief of Staff does not reimplement the specialists. The lazy version gives the orchestrator its own Gmail tools and its own calendar logic, and that produces one god-object bot that knows everything, holds every secret, and resists reasoning. So the Chief of Staff *calls* the specialists instead. It declares each one as a remote agent rather than copying its capabilities.\n\nEach specialist is declared as a remote agent that points at its own deployment's HTTP endpoint, a `POST`\n\nto `/eve/v1/session`\n\n, the same session API eve exposes for every agent. eve lowers that declaration into an ordinary tool with a `{ message, outputSchema }`\n\nshape. From the orchestrator model's point of view, delegating to Inbox or Margin looks identical to calling any other tool, or to spawning one of its own subagents. It says \"draft a reply to this lead\" or \"find a time that works for me and Nick,\" the specialist runs its own durable session against its own connectors, and it returns a structured result.\n\nDay to day, I hold one conversation. I tell the Chief of Staff what I want in plain Slack, and it decides which specialists to wake, in what order, and how to thread their results into one answer. The fleet's complexity stays inside the orchestrator instead of landing on me.\n\n``` js\n// chief-of-staff/agent/agents/margin.ts\nimport { defineRemoteAgent } from 'eve'\nimport { z } from 'zod'\n\n// Margin is a different Vercel deployment. The Chief of Staff\n// doesn't know how Margin reads my calendar or my Oura ring.\n// It only knows the contract.\nexport default defineRemoteAgent({\n  url: 'https://margin.example.vercel.app/eve/v1/session',\n  description: 'Find availability that respects rest and childcare.',\n  outputSchema: z.object({\n    slots: z.array(z.object({ start: z.string(), end: z.string() })),\n    blockedReason: z.string().optional(), // e.g. \"low Oura readiness\"\n  }),\n})\n```\n\nThe orchestrator's model now has a `margin`\n\ntool. It passes a message and gets back typed slots. It never learns how Margin talks to Google Calendar or what an Oura readiness score is, the same way one service doesn't reach into another's database. The contract is the whole relationship.\n\nA real request crossing the fleet looks like this: get a new lead onto the roster and find a time, from my phone.\n\nIn the diagram, `get_availability(collective, ...)`\n\nmeans \"find a slot that works for everyone on this thread,\" and \"WorkOS-aware\" means Margin already knows my day-job hours are off-limits. The Chief of Staff orchestrates. The specialists do the work in their own sessions. The structured results flow back up, and a draft plus a one-tap approval is the only thing that reaches me. I'm coordinating a team over chat. The team happens to be made of durable agent sessions instead of people.\n\nThe example above touches two bots. The finished vision chains the whole fleet behind one sentence. When I close a deal, I want to tell the Chief of Staff \"we won Acme, kick it off\" and watch it route the work: Docs mints and sends the SOW, Bookkeeper schedules the kickoff invoice, Inbox drafts the welcome email, and Margin finds a kickoff slot that survives my readiness and my partner's calendar. Each specialist runs its own durable session, each outbound step waits for my approval, and the Chief of Staff holds the thread that ties them together. I describe the outcome once; the orchestrator decomposes it into the right calls and reassembles the results. That's the difference between a pile of bots and a fleet.\n\nThe bus is the security boundary\n\nA team of bots that can call each other is a team of bots that can be *made* to call each other. So the interface between them is where I spent the most care. Those `/eve/v1/*`\n\nroutes are protected and **fail closed by default**: an unauthenticated or unrecognized caller gets a 403 and nothing else.\n\nInter-bot calls authenticate with **Vercel OIDC**. Vercel mints a per-deployment identity token, so each bot proves who it is with a short-lived, environment-pinned identity rather than a secret it carries around. In eve, the auth wrapper on those routes trusts same-project OIDC subjects by default. To let the Chief of Staff, which lives in a *different* Vercel project, call a specialist, the specialist allow-lists the orchestrator's project identity by its `vercelSubject`\n\n. The fleet passes no shared secrets, no API keys handed bot to bot, and no long-lived token sitting in an env var waiting to leak. The identity is project-scoped and environment-pinned, and the specialist decides who it answers to.\n\n``` js\n// margin/agent/auth.ts — Margin decides who it answers to.\nimport { allowProjects } from 'eve'\n\n// Same-project calls are trusted by default. To let the Chief of Staff\n// (a different Vercel project) in, Margin allow-lists its OIDC subject.\n// Anything not on the list hits the default: fail closed, 403.\nexport default allowProjects({\n  'chief-of-staff': {\n    // illustrative shape; use the exact subject Vercel issues for the deployment\n    vercelSubject: 'owner:zack:project:chief-of-staff:environment:production',\n  },\n})\n```\n\nIf you've designed distributed systems, this should feel familiar, because it's the same playbook:\n\n**Typed contracts between services.** The`outputSchema`\n\nis an API contract. A specialist can change how it does its job without the orchestrator knowing or caring, as long as the shape holds.**Identity-based auth.** OIDC subjects in place of shared secrets, the same reason you'd use workload identity over a static key in any service mesh.**Idempotency, designed per side effect.** Durability gives a session somewhere to resume; it doesn't make side effects safe to retry. So each bot keys its dangerous actions and stores what it has already done. Resend keys a send on`campaignId + approvedRevision`\n\n, Docs keys a DocuSign send on`artifactId + approvedRevision`\n\n, and Bookkeeper keys an invoice on`clientId + engagementId`\n\n, so a retried or replayed approval fires once.**Blast-radius containment.** Each bot holds only its own connectors and secrets. Compromise one and you get one domain, not the keys to the business.**Kill-switches on dangerous actions.** Resend's outbound send has a hard off-switch. Money and contracts don't move on a model's confidence.\n\nThe rule on top of all of it: anything outbound is human-in-the-loop. Before it sends an email, moves money, or signs a contract, eve parks the session and renders the action as a one-tap approval button in Slack. I draw [that same line across every bot I run](/blog/the-autonomy-boundary): anything reversible runs unattended, and anything that reaches another person or can't be undone stops for me. The bus gives the fleet its reach; the approval gates make it safe to leave running.\n\nThis is complexity management with new nouns\n\nStrip the AI out and there's nothing exotic here. I took an unmanageable amount of work, decomposed it into single-responsibility modules, gave each a clean typed interface and a least-privilege boundary, put identity-based auth on the wire, contained the blast radius, and kept a human at every irreversible gate. It's the same systems design I'd defend in any architecture review.\n\nWhat changed is the unit of decomposition. The module used to be a service; now it's an agent. The thing I'm encapsulating used to be code; now it's *judgment*: Margin's judgment about when I'm too depleted to take a meeting, Inbox's judgment about which lead is real. The discipline that keeps it legible is the old discipline. The people who build good agent teams are the ones who already knew how to tame a system and pointed that skill at a new kind of module.\n\nThe useful part is the system underneath: decomposition, typed contracts, narrow permissions, durable execution, and a human at every gate where the work can hurt someone. I run that system from my phone, in a pickup line, with the same authority I'd have at my desk.\n\nIf you want this for your team\n\nThis is the work I do: AI-transformation consulting, workshops and trainings for teams that want to ship AI in production, and helping people design their own agent fleets. In a workshop you leave with a workflow map, an autonomy-boundary table, and a spec for the first specialist or two, with the approval gates drawn before anything gets wired into a system that can spend your name or your money.\n\nIf that's what you need, [reach out](https://zackproser.com/services). I'll help you build the version of this that fits your business.", "url": "https://wpnews.pro/news/the-agent-fleet-that-runs-my-business", "canonical_source": "https://zackproser.com/blog/the-agent-fleet", "published_at": "2026-06-25 00:00:00+00:00", "updated_at": "2026-06-25 15:45:19.499911+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "ai-infrastructure", "ai-products", "developer-tools"], "entities": ["Zack Proser", "WorkOS", "Vercel", "Claude Opus 4.8", "Vercel AI Gateway", "Vercel Connect", "Vercel Workflow", "eve"], "alternates": {"html": "https://wpnews.pro/news/the-agent-fleet-that-runs-my-business", "markdown": "https://wpnews.pro/news/the-agent-fleet-that-runs-my-business.md", "text": "https://wpnews.pro/news/the-agent-fleet-that-runs-my-business.txt", "jsonld": "https://wpnews.pro/news/the-agent-fleet-that-runs-my-business.jsonld"}}