Send a product update email with Claude and an MCP server

Connect Claude to Unitpost's MCP server and let it do the drafting. It picks a segment of people who opted in, scopes the campaign to a Product updates topic so readers can leave just that mail, turns your changelog into a marketing template with design_library and email_templates_create, creates a draft campaign and runs email_campaigns_validate. You read a test send. A person, not the model, runs email_campaigns_send.

Unitpost ·

Writing a product update is the part a model does well. The parts that go wrong are who receives it and who decides it goes out. This walkthrough gives Claude everything up to the send and keeps the send for a person, using the tools Unitpost's MCP server lists.

Which tools does the connection need?

The default tool list covers the whole flow: segments, topics, templates, campaign create, validate and send, and the test send. A few useful extras sit in groups: email_templates_render (templates), email_campaigns_stats and email_campaigns_list_recipients (campaigns), and segments_get_preview (audience). Add groups to the server URL, or send them in an X-MCP-Toolsets header:

cURL
https://mcp.unitpost.com/mcp?toolsets=default,campaigns,templates

Append audience to the list for the segment preview.

Who should get it?

Only people who asked to hear from you: customers and sign-ups who agreed to product email. Unitpost's acceptable use policy bans purchased, rented or scraped lists, and the MCP server's instructions tell the agent not to send to or import them.

Ask Claude to list your segments with segments_list and check the one you mean with segments_get. segments_get_preview returns subscribed_count, the number a campaign would actually mail; 0 means it would send nothing. If you need a new audience, segments_create makes either a static list (add people with segments_add_member) or a dynamic segment whose filter is evaluated at send time, such as everyone whose plan field is pro.

Why scope it to a topic?

Without a topic, an unsubscribe from a product update opts the contact out of all your marketing email. The email_campaigns_create description says so and suggests a topic for any recurring kind of mail, and validate adds a NO_TOPIC note when one is missing.

Have Claude find or make one with email_topics_list or email_topics_create. For product updates the docs use default_opt_in: true: contacts already on your list receive it unless they opt out. false makes an opt-in topic, which suits beta invites. A contact's explicit choice beats the default either way.

A topic is not consent. It narrows mail to people already on your list, and lets them leave one kind of message. The contact_topics_update description puts the limit plainly: subscribe someone only when they asked, because subscribing people to topics they never chose manufactures consent.

How does Claude draft from a changelog?

Paste the changelog entries and ask for one email. Something like: "Write this month's product update from these notes. Lead with the biggest change, link each item to its docs page, and don't add anything that isn't in the notes."

The template tools and the design guide behind them carry their own rules, and Claude reads them as it works:

  • Start from the recipe. design_library with topic: guide and key: newsletter returns the "Newsletter / digest / changelog" recipe and a complete starter. Use key: product-launch when the update is one feature. Pass the Brand Kit's accent and logo from brand_kits_list and the starter comes back in your colours.
  • Write it as a Design email. email_templates_create takes tsx built from Unitpost's components inside one <Email> element. Design is the default; plain text or raw html only when you ask for them.
  • No facts it wasn't given. Features, numbers, prices and dates come only from your notes, the Brand Kit or a tool result. Example lines it couldn't avoid are listed in its reply for you to replace.
  • The recipe's shape. Three to five sections with the most important first, a subject that names the lead item rather than "Newsletter #12", preview text that lists the rest, text links per item and at most one button.
  • No footer. It never writes the unsubscribe link or postal address. Marketing templates get the managed footer at send.
  • Publish before use. The template is created as a draft. email_templates_update with status: "published" makes it usable by a campaign. Claude should repeat any warnings and fix any fix item in design_hints.

The newsletter recipe is a marketing template, which is what a campaign needs. {{first_name}} fills from the contact and {{company_name}} fills itself on campaigns.

Create the draft and validate it

email_campaigns_create takes name, template_id, segment_id, topic_id, from and optionally subject and preview_text. It creates a draft; nothing sends. The from must be on a verified domain.

Then email_campaigns_validate. It changes nothing and returns:

  • can_send and blockers, such as an unverified domain or an archived topic.
  • sendable, who will receive it.
  • variable_coverage[]. A variable marked missing_for_all needs a default in variable_fallbacks before it can send.
  • warnings[], such as scheduled sends that may outrun the period's credits. They never block, but Claude should tell you each one.

Claude fixes what it can with email_campaigns_update and validates again. For a large audience the first call answers with a job while it counts; it calls again until the report arrives. email_campaigns_list_recipients shows, per member, who is sendable, suppressed, excluded or missing data, and why.

Review a test, not a summary

Ask for a test to your own address. email_templates_test_send renders the template with sample variables exactly as a recipient gets it, footer included. It is a real email, so Claude asks first. With a verified domain the test can go to anyone; without one, only to workspace members. unresolved_variables lists any variable that had no sample value.

Read it on a phone. Click every link. Check each claim against the changelog. email_templates_render returns the same subject, HTML and text without sending anything, which helps when you're iterating on copy. If something is wrong, Claude edits the template and you test again.

A person sends it

email_campaigns_send needs body.scheduled_at: a time schedules it and null sends now. Its description tells the client to show you validate's sendable, every blocker and warning, and the time before sending, and Claude asks before it runs because the tool is marked destructive. Afterwards, email_campaigns_get should show scheduled, sending or sent; until it does, it isn't done.

A confirmation dialog is a setting someone can change. To make the approval structural, connect Claude with a key that has campaigns:write but not campaigns:send. It builds, validates and tests; a person opens the campaign in the dashboard and presses Send. How to make an AI agent ask before it sends email covers that split.

If you'd rather stay in Unitpost, the dashboard assistant, Unit, runs the same steps and shows an Approve or Cancel card before any campaign is sent or scheduled.

After it goes out

email_campaigns_pause stops a sending campaign between recipients. Unitpost also pauses a campaign on its own when hard bounces or complaints cross its threshold, and pause_reason on email_campaigns_get says which. Once it finishes, email_campaigns_stats reports delivered, unique opens and clicks, unsubscribes, bounces and complaints, and the topic's unsubscribed_count on email_topics_get shows how many left product updates without leaving your list.

Frequently asked questions

Can Claude send the campaign without me?

Only if its credential holds campaigns:send and the client doesn't ask. email_campaigns_send is marked destructive, so Claude asks before it runs. To make the person's step a rule rather than a habit, connect with a key that has campaigns:write but not campaigns:send: Claude can build and validate the draft, and a person sends it from the dashboard.

Will people who unsubscribed get the update?

No. Unsubscribed and suppressed contacts are counted out in the validate report, and with topic_id set, anyone who opted out of that topic is gated out at send. Every marketing send also carries the managed footer and one-click List-Unsubscribe headers, and there is no flag to turn them off.

Can a campaign use a transactional template?

No. A campaign sends only a marketing template, and create refuses a transactional one with template_transactional on template_id. Set the template's category to marketing, on its <Email> element or with email_templates_update.

Send email your users actually receive

5,000 emails a month free — API, SMTP, templates, tracking. No credit card.