MCP tools
Create and revise a saved broadcast, prepare its review, and read the same operation after an interruption. Copyable MCP calls for real account work.
Follow one draft from start to review
Start with a connected account. Choose a workspace, save a broadcast, review the current revision, and inspect the result. This walkthrough stops at review; it does not send email.
Examples follow the MCP schemas published with CLI 0.4.0. Each JSON block shows a tool name and its arguments; your client handles the connection. Acme, sender_example and the UUIDs are fictional. Use returned workspace and sender choices, and generate fresh UUIDs for your own new drafts and requests.
Choose the workspace
Call fonte_list_workspaces and select the intended workspace from its returned names. Use its slug in later calls.
{
"name": "fonte_list_workspaces",
"arguments": {}
}A fictional completed response:
{
"outcome": "completed",
"reason": null,
"status_code": null,
"core_effect": "none",
"workspaces": [
{
"slug": "acme",
"name": "Acme",
"role": "owner",
"available_environments": [
"production"
]
}
]
}fonte_status reads connection readiness. If it reports workspace_required, resolve the workspace from the authenticated catalog and keep that choice in your client’s context.
{
"name": "fonte_status",
"arguments": {}
}Find sender and audience choices
On hosted MCP, fonte_list_broadcast_options returns saved senders, communication purposes, and audience sources. Choose the intended entries; copy their identifiers into the draft call below.
{
"name": "fonte_list_broadcast_options",
"arguments": {
"workspace": "acme"
}
}Sender profiles are in receipt.senders.sender_profiles. Purpose and audience choices are in receipt.audience.communication_purposes and receipt.audience.sources. A sender’s email address is not its sender_profile_id. Collection sources return collection_id; use that value as collectionId in the draft’s recipient_selection.
For local MCP, use fonte_list_broadcast_senders for sender discovery. The hosted options tool is not part of the local CLI 0.4.0 tool catalog; use the documented CLI audience-options command for purposes and audience source IDs.
{
"name": "fonte_list_broadcast_senders",
"arguments": {
"workspace": "acme"
}
}Create or read a draft
fonte_create_broadcast_draft saves one unsent draft under your chosen draft_id. Save that ID before calling. This example selects one existing collection; use the collection, sender, and purpose IDs returned for your workspace.
{
"name": "fonte_create_broadcast_draft",
"arguments": {
"workspace": "acme",
"draft_id": "10000000-0000-4000-8000-000000000001",
"title": "October update",
"subject": "A note from the studio",
"preheader": "A few things we have been making.",
"active_source": "html",
"composer_body": null,
"html_body": "<h1>Something worth sharing.</h1><p>Here is what we have been making.</p>",
"sender_profile_id": "sender_example",
"communication_purpose_id": "10000000-0000-4000-8000-000000000002",
"recipient_selection": {
"to": {
"kind": "selected",
"references": [
{
"kind": "collection",
"collectionId": "10000000-0000-4000-8000-000000000003"
}
]
},
"except": []
}
}
}Selected fields from a successful response:
{
"outcome": "completed",
"draft": {
"kind": "broadcast_draft",
"outcome": "applied",
"draft_id": "10000000-0000-4000-8000-000000000001",
"revision": 1
}
}If you already have a draft, read it with fonte_read_broadcast_draft and continue from its current revision. After a lost create response, read the same draft_id before attempting anything else.
{
"name": "fonte_read_broadcast_draft",
"arguments": {
"workspace": "acme",
"draft_id": "10000000-0000-4000-8000-000000000001"
}
}Save changes to the same draft
fonte_update_broadcast_draft applies changes against base_revision. Use the revision you just read, and keep one operation_id for that exact edit. The HTML below is a short source example; use your complete message when preparing a real broadcast.
{
"name": "fonte_update_broadcast_draft",
"arguments": {
"workspace": "acme",
"draft_id": "10000000-0000-4000-8000-000000000001",
"base_revision": 1,
"operation_id": "10000000-0000-4000-8000-000000000004",
"changes": {
"subject": "A few things worth sharing",
"preheader": "Fresh ideas, straight from the studio.",
"active_source": "html",
"html_body": "<h1>Something worth sharing.</h1><p>Our October update is ready.</p>"
}
}
}Selected fields from the saved revision:
{
"outcome": "completed",
"revision": {
"kind": "broadcast_draft_revision",
"draft_id": "10000000-0000-4000-8000-000000000001",
"base_revision": 1,
"revision": 2,
"operation_id": "10000000-0000-4000-8000-000000000004"
}
}Keep this returned revision for the review. If another editor changed the draft, read the latest version and reconcile the change before making a new edit. After an uncertain update, read the draft and compare its saved content with your intended change.
Prepare the saved revision
fonte_prepare_broadcast requests a review of the saved draft. Authoring calls use draft_id; this review call uses draftId. Set expectedDraftVersion to the revision returned by your latest save or read.
{
"name": "fonte_prepare_broadcast",
"arguments": {
"workspace": "acme",
"environment": "production",
"draftId": "10000000-0000-4000-8000-000000000001",
"request": {
"schema": "broadcast_review_request.v1",
"requestId": "10000000-0000-4000-8000-000000000005",
"expectedDraftVersion": 2,
"audienceMode": "reuse_compatible"
},
"wait_ms": 1000
}
}Keep the complete call, including requestId. A bounded wait can return this fictional pending response:
{
"outcome": "pending",
"request_id": "10000000-0000-4000-8000-000000000005",
"reason": "broadcast_review_queued",
"operation": {
"operationId": "10000000-0000-4000-8000-000000000006",
"operationVersion": 1,
"draftId": "10000000-0000-4000-8000-000000000001",
"reviewId": null,
"operationUri": "/v1/workspaces/acme/broadcast-review-operations/10000000-0000-4000-8000-000000000006?environment=production",
"observedAt": "2026-10-13T12:00:00.000Z",
"state": "queued",
"executionAuthorized": false,
"review": null,
"summary": null
}
}Pending means the review is still being prepared. The returned operationUri identifies the work already underway. Keep it and continue reading that operation.
Read the review
fonte_read_broadcast_send_operation observes the returned operationUri. Use kind review while preparing a broadcast; kind send is for an existing Send operation.
{
"name": "fonte_read_broadcast_send_operation",
"arguments": {
"workspace": "acme",
"environment": "production",
"draftId": "10000000-0000-4000-8000-000000000001",
"operation_uri": "/v1/workspaces/acme/broadcast-review-operations/10000000-0000-4000-8000-000000000006?environment=production",
"kind": "review",
"wait_ms": 1000
}
}Selected fields when the fictional review is ready:
{
"outcome": "observed",
"operation": {
"draftId": "10000000-0000-4000-8000-000000000001",
"state": "ready",
"executionAuthorized": false,
"summary": {
"recipientCount": 120,
"excludedCount": 3
}
}
}Ready means the review is available. Read its recipient and exclusion counts and the review’s audience, message, sender-route, and commercial references. commercialReviewRef is an opaque reference, not a currency amount; do not invent a price from it. Use Billing to inspect payment terms or a required card authorization. Check the recipient counts in Fonte before approving the send.
Resume after an interruption
- Create response lost: read the original draft_id. Creating another draft would leave the first one behind.
- Save response lost: read the same draft and compare the saved fields. Keep the original operation_id and exact edit when recovering that edit.
- Review response lost on hosted MCP: repeat the exact fonte_prepare_broadcast call with the original requestId and unchanged inputs. Core reuses that request; do not create a replacement UUID.
- Review still queued or running: read its returned operationUri. A timeout does not mean the review failed.
- Draft changed: read and reconcile the current draft. A deliberate new review uses the newly observed revision and a new request ID.
Local MCP also exposes fonte_recover_broadcast_request. It reloads the original saved review or Send request from that installation; hosted MCP keeps request custody with the caller and does not expose this recovery tool.
{
"name": "fonte_recover_broadcast_request",
"arguments": {
"workspace": "acme",
"environment": "production",
"draftId": "10000000-0000-4000-8000-000000000001",
"request_id": "10000000-0000-4000-8000-000000000005",
"wait_ms": 1000
}
}Read results from an existing broadcast
On hosted MCP, fonte_read_broadcast_results reads delivery and engagement reporting by draft_id. Use the existing broadcast’s draft ID; this read does not prepare or send anything.
{
"name": "fonte_read_broadcast_results",
"arguments": {
"workspace": "acme",
"draft_id": "10000000-0000-4000-8000-000000000001"
}
}Report pending, unavailable, partial, or unknown results as returned. Provider acceptance, delivery, opens, and clicks describe different events.
Understand the outcome
- Draft calls: outcome completed confirms a saved or read result. Use its returned revision.
- Review calls: outcome pending means the observation wait ended while work continues; observed means a state was read, which can still be queued or running.
- Review state ready exposes the review. executionAuthorized remains false: review never sends.
- Review state failed or cancelled needs the returned blocker or recovery guidance.
- An ambiguous result or core_effect unknown requires reading or recovering the original work. It does not prove that the write failed.
When the user separately approves sending, fonte_send_broadcast accepts the complete immutable approved input. Preserve that input and request identity. Preparing a review, connecting an agent, and sending a test do not supply that approval.