MuninMunin
Sign inStart free
Home/Journal/Your outreach should draft itself. Then stop.
Field note · 8 min read

Your outreach should draft itself. Then stop.

The intro you meant to write, the follow-up you meant to send, the reply that deserved twenty minutes. An agent can draft all three overnight from the customer record you already have. What makes it safe is the part that happens next: it files them and waits for a person.

Seen from below, a row of blank cream paper sheets pegged along a twine line strung between light-wood ceiling beams, backlit and glowing, with a figure reaching up to lift one down — a night's work drafted and hung, none of it gone anywhere until someone decides.
Drafted overnight. None of it has left the building.

Every company has a folder of the emails that were going to go out. The intro to the person who asked for one at a conference in March. The follow-up to the prospect who said circle back in September. The reply to the trial user who wrote three careful paragraphs about pricing and got a thumbs-up emoji. Nobody decided not to send them. They just never reached the top of anybody's afternoon.

Why is outbound the job that never gets done?

Because outreach is three jobs wearing one name: deciding who to contact, writing something specific to them, and remembering to come back in a week. The first and third are bookkeeping. The second is judgment. Most teams either do none of it or automate all of it — and automating the judgment is how you send a tone-deaf email you can't take back.

The bookkeeping half is genuinely mechanical. Who in this segment hasn't been contacted. Who already has a draft in flight. Who unsubscribed last month and must never hear from us again. Who is now four days past the wait period on step two of a sequence nobody has looked at since April. None of that needs a person, and all of it is precisely what a person drops on a Thursday.

The writing half is not mechanical, and the last two years have taught every inbox on earth what happens when you pretend it is. The generic AI cold email is now recognisable in under a second, and it doesn't just fail — it burns the address it lands on.

Can AI write my sales outreach emails?

Yes, and the serious platforms already do it. Klaviyo runs an MCP server and a Claude connector that drafts campaign copy from your live segments and audits your flows. Customer.io lists an AI Agent with core execution skills and scheduled Routines on every plan, Essentials upward. Munin drafts one email per contact per campaign and files it as a pending proposal a human approves before anything leaves.

The interesting difference isn't whether the model can write. All of them can write. It's what the system does with the draft once it exists — and specifically whether there is somewhere for a draft to wait.

What happens between Thursday night and Friday morning?

Four curator passes run on a schedule, and every one of them ends the same way: a draft filed for review. A weekly pass drafts first-touch emails for enabled campaigns. A daily pass drafts the next sequence step for anyone who hasn't replied. An event-driven pass drafts a reply the moment a prospect writes back. None of them send. You wake up to a queue, not to sent mail.

What makes the drafts worth reading is where they're drawn from. A campaign is an operator-written brief plus a target CRM segment, so the pass materialises a real audience, pulls supporting facts out of the knowledge base with kb_search to ground the claims, and writes 80 to 200 words to one named person at one named company. It is the same shape as keeping the CRM current from conversations you were already having: read what you already have, write the thing nobody had time for, stop before the irreversible bit.

  • 01Materialise the audience. crm_list_contacts_in_segment — not crm_list_contacts. The segment surface applies the suppression and lawful-basis floor in the service, so what comes back is already the eligible set.
  • 02Dedupe before drafting. outreach_list_proposals per (campaign, contact). A pending, approved, or sent proposal means that person is spoken for. Only dismissed, withdrawn, and failed reopen the slot.
  • 03Ground the claim. kb_search against the campaign brief for one to three real documents. If nothing comes back, the draft is written at a higher level — no invented features, no invented numbers.
  • 04File it. outreach_propose_first_touch with the draft subject, the draft body, and an evidence payload carrying the KB doc ids and the reasoning a reviewer would want to see.
  • 05Stop. No further calls. The approve surface belongs to the operator, and a curator never decides its own drafts.
jsoncone draft, filed for review
{
  "name": "outreach_propose_first_touch",
  "arguments": {
    "campaignId": "ocmp_…",
    "contactId": "cct_…",
    "draftSubject": "Quick thought on Acme's onboarding loop",
    "draftBody": "Hi Jane,\n\nI noticed Acme just shipped self-serve onboarding …",
    "evidence": {
      "kbDocIds": ["kdoc_abc"],
      "contactSignals": ["title=Head of Ops", "tag=enterprise"],
      "reasoning": "Brief targets ops leaders; title matches; one KB doc on onboarding loops."
    }
  }
}

Why doesn't the draft just send itself?

Because a sent email has no undo, and a cold email is generative rather than transcriptive. Extracting a phone number a customer typed is faithful copying. Writing a pitch in your company's name to someone who has never heard of you is invention — a different risk profile entirely, and the one place where a confident model is most expensive.

So approval is the send decision, not a status flip. outreach_approve_proposal on a first-touch creates the outbound conversation, sends through the campaign's channel, and appends the CTA and the signed unsubscribe footer. On a follow-up or reply it sends the body verbatim on the existing thread. There is no confidence threshold that skips this, and no configuration that turns it off.

Voice and SMS go further: those proposals can only be approved by a signed-in person in the Munin dashboard. An agent can't approve one. Neither can an admin API key or a Slack button. The server refuses every other caller, which means outbound calling is bounded by something sturdier than a well-written system prompt.

Approval is bound to the text, not the id

Every proposal carries a draftFingerprint — a digest of the campaign, the recipient, the subject, the body, and the proposed send time — and outreach_approve_proposal requires it. If the draft moved since the operator read it, from anyone's revision, the fingerprint no longer matches, the call fails with outreach_conflict, and nothing is sent.

The tempting fix is to re-fetch the proposal and retry with the new fingerprint. That is exactly the failure the check exists to stop: it approves whatever happens to be in the slot rather than the text a person read. Re-read the current body, put it in front of them, and get their word on that one.

A revision also stamps revisedAfterReviewAt, so an operator who read Monday's draft is told, in the panel and in the dashboard drawer, that Wednesday's is not what they read.

A pending queue is not permission. The invariant that makes propose-only outreach safe is that a human read each draft.

What does the queue refuse to draft?

More than it drafts, on most weeks, and the refusals are where the trust comes from.

Anyone suppressed or without a lawful basis. do_not_contact, unsubscribed_at, and a null consent_lawful_basis are filtered inside the service, on the segment surface the curator is required to use. That floor is not an argument the agent can win, which is the point of putting it below the agent rather than in its instructions. It is the same reasoning that runs through what EU data residency actually covers.

Anyone who already has a draft in flight. A unique index covers pending and approved proposals alike, so two passes racing each other produce one draft, not two.

Anyone who replied. The moment an inbound message lands, the follow-up sequence permanently stops and the reply flow owns the thread. A follow-up that was already approved and scheduled for Tuesday fails its send-time re-check rather than delivering — because approval authorises a message, it doesn't freeze the world.

Anyone who became ineligible while waiting. When the worker picks up a scheduled send it re-verifies the campaign is still enabled and the contact still consented. A proposal that fails lands on status: "failed" with a reason attached. It is never sent to someone who unsubscribed during the wait.

How is this different from Klaviyo, Customer.io, or a cold-email tool?

They are shaped for different jobs, and the differences are real rather than positioning. Klaviyo is built around commerce volume and bills on active profiles — every contact who could be emailed, whether you email them or not. Customer.io is built around lifecycle journeys and bills per profile from $100 a month. Munin is built around one-to-one outbound off a shared customer record, with a human gate on every send.

  • KlaviyoCommerce marketing at volume, with a drag-and-drop editor, SMS, WhatsApp, push, and a deep flow library. Billing is on active profiles: the free tier is 250 profiles and 500 sends a month, and a 500–1,000 profile plan is listed at $30/month with 10,000 sends. Customer Hub starts at $20/month and Helpdesk at $10/month on top.
  • Customer.ioLifecycle journeys for product-led teams. Essentials is $100/month for 5,000 profiles and 1 million emails, with additional profiles at $0.009 and additional thousand-email blocks at $0.12; Premium starts at $1,000/month billed yearly. Seats are unlimited on every plan, and the pricing page lists an MCP server and an AI Agent across all three.
  • Munin outreachOne-to-one outbound drafted from the same contacts table the CRM, inbox, and knowledge base use. Every message — first touch, follow-up, reply — arrives as a pending proposal bound by fingerprint to the text a person read. MIT throughout, and the drafting procedures are markdown you can edit.

Which outreach desk is this for?

Munin has no drag-and-drop email builder, no abandoned-cart or browse-abandonment flow library, no managed deliverability or dedicated IP warm-up, and no push or in-app channels. Klaviyo and Customer.io have spent years on exactly those, and if you are sending a styled campaign to eighty thousand shoppers on Black Friday, buy one of them — that is the job they were built for and they are good at it.

Munin is for the other outbound problem, and it is the more common one below a certain size. You are sending fifteen emails a week, each one to a named person, and every one of them should read as though you wrote it — because in the only sense that matters, you approved it. Here the draft is written from the same customer record your support inbox and knowledge base already share, the consent floor is enforced in the database rather than in a checkbox, and the send decision is physically a human's. That is a different product for a different desk, and it is the one that fits a team that doesn't have a marketing hire.

Which one should you pick?

Pick Munin when the constraint is that outbound has to sound like a person and there is no person with time to write it.

The draft knows things. The prospect's support history, the deal stage, the article they read last Tuesday, and the campaign brief are one Postgres schema with one contacts table behind all six modules. No sync job stands between the conversation and the email, because nothing is apart. When a reply lands on an outreach thread, the reply-drafting pass reads that thread — not a summary of it.

It runs where you already work. The passes are MCP tools plus markdown procedures, not a feature inside a UI you log into. Claude, Claude Code, Cursor, ChatGPT, the OpenAI Agents SDK, or a runner you wrote — same 204 tools, same audit log, same review queue. In hosts that support MCP Apps the queue renders as an inline panel where the decision tools are hidden from the model entirely and only your click can invoke them.

You can read the rules before you trust them. The first-touch, follow-up, reply, SMS, and call procedures are five of the 47 bundled markdown skills. They say how long a draft should be, that a breakup email is graceful and never guilt-trips, and that a curator must never approve its own work. When one is wrong for your team, you edit the markdown and the next run behaves differently.

And the meter isn't on the outcome. Munin Cloud Free is €0 a month with 5,000 MCP calls, 250 contacts, and 100 MB — enough to run real campaigns for a small team. Self-hosting is docker compose up under MIT, with no enterprise/ directory holding the useful half. The model cost is whatever your provider charges, not a per-send fee to us — the same argument I made about meters generally, applied to the module where a meter bites hardest.

What does it look like after a month?

A short queue every morning and a follow-up rate that stopped depending on anyone's memory. Fifteen or twenty drafts a week is normal for a small team: read, edit a sentence, approve or dismiss.

The habit that forms is worth naming. Dismissing a follow-up permanently stops the sequence for that contact — it is the right verb for stop chasing this person and the wrong one for reword this. For wording you revise in place and approve the edited version, which keeps the review history attached. Operators who learn that distinction in the first week end up with a queue that reflects real decisions rather than tidying.

The second-order effect is the one you notice. Because the drafts are grounded in the knowledge base, the gaps show up fast — a campaign brief with nothing behind it produces vague drafts, which is a useful signal about the documentation rather than the model. That loop runs the same way the knowledge base fills itself from resolved handovers.

Frequently asked questions

Can AI send cold emails for me automatically? In Munin, no — and that is the design. An agent drafts first-touch emails, follow-ups, and replies, then files each one as a pending proposal. outreach_approve_proposal is the send, and it is bound by fingerprint to the exact text a person read. Voice and SMS approvals only work from a signed-in dashboard session.

What stops an AI outreach agent from emailing someone who unsubscribed? The suppression and lawful-basis filter lives in the service, on the segment surface the drafting pass is required to call. Contacts flagged do_not_contact, contacts with unsubscribed_at set, and contacts with no consent_lawful_basis never reach the agent. The check runs again at send time, so a scheduled email fails rather than delivers if consent changed while it waited.

Can I schedule an approved outreach email for later? Yes. A curator can suggest a time with proposedSendAt, and the operator's approval is what turns it into an authorised send — inherit the suggested time, name a different one, or pass sendAt: null to send immediately. A scheduled proposal sits at status: "approved", and outreach_cancel_scheduled_send pulls it back to the review queue before delivery.

What is the open-source alternative to Klaviyo or Mailchimp? For bulk newsletters, listmonk (AGPLv3, a single Go binary plus Postgres) and Keila (AGPLv3, Elixir) are both excellent and self-host cleanly. For full marketing automation, Mautic is GPL-3.0 and reached version 7.0.0 in January 2026. Munin is MIT and covers a different job: one-to-one outbound on the same record as your CRM, inbox, and knowledge base.

Which AI model writes the drafts? Whichever one you point at the tools. The passes are markdown procedures over MCP, so Claude, ChatGPT, Gemini, or a model you host yourself all work, and switching is a config line rather than a migration.

Does the agent write the unsubscribe link? No. The system appends a signed unsubscribe footer at approve time so it can't be tampered with at draft time, and the drafting skills explicitly forbid writing one into the body.

The short version

  • Outreach is three jobs: choosing, writing, and remembering. Two of them are bookkeeping an agent should do, and one is judgment a person should keep.
  • Munin drafts first touches weekly, follow-ups daily, and replies on arrival — and files every one as a pending proposal instead of sending it.
  • Approving is the send. It is bound by draftFingerprint to the exact text the reviewer read, so a draft edited in between refuses rather than ships.
  • Suppression and lawful basis are enforced in the service on the segment surface the agent must use, and re-checked at send time.
  • Voice and SMS proposals can only be approved by a signed-in person in the Munin dashboard — no agent, API key, or Slack button can place that call.
  • Klaviyo and Customer.io both run MCP servers and AI agents and are strong at commerce volume and lifecycle journeys; Munin is MIT, drafts from the same contacts table as the CRM and inbox, and is €0 to start on Cloud Free.

Set up one campaign, let a pass draft into it overnight, and read what's waiting in the morning — Munin Cloud is free for that, and the whole platform is MIT on GitHub.

The drafting is the easy half. Stopping is the product.

Kjell Rune Monsø, founder.