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.