# Banger MCP tool reference

Canonical URL: https://bangermail.com/mcp.md

Schema snapshot: 2026-09-29. This reference contains all 191 tools exposed by the connected Banger catalog at the time of generation. A live MCP `tools/list` response is authoritative for the connected workspace, permissions, and server version. These are interface definitions, not customer data.

Remote endpoint: `https://api.bangermail.com/mcp`. Authenticate through your client's Banger OAuth connection or a supported scoped API key. See the [product guide](https://bangermail.com/index.md) and [API guide](https://bangermail.com/api.md).

## Reading this reference

Tool names below use their public `banger_` names; connector-specific namespace prefixes have been removed. Input signatures use TypeScript notation: `?` marks optional fields, string unions list accepted values, and comments explain constraints. `CallToolResult` is the MCP result envelope. Check returned errors and status before claiming an action succeeded. Sending tools can send real email; preview and readiness tools are separate operations.

## Tool index

- [banger_add_contact_list_members](#banger_add_contact_list_members)
- [banger_add_product_domain](#banger_add_product_domain)
- [banger_archive_broadcast](#banger_archive_broadcast)
- [banger_cancel_broadcast](#banger_cancel_broadcast)
- [banger_check_broadcast_readiness](#banger_check_broadcast_readiness)
- [banger_claim_journey](#banger_claim_journey)
- [banger_complete_feedback_attachment](#banger_complete_feedback_attachment)
- [banger_confirm_connection](#banger_confirm_connection)
- [banger_convert_journey_to_managed](#banger_convert_journey_to_managed)
- [banger_create_api_key](#banger_create_api_key)
- [banger_create_broadcast](#banger_create_broadcast)
- [banger_create_contact_field](#banger_create_contact_field)
- [banger_create_contact_list](#banger_create_contact_list)
- [banger_create_experiment](#banger_create_experiment)
- [banger_create_incoming_webhook](#banger_create_incoming_webhook)
- [banger_create_journey](#banger_create_journey)
- [banger_create_label](#banger_create_label)
- [banger_create_layout](#banger_create_layout)
- [banger_create_managed_content](#banger_create_managed_content)
- [banger_create_native_mailbox](#banger_create_native_mailbox)
- [banger_create_native_sending_domain](#banger_create_native_sending_domain)
- [banger_create_product](#banger_create_product)
- [banger_create_segment](#banger_create_segment)
- [banger_create_signup_form](#banger_create_signup_form)
- [banger_create_starter_mailbox](#banger_create_starter_mailbox)
- [banger_create_template](#banger_create_template)
- [banger_create_triage_rule](#banger_create_triage_rule)
- [banger_decide_experiment](#banger_decide_experiment)
- [banger_decide_split](#banger_decide_split)
- [banger_delete_broadcast](#banger_delete_broadcast)
- [banger_delete_label](#banger_delete_label)
- [banger_delete_native_sending_domain](#banger_delete_native_sending_domain)
- [banger_delete_segment](#banger_delete_segment)
- [banger_delete_triage_rule](#banger_delete_triage_rule)
- [banger_deliverability_summary](#banger_deliverability_summary)
- [banger_duplicate_template](#banger_duplicate_template)
- [banger_enroll_journey_contacts](#banger_enroll_journey_contacts)
- [banger_generate_email_design](#banger_generate_email_design)
- [banger_get_approval](#banger_get_approval)
- [banger_get_billing](#banger_get_billing)
- [banger_get_brand](#banger_get_brand)
- [banger_get_broadcast](#banger_get_broadcast)
- [banger_get_communication_policy](#banger_get_communication_policy)
- [banger_get_company_context](#banger_get_company_context)
- [banger_get_contact](#banger_get_contact)
- [banger_get_contact_import](#banger_get_contact_import)
- [banger_get_contact_list](#banger_get_contact_list)
- [banger_get_content_settings](#banger_get_content_settings)
- [banger_get_content_translations](#banger_get_content_translations)
- [banger_get_delivery_status](#banger_get_delivery_status)
- [banger_get_domain_activation_proof](#banger_get_domain_activation_proof)
- [banger_get_experiment](#banger_get_experiment)
- [banger_get_incoming_webhook_credentials](#banger_get_incoming_webhook_credentials)
- [banger_get_journey](#banger_get_journey)
- [banger_get_layout](#banger_get_layout)
- [banger_get_layout_approval_preview](#banger_get_layout_approval_preview)
- [banger_get_layout_impact](#banger_get_layout_impact)
- [banger_get_managed_content](#banger_get_managed_content)
- [banger_get_message_body](#banger_get_message_body)
- [banger_get_native_sending_domain](#banger_get_native_sending_domain)
- [banger_get_sending_health](#banger_get_sending_health)
- [banger_get_signup_form](#banger_get_signup_form)
- [banger_get_starter_mailbox_proof](#banger_get_starter_mailbox_proof)
- [banger_get_template](#banger_get_template)
- [banger_get_thread](#banger_get_thread)
- [banger_get_transactional_send](#banger_get_transactional_send)
- [banger_list_api_keys](#banger_list_api_keys)
- [banger_list_approvals](#banger_list_approvals)
- [banger_list_broadcast_recipients](#banger_list_broadcast_recipients)
- [banger_list_broadcast_timeline](#banger_list_broadcast_timeline)
- [banger_list_campaigns](#banger_list_campaigns)
- [banger_list_connected_agents](#banger_list_connected_agents)
- [banger_list_connections](#banger_list_connections)
- [banger_list_contact_fields](#banger_list_contact_fields)
- [banger_list_contact_imports](#banger_list_contact_imports)
- [banger_list_contact_lists](#banger_list_contact_lists)
- [banger_list_contacts](#banger_list_contacts)
- [banger_list_content_publications](#banger_list_content_publications)
- [banger_list_email_assets](#banger_list_email_assets)
- [banger_list_experiments](#banger_list_experiments)
- [banger_list_journey_executions](#banger_list_journey_executions)
- [banger_list_journeys](#banger_list_journeys)
- [banger_list_labels](#banger_list_labels)
- [banger_list_layout_versions](#banger_list_layout_versions)
- [banger_list_layouts](#banger_list_layouts)
- [banger_list_logs](#banger_list_logs)
- [banger_list_mailboxes](#banger_list_mailboxes)
- [banger_list_managed_content](#banger_list_managed_content)
- [banger_list_native_sending_domains](#banger_list_native_sending_domains)
- [banger_list_products](#banger_list_products)
- [banger_list_provider_connections](#banger_list_provider_connections)
- [banger_list_segments](#banger_list_segments)
- [banger_list_sends](#banger_list_sends)
- [banger_list_signup_forms](#banger_list_signup_forms)
- [banger_list_starters](#banger_list_starters)
- [banger_list_suggested_labels](#banger_list_suggested_labels)
- [banger_list_templates](#banger_list_templates)
- [banger_list_threads](#banger_list_threads)
- [banger_list_triage_actions](#banger_list_triage_actions)
- [banger_list_triage_rules](#banger_list_triage_rules)
- [banger_list_webhooks](#banger_list_webhooks)
- [banger_list_work](#banger_list_work)
- [banger_mutate_thread](#banger_mutate_thread)
- [banger_onboarding_act](#banger_onboarding_act)
- [banger_onboarding_apply_plan](#banger_onboarding_apply_plan)
- [banger_onboarding_choose_domain](#banger_onboarding_choose_domain)
- [banger_onboarding_complete](#banger_onboarding_complete)
- [banger_onboarding_discover_domain](#banger_onboarding_discover_domain)
- [banger_onboarding_ensure_aha_one](#banger_onboarding_ensure_aha_one)
- [banger_onboarding_get_state](#banger_onboarding_get_state)
- [banger_onboarding_open_setup](#banger_onboarding_open_setup)
- [banger_onboarding_propose_plan](#banger_onboarding_propose_plan)
- [banger_onboarding_record_decision](#banger_onboarding_record_decision)
- [banger_onboarding_send_agent_test](#banger_onboarding_send_agent_test)
- [banger_onboarding_start](#banger_onboarding_start)
- [banger_onboarding_submit_context](#banger_onboarding_submit_context)
- [banger_onboarding_validate](#banger_onboarding_validate)
- [banger_open_billing_portal](#banger_open_billing_portal)
- [banger_pause_broadcast](#banger_pause_broadcast)
- [banger_pause_native_sending_lane](#banger_pause_native_sending_lane)
- [banger_prepare_feedback_attachment](#banger_prepare_feedback_attachment)
- [banger_preview_broadcast_audience](#banger_preview_broadcast_audience)
- [banger_preview_email_design](#banger_preview_email_design)
- [banger_preview_journey](#banger_preview_journey)
- [banger_preview_journey_approval](#banger_preview_journey_approval)
- [banger_preview_segment](#banger_preview_segment)
- [banger_preview_signup_form](#banger_preview_signup_form)
- [banger_preview_template](#banger_preview_template)
- [banger_preview_triage_rule](#banger_preview_triage_rule)
- [banger_propose_action](#banger_propose_action)
- [banger_propose_contact_import_mapping](#banger_propose_contact_import_mapping)
- [banger_publish_layout](#banger_publish_layout)
- [banger_publish_managed_content](#banger_publish_managed_content)
- [banger_query_connection](#banger_query_connection)
- [banger_reactivate_mailbox](#banger_reactivate_mailbox)
- [banger_recommend_arms](#banger_recommend_arms)
- [banger_register_api_journey](#banger_register_api_journey)
- [banger_remove_contact_list_members](#banger_remove_contact_list_members)
- [banger_render_journey](#banger_render_journey)
- [banger_render_managed_content](#banger_render_managed_content)
- [banger_report_bug](#banger_report_bug)
- [banger_request_contact_import](#banger_request_contact_import)
- [banger_request_domain_migration](#banger_request_domain_migration)
- [banger_restore_content_revision](#banger_restore_content_revision)
- [banger_restore_layout_version](#banger_restore_layout_version)
- [banger_resume_broadcast](#banger_resume_broadcast)
- [banger_resume_native_sending_lane](#banger_resume_native_sending_lane)
- [banger_resume_sending](#banger_resume_sending)
- [banger_review_content_translation](#banger_review_content_translation)
- [banger_revise_email_design](#banger_revise_email_design)
- [banger_revoke_api_key](#banger_revoke_api_key)
- [banger_revoke_connected_agent](#banger_revoke_connected_agent)
- [banger_run_triage_on_past_mail](#banger_run_triage_on_past_mail)
- [banger_schedule_broadcast](#banger_schedule_broadcast)
- [banger_search_mail](#banger_search_mail)
- [banger_send_broadcast](#banger_send_broadcast)
- [banger_send_email](#banger_send_email)
- [banger_set_journey_status](#banger_set_journey_status)
- [banger_set_product_setup](#banger_set_product_setup)
- [banger_set_triage_rule_status](#banger_set_triage_rule_status)
- [banger_set_webhook_status](#banger_set_webhook_status)
- [banger_show_email_preview](#banger_show_email_preview)
- [banger_simulate_communication_policy](#banger_simulate_communication_policy)
- [banger_simulate_journey](#banger_simulate_journey)
- [banger_start_domain_activation_proof](#banger_start_domain_activation_proof)
- [banger_start_starter_mailbox_proof](#banger_start_starter_mailbox_proof)
- [banger_start_upgrade](#banger_start_upgrade)
- [banger_stop_experiment](#banger_stop_experiment)
- [banger_submit_feedback](#banger_submit_feedback)
- [banger_suggest_feature](#banger_suggest_feature)
- [banger_test_webhook](#banger_test_webhook)
- [banger_undo_triage_action](#banger_undo_triage_action)
- [banger_update_brand_footer](#banger_update_brand_footer)
- [banger_update_broadcast](#banger_update_broadcast)
- [banger_update_communication_policy](#banger_update_communication_policy)
- [banger_update_contact_field](#banger_update_contact_field)
- [banger_update_content_settings](#banger_update_content_settings)
- [banger_update_journey](#banger_update_journey)
- [banger_update_label](#banger_update_label)
- [banger_update_layout](#banger_update_layout)
- [banger_update_managed_content](#banger_update_managed_content)
- [banger_update_product](#banger_update_product)
- [banger_update_signup_form](#banger_update_signup_form)
- [banger_update_template](#banger_update_template)
- [banger_update_triage_rule](#banger_update_triage_rule)
- [banger_upload_email_asset](#banger_upload_email_asset)
- [banger_upload_email_image](#banger_upload_email_image)
- [banger_upload_feedback_attachment](#banger_upload_feedback_attachment)
- [banger_upsert_contact](#banger_upsert_contact)
- [banger_validate_contact_import](#banger_validate_contact_import)
- [banger_verify_native_sending_domain](#banger_verify_native_sending_domain)

## banger_add_contact_list_members

Add existing product contacts to a product list by identifier; consent and suppression are preserved. Safe retries return canonical membership read-back.

exec tool declaration:
```ts
declare const tools: { banger_add_contact_list_members(args: {
  contact_ids: Array<string>;
  idempotency_key: string;
  list_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_add_product_domain

Record a domain for this product and use its first reported domain as an initial brand-discovery source. This does not configure sending or change DNS; several products may report the same domain.

exec tool declaration:
```ts
declare const tools: { banger_add_product_domain(args: {
  domain: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_archive_broadcast

Archive a Broadcast (archived=true) to hide it from the Broadcast list while keeping its recipients, statistics, Logs, and unsubscribe links, or restore it (archived=false). Applies to Broadcasts that sent; unsent ones can be deleted instead. Not allowed while scheduled, sending, or paused.

exec tool declaration:
```ts
declare const tools: { banger_archive_broadcast(args: {
  archived: boolean;
  broadcast_id: string;
  idempotency_key: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_cancel_broadcast

Cancel a draft, scheduled, sending, or paused Broadcast. Irreversible: a cancelled Broadcast cannot be resumed or sent again, and pending recipients are dropped (recipients already sent stay sent). Pausing is the reversible alternative. Returns the Broadcast read-back (status cancelled).

exec tool declaration:
```ts
declare const tools: { banger_cancel_broadcast(args: {
  broadcast_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_check_broadcast_readiness

Read actionable blockers for footer identity/address, canonical Broadcast route, consent/suppression, selected audience, personalization, sending allowance, and automatic or human approval requirements. Does not send test messages or freeze recipients. Send-time controls remain authoritative.

exec tool declaration:
```ts
declare const tools: { banger_check_broadcast_readiness(args: {
  broadcast_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_claim_journey

Name and configure a Journey Banger discovered from raw API sends. Saving a draft sends nothing and needs no review; a Journey's first activation needs one human review of its sending setup.

exec tool declaration:
```ts
declare const tools: { banger_claim_journey(args: {
  activate?: boolean;
  content_mode: "code" | "managed";
  delivery_class: "product" | "broadcast";
  // Turn changing spans in stored sends into managed template fields.
  from_sample?: boolean;
  // Discovered Journey identifier.
  journey_id: string;
  // Sender mailbox.
  mailbox_id: string;
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Managed design.
  template_id?: string;
  variables?: Array<{ literal: string; name: string; }>;
}): Promise<CallToolResult>; };
```

## banger_complete_feedback_attachment

Verify that a file uploaded to its signed URL exists with its declared size and media format, and mark the attachment ready. Only ready attachments can be submitted. Up to five files per report within 24 hours; attachments belong to the uploading user and workspace and cannot be reused on another report.

exec tool declaration:
```ts
declare const tools: { banger_complete_feedback_attachment(args: {
  // Generate one UUID per file and reuse it on retry.
  attachment_id: string;
}): Promise<CallToolResult>; };
```

## banger_confirm_connection

Reconcile the connection checkpoint when an authorized OAuth connection still appears pending. Normal OAuth authorization completes the checkpoint automatically. Idempotent; changes no mailbox, DNS, sending, Journey, Broadcast, or billing state, and returns no credentials.

exec tool declaration:
```ts
declare const tools: { banger_confirm_connection(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_convert_journey_to_managed

One-way conversion of a paused or draft legacy Journey using HTML/Liquid already prepared by your migration skill. Supply contract only for a single-email Journey, or step_contents with exactly one contract per email step, including split arms. Banger does not import or execute TSX/MJML. Creates managed drafts and requests publication review; nothing is sent.

exec tool declaration:
```ts
declare const tools: { banger_convert_journey_to_managed(args: { [key: string]: unknown; } | { [key: string]: unknown; }): Promise<CallToolResult>; };
```

## banger_create_api_key

Issue a product-scoped API key with only the scopes approved for this integration. The one-time token appears in the private credential card attached to this tool result in an MCP Apps host, outside model context; it cannot be reopened from the Banger website. The result also links to the Banger app's API keys section. Without an MCP Apps host, keys are created in the Banger app. Does not verify or activate an integration. Not idempotent: each call issues another key; a key whose token was lost can be revoked.

exec tool declaration:
```ts
declare const tools: { banger_create_api_key(args: {
  // Optional future expiry timestamp.
  expires_at?: string;
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  scopes: Array<"mail:read" | "mail:write" | "mail:send" | "contacts:read" | "contacts:write" | "campaigns:read" | "campaigns:write" | "campaigns:send" | "automation:read" | "automation:execute" | "connections:read" | "connections:use" | "connections:admin" | "workspace:admin">;
}): Promise<CallToolResult>; };
```

## banger_create_broadcast

Create an editable Broadcast draft from source-only managed content or a saved product design and mailbox. Managed source creates a reviewed draft and queues missing languages for free translation. Empty audience drafts are allowed; sends stay blocked until eligible recipients and a published source are ready. Requires a retry key and returns canonical read-back. Saving a draft sends nothing and needs no review; a Journey's first activation needs one human review of its sending setup.

exec tool declaration:
```ts
declare const tools: { banger_create_broadcast(args: {
  audience?: { all_subscribed?: boolean; contact_ids?: Array<string>; list_ids?: Array<string>; segment_ids?: Array<string>; };
  content_overrides?: { [key: string]: string; };
  expires_after_seconds?: number;
  idempotency_key: string;
  localization_failure_policy?: "hold" | "fallback";
  mailbox_id: string;
  managed_content?: {
  configured_locales?: Array<string>;
  fallback_locale?: string;
  layout_id?: string;
  localization_policy?: {
  // Optional bounded Journey hold for missing or review-pending translations. Wait requires max_wait_seconds and on_timeout. Urgent messages fall back immediately.
  journey_translation?: { max_wait_seconds?: number; mode: "fallback" | "wait"; on_timeout?: "fallback" | "discard"; };
  manual_review?: boolean;
};
  // Named sample variable sets for immediate preview and validation.
  samples?: { [key: string]: { [key: string]: unknown; }; };
  source: {
  body_html: string;
  layout?: string;
  preheader?: string;
  subject: string;
  // Map of variable names to typed definitions. Types: string, text, url, image_url, html, date, datetime, money ({amount_cents,currency}), number, boolean, object (properties), list (items). Each field accepts required (boolean), default, and an optional description of at most 2000 characters.
  variables: { [key: string]: { [key: string]: unknown; }; };
  variants?: { [key: string]: { body_html: string; body_text?: string; layout?: string; preheader?: string; subject: string; }; };
};
  source_locale?: string;
  // Optional supplied message catalogs keyed by locale. Supply source messages used by the template; other languages are prepared asynchronously without charge.
  translations?: { [key: string]: { [key: string]: string; }; };
};
  managed_content_id?: string;
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  sample_name?: string;
  selected_subject_variant?: number;
  subject_variants?: Array<string>;
  template_id?: string;
}): Promise<CallToolResult>; };
```

## banger_create_contact_field

Declare a contact field before data arrives, so imports, forms and the API store it in the right type under a clear label. key defaults from the label ("Team size" becomes team_size). choice and choices fields can list their allowed options.

exec tool declaration:
```ts
declare const tools: { banger_create_contact_field(args: {
  description?: string;
  idempotency_key: string;
  key?: string;
  label: string;
  options?: Array<string>;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  type: "text" | "number" | "boolean" | "date" | "choice" | "choices";
}): Promise<CallToolResult>; };
```

## banger_create_contact_list

Create one product contact list with safe retries and canonical read-back. Does not import or subscribe contacts.

exec tool declaration:
```ts
declare const tools: { banger_create_contact_list(args: {
  description?: string;
  idempotency_key: string;
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_create_experiment

Test 2-4 variants of a subject, design, content, or from-name on a Broadcast (subject_kind campaign, subject_id = campaign id), a journey step (sequence_step, subject_id = '<sequence_id>:<step_id>'), or an automation rule (automation_rule, subject_id = rule id). Broadcasts can test on a sample_percent first and send the winner to the rest; journeys and automations split continuously. Winners are judged on human-only opens, clicks, replies, or the journey goal. With decision.mode auto, the winner is promoted as soon as every arm reaches min_sample_per_arm and the leader clears decision.confidence (default 0.95); if that has not happened by decision.after_hours, the current leader is promoted anyway and the test records decision_basis deadline.

exec tool declaration:
```ts
declare const tools: { banger_create_experiment(args: {
  // Percent per variant; defaults to an even split.
  allocation?: Array<number>;
  decision?: { after_hours?: number; confidence?: number; mode?: "manual" | "auto"; };
  dimension: "subject" | "design" | "content" | "from_name";
  guardrails?: { max_complaint_rate?: number; max_unsubscribe_rate?: number; };
  min_sample_per_arm?: number;
  name: string;
  primary_metric?: "human_open" | "human_click" | "reply" | "conversion";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Broadcasts only: share of the audience that receives the test; the rest waits for the winner.
  sample_percent?: number;
  subject_id: string;
  subject_kind: "campaign" | "sequence_step" | "automation_rule";
  variants: Array<{
  // For dimension content.
  content?: { [key: string]: string; };
  // For dimension from_name.
  from_name?: string;
  // Short arm key such as a or b. Defaults to a, b, c, d.
  key?: string;
  label?: string;
  // For dimension subject.
  subject?: string;
  // For dimension design.
  template_id?: string;
}>;
}): Promise<CallToolResult>; };
```

## banger_create_incoming_webhook

Create an incoming endpoint and its durable Banger connection for an approved product integration. Returns connection_id for Journey triggers. The private credential panel shows a secret URL, or a public URL with a separate Authorization: Bearer token; credentials stay outside model context. Requires an MCP Apps host; Banger's Webhooks page offers the same. Supabase auth hooks use the secure Banger setup page. Does not activate Journeys or prove event receipt. Not idempotent: each call creates another webhook.

exec tool declaration:
```ts
declare const tools: { banger_create_incoming_webhook(args: {
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  // Non-secret source settings for Zendesk or Intercom; omit for other sources.
  source_config?: { [key: string]: unknown; };
  // Source identifier, such as custom, stripe, or shopify. Defaults to custom. Supabase auth hooks use Banger's secure setup page.
  source_key?: string;
}): Promise<CallToolResult>; };
```

## banger_create_journey

Create a draft Journey with a trigger and a tree of email, wait, condition, action, or split steps; step names are customer-facing. A monitored wait is kind=wait with config={amount:3,unit:"days",until:{name:"Registration completed",path:"attributes.registered",operator:"equals",value:true},on_met:"continue"}; on_met is required: continue (skip the following reminder email and proceed) or end_journey (complete this Journey), and the reminder email is the following sibling step. Missing customer fields are unknown and hold the reminder. Checks use current contact data about once per minute. Milestones map to verified contact data, not eligibility flags. Each person enters once by default; trigger.config.once_per_person=false lets people re-enter after they finish, optionally after trigger.config.reentry_days. An email step config takes one content source, the same shapes a Broadcast stores: template_id (a saved design) with content_overrides filling its slots; or the step's own design as subject, body_html, body_text and content_overrides; or managed_content_id. delivery_class is product or broadcast. Drafts may leave a button link empty; activation and send report it. Saving a draft sends nothing and needs no review; a Journey's first activation needs one human review of its sending setup.

exec tool declaration:
```ts
declare const tools: { banger_create_journey(args: {
  api?: { [key: string]: unknown; };
  approval_mode?: "policy" | "required";
  audience?: { [key: string]: unknown; };
  description?: string;
  exit?: { [key: string]: unknown; };
  // From local part on the product's Product or Broadcast sending lane, for example noreply. Defaults to the mailbox local part.
  from_local_part?: string;
  goal?: { [key: string]: unknown; };
  idempotency_key: string;
  // Mailbox that receives replies. Its local part is the default From.
  mailbox_id?: string;
  managed_content?: {
  configured_locales?: Array<string>;
  fallback_locale?: string;
  layout_id?: string;
  localization_policy?: {
  // Optional bounded Journey hold for missing or review-pending translations. Wait requires max_wait_seconds and on_timeout. Urgent messages fall back immediately.
  journey_translation?: { max_wait_seconds?: number; mode: "fallback" | "wait"; on_timeout?: "fallback" | "discard"; };
  manual_review?: boolean;
};
  // Named sample variable sets for immediate preview and validation.
  samples?: { [key: string]: { [key: string]: unknown; }; };
  source: {
  body_html: string;
  layout?: string;
  preheader?: string;
  subject: string;
  // Map of variable names to typed definitions. Types: string, text, url, image_url, html, date, datetime, money ({amount_cents,currency}), number, boolean, object (properties), list (items). Each field accepts required (boolean), default, and an optional description of at most 2000 characters.
  variables: { [key: string]: { [key: string]: unknown; }; };
  variants?: { [key: string]: { body_html: string; body_text?: string; layout?: string; preheader?: string; subject: string; }; };
};
  source_locale?: string;
  // Optional supplied message catalogs keyed by locale. Supply source messages used by the template; other languages are prepared asynchronously without charge.
  translations?: { [key: string]: { [key: string]: string; }; };
};
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  steps: Array<{ [key: string]: unknown; }>;
  trigger: {
  config?: {
  // Event name that starts an event Journey.
  event?: string;
  // Each person enters once. Set false to let people re-enter after they finish.
  once_per_person?: boolean;
  // With once_per_person=false, days after a person's last entry before they may enter again.
  reentry_days?: number;
  [key: string]: unknown;
};
  // Incoming webhook connection that starts an event Journey.
  connection_id?: string;
  // What starts the Journey, for example manual, contact_created, audience_joined, event, or api.
  kind?: string;
  [key: string]: unknown;
};
}): Promise<CallToolResult>; };
```

## banger_create_label

Create a Banger label in one mailbox. suggestion_id creates a suggested label (auto-set turns on when the plan's Triage rule amount has room). Optionally sets emoji and auto_set. Creating an existing name returns the existing label. Banger labels are not synced to Gmail.

exec tool declaration:
```ts
declare const tools: { banger_create_label(args: {
  // The label's auto-set rule. Needs a description and/or exact conditions when enabled. Enabled rules count toward the plan's Triage rule amount.
  auto_set?: {
  // Plain-language condition Jev judges, e.g. "a customer reporting a bug". It is read literally; exact conditions cover senders, numbers and dates.
  description?: string;
  enabled: boolean;
  // Exact conditions checked in code (like Gmail filters). All fields given have to hold.
  exact_conditions?: {
  // Subject and body contain none of these.
  excludes_words?: Array<string>;
  // Sender address, @domain or domain (matches subdomains). Any may match.
  from?: Array<string>;
  has_attachment?: boolean;
  // Subject or body contains all of these.
  has_words?: Array<string>;
  // Subject contains any of these.
  subject_contains?: Array<string>;
  // Recipient (to/cc) address, @domain or domain. Any may match.
  to?: Array<string>;
};
};
  // CSS color such as #3b82f6.
  color?: string;
  // What the label means, for people.
  description?: string;
  // One emoji shown before the name.
  emoji?: string;
  idempotency_key: string;
  // Mailbox identifier.
  mailbox_id: string;
  name?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Identifier of a suggested label.
  suggestion_id?: string;
}): Promise<CallToolResult>; };
```

## banger_create_layout

Create a shared layout draft. Without html it is seeded from the existing product brand. The HTML contains exactly one {{ content }} slot. Does not publish.

exec tool declaration:
```ts
declare const tools: { banger_create_layout(args: {
  html?: string;
  idempotency_key: string;
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  source_locale?: string;
  source_messages?: { [key: string]: string; };
  translations?: { [key: string]: { [key: string]: string; }; };
}): Promise<CallToolResult>; };
```

## banger_create_managed_content

Create source-only managed content. Nothing is sent or published. Missing configured languages are queued for free background translation, so not every variant needs to be supplied.

exec tool declaration:
```ts
declare const tools: { banger_create_managed_content(args: {
  contract: {
  configured_locales?: Array<string>;
  fallback_locale?: string;
  layout_id?: string;
  localization_policy?: {
  // Optional bounded Journey hold for missing or review-pending translations. Wait requires max_wait_seconds and on_timeout. Urgent messages fall back immediately.
  journey_translation?: { max_wait_seconds?: number; mode: "fallback" | "wait"; on_timeout?: "fallback" | "discard"; };
  manual_review?: boolean;
};
  // Named sample variable sets for immediate preview and validation.
  samples?: { [key: string]: { [key: string]: unknown; }; };
  source: {
  body_html: string;
  layout?: string;
  preheader?: string;
  subject: string;
  // Map of variable names to typed definitions. Types: string, text, url, image_url, html, date, datetime, money ({amount_cents,currency}), number, boolean, object (properties), list (items). Each field accepts required (boolean), default, and an optional description of at most 2000 characters.
  variables: { [key: string]: { [key: string]: unknown; }; };
  variants?: { [key: string]: { body_html: string; body_text?: string; layout?: string; preheader?: string; subject: string; }; };
};
  source_locale?: string;
  // Optional supplied message catalogs keyed by locale. Supply source messages used by the template; other languages are prepared asynchronously without charge.
  translations?: { [key: string]: { [key: string]: string; }; };
};
  idempotency_key: string;
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_create_native_mailbox

Create an idempotent native mailbox on a workspace sending domain. It remains pending until the domain, stream, and inbound MX are verified.

exec tool declaration:
```ts
declare const tools: { banger_create_native_mailbox(args: {
  display_name?: string;
  // Banger-native sending domain identifier.
  domain_id: string;
  idempotency_key: string;
  local_part: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_create_native_sending_domain

Low-level setup of a company domain for Banger sending and receiving. Defaults to simple setup: one mailbox domain for receiving and sending, including Broadcasts and Journeys from selected mailbox addresses; guided onboarding keeps the same saved choices and DNS plan (mailbox_mode, mailbox_prefix). Advanced setup uses separate lane domains: domain is the company's root domain (example.com), and Banger derives Mailboxes at mail.<domain>, Product at tx.<domain>, Broadcast at broadcast.<domain>; lane_prefixes customizes them (lane_prefixes.mailbox hello gives @hello.example.com), and mailbox_mode migrate keeps Mailboxes on the exact root domain. A new root DMARC p=reject policy is published only with root_dmarc_confirmed=true, the owner's confirmation that all root From senders authenticate with aligned SPF or DKIM; dedicated subdomains need no confirmation. Creation is blocked only when a proposed lane already carries email DNS (an MX record, an SPF TXT record, or a CNAME where Banger publishes MX or TXT); website A, AAAA, or verification TXT records leave it unblocked, and the error names the conflicting records. Replacing existing email setup requires a migration request authorized by a signed-in administrator in Banger's Approvals panel; agent claims, chat consent, and confirmation fields are not authorization. External routes require the exact discovered provider and an active product connection.

exec tool declaration:
```ts
declare const tools: { banger_create_native_sending_domain(args: {
  // banger, or an existing provider key returned by discovery.
  broadcast_route?: string;
  domain: string;
  idempotency_key: string;
  // Optional subdomain labels, one per lane, applied under the root domain. Defaults: mailbox mail, product tx, broadcast broadcast.
  lane_prefixes?: {
  // Broadcast subdomain label (default broadcast).
  broadcast?: string;
  // Mailboxes subdomain label; hello gives addresses @hello.<domain>.
  mailbox?: string;
  // Product email subdomain label (default tx).
  product?: string;
};
  // subdomain puts Mailboxes on a subdomain and preserves existing domain mail. Simple setup defaults to the root if no prefix is supplied; advanced defaults to a subdomain. migrate puts Mailboxes on the exact root domain (@example.com); omit lane_prefixes.mailbox with it.
  mailbox_mode?: "subdomain" | "migrate";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // banger, or an existing provider key returned by discovery.
  product_route?: string;
  // The domain owner's explicit confirmation that every sender using root From addresses has aligned SPF or DKIM. Required before Banger advertises a new root DMARC p=reject policy; DNS discovery cannot establish it.
  root_dmarc_confirmed?: boolean;
  // simple (default, and what guided onboarding uses) provisions only mailboxes for receiving and sending, including Broadcasts and Journeys from their exact addresses. With no mailbox_mode or prefix, simple uses the root; existing email DNS blocks creation until an available subdomain is chosen or a migration is approved. Guided onboarding's choose_identity step adds provider detection and checked suggestions. advanced preserves separate sending domains.
  setup_mode?: "simple" | "advanced";
}): Promise<CallToolResult>; };
```

## banger_create_product

Create an isolated email operating scope for one product, store, brand, newsletter, or company, with its own audiences, domains, Mailboxes, Broadcasts and Journeys.

exec tool declaration:
```ts
declare const tools: { banger_create_product(args: {
  context?: { [key: string]: unknown; };
  description?: string;
  // Domains assigned to this product. None is treated as primary.
  domains?: Array<string>;
  kind?: "product" | "store" | "brand" | "newsletter" | "company" | "other";
  name: string;
  website_url?: string | null;
}): Promise<CallToolResult>; };
```

## banger_create_segment

Save a product contact segment, with safe retries and canonical preview read-back. Does not create consent. filter.conditions are typed checks on contact fields (each contact field lists the operators its type allows): {field, op, value} with op is, is_not, contains, set, not_set, gt, gte, lt, lte (numbers and dates), within_days (dates, value = days), any_of (value = list), includes (several-choice fields). filter.match is all (default) or any. status and exact attributes also work.

exec tool declaration:
```ts
declare const tools: { banger_create_segment(args: {
  filter: { attributes?: { [key: string]: unknown; }; conditions?: Array<{ field: string; op: "is" | "is_not" | "contains" | "set" | "not_set" | "gt" | "gte" | "lt" | "lte" | "within_days" | "any_of" | "includes"; value?: unknown; }>; match?: "all" | "any"; status?: "subscribed" | "unsubscribed" | "bounced" | "complained"; };
  idempotency_key: string;
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_create_signup_form

Signup forms grow a product list from the person's own site: inline card, popup (delay/scroll/exit-intent triggers), bar, corner slide-in, or a hosted page (a link for bios and posts). Widgets wear the product brand and email style, so signups get matching email. Double opt-in is on by default: a branded confirmation email is sent and people join the list only after confirming; consent evidence is recorded. Free plans show a small 'Made with Banger' badge. Banger's own words (defaults left untouched, messages, the confirmation email, the confirmed page) appear in the visitor's language (English, Portuguese, Spanish, French, German), or in config.locale when set; copy the person writes stays exactly as written. config.fields adds up to 6 extra questions (text, select with options, or checkbox; optional required); answers are saved on the contact under each field's key (derived from the label when omitted), usable in segments and personalization. Bars ask only for the email. Forms can be created and set live only once the product has a verified sending domain (otherwise 409 verified_domain_required). Creates a form. list_id selects a list; list_name uses or creates a list by name (default "Newsletter"). config is partial: omitted settings use defaults for the kind; headline, body and button_label are the form's own copy. style empty follows the brand's email style. Returns embed_code and hosted_url. Requires a retry key.

exec tool declaration:
```ts
declare const tools: { banger_create_signup_form(args: {
  config?: {
  art?: "arcs" | "blocks" | "horizon" | "confetti" | "frame" | "bands" | "dots";
  body?: string;
  button_label?: string;
  collect_name?: boolean;
  confirm_promise?: string;
  count_noun?: string;
  delay_seconds?: number;
  email_placeholder?: string;
  exit_intent?: boolean;
  eyebrow?: string;
  fields?: Array<{ key?: string; label: string; options?: Array<string>; placeholder?: string; required?: boolean; type?: "text" | "select" | "checkbox"; }>;
  fine_print?: string;
  frequency_days?: number;
  headline?: string;
  image?: "none" | "photo" | "art";
  image_url?: string;
  incentive?: string;
  layout?: "stacked" | "split";
  // The language the form is written in (en, pt-BR, es, fr, de…). Banger's own words on the form and its confirmation email follow it; empty (the default) follows each visitor's browser language.
  locale?: string;
  name_placeholder?: string;
  position?: "bottom" | "top" | "right" | "left";
  redirect_url?: string;
  scroll_percent?: number;
  show_count?: boolean;
  show_logo?: boolean;
  style?: "" | "brand" | "clarity" | "editorial" | "luxe" | "material" | "playful" | "bold" | "plain";
  success_body?: string;
  success_headline?: string;
  theme?: "light" | "dark" | "brand" | "auto";
};
  double_opt_in?: boolean;
  idempotency_key: string;
  kind: "inline" | "popup" | "bar" | "slide_in" | "page";
  list_id?: string;
  list_name?: string;
  mailbox_id?: string;
  name?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_create_starter_mailbox

Create or resume a Banger-hosted mailbox without a company domain. create_new:true creates an additional mailbox. Its address is <local_part>@bangermail.com when a name is given, otherwise a friendly word name such as quiet-maple-harbor. Every hosted mailbox can send only to itself, other hosted inboxes in the same product, and the workspace signup email, including To, Cc and Bcc; hosted inboxes in another product or workspace are not allowed. A connected custom domain is required to send to other recipients.

exec tool declaration:
```ts
declare const tools: { banger_create_starter_mailbox(args: {
  create_new?: boolean;
  display_name?: string;
  idempotency_key: string;
  // Optional name before @bangermail.com. Taken or reserved names are refused.
  local_part?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_create_template

Save a reusable email design. {{placeholders}} mark fill-in content whose values go in content; recipient fields use {{first_name|there}} style placeholders with fallbacks. Designs carry the product brand. Nothing is sent. Saving a draft sends nothing and needs no review; a Journey's first activation needs one human review of its sending setup.

exec tool declaration:
```ts
declare const tools: { banger_create_template(args: {
  body_html: string;
  body_text?: string;
  // Fill-in values keyed by placeholder name, for example { headline: "Meet v2" }.
  content?: { [key: string]: string; };
  // What kind of message the design is, so Product compose and agents can find it.
  message_kind?: "custom" | "receipt" | "verification" | "magic_link" | "password_reset" | "login_code" | "invite" | "security" | "policy_update" | "welcome" | "tips" | "trial_ending" | "review_request" | "win_back" | "plan_change" | "announcement" | "newsletter" | "digest" | "event" | "story" | "promotion" | "changelog" | "survey" | "notice" | "cart_recovery" | "order_update" | "restock" | "payment_failed" | "usage_alert" | "booking" | "milestone" | "referral" | "waitlist" | "reengagement" | "appeal";
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Declared fill-in fields. Undeclared placeholders still become editable text slots.
  slots?: Array<{ help?: string; key: string; label?: string; type?: "text" | "paragraph" | "url" | "image"; }>;
  starter_id?: string;
  starter_version?: number;
  subject: string;
}): Promise<CallToolResult>; };
```

## banger_create_triage_rule

Create a Triage rule for incoming mail in one mailbox. When: description (judged by Jev), exact_conditions, and/or has_label_ids (all given have to hold). Then: actions (apply_label, archive, mark_read, star). Every plan has Triage; plans differ in how many rules can be on and how many emails are triaged per month.

exec tool declaration:
```ts
declare const tools: { banger_create_triage_rule(args: {
  actions: Array<{
  // Required for apply_label: a Banger label in the same mailbox.
  label_id?: string;
  type: "apply_label" | "archive" | "mark_read" | "star";
}>;
  // Plain-language condition Jev judges, e.g. "a customer reporting a bug". It is read literally; exact conditions cover senders, numbers and dates.
  description?: string;
  enabled?: boolean;
  // Exact conditions checked in code (like Gmail filters). All fields given have to hold.
  exact_conditions?: {
  // Subject and body contain none of these.
  excludes_words?: Array<string>;
  // Sender address, @domain or domain (matches subdomains). Any may match.
  from?: Array<string>;
  has_attachment?: boolean;
  // Subject or body contains all of these.
  has_words?: Array<string>;
  // Subject contains any of these.
  subject_contains?: Array<string>;
  // Recipient (to/cc) address, @domain or domain. Any may match.
  to?: Array<string>;
};
  // Matches threads that already carry all of these labels.
  has_label_ids?: Array<string>;
  idempotency_key: string;
  // Mailbox identifier.
  mailbox_id: string;
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_decide_experiment

Ends a running experiment with the chosen arm. A sampled Broadcast then sends its remainder with the winner; journeys and automations keep sending only the winner.

exec tool declaration:
```ts
declare const tools: { banger_decide_experiment(args: {
  // Experiment identifier.
  experiment_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  reason?: string;
  winner_key: string;
}): Promise<CallToolResult>; };
```

## banger_decide_split

Promote one split arm and flatten it into the Journey's main path.

exec tool declaration:
```ts
declare const tools: { banger_decide_split(args: {
  arm_key: "A" | "B" | "C" | "D";
  // Journey identifier.
  journey_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Split step identifier.
  step_id: string;
}): Promise<CallToolResult>; };
```

## banger_delete_broadcast

Permanently delete a Broadcast that has not sent to anyone (a draft, or one cancelled or failed before any recipient was sent) together with its own design. A Broadcast that sent cannot be deleted, only archived. A scheduled, sending, or paused Broadcast is refused until it is cancelled. Irreversible.

exec tool declaration:
```ts
declare const tools: { banger_delete_broadcast(args: {
  broadcast_id: string;
  idempotency_key: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_delete_label

Delete a Banger label. Its auto-set rule is deleted with it, it is removed from threads, and other Triage rules stop applying it.

exec tool declaration:
```ts
declare const tools: { banger_delete_label(args: {
  // Label identifier.
  label_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_delete_native_sending_domain

Stop all Mailboxes, Product, and Broadcast delivery for one domain and queue Banger-owned provider teardown. Message history and audit records are preserved. The exact root domain is required as confirmation.

exec tool declaration:
```ts
declare const tools: { banger_delete_native_sending_domain(args: {
  // Exact root domain returned by Banger for this domain identifier.
  confirm_domain: string;
  // Banger-native sending domain identifier.
  domain_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_delete_segment

Delete a product contact segment. Refused while a Broadcast that hasn't sent yet or a Journey that isn't archived still uses it as its audience; the error names them. Sent Broadcasts keep their frozen audience. Contacts are not deleted.

exec tool declaration:
```ts
declare const tools: { banger_delete_segment(args: {
  idempotency_key: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  segment_id: string;
}): Promise<CallToolResult>; };
```

## banger_delete_triage_rule

Delete a Triage rule. A label's auto-set rule is removed by turning auto-set off or deleting the label.

exec tool declaration:
```ts
declare const tools: { banger_delete_triage_rule(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Triage rule identifier.
  rule_id: string;
}): Promise<CallToolResult>; };
```

## banger_deliverability_summary

Get computed delivery, bounce, complaint, open, and click aggregates since a timestamp.

exec tool declaration:
```ts
declare const tools: { banger_deliverability_summary(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  since?: string;
}): Promise<CallToolResult>; };
```

## banger_duplicate_template

Copy a saved design (template) into a new active design with the same subject, HTML, text, fill-in content, and slots, as the Designs page's Duplicate does. name defaults to "<name> copy". Returns the new design. Not idempotent: each call creates another copy.

exec tool declaration:
```ts
declare const tools: { banger_duplicate_template(args: {
  name?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Design (template) identifier to copy.
  template_id: string;
}): Promise<CallToolResult>; };
```

## banger_enroll_journey_contacts

Enroll explicit subscribed contacts in a Journey. First activation and material sending changes create a request for one human Journey review. Unchanged reviewed Journeys resume and enroll within their approved scope without another review.

exec tool declaration:
```ts
declare const tools: { banger_enroll_journey_contacts(args: {
  contact_ids: Array<string>;
  idempotency_key: string;
  // Journey identifier.
  journey_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_generate_email_design

Have Banger's managed model (or a connected OpenAI/Anthropic connection) write a complete, on-brand email: subject options, text, and responsive HTML. Returns a proposal only; nothing is saved.

exec tool declaration:
```ts
declare const tools: { banger_generate_email_design(args: {
  audience?: string;
  // What the email should achieve, who it is for, and the facts it includes.
  brief: string;
  // Optional OpenAI or Anthropic connection. Omit to use Banger's managed model.
  connection_id?: string;
  idempotency_key: string;
  model?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  provider?: "openai" | "anthropic";
  // Optional layout to keep: subject, body_text, body_html.
  starter?: { [key: string]: unknown; };
}): Promise<CallToolResult>; };
```

## banger_get_approval

Read pending/approved/rejected state, immutable payload, blockers/reason, execution identifiers/results, and the human-review link. Agents cannot make human approval decisions.

exec tool declaration:
```ts
declare const tools: { banger_get_approval(args: {
  approval_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_billing

The workspace's plan, subscription status, this month's sends against the plan (and today's against the Free daily cap), storage used, and the plans it can move to with prices. The plan decides whether sent email carries the Free plan's 'Sent with Banger' footer; every paid plan removes it.

exec tool declaration:
```ts
declare const tools: { banger_get_billing(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_brand

Read the brand kit email designs render with: logo, colors, fonts, tone, company name, and email_style (the visual style every email follows: brand, the Clarity layout in the brand's own fonts and colors, or a preset: clarity, editorial, luxe, material, playful, bold, plain). Reports which values came from the product, from domain discovery, or are still defaults. email_fonts reports, for the heading and body font, which font readers see in each major mail client: brand web fonts load in Apple Mail and Outlook for Mac, and other clients show the fallback.

exec tool declaration:
```ts
declare const tools: { banger_get_brand(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_broadcast

Read the saved Broadcast content, source revision and translation state, sender and reply mailbox, audience, versions, statistics, and current state.

exec tool declaration:
```ts
declare const tools: { banger_get_broadcast(args: {
  broadcast_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_communication_policy

Read the product-wide recipient frequency and delivery-window policy shared by Journeys and broadcasts.

exec tool declaration:
```ts
declare const tools: { banger_get_communication_policy(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_company_context

Read the reviewed company profile, visual identity, and public email-stack discovery used by Banger agents.

exec tool declaration:
```ts
declare const tools: { banger_get_company_context(args: {
  // The exact product domain, when the product has several.
  domain?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_contact

Read subscription status, all consent evidence and source history, list memberships, and suppression status/reason for one product contact.

exec tool declaration:
```ts
declare const tools: { banger_get_contact(args: {
  contact_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_contact_import

Read canonical queued/running/completed/failed import status, processed/imported/invalid counts and errors. Queue acceptance is not import completion.

exec tool declaration:
```ts
declare const tools: { banger_get_contact_import(args: {
  import_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_contact_list

Read an existing product contact list, membership and source history.

exec tool declaration:
```ts
declare const tools: { banger_get_contact_list(args: {
  list_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_content_settings

Read product source/configured languages, fallback chain, timezone, glossary and optional manual translation review.

exec tool declaration:
```ts
declare const tools: { banger_get_content_settings(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_content_translations

Read translation coverage and preparation status for the current source revision.

exec tool declaration:
```ts
declare const tools: { banger_get_content_translations(args: {
  content_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_delivery_status

Read the canonical provider attempt, provider message identifier, and terminal delivery state for one send intent.

exec tool declaration:
```ts
declare const tools: { banger_get_delivery_status(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Canonical send-intent identifier.
  send_intent_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_domain_activation_proof

Read Banger's canonical Mailboxes, Product, and Broadcast send-and-receive evidence; status is running until it is complete or failed. DNS or provider UI state does not indicate readiness.

exec tool declaration:
```ts
declare const tools: { banger_get_domain_activation_proof(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_experiment

Per-variant sends, human opens and clicks, replies, conversions, lift, and confidence, plus a suggested winner when the evidence supports one. A decided test carries decision_basis (confident = every arm sampled and the bar cleared; deadline = the auto-decision deadline arrived first and the leader was promoted below the bar; guardrail; manual), decision_confidence (the confidence actually reached), and decision_reason.

exec tool declaration:
```ts
declare const tools: { banger_get_experiment(args: {
  // Experiment identifier.
  experiment_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_incoming_webhook_credentials

Reopen an existing incoming webhook in the private MCP panel, where its secret URL, or its public URL and separate Authorization: Bearer token, can be copied. Credentials stay outside model context. Requires a host with private MCP Apps rendering. Does not create, rotate, or activate anything; no secret-manager connection is needed.

exec tool declaration:
```ts
declare const tools: { banger_get_incoming_webhook_credentials(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  // Existing incoming webhook identifier, as listed with the workspace's webhooks.
  webhook_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_journey

Read one Journey's trigger, tree of steps, audience, goal, health, enrollments, and executions.

exec tool declaration:
```ts
declare const tools: { banger_get_journey(args: {
  // Journey identifier.
  journey_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_layout

Read shared layout state and its current draft revision.

exec tool declaration:
```ts
declare const tools: { banger_get_layout(args: {
  layout_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_layout_approval_preview

Retrieve full before/after source-language renders for one content item in a grouped layout approval. Immutable revision hashes are checked against the bound review manifest; does not approve or publish.

exec tool declaration:
```ts
declare const tools: { banger_get_layout_approval_preview(args: {
  approval_id: string;
  content_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  sample?: string;
}): Promise<CallToolResult>; };
```

## banger_get_layout_impact

Inspect affected published content and active Journeys before grouped layout review.

exec tool declaration:
```ts
declare const tools: { banger_get_layout_impact(args: {
  layout_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_managed_content

Read the current managed content draft, source revision, supplied translations and translation preparation state.

exec tool declaration:
```ts
declare const tools: { banger_get_managed_content(args: {
  content_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_message_body

Read one message's full HTML body, rendered to readable text (default) or as the raw HTML. Covers bodies that thread reads truncated (body_text_truncated). Messages without an HTML body already carry their full body_text in the thread.

exec tool declaration:
```ts
declare const tools: { banger_get_message_body(args: {
  format?: "text" | "html";
  max_chars?: number;
  // Message identifier within a thread.
  message_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_native_sending_domain

Read one canonical Banger-native sending domain, its complete required DNS record set, and Banger-owned verification statuses. Pending can mean normal propagation; it is not permission to alter a correctly saved record.

exec tool declaration:
```ts
declare const tools: { banger_get_native_sending_domain(args: {
  // Banger-native sending domain identifier.
  domain_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_sending_health

Read Banger's sender-reputation state: whether the workspace is frozen, each sending domain's state, each lane's (Mailbox, Product, Broadcast) trailing 24-hour hard bounce and complaint rates and state (active, warning, paused), post-resume probation, and paused mailboxes. Each pause lists its reason, the top sources and recipient domains of its bounces and complaints, and whether a workspace admin may resume it now (resume.self_serve) or when (resume.resumable_at), or why not (review_required, resume_limit_reached). Also returns the enforced thresholds. This is the Sending health view in Banger.

exec tool declaration:
```ts
declare const tools: { banger_get_sending_health(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_signup_form

Read one signup form: settings, list, embed code (a single script tag to paste before </body>, or where an inline form should appear), hosted page URL, and results.

exec tool declaration:
```ts
declare const tools: { banger_get_signup_form(args: {
  form_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_starter_mailbox_proof

Read Banger's canonical starter-address round-trip status.

exec tool declaration:
```ts
declare const tools: { banger_get_starter_mailbox_proof(args: {
  // Starter mailbox identifier.
  mailbox_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_get_template

Read one email design including its complete HTML, plain text, fill-in content, and the slots a person can edit.

exec tool declaration:
```ts
declare const tools: { banger_get_template(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Design (template) identifier.
  template_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_thread

Get a thread with its messages and readable bodies. Messages that only have an HTML body are rendered into body_text (links kept as "label (url)", body_text_source = rendered_html). Long renders are cut per message and flagged with body_text_truncated; the full body is available per message. include_html also returns each message's raw body_html. triage_actions lists what Triage did to the thread and which rule did it.

exec tool declaration:
```ts
declare const tools: { banger_get_thread(args: {
  // Also return each message's raw HTML as body_html (capped, body_html_truncated when cut).
  include_html?: boolean;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Thread identifier.
  thread_id: string;
}): Promise<CallToolResult>; };
```

## banger_get_transactional_send

Read the durable command state and provider-send correlation for one Banger Product message.

exec tool declaration:
```ts
declare const tools: { banger_get_transactional_send(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Product send identifier.
  send_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_api_keys

List product API key identifiers, names, prefixes, scopes, and expiry without revealing tokens.

exec tool declaration:
```ts
declare const tools: { banger_list_api_keys(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_approvals

List canonical product approvals with state, blockers/reason, execution identifiers, and human-review links. No human approval action is exposed.

exec tool declaration:
```ts
declare const tools: { banger_list_approvals(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  status?: "pending" | "approved" | "rejected" | "cancelled" | "expired" | "undecided";
}): Promise<CallToolResult>; };
```

## banger_list_broadcast_recipients

Read paginated queued, sent, delivered, failed, skipped, bounced, and complained recipient outcomes. Provider acceptance is sent; delivered requires a delivery event and does not prove inbox placement.

exec tool declaration:
```ts
declare const tools: { banger_list_broadcast_recipients(args: {
  broadcast_id: string;
  cursor?: string;
  limit?: number;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  status?: "pending" | "queued" | "sent" | "delivered" | "failed" | "skipped" | "bounced" | "complained";
}): Promise<CallToolResult>; };
```

## banger_list_broadcast_timeline

Read canonical Broadcast audit, approval, queue, and provider-event timeline. Provider acceptance is not inbox delivery.

exec tool declaration:
```ts
declare const tools: { banger_list_broadcast_timeline(args: {
  broadcast_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_campaigns

List the workspace's Broadcast messages and their current state. Archived Broadcasts are hidden; pass archived=true to list only those.

exec tool declaration:
```ts
declare const tools: { banger_list_campaigns(args: {
  // List only archived Broadcasts.
  archived?: boolean;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_connected_agents

List the AI assistants (ChatGPT, Claude, Codex and other MCP clients) that can act for this workspace, with identifiers and when each was connected and last active.

exec tool declaration:
```ts
declare const tools: { banger_list_connected_agents(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_connections

List product and business data sources whose credentials are managed by Banger. Client-owned MCP servers are intentionally not included.

exec tool declaration:
```ts
declare const tools: { banger_list_connections(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_contact_fields

List this product's contact fields: key, label, what it means (description), type (text, number, boolean, date, choice, choices), choices, where it came from (system, form, import, api, event, discovered, person, agent), how many contacts have a value, and the segment operators it supports. Values live in contact attributes under the key and personalize as {{attributes.key|fallback}}. Keys nobody declared are added as discovered fields the first time data carries them and can be renamed or retyped.

exec tool declaration:
```ts
declare const tools: { banger_list_contact_fields(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_contact_imports

List canonical product bulk import jobs and validation/processing status.

exec tool declaration:
```ts
declare const tools: { banger_list_contact_imports(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_contact_lists

List existing contact lists within this product. Lists select contacts; membership does not establish consent.

exec tool declaration:
```ts
declare const tools: { banger_list_contact_lists(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_contacts

List or search workspace contacts with cursor pagination. search filters by email address or display name (case-insensitive substring, e.g. "@acme.com" or "maya"); omit it to list everyone.

exec tool declaration:
```ts
declare const tools: { banger_list_contacts(args: {
  cursor?: string;
  limit?: number;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Alias of search.
  query?: string;
  // Case-insensitive substring of the contact's email address or display name.
  search?: string;
}): Promise<CallToolResult>; };
```

## banger_list_content_publications

List immutable managed content publications and their source revision identifiers.

exec tool declaration:
```ts
declare const tools: { banger_list_content_publications(args: {
  content_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_email_assets

List this product's uploaded email images and immutable public HTTPS URLs.

exec tool declaration:
```ts
declare const tools: { banger_list_email_assets(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_experiments

List experiments, optionally for one Broadcast, journey step, or automation rule. Decided tests include decision_basis (confident, deadline, guardrail, or manual), decision_confidence, and decision_reason; a deadline decision means the winner was picked at the auto-decision deadline without reaching the confidence bar.

exec tool declaration:
```ts
declare const tools: { banger_list_experiments(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  status?: "running" | "decided" | "stopped";
  subject_id?: string;
  subject_kind?: "campaign" | "sequence_step" | "automation_rule";
}): Promise<CallToolResult>; };
```

## banger_list_journey_executions

Read durable wait, send, split, completion, and failure receipts for a Journey.

exec tool declaration:
```ts
declare const tools: { banger_list_journey_executions(args: {
  // Journey identifier.
  journey_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_journeys

List every automated product email Journey, including unclaimed API sends, filters, health, and results.

exec tool declaration:
```ts
declare const tools: { banger_list_journeys(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  q?: string;
  status?: "draft" | "discovered" | "active" | "paused" | "archived";
  testing?: boolean;
  trigger_kind?: string;
}): Promise<CallToolResult>; };
```

## banger_list_labels

List a mailbox's labels with emoji, color, description, source (banger or provider), and auto_set (the label's auto-set rule, if any). Gmail/system labels are read-only.

exec tool declaration:
```ts
declare const tools: { banger_list_labels(args: {
  // Mailbox identifier.
  mailbox_id?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_layout_versions

Read immutable layout revision history.

exec tool declaration:
```ts
declare const tools: { banger_list_layout_versions(args: {
  layout_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_layouts

List versioned shared product layouts.

exec tool declaration:
```ts
declare const tools: { banger_list_layouts(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_logs

List the product's merged sent and received email timeline, newest first, with cursor pagination and operational filters.

exec tool declaration:
```ts
declare const tools: { banger_list_logs(args: {
  cursor?: string;
  direction?: "all" | "out" | "in";
  // First calendar date to include.
  from?: string;
  limit?: number;
  // Only entries for this product mailbox.
  mailbox_id?: string;
  origin?: "journey" | "broadcast" | "mailbox" | "api" | "agent";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Search subject or sender/recipient address.
  query?: string;
  status?: "queued" | "sent" | "delivered" | "bounced" | "complained" | "opened" | "clicked" | "replied" | "received" | "failed";
  // Last calendar date to include.
  to?: string;
}): Promise<CallToolResult>; };
```

## banger_list_mailboxes

List the work mailboxes visible to this workspace API key.

exec tool declaration:
```ts
declare const tools: { banger_list_mailboxes(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_managed_content

List product-scoped managed email drafts and publication identities, continuing with next_cursor. Does not send or change content.

exec tool declaration:
```ts
declare const tools: { banger_list_managed_content(args: {
  cursor?: string;
  limit?: number;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_native_sending_domains

List canonical Banger-native sending domains, provisioning checkpoints, and the complete required DNS record set (host, type, value, priority, and verification status). TTL is omitted: the DNS provider's default or any accepted value works. Pending after correct entry normally means propagation. Readiness is reported only by Banger's statuses.

exec tool declaration:
```ts
declare const tools: { banger_list_native_sending_domains(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_products

List the workspace's products, stores, brands, newsletters, and their setup progress. With one active product, product_id is optional; with several, operational writes require the product_id of the target product.

exec tool declaration:
```ts
declare const tools: { banger_list_products(args: {}): Promise<CallToolResult>; };
```

## banger_list_provider_connections

Inspect the workspace's Banger-native and customer-owned provider connections.

exec tool declaration:
```ts
declare const tools: { banger_list_provider_connections(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_segments

List existing product contact segments and their canonical filters.

exec tool declaration:
```ts
declare const tools: { banger_list_segments(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_sends

List canonical Product and Broadcast send intents with provider state so an agent can verify what actually happened.

exec tool declaration:
```ts
declare const tools: { banger_list_sends(args: {
  limit?: number;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_signup_forms

Signup forms grow a product list from the person's own site: inline card, popup (delay/scroll/exit-intent triggers), bar, corner slide-in, or a hosted page (a link for bios and posts). Widgets wear the product brand and email style, so signups get matching email. Double opt-in is on by default: a branded confirmation email is sent and people join the list only after confirming; consent evidence is recorded. Free plans show a small 'Made with Banger' badge. Banger's own words (defaults left untouched, messages, the confirmation email, the confirmed page) appear in the visitor's language (English, Portuguese, Spanish, French, German), or in config.locale when set; copy the person writes stays exactly as written. config.fields adds up to 6 extra questions (text, select with options, or checkbox; optional required); answers are saved on the contact under each field's key (derived from the label when omitted), usable in segments and personalization. Bars ask only for the email. Forms can be created and set live only once the product has a verified sending domain (otherwise 409 verified_domain_required). Lists this product's forms with embed code, hosted link, views, signups, confirmations, subscribers and conversion rate.

exec tool declaration:
```ts
declare const tools: { banger_list_signup_forms(args: {
  include_archived?: boolean;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_list_starters

70 designed email starters rendered in this product's brand, grouped by kind of business (saas, shop, creator, services, local, community) and customer stage (onboarding, activation, revenue, retention, publish, account). Every starter renders in the brand's style (brand, the default: Clarity in the brand's own fonts and colors) or any of seven presets (clarity, editorial, luxe, material, playful, bold, plain; via style). Each has a brief: its one job, when to send it, the metric to watch, the mechanic that makes it convert, subject lines to A/B test, and what to keep or avoid when rewriting. The list is compact and defaults to the product's own kind of business (business=all for everything); with id it returns one starter's body_html with fillable slots (image slots start on hand-picked photos or brand art). Saved designs record starter_id and starter_version.

exec tool declaration:
```ts
declare const tools: { banger_list_starters(args: {
  // Kind of business. Defaults to the product's kind.
  business?: "all" | "saas" | "shop" | "creator" | "services" | "local" | "community";
  // product = account and order mail without an unsubscribe link.
  category?: "product" | "lifecycle" | "broadcast";
  // One starter's id; returns it with body_html.
  id?: string;
  // Include body_html for every listed starter (large).
  include_html?: boolean;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  stage?: "onboarding" | "activation" | "revenue" | "retention" | "publish" | "account";
  // Visual style. brand (the default) is the clean Clarity layout in the brand's own fonts and colors; the other seven are designed presets with their own type, in the brand's colors. Every starter works in every style. Starters follow the brand's email_style unless you pass style; change it with the brand.
  style?: "brand" | "clarity" | "editorial" | "luxe" | "material" | "playful" | "bold" | "plain";
}): Promise<CallToolResult>; };
```

## banger_list_suggested_labels

List ready-made labels (name, emoji, color, auto-set description) with a suggestion_id each and whether each is already in the mailbox.

exec tool declaration:
```ts
declare const tools: { banger_list_suggested_labels(args: {
  // Mailbox identifier.
  mailbox_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_templates

List reusable email designs (templates) with their fill-in content, declared slots, and status.

exec tool declaration:
```ts
declare const tools: { banger_list_templates(args: {
  include_archived?: boolean;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_threads

List a cursor-paginated page of threads from one workspace mailbox view.

exec tool declaration:
```ts
declare const tools: { banger_list_threads(args: {
  cursor?: string;
  // Optional label filter.
  label_id?: string;
  limit?: number;
  // Optional mailbox filter.
  mailbox_id?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  view?: "inbox" | "sent" | "drafts" | "archive" | "trash" | "spam" | "all";
}): Promise<CallToolResult>; };
```

## banger_list_triage_actions

What Triage did and why: each action (apply_label, archive, mark_read, star) with its rule, thread, and whether it was undone. Filter by mailbox, thread, or rule.

exec tool declaration:
```ts
declare const tools: { banger_list_triage_actions(args: {
  limit?: number;
  // Mailbox identifier.
  mailbox_id?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Triage rule identifier.
  rule_id?: string;
  // Thread identifier.
  thread_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_triage_rules

List a mailbox's Triage rules (When -> Then). Labels' auto-set rules belong to their label and are listed here only with include_auto_set=true.

exec tool declaration:
```ts
declare const tools: { banger_list_triage_rules(args: {
  include_auto_set?: boolean;
  // Mailbox identifier.
  mailbox_id?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_webhooks

List incoming webhook connections and outbound endpoints, including connection_id, status, last_received_at, errors, and recent test deliveries. Credentials are not returned.

exec tool declaration:
```ts
declare const tools: { banger_list_webhooks(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_list_work

List the shared Work queue across every mailbox in the workspace.

exec tool declaration:
```ts
declare const tools: { banger_list_work(args: {
  cursor?: string;
  limit?: number;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  status?: "open" | "waiting" | "done";
}): Promise<CallToolResult>; };
```

## banger_mutate_thread

Apply an idempotent thread command such as archive, label, assignment, or Work status.

exec tool declaration:
```ts
declare const tools: { banger_mutate_thread(args: {
  command: "mark_read" | "mark_unread" | "archive" | "unarchive" | "trash" | "restore" | "spam" | "not_spam" | "star" | "unstar" | "add_label" | "remove_label" | "move" | "assign" | "set_work_status";
  idempotency_key: string;
  parameters?: { [key: string]: unknown; };
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Thread identifier.
  thread_id: string;
}): Promise<CallToolResult>; };
```

## banger_onboarding_act

Performs one step of the guided onboarding shared by the Banger web app and MCP clients, and returns the updated state with the current lesson (purpose, example_request, result, boundary) and steps[].actions. action names the step; data carries its fields. begin_guidance records the conversation handoff and creates or sends nothing. save_business saves brand and business context (an empty object accepts the resolved brand; optional company_name, primary_goal, brand, and data.brand.email_style for the email style); skip_business skips Brand without marking it reviewed. send_first sends the first email from the hosted mailbox to the workspace's verified signup address only (destination input is ignored); skip_reply moves past the reply phase. save_broadcast and save_journey resume existing inactive drafts (edit:true edits one). choose_identity saves the domain and mailbox route (root, or subdomain with its prefix; availability is checked server-side, including website records); setup_sending prepares the exact DNS records; dns_applied records that every record was saved; verify_dns checks them; continue_domain moves to Add inboxes without marking verification complete; add_inboxes creates the inboxes in data.addresses (1-25 local names; the domain comes from saved state), which stay pending until verification succeeds; skip_inboxes finishes without creating inboxes. On a root domain, setup_sending publishes DMARC p=reject only with data.root_dmarc_confirmed=true, which records the owner's confirmation that every service sending from root addresses authenticates with aligned SPF or DKIM; a dedicated subdomain needs no confirmation. Hosted mailboxes send only to themselves, the signup address, or other hosted mailboxes in the same product. Moving an existing mail provider's domain to Banger requires a signed-in administrator's migration approval. Does not activate a Journey or launch a Broadcast; repeated creates resume existing resources.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_act(args: {
  action: string;
  // Action-specific fields. For add_inboxes use exactly { addresses: ["hello", "support"] }: 1–25 local mailbox names without @domain. The domain comes from the saved onboarding state.
  data?: { [key: string]: unknown; };
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_onboarding_apply_plan

Apply the current onboarding plan and record the prepared artifacts. Routine plan acceptance is recorded directly under the default policy; saved stricter policies still apply. Does not authorize Journey activation or domain migration.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_apply_plan(args: { summary: { [key: string]: unknown; }; }): Promise<CallToolResult>; };
```

## banger_onboarding_choose_domain

Persist the domain decision: add a company domain, or continue without one. For a company domain Banger immediately performs canonical DNS/provider discovery.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_choose_domain(args: {
  choice: "company_domain" | "no_domain";
  // Required only when choice is company_domain.
  domain?: string;
}): Promise<CallToolResult>; };
```

## banger_onboarding_complete

Complete onboarding once validation has passed. Returns the stable dashboard URL without embedding a credential.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_complete(args: {}): Promise<CallToolResult>; };
```

## banger_onboarding_discover_domain

Have Banger's backend inspect public DNS and the company website. Returns the authoritative DNS provider, existing email services, and the canonical recommended connection plan. Discovery does not indicate DNS readiness.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_discover_domain(args: { domain: string; }): Promise<CallToolResult>; };
```

## banger_onboarding_ensure_aha_one

Legacy helper that returns an existing hosted-mailbox proof receipt. Automatic loopback sends are retired; new setups provision the starter mailbox without sending.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_ensure_aha_one(args: {}): Promise<CallToolResult>; };
```

## banger_onboarding_get_state

Reads the workspace's server-owned onboarding state (current step, lesson, progress, domain options and DNS guide) without rendering a UI card. The workspace comes from this MCP credential, not from model input. details=true adds full step detail.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_get_state(args: {
  details?: boolean;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_onboarding_open_setup

Renders the interactive onboarding card in MCP Apps hosts and returns the same saved state for text-only clients. task opens one part: mailbox, business, journey, broadcast, identity, or sending. The Banger web app shows the same onboarding on Home until it is complete.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_open_setup(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  task?: "mailbox" | "business" | "journey" | "broadcast" | "identity" | "sending";
}): Promise<CallToolResult>; };
```

## banger_onboarding_propose_plan

Save 1-100 lifecycle opportunities as a reviewable proposal. Each opportunity carries audience, trigger, sequence drafts, timing, exits, metric, required connections, policy, expected impact, approval needs, and recommended=true for the strongest. Does not approve or execute the plan.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_propose_plan(args: { opportunities: Array<{ [key: string]: unknown; }>; }): Promise<CallToolResult>; };
```

## banger_onboarding_record_decision

Persist the current progressive-onboarding choice or the completed dns_records_applied checkpoint (every Banger DNS record saved). Autopilot proposals grant no authority; activation happens in the secure signed-in Banger app.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_record_decision(args: { decision: "domain_bundle_approved" | "dns_computer_use_authorized" | "dns_manual_selected" | "dns_records_applied" | "services_reviewed" | "persistent_mcp_acknowledged" | "autopilot_proposed" | "autopilot_skipped"; details?: { [key: string]: unknown; }; }): Promise<CallToolResult>; };
```

## banger_onboarding_send_agent_test

Sends one diagnostic email to the canonical hosted mailbox to test this connection. Optional: OAuth authorization itself completes the agent-connection checkpoint.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_send_agent_test(args: {}): Promise<CallToolResult>; };
```

## banger_onboarding_start

Identify the connected client and begin or resume discovery in the same onboarding journey used by the browser.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_start(args: { client_name: string; }): Promise<CallToolResult>; };
```

## banger_onboarding_submit_context

Save structured, reviewed business, product, audience, stack, goal, constraint, and data-source context for onboarding. Credentials are not accepted.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_submit_context(args: { client_name?: string; company_domain?: string; context: { [key: string]: unknown; }; }): Promise<CallToolResult>; };
```

## banger_onboarding_validate

Derive onboarding validation exclusively from Banger's canonical send-and-receive proofs. The optional summary may describe external work; it does not change readiness.

exec tool declaration:
```ts
declare const tools: { banger_onboarding_validate(args: { summary?: { [key: string]: unknown; }; }): Promise<CallToolResult>; };
```

## banger_open_billing_portal

Returns a Stripe billing portal link where a person can change plan, update the card, see invoices or cancel. Requires workspace admin.

exec tool declaration:
```ts
declare const tools: { banger_open_billing_portal(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_pause_broadcast

Pause a scheduled or sending Broadcast. Recipients already sent stay sent; nobody else is sent to until it is resumed. Returns the Broadcast read-back (status paused). Retrying on an already paused Broadcast returns its current state.

exec tool declaration:
```ts
declare const tools: { banger_pause_broadcast(args: {
  broadcast_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_pause_native_sending_lane

Pause exactly one Mailboxes, Product, or Broadcast lane. Its DNS and the other lanes are left unchanged.

exec tool declaration:
```ts
declare const tools: { banger_pause_native_sending_lane(args: {
  // Banger-native sending domain identifier.
  domain_id: string;
  lane: "mailbox" | "product" | "broadcast";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_prepare_feedback_attachment

Prepare a screenshot or video upload up to 25 MiB into private Linear storage. Returns a temporary signed upload.url and upload.headers; the file bytes are PUT to that URL with exactly those headers and no Banger credentials, from an HTTP client on the agent or server (browser uploads go through the Banger proxy). The upload is then completed to get attachment_id. status ready means the upload is already complete.

exec tool declaration:
```ts
declare const tools: { banger_prepare_feedback_attachment(args: {
  // Generate one UUID per file and reuse it on retry.
  attachment_id: string;
  filename: string;
  mime_type: "image/png" | "image/jpeg" | "image/gif" | "image/webp" | "video/mp4" | "video/webm" | "video/quicktime";
  size_bytes: number;
}): Promise<CallToolResult>; };
```

## banger_preview_broadcast_audience

Read eligible recipient count/sample, exclusions with reasons, and missing personalization fields for existing contacts, lists, or segments. Optionally previews a saved Broadcast or design. Read-only: does not import contacts or freeze recipients.

exec tool declaration:
```ts
declare const tools: { banger_preview_broadcast_audience(args: {
  audience?: { all_subscribed?: boolean; contact_ids?: Array<string>; list_ids?: Array<string>; segment_ids?: Array<string>; };
  broadcast_id?: string;
  content_overrides?: { [key: string]: string; };
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  subject?: string;
  template_id?: string;
}): Promise<CallToolResult>; };
```

## banger_preview_email_design

Render an unsaved email design with sample recipient values and optional audience placeholder checks. Placeholders are filled without restyling the HTML. Returns rendered subject, text, and HTML, plus font_rendering: for each font stack, the font each major mail client shows. Read-only; nothing is saved or sent.

exec tool declaration:
```ts
declare const tools: { banger_preview_email_design(args: {
  // Optional Broadcast audience: all_subscribed, list_ids, segment_ids, contact_ids.
  audience?: { [key: string]: unknown; };
  body_html: string;
  body_text?: string;
  // Fill-in values keyed by placeholder name, for example { headline: "Meet v2" }.
  content?: { [key: string]: string; };
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Render for this contact instead of a sample recipient.
  sample_email?: string;
  subject: string;
}): Promise<CallToolResult>; };
```

## banger_preview_journey

Estimate the eligible audience and verify Journey activation readiness. Returns steps as a tree (a split keeps its arms, each with its own steps), plus emails: every email step including each split arm with its content source, subject, short text preview and blockers (for example a button without a link). Does not approve designs.

exec tool declaration:
```ts
declare const tools: { banger_preview_journey(args: {
  // Journey identifier.
  journey_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_preview_journey_approval

Read what a person sees when reviewing a Journey activation or enrollment approval: every email rendered with sample values from the approval's bound review snapshot (not the live Journey), keyed by step position (arm steps as parent.arm.position), plus the audience lists with sizes, segments and trigger/goal connection names. Emails that cannot be drawn carry an error; unpublished managed emails are marked published=false. Read-only; does not approve.

exec tool declaration:
```ts
declare const tools: { banger_preview_journey_approval(args: {
  approval_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_preview_segment

Read matching existing product contacts without importing or subscribing anyone.

exec tool declaration:
```ts
declare const tools: { banger_preview_segment(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  segment_id: string;
}): Promise<CallToolResult>; };
```

## banger_preview_signup_form

Render a signup form as a complete HTML page on a sketched website, as visitors will see it, in the form or success state. Preview a saved form (form_id, optionally with unsaved kind/config changes) or unsaved settings (kind and config). Read-only.

exec tool declaration:
```ts
declare const tools: { banger_preview_signup_form(args: {
  config?: {
  art?: "arcs" | "blocks" | "horizon" | "confetti" | "frame" | "bands" | "dots";
  body?: string;
  button_label?: string;
  collect_name?: boolean;
  confirm_promise?: string;
  count_noun?: string;
  delay_seconds?: number;
  email_placeholder?: string;
  exit_intent?: boolean;
  eyebrow?: string;
  fields?: Array<{ key?: string; label: string; options?: Array<string>; placeholder?: string; required?: boolean; type?: "text" | "select" | "checkbox"; }>;
  fine_print?: string;
  frequency_days?: number;
  headline?: string;
  image?: "none" | "photo" | "art";
  image_url?: string;
  incentive?: string;
  layout?: "stacked" | "split";
  // The language the form is written in (en, pt-BR, es, fr, de…). Banger's own words on the form and its confirmation email follow it; empty (the default) follows each visitor's browser language.
  locale?: string;
  name_placeholder?: string;
  position?: "bottom" | "top" | "right" | "left";
  redirect_url?: string;
  scroll_percent?: number;
  show_count?: boolean;
  show_logo?: boolean;
  style?: "" | "brand" | "clarity" | "editorial" | "luxe" | "material" | "playful" | "bold" | "plain";
  success_body?: string;
  success_headline?: string;
  theme?: "light" | "dark" | "brand" | "auto";
};
  form_id?: string;
  kind?: "inline" | "popup" | "bar" | "slide_in" | "page";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  state?: "form" | "success";
}): Promise<CallToolResult>; };
```

## banger_preview_template

Render a design with sample or real recipient values and, when an audience is given, report which required placeholders that audience cannot fill (the same check a Broadcast review runs). Read-only.

exec tool declaration:
```ts
declare const tools: { banger_preview_template(args: {
  // Optional Broadcast audience: all_subscribed, list_ids, segment_ids, contact_ids.
  audience?: { [key: string]: unknown; };
  // Fill-in values keyed by placeholder name, for example { headline: "Meet v2" }.
  content?: { [key: string]: string; };
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Render for this contact instead of a sample recipient.
  sample_email?: string;
  // Design (template) identifier.
  template_id: string;
}): Promise<CallToolResult>; };
```

## banger_preview_triage_rule

See which of the mailbox's recent threads a When would match, before saving it. Pass rule_id to preview a saved rule (including a label's auto-set), or an unsaved description / exact_conditions / has_label_ids. Read-only.

exec tool declaration:
```ts
declare const tools: { banger_preview_triage_rule(args: {
  // Plain-language condition Jev judges, e.g. "a customer reporting a bug". It is read literally; exact conditions cover senders, numbers and dates.
  description?: string;
  // Exact conditions checked in code (like Gmail filters). All fields given have to hold.
  exact_conditions?: {
  // Subject and body contain none of these.
  excludes_words?: Array<string>;
  // Sender address, @domain or domain (matches subdomains). Any may match.
  from?: Array<string>;
  has_attachment?: boolean;
  // Subject or body contains all of these.
  has_words?: Array<string>;
  // Subject contains any of these.
  subject_contains?: Array<string>;
  // Recipient (to/cc) address, @domain or domain. Any may match.
  to?: Array<string>;
};
  // Matches threads that already carry all of these labels.
  has_label_ids?: Array<string>;
  // How many recent threads to check.
  limit?: number;
  // Mailbox identifier.
  mailbox_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Preview a saved rule instead of an unsaved condition.
  rule_id?: string;
}): Promise<CallToolResult>; };
```

## banger_propose_action

Execute a concrete Banger draft or send request with an immutable action receipt. Under the default policy, draft and send actions run directly. Journey activation creates a request for one human review of its sending setup; unchanged reviewed Journeys resume or enroll within their approved scope. Stricter saved policies apply.

exec tool declaration:
```ts
declare const tools: { banger_propose_action(args: {
  action_kind: "mail.draft" | "transactional.send" | "campaign.draft" | "campaign.schedule" | "sequence.activate" | "sequence.enroll";
  idempotency_key: string;
  payload: { [key: string]: unknown; };
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  summary?: string;
}): Promise<CallToolResult>; };
```

## banger_propose_contact_import_mapping

Map the columns of a CSV or another tool's export onto contacts, from each column's header and up to 8 distinct sample values (not the whole file). Returns, per column, a target (email, display_name, first_name, last_name, locale, time_zone, status, unsubscribed_flag, subscribed_flag, field with field_key and field_type, or ignore) with a confidence, plus review.needed and review.reasons. source is saved (this product imported the same columns before), ai, or rules. In import rows, status comes from the status column, and any unsubscribed_flag yes or subscribed_flag no makes the row unsubscribed. Locale values are BCP 47 tags (pt-BR, en). Read-only; creates no contacts.

exec tool declaration:
```ts
declare const tools: { banger_propose_contact_import_mapping(args: {
  columns: Array<{ filled?: number; name: string; rows?: number; samples: Array<string>; }>;
  filename?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_publish_layout

Request human review of the exact shared layout and affected email set. Frozen broadcasts retain their existing layout.

exec tool declaration:
```ts
declare const tools: { banger_publish_layout(args: {
  expected_version: number;
  idempotency_key: string;
  layout_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_publish_managed_content

Request governed publication of the exact current source revision. Returns approval state; does not bypass human review. Automatic translations follow the saved translation review policy.

exec tool declaration:
```ts
declare const tools: { banger_publish_managed_content(args: {
  content_id: string;
  expected_version: number;
  idempotency_key: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_query_connection

Run one typed, bounded read against a connected source. Available only when the connection grants the calling credential this capability.

exec tool declaration:
```ts
declare const tools: { banger_query_connection(args: {
  adapter_key: "figma" | "github" | "google-analytics" | "google-calendar" | "hubspot" | "linear" | "mailchimp" | "notion" | "slack" | "zendesk";
  // Delegated namespace connection identifier.
  connection_id: string;
  operation: "audiences.list" | "campaigns.list" | "changelog.brief" | "channels.list" | "commits.list" | "companies.list" | "contacts.list" | "cohorts.list" | "deals.list" | "events.list" | "invoices.list" | "issues.list" | "messages.history" | "messages.search" | "notifications.list" | "payment_intents.list" | "persons.list" | "releases.list" | "reports.list" | "reports.run" | "repositories.list" | "subscriptions.list" | "customers.list" | "search.list" | "pages.retrieve" | "blocks.children.list" | "profiles.list" | "funnels.list" | "file.summary" | "nodes.get" | "images.render" | "comments.list" | "launch.brief" | "users.get";
  parameters?: { [key: string]: unknown; };
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_reactivate_mailbox

Resume sending for one mailbox that Banger paused for sender-reputation safety (status suspended, or a paused domain or lane it sends on). It resumes whatever pause holds the mailbox under the same rules as resuming sending: workspace admin only, 24 hours after a lane or domain pause, once per 30 days per domain, and not for a repeat pause or a frozen workspace, which need Banger review. acknowledge_recipient_complaint=true records the admin's acknowledgement and reason for the audit log. Retrying an already active mailbox is safe and returns it unchanged.

exec tool declaration:
```ts
declare const tools: { banger_reactivate_mailbox(args: {
  // True only after the person acknowledged the recipient complaint that suspended this mailbox and asked to resume sending.
  acknowledge_recipient_complaint: boolean;
  idempotency_key: string;
  // Identifier of a suspended mailbox.
  mailbox_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  // Why sending is being restored, in the person's words. Recorded in the audit log.
  reason: string;
}): Promise<CallToolResult>; };
```

## banger_recommend_arms

Estimate how many split arms the Journey's arrival volume can decide reliably.

exec tool declaration:
```ts
declare const tools: { banger_recommend_arms(args: {
  // Journey identifier.
  journey_id: string;
  position?: number;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_register_api_journey

Register a keyed Journey. Managed is the default: managed_content carries source-language HTML, typed variables and samples, and Banger prepares other languages asynchronously for free. Existing code Journeys remain supported. Saving a draft sends nothing and needs no review; a Journey's first activation needs one human review of its sending setup.

exec tool declaration:
```ts
declare const tools: { banger_register_api_journey(args: {
  body_text?: string;
  content_mode?: "code" | "managed";
  delivery_class: "product" | "broadcast";
  idempotency_key: string;
  key: string;
  // Sender mailbox.
  mailbox_id: string;
  managed_content?: {
  configured_locales?: Array<string>;
  fallback_locale?: string;
  layout_id?: string;
  localization_policy?: {
  // Optional bounded Journey hold for missing or review-pending translations. Wait requires max_wait_seconds and on_timeout. Urgent messages fall back immediately.
  journey_translation?: { max_wait_seconds?: number; mode: "fallback" | "wait"; on_timeout?: "fallback" | "discard"; };
  manual_review?: boolean;
};
  // Named sample variable sets for immediate preview and validation.
  samples?: { [key: string]: { [key: string]: unknown; }; };
  source: {
  body_html: string;
  layout?: string;
  preheader?: string;
  subject: string;
  // Map of variable names to typed definitions. Types: string, text, url, image_url, html, date, datetime, money ({amount_cents,currency}), number, boolean, object (properties), list (items). Each field accepts required (boolean), default, and an optional description of at most 2000 characters.
  variables: { [key: string]: { [key: string]: unknown; }; };
  variants?: { [key: string]: { body_html: string; body_text?: string; layout?: string; preheader?: string; subject: string; }; };
};
  source_locale?: string;
  // Optional supplied message catalogs keyed by locale. Supply source messages used by the template; other languages are prepared asynchronously without charge.
  translations?: { [key: string]: { [key: string]: string; }; };
};
  name: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  subject?: string;
  // Managed design.
  template_id?: string;
}): Promise<CallToolResult>; };
```

## banger_remove_contact_list_members

Remove existing product contacts from a product list by identifier; consent and suppression are preserved. Safe retries return canonical membership read-back.

exec tool declaration:
```ts
declare const tools: { banger_remove_contact_list_members(args: {
  contact_ids: Array<string>;
  idempotency_key: string;
  list_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_render_journey

Render a managed Journey email using the production renderer and saved samples when variables are omitted. Specify step_id for multi-email Journeys, including split branches. Returns HTML, text, locale and warnings without sending.

exec tool declaration:
```ts
declare const tools: { banger_render_journey(args: {
  content_state?: "draft" | "published";
  journey_id: string;
  locale?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  sample_set?: string;
  step_id?: string;
  timezone?: string;
  variables?: { [key: string]: unknown; };
}): Promise<CallToolResult>; };
```

## banger_render_managed_content

Render saved content with an explicit locale and either variables or a named sample. Uses the same renderer as sending; does not send or publish.

exec tool declaration:
```ts
declare const tools: { banger_render_managed_content(args: {
  content_id: string;
  locale?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  sample_set?: string;
  source_revision_id?: string;
  timezone?: string;
  variables?: { [key: string]: unknown; };
  variant?: string;
}): Promise<CallToolResult>; };
```

## banger_report_bug

Report a problem with Banger v2: what happened and what was expected. Creates an internal Linear issue and alerts the Banger team in Slack. attachment_ids takes uploaded feedback attachments (screenshots or videos, up to 25 MiB each). submission_id is a UUID; retrying the same submission with the same submission_id does not create a duplicate.

exec tool declaration:
```ts
declare const tools: { banger_report_bug(args: {
  attachment_ids?: Array<string>;
  description: string;
  // Unique ID for this submission; reuse on retry.
  submission_id: string;
  title: string;
}): Promise<CallToolResult>; };
```

## banger_request_contact_import

Validate and queue a consent-valid bulk import, bound to exact rows/consent and a stable import identifier. Under the default policy it queues directly; saved stricter workspace policies still apply. Returns approval evidence; contacts are imported once canonical import status reports completion.

exec tool declaration:
```ts
declare const tools: { banger_request_contact_import(args: {
  consent_confirmed?: boolean;
  filename: string;
  idempotency_key: string;
  import_id: string;
  list_id?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  rows: Array<{ attributes?: { [key: string]: unknown; }; consent_evidence?: { observed_at?: string; reference?: string; source?: string; statement?: string; }; display_name?: string; email: string; status: "subscribed" | "unsubscribed" | "bounced" | "complained"; }>;
}): Promise<CallToolResult>; };
```

## banger_request_domain_migration

Prepare an immutable migration request in Banger's Approvals panel for a domain whose existing email DNS blocks direct setup, or for Mailboxes on a domain that already receives mail. Reads the current DNS and creates only a pending request: no domains, Mailboxes, provider configuration, or DNS changes. Takes the same root domain, lane_prefixes, and routes as sending-domain creation; mailbox_mode migrate keeps existing address spellings on the exact domain, subdomain reviews occupied lane subdomains. A signed-in administrator authorizes the request in the Banger panel; no tool and no chat consent can approve it. Banger applies the setup automatically when it is authorized.

exec tool declaration:
```ts
declare const tools: { banger_request_domain_migration(args: {
  // banger, or an existing provider key returned by discovery.
  broadcast_route?: string;
  domain: string;
  idempotency_key: string;
  // Optional subdomain labels, one per lane, applied under the root domain. Defaults: mailbox mail, product tx, broadcast broadcast.
  lane_prefixes?: {
  // Broadcast subdomain label (default broadcast).
  broadcast?: string;
  // Mailboxes subdomain label; hello gives addresses @hello.<domain>.
  mailbox?: string;
  // Product email subdomain label (default tx).
  product?: string;
};
  // subdomain puts Mailboxes on a subdomain and preserves existing domain mail. Simple setup defaults to the root if no prefix is supplied; advanced defaults to a subdomain. migrate puts Mailboxes on the exact root domain (@example.com); omit lane_prefixes.mailbox with it.
  mailbox_mode?: "subdomain" | "migrate";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // banger, or an existing provider key returned by discovery.
  product_route?: string;
  // The domain owner's explicit confirmation that other root From senders authenticate with aligned SPF or DKIM.
  root_dmarc_confirmed?: boolean;
  // simple (default, and what guided onboarding uses) provisions only mailboxes for receiving and sending, including Broadcasts and Journeys from their exact addresses. With no mailbox_mode or prefix, simple uses the root; existing email DNS blocks creation until an available subdomain is chosen or a migration is approved. Guided onboarding's choose_identity step adds provider detection and checked suggestions. advanced preserves separate sending domains.
  setup_mode?: "simple" | "advanced";
}): Promise<CallToolResult>; };
```

## banger_restore_content_revision

Create a new draft from an earlier source revision. Does not publish or bypass review.

exec tool declaration:
```ts
declare const tools: { banger_restore_content_revision(args: {
  content_id: string;
  expected_version: number;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  source_revision_id: string;
}): Promise<CallToolResult>; };
```

## banger_restore_layout_version

Copy a previous layout revision into a new draft; publishing it goes through the normal grouped review.

exec tool declaration:
```ts
declare const tools: { banger_restore_layout_version(args: {
  expected_version: number;
  layout_id: string;
  layout_revision_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_resume_broadcast

Resume a paused Broadcast. One paused before its send time goes back to waiting for that scheduled_at; one paused mid-send, or whose send time passed while paused, continues sending now to the recipients not yet sent. Returns the Broadcast read-back with status and scheduled_at. Retrying on a Broadcast already scheduled or sending returns its current state.

exec tool declaration:
```ts
declare const tools: { banger_resume_broadcast(args: {
  broadcast_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_resume_native_sending_lane

Resume exactly one Mailboxes, Product, or Broadcast lane. Banger rechecks the lane's own provider readiness without changing another lane.

exec tool declaration:
```ts
declare const tools: { banger_resume_native_sending_lane(args: {
  // Banger-native sending domain identifier.
  domain_id: string;
  lane: "mailbox" | "product" | "broadcast";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_resume_sending

Resume one lane, domain or mailbox pause that Banger applied for sender-reputation safety; hold_id is the pause identifier from sending health. Workspace admin only. acknowledge_reputation_risk=true records that the admin reviewed the pause's rates and top bounce and complaint sources and fixed the cause (cleaned the list, removed unconsented recipients, secured a compromised mailbox). Allowed 24 hours after a lane or domain pause and once per 30 days per domain; a repeat pause or a frozen workspace needs Banger review and is refused. After a resume the lane sends in smaller batches for 24 hours, and held Broadcasts and Journeys continue on their own. Returns the released pause and the updated sending health.

exec tool declaration:
```ts
declare const tools: { banger_resume_sending(args: {
  // True only after the person reviewed the rates and sources, fixed the cause, and asked to resume.
  acknowledge_reputation_risk: boolean;
  // Pause identifier (hold.id) from sending health.
  hold_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // What was fixed, in the person's words. Recorded in the audit log.
  reason: string;
}): Promise<CallToolResult>; };
```

## banger_review_content_translation

Mark a pending translation reviewed after inspecting it, optionally supplying corrected strings. Requires the exact source revision and catalog hash from readback. Does not publish the source or overwrite ready translations.

exec tool declaration:
```ts
declare const tools: { banger_review_content_translation(args: {
  content_id: string;
  expected_translation_sha256: string;
  locale: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  source_revision_id: string;
  strings?: { [key: string]: string; };
}): Promise<CallToolResult>; };
```

## banger_revise_email_design

Propose a revision of the supplied email according to an instruction, keeping the product brand and every placeholder. Returns a proposal only; nothing is saved.

exec tool declaration:
```ts
declare const tools: { banger_revise_email_design(args: {
  // Optional OpenAI or Anthropic connection. Omit to use Banger's managed model.
  connection_id?: string;
  // The email to revise: subject, body_text, body_html.
  current: { [key: string]: unknown; };
  idempotency_key: string;
  instruction: string;
  model?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  provider?: "openai" | "anthropic";
}): Promise<CallToolResult>; };
```

## banger_revoke_api_key

Revoke an approved product API key by identifier, including an unused key whose one-time token was lost. Integrations using it immediately lose access.

exec tool declaration:
```ts
declare const tools: { banger_revoke_api_key(args: {
  // API key identifier.
  api_key_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_revoke_connected_agent

Revoke one connected AI agent by identifier. It loses access within about 30 seconds and has to be connected again to come back.

exec tool declaration:
```ts
declare const tools: { banger_revoke_connected_agent(args: {
  // Agent connection identifier.
  agent_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_run_triage_on_past_mail

Run the mailbox's Triage rules (or rule_ids) on threads from the last 1-90 days. Applies labels only unless include_other_actions is true (then archive/read/star too).

exec tool declaration:
```ts
declare const tools: { banger_run_triage_on_past_mail(args: {
  days?: number;
  idempotency_key: string;
  include_other_actions?: boolean;
  // Mailbox identifier.
  mailbox_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Only these Triage rules (default: all enabled).
  rule_ids?: Array<string>;
}): Promise<CallToolResult>; };
```

## banger_schedule_broadcast

Submit the exact saved Broadcast and design versions and recipient selection for sending at scheduled_at. Banger freezes eligible recipients and binds their snapshot to the approval. Requires an idempotency key; retries return the same approval/execution identifiers. Under the default policy the schedule executes directly; saved stricter policies may require human review in Approvals. Broadcasts send on the Broadcast lane, not as Product email. Sending readiness and stricter saved workspace policies are enforced.

exec tool declaration:
```ts
declare const tools: { banger_schedule_broadcast(args: {
  broadcast_id: string;
  expected_design_version: number;
  expected_version: number;
  idempotency_key: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  recipient_selection: { all_subscribed?: boolean; contact_ids?: Array<string>; list_ids?: Array<string>; segment_ids?: Array<string>; };
  scheduled_at: string;
}): Promise<CallToolResult>; };
```

## banger_search_mail

Search mail server-side across all mailboxes in the workspace, or within one mailbox.

exec tool declaration:
```ts
declare const tools: { banger_search_mail(args: {
  cursor?: string;
  limit?: number;
  // Optional mailbox filter.
  mailbox_id?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  query: string;
}): Promise<CallToolResult>; };
```

## banger_send_broadcast

Submit the exact saved Broadcast and design versions and recipient selection for sending now. Banger freezes eligible recipients and binds their snapshot to the approval. Requires an idempotency key; retries return the same approval/execution identifiers. Under the default policy the send executes directly; saved stricter policies may require human review in Approvals. Broadcasts send on the Broadcast lane, not as Product email. Sending readiness and stricter saved workspace policies are enforced.

exec tool declaration:
```ts
declare const tools: { banger_send_broadcast(args: {
  broadcast_id: string;
  expected_design_version: number;
  expected_version: number;
  idempotency_key: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  recipient_selection: { all_subscribed?: boolean; contact_ids?: Array<string>; list_ids?: Array<string>; segment_ids?: Array<string>; };
}): Promise<CallToolResult>; };
```

## banger_send_email

Send through the selected mailbox, using its exact address and the same draft-send delivery path as Mailboxes in the UI. mailbox_id identifies the actual mailbox, not a Product-lane sender; Banger does not move it onto tx.*. Sending readiness, suppression, allowances, and explicitly saved stricter review policies are enforced. A queued execution is not proof of delivery. On the Free plan (or a cancelled paid plan), Banger adds a small 'Sent with Banger' line with a link to bangermail.com at the very bottom of every email it sends: mailbox, Product, Broadcast and Journey. It is added at delivery, so it is not part of drafts, previews or stored bodies. Any paid plan removes it, including mail already queued.

exec tool declaration:
```ts
declare const tools: { banger_send_email(args: {
  bcc?: string | Array<string | { email: string; name?: string; }>;
  cc?: string | Array<string | { email: string; name?: string; }>;
  // Fill-in values keyed by placeholder name, for example { headline: "Meet v2" }.
  content?: { [key: string]: string; };
  headers?: { [key: string]: string; };
  html?: string;
  idempotency_key: string;
  // Actual Banger mailbox to send through, using its exact address.
  mailbox_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  reply_to: string | Array<string | { email: string; name?: string; }>;
  subject?: string;
  tags?: Array<{ name: string; value: string; }>;
  // Optional saved design to render instead of text/html; Banger fills its content and the product brand.
  template_id?: string;
  text?: string;
  to: string | Array<string | { email: string; name?: string; }>;
  [key: string]: unknown;
}): Promise<CallToolResult>; };
```

## banger_set_journey_status

Activate, pause, resume, return to draft, or archive a Journey. First activation and material sending changes create a request for one human Journey review. Unchanged reviewed Journeys resume and enroll within their approved scope without another review.

exec tool declaration:
```ts
declare const tools: { banger_set_journey_status(args: {
  idempotency_key: string;
  // Journey identifier.
  journey_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  status: "draft" | "active" | "paused" | "archived";
}): Promise<CallToolResult>; };
```

## banger_set_product_setup

Mark one product setup item todo, in progress, complete, or not relevant. The item records confirmed facts.

exec tool declaration:
```ts
declare const tools: { banger_set_product_setup(args: {
  item: "context" | "domain" | "mailboxes" | "journeys" | "broadcasts" | "compliance";
  note?: string;
  // Product identifier.
  product_id: string;
  status: "todo" | "in_progress" | "complete" | "not_relevant";
}): Promise<CallToolResult>; };
```

## banger_set_triage_rule_status

Enable or pause a Triage rule. Pausing keeps its condition and history.

exec tool declaration:
```ts
declare const tools: { banger_set_triage_rule_status(args: {
  enabled: boolean;
  idempotency_key: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Triage rule identifier.
  rule_id: string;
}): Promise<CallToolResult>; };
```

## banger_set_webhook_status

Disable a webhook (status=disabled) or turn a disabled or failing one back on (status=active), as the Webhooks page does. Disabling an incoming webhook also disables its connection, so Journeys triggered by it stop receiving events until it is re-enabled; disabling an outbound one stops deliveries. Returns the webhook read-back; retrying when it already has that status returns its current state.

exec tool declaration:
```ts
declare const tools: { banger_set_webhook_status(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  status: "active" | "disabled";
  // Webhook identifier, as listed with the workspace's webhooks.
  webhook_id: string;
}): Promise<CallToolResult>; };
```

## banger_show_email_preview

Show the actual saved template, Broadcast or Journey email inside the MCP conversation (MCP Apps hosts; the result also carries the email text). For a managed Broadcast, locale and variant_key select a frozen translation and exact experiment version. For a Journey, email_key selects the step; defaults to the first email. There is no web-app preview page or link. Nothing is sent or activated.

exec tool declaration:
```ts
declare const tools: { banger_show_email_preview(args: {
  // Journey step key of the email to preview.
  email_key?: string;
  // Optional BCP 47 locale for a managed Broadcast preview, such as pt-BR.
  locale?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  // Saved email design, Broadcast or Journey ID.
  resource_id: string;
  resource_kind: "template" | "broadcast" | "journey";
  // Optional managed Broadcast experiment key, such as a or b.
  variant_key?: string;
}): Promise<CallToolResult>; };
```

## banger_simulate_communication_policy

Read-only scheduling simulation for fixed Journey and broadcast send requests to one recipient. Does not send, reserve slots or move dependent Journey steps.

exec tool declaration:
```ts
declare const tools: { banger_simulate_communication_policy(args: {
  history?: Array<string>;
  policy?: { caps?: Array<{ count: number; windowSeconds: number; }>; conflict: "defer" | "discard"; minimumIntervalSeconds?: number; window?: {
  // HH:mm
  end: string;
  // HH:mm
  start: string;
  timeZone: string;
  weekdays?: Array<number>;
}; };
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  requests: Array<{ at: string; category: "urgent" | "product" | "promotional"; deliveryBlocked?: boolean; expiresAt?: string; id: string; source_kind: "journey" | "broadcast"; }>;
}): Promise<CallToolResult>; };
```

## banger_simulate_journey

Read-only Journey and selected managed Broadcast simulation. Without enrollment it previews after enrollment; with an explicit trigger scenario it checks current saved contact eligibility. Covers shared communication policy, frozen campaign recipients, locale rendering, exits and blocked steps; does not send or queue translations. Renders every email kind with the sender's renderer: saved designs (template_id with content_overrides), a step's own design (subject/body_html/body_text) and managed content. emails lists every email step, including split arms the sample recipient did not take, with its rendered subject and preview or the blocker. enrollment_id reproduces the same split assignment as a real enrollment.

exec tool declaration:
```ts
declare const tools: { banger_simulate_journey(args: {
  at: string;
  // Selected managed campaigns use their frozen recipient values, locale and expiry. Explicit content candidates use provided values at simulation start.
  broadcasts?: Array<{ [key: string]: unknown; } | { [key: string]: unknown; }>;
  // Prior or reserved sends to this sample recipient; used with the product communication policy.
  communication_history?: Array<string>;
  contact: { attributes: { [key: string]: unknown; }; display_name: string; email: string; };
  content_state?: "draft" | "published";
  // Optional trigger-time eligibility scenario. Omit to preserve after-enrollment simulation. Manual and scan triggers use current saved contact scope/status; hypothetical event contacts require explicit subscribed and unsuppressed state. API Journeys model their contact upsert without writing.
  enrollment?: { assume_active?: boolean; contact_status?: "subscribed" | "unsubscribed"; event?: string; kind: "manual" | "api" | "contact_created" | "audience_joined" | "event"; suppressed?: boolean; };
  enrollment_id?: string;
  events?: Array<{ at: string; attributes?: { [key: string]: unknown; }; kind: "attributes" | "reply" | "unsubscribe" | "suppress" | "goal"; }>;
  journey_id: string;
  locale?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  variables?: { [key: string]: unknown; };
}): Promise<CallToolResult>; };
```

## banger_start_domain_activation_proof

For a domain whose required DNS records Banger reports verified, create hello@ and start real Product and Broadcast messages that are received back in the Banger mailbox.

exec tool declaration:
```ts
declare const tools: { banger_start_domain_activation_proof(args: {
  // Verified Banger sending-domain identifier.
  native_domain_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_start_starter_mailbox_proof

Read an existing historical starter-mailbox proof. New automatic loopback sends are disabled; the first send in guided onboarding goes to the workspace signup address.

exec tool declaration:
```ts
declare const tools: { banger_start_starter_mailbox_proof(args: {
  // Starter mailbox identifier.
  mailbox_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_start_upgrade

Returns a Stripe link where a person upgrades the workspace (Checkout for a new subscription, or the billing portal to switch plans when one is active). Payment happens on Stripe's page; this tool charges nothing. Requires workspace admin.

exec tool declaration:
```ts
declare const tools: { banger_start_upgrade(args: {
  // Yearly is the headline price and costs about 17% less than paying monthly.
  interval?: "month" | "year";
  plan_key: "starter" | "pro" | "business" | "scale";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_stop_experiment

Stops a running experiment without a winner. A sampled Broadcast sends its remainder with the first arm.

exec tool declaration:
```ts
declare const tools: { banger_stop_experiment(args: {
  // Experiment identifier.
  experiment_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_submit_feedback

Send feedback about Banger v2. Creates an internal Linear issue and alerts the Banger team in Slack. attachment_ids takes uploaded feedback attachments (screenshots or videos, up to 25 MiB each). submission_id is a UUID; retrying the same submission with the same submission_id does not create a duplicate.

exec tool declaration:
```ts
declare const tools: { banger_submit_feedback(args: {
  attachment_ids?: Array<string>;
  description: string;
  // Unique ID for this submission; reuse on retry.
  submission_id: string;
  title: string;
}): Promise<CallToolResult>; };
```

## banger_suggest_feature

Suggest a feature for Banger v2. Creates an internal Linear issue and alerts the Banger team in Slack. attachment_ids takes uploaded feedback attachments (screenshots or videos, up to 25 MiB each). submission_id is a UUID; retrying the same submission with the same submission_id does not create a duplicate.

exec tool declaration:
```ts
declare const tools: { banger_suggest_feature(args: {
  attachment_ids?: Array<string>;
  description: string;
  // Unique ID for this submission; reuse on retry.
  submission_id: string;
  title: string;
}): Promise<CallToolResult>; };
```

## banger_test_webhook

Queue one test event to an active outbound webhook endpoint, the same test the Webhooks page sends, to check that the endpoint receives and verifies Banger events. Returns the queued delivery; its result appears in the webhook list. Incoming webhooks are tested by sending a request to their own URL instead. Each call sends another test event.

exec tool declaration:
```ts
declare const tools: { banger_test_webhook(args: {
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  // Outbound webhook identifier, as listed with the workspace's webhooks.
  webhook_id: string;
}): Promise<CallToolResult>; };
```

## banger_undo_triage_action

Reverse one Triage action (remove the label, unarchive, mark unread, or unstar) and teach its rule that this email is not a match.

exec tool declaration:
```ts
declare const tools: { banger_undo_triage_action(args: {
  // Triage action identifier, from the Triage action list or a thread's triage_actions.
  action_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_update_brand_footer

Partially update the canonical product brand/footer, preserving unrelated fields and synchronizing compliance readiness. Empty string clears a supplied field. Requires a retry key and returns canonical brand read-back.

exec tool declaration:
```ts
declare const tools: { banger_update_brand_footer(args: {
  brand: { accent_color?: string; background_color?: string; body_font_family?: string; company_name?: string; footer_address?: string; heading_font_family?: string; logo_url?: string; muted_text_color?: string; primary_color?: string; surface_color?: string; text_color?: string; tone?: string; website_url?: string; wordmark_url?: string; };
  idempotency_key: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_update_broadcast

Partially update a draft Broadcast while preserving omitted fields. Requires its expected version and a retry key. Editing clears previous recipient snapshots, so a send reviews the new version. Saving a draft sends nothing and needs no review; a Journey's first activation needs one human review of its sending setup.

exec tool declaration:
```ts
declare const tools: { banger_update_broadcast(args: {
  audience?: { all_subscribed?: boolean; contact_ids?: Array<string>; list_ids?: Array<string>; segment_ids?: Array<string>; };
  broadcast_id: string;
  content_overrides?: { [key: string]: string; };
  expected_version: number;
  expires_after_seconds?: number;
  idempotency_key: string;
  localization_failure_policy?: "hold" | "fallback";
  mailbox_id?: string;
  managed_content?: {
  configured_locales?: Array<string>;
  fallback_locale?: string;
  layout_id?: string;
  localization_policy?: {
  // Optional bounded Journey hold for missing or review-pending translations. Wait requires max_wait_seconds and on_timeout. Urgent messages fall back immediately.
  journey_translation?: { max_wait_seconds?: number; mode: "fallback" | "wait"; on_timeout?: "fallback" | "discard"; };
  manual_review?: boolean;
};
  // Named sample variable sets for immediate preview and validation.
  samples?: { [key: string]: { [key: string]: unknown; }; };
  source: {
  body_html: string;
  layout?: string;
  preheader?: string;
  subject: string;
  // Map of variable names to typed definitions. Types: string, text, url, image_url, html, date, datetime, money ({amount_cents,currency}), number, boolean, object (properties), list (items). Each field accepts required (boolean), default, and an optional description of at most 2000 characters.
  variables: { [key: string]: { [key: string]: unknown; }; };
  variants?: { [key: string]: { body_html: string; body_text?: string; layout?: string; preheader?: string; subject: string; }; };
};
  source_locale?: string;
  // Optional supplied message catalogs keyed by locale. Supply source messages used by the template; other languages are prepared asynchronously without charge.
  translations?: { [key: string]: { [key: string]: string; }; };
};
  managed_content_id?: string;
  name?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  sample_name?: string;
  selected_subject_variant?: number;
  subject_variants?: Array<string>;
  template_id?: string;
}): Promise<CallToolResult>; };
```

## banger_update_communication_policy

Update shared recipient caps, spacing and delivery window with optimistic concurrency. Urgent messages bypass frequency caps but cannot bypass delivery suppression or expiry.

exec tool declaration:
```ts
declare const tools: { banger_update_communication_policy(args: {
  expected_version: number;
  policy: { caps?: Array<{ count: number; windowSeconds: number; }>; conflict: "defer" | "discard"; minimumIntervalSeconds?: number; window?: {
  // HH:mm
  end: string;
  // HH:mm
  start: string;
  timeZone: string;
  weekdays?: Array<number>;
}; };
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_update_contact_field

Rename, describe, retype, change the choices of, or hide a contact field. Retyping converts every stored value and is refused, with an example contact, if any value doesn't fit. Built-in fields (first_name, last_name, locale, time_zone) can't change.

exec tool declaration:
```ts
declare const tools: { banger_update_contact_field(args: {
  description?: string;
  field_key: string;
  idempotency_key: string;
  label?: string;
  options?: Array<string>;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  status?: "active" | "hidden";
  type?: "text" | "number" | "boolean" | "date" | "choice" | "choices";
}): Promise<CallToolResult>; };
```

## banger_update_content_settings

Set localization defaults using expected_version (0 to initialize). Automatic translation is free; manual translation review is off by default.

exec tool declaration:
```ts
declare const tools: { banger_update_content_settings(args: {
  configured_locales: Array<string>;
  expected_version: number;
  fallback_chain: Array<string>;
  glossary: { [key: string]: string; };
  manual_translation_review: boolean;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  source_locale: string;
  timezone: string;
}): Promise<CallToolResult>; };
```

## banger_update_journey

Partially update a Journey. journey carries only the fields to change; omitted fields and steps are preserved. expected_version rejects concurrent changes. Replacing steps takes their complete tree; existing IDs and monitored wait behavior are kept when supplied. trigger, goal, exit and api merge into the saved values; journey.trigger.connection_id set to a webhook's connection_id starts the Journey from that webhook. Each person enters once unless journey.trigger.config.once_per_person is false (then they may re-enter after they finish, after journey.trigger.config.reentry_days if set). Saving a draft sends nothing and needs no review; a Journey's first activation needs one human review of its sending setup.

exec tool declaration:
```ts
declare const tools: { banger_update_journey(args: {
  // Partial update. Omitted fields are preserved; supplied steps replace the complete tree.
  journey: { [key: string]: unknown; };
  // Journey identifier.
  journey_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_update_label

Rename a Banger label or change its color, emoji (null clears it), description, or auto-set (turn it on/off and edit its description or exact conditions). Turning auto-set off pauses it and keeps its condition.

exec tool declaration:
```ts
declare const tools: { banger_update_label(args: {
  // The label's auto-set rule. Needs a description and/or exact conditions when enabled. Enabled rules count toward the plan's Triage rule amount.
  auto_set?: {
  // Plain-language condition Jev judges, e.g. "a customer reporting a bug". It is read literally; exact conditions cover senders, numbers and dates.
  description?: string;
  enabled: boolean;
  // Exact conditions checked in code (like Gmail filters). All fields given have to hold.
  exact_conditions?: {
  // Subject and body contain none of these.
  excludes_words?: Array<string>;
  // Sender address, @domain or domain (matches subdomains). Any may match.
  from?: Array<string>;
  has_attachment?: boolean;
  // Subject or body contains all of these.
  has_words?: Array<string>;
  // Subject contains any of these.
  subject_contains?: Array<string>;
  // Recipient (to/cc) address, @domain or domain. Any may match.
  to?: Array<string>;
};
};
  color?: string | null;
  description?: string | null;
  emoji?: string | null;
  idempotency_key: string;
  // Label identifier.
  label_id: string;
  name?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```

## banger_update_layout

Save a shared layout revision with optimistic concurrency. Supersedes pending layout review; published emails remain unchanged until grouped publication.

exec tool declaration:
```ts
declare const tools: { banger_update_layout(args: {
  expected_version: number;
  html: string;
  layout_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  source_locale?: string;
  source_messages?: { [key: string]: string; };
  translations?: { [key: string]: { [key: string]: string; }; };
}): Promise<CallToolResult>; };
```

## banger_update_managed_content

Save a new source revision using optimistic concurrency. Production remains on its published revision. Missing languages are prepared asynchronously.

exec tool declaration:
```ts
declare const tools: { banger_update_managed_content(args: {
  content_id: string;
  contract: {
  configured_locales?: Array<string>;
  fallback_locale?: string;
  layout_id?: string;
  localization_policy?: {
  // Optional bounded Journey hold for missing or review-pending translations. Wait requires max_wait_seconds and on_timeout. Urgent messages fall back immediately.
  journey_translation?: { max_wait_seconds?: number; mode: "fallback" | "wait"; on_timeout?: "fallback" | "discard"; };
  manual_review?: boolean;
};
  // Named sample variable sets for immediate preview and validation.
  samples?: { [key: string]: { [key: string]: unknown; }; };
  source: {
  body_html: string;
  layout?: string;
  preheader?: string;
  subject: string;
  // Map of variable names to typed definitions. Types: string, text, url, image_url, html, date, datetime, money ({amount_cents,currency}), number, boolean, object (properties), list (items). Each field accepts required (boolean), default, and an optional description of at most 2000 characters.
  variables: { [key: string]: { [key: string]: unknown; }; };
  variants?: { [key: string]: { body_html: string; body_text?: string; layout?: string; preheader?: string; subject: string; }; };
};
  source_locale?: string;
  // Optional supplied message catalogs keyed by locale. Supply source messages used by the template; other languages are prepared asynchronously without charge.
  translations?: { [key: string]: { [key: string]: string; }; };
};
  expected_version: number;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_update_product

Update the confirmed identity, context, or lifecycle of one product. Archiving a product keeps its email history.

exec tool declaration:
```ts
declare const tools: { banger_update_product(args: {
  // Brand kit values. Colors are #rrggbb; URLs are https. Empty string clears a value.
  brand?: { accent_color?: string; background_color?: string; body_font_family?: string; company_name?: string; footer_address?: string; heading_font_family?: string; logo_url?: string; muted_text_color?: string; primary_color?: string; surface_color?: string; text_color?: string; tone?: string; website_url?: string; };
  context?: { [key: string]: unknown; };
  description?: string;
  kind?: "product" | "store" | "brand" | "newsletter" | "company" | "other";
  name?: string;
  // Product identifier.
  product_id: string;
  status?: "active" | "archived";
  website_url?: string | null;
}): Promise<CallToolResult>; };
```

## banger_update_signup_form

Partially update a signup form: config merges into the saved settings; status active, paused (stops taking signups; widgets disappear) or archived. Changes reach live widgets within a minute. Requires a retry key; pass expected_version to avoid overwriting someone else's edit.

exec tool declaration:
```ts
declare const tools: { banger_update_signup_form(args: {
  config?: {
  art?: "arcs" | "blocks" | "horizon" | "confetti" | "frame" | "bands" | "dots";
  body?: string;
  button_label?: string;
  collect_name?: boolean;
  confirm_promise?: string;
  count_noun?: string;
  delay_seconds?: number;
  email_placeholder?: string;
  exit_intent?: boolean;
  eyebrow?: string;
  fields?: Array<{ key?: string; label: string; options?: Array<string>; placeholder?: string; required?: boolean; type?: "text" | "select" | "checkbox"; }>;
  fine_print?: string;
  frequency_days?: number;
  headline?: string;
  image?: "none" | "photo" | "art";
  image_url?: string;
  incentive?: string;
  layout?: "stacked" | "split";
  // The language the form is written in (en, pt-BR, es, fr, de…). Banger's own words on the form and its confirmation email follow it; empty (the default) follows each visitor's browser language.
  locale?: string;
  name_placeholder?: string;
  position?: "bottom" | "top" | "right" | "left";
  redirect_url?: string;
  scroll_percent?: number;
  show_count?: boolean;
  show_logo?: boolean;
  style?: "" | "brand" | "clarity" | "editorial" | "luxe" | "material" | "playful" | "bold" | "plain";
  success_body?: string;
  success_headline?: string;
  theme?: "light" | "dark" | "brand" | "auto";
};
  double_opt_in?: boolean;
  expected_version?: number;
  form_id: string;
  idempotency_key: string;
  kind?: "inline" | "popup" | "bar" | "slide_in" | "page";
  list_id?: string;
  list_name?: string;
  mailbox_id?: string;
  name?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  status?: "active" | "paused" | "archived";
}): Promise<CallToolResult>; };
```

## banger_update_template

Change a design's name, subject, HTML, text, fill-in content, slots, or archive it. Saving creates a new version; designs attached to a scheduled or sending Broadcast cannot change. Saving a draft sends nothing and needs no review; a Journey's first activation needs one human review of its sending setup.

exec tool declaration:
```ts
declare const tools: { banger_update_template(args: {
  body_html?: string;
  body_text?: string;
  // Fill-in values keyed by placeholder name, for example { headline: "Meet v2" }.
  content?: { [key: string]: string; };
  // What kind of message the design is, so Product compose and agents can find it.
  message_kind?: "custom" | "receipt" | "verification" | "magic_link" | "password_reset" | "login_code" | "invite" | "security" | "policy_update" | "welcome" | "tips" | "trial_ending" | "review_request" | "win_back" | "plan_change" | "announcement" | "newsletter" | "digest" | "event" | "story" | "promotion" | "changelog" | "survey" | "notice" | "cart_recovery" | "order_update" | "restock" | "payment_failed" | "usage_alert" | "booking" | "milestone" | "referral" | "waitlist" | "reengagement" | "appeal";
  name?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Declared fill-in fields. Undeclared placeholders still become editable text slots.
  slots?: Array<{ help?: string; key: string; label?: string; type?: "text" | "paragraph" | "url" | "image"; }>;
  status?: "active" | "archived";
  subject?: string;
  // Design (template) identifier.
  template_id: string;
}): Promise<CallToolResult>; };
```

## banger_update_triage_rule

Edit a Triage rule's name, When, or Then. A label's auto-set rule is changed on its label instead.

exec tool declaration:
```ts
declare const tools: { banger_update_triage_rule(args: {
  actions?: Array<{
  // Required for apply_label: a Banger label in the same mailbox.
  label_id?: string;
  type: "apply_label" | "archive" | "mark_read" | "star";
}>;
  description?: string | null;
  // Exact conditions checked in code (like Gmail filters). All fields given have to hold.
  exact_conditions?: {
  // Subject and body contain none of these.
  excludes_words?: Array<string>;
  // Sender address, @domain or domain (matches subdomains). Any may match.
  from?: Array<string>;
  has_attachment?: boolean;
  // Subject or body contains all of these.
  has_words?: Array<string>;
  // Subject contains any of these.
  subject_contains?: Array<string>;
  // Recipient (to/cc) address, @domain or domain. Any may match.
  to?: Array<string>;
};
  // Matches threads that already carry all of these labels.
  has_label_ids?: Array<string>;
  idempotency_key: string;
  name?: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Triage rule identifier.
  rule_id: string;
}): Promise<CallToolResult>; };
```

## banger_upload_email_asset

Upload a PNG, JPEG, GIF, or WebP image up to 2 MiB from base64 and return an immutable public email URL.

exec tool declaration:
```ts
declare const tools: { banger_upload_email_asset(args: {
  base64: string;
  filename: string;
  mime_type: "image/png" | "image/jpeg" | "image/gif" | "image/webp";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
}): Promise<CallToolResult>; };
```

## banger_upload_email_image

Store an image in Banger so a design does not depend on someone else's server: url (a public https link straight to the image file; Banger downloads it once) or base64 with mime_type. PNG, JPEG, GIF or WebP, at most 2 MB. Returns public_url for a design's image slot (the matching alt slot describes the image). Nothing is sent.

exec tool declaration:
```ts
declare const tools: { banger_upload_email_image(args: {
  // Image bytes as base64, when the person shared the file itself.
  base64?: string;
  filename?: string;
  // Required with base64.
  mime_type?: "image/png" | "image/jpeg" | "image/gif" | "image/webp";
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
  // Public https URL of the image file.
  url?: string;
}): Promise<CallToolResult>; };
```

## banger_upload_feedback_attachment

Upload a screenshot or video up to 2 MiB from base64 into private Linear storage. Returns attachment_id for the attachment_ids of a bug report, feedback, or feature suggestion. Files up to 25 MiB use the prepare, signed-URL PUT, and complete upload flow instead.

exec tool declaration:
```ts
declare const tools: { banger_upload_feedback_attachment(args: {
  // Generate one UUID per file and reuse it on retry.
  attachment_id: string;
  base64: string;
  filename: string;
  mime_type: "image/png" | "image/jpeg" | "image/gif" | "image/webp" | "video/mp4" | "video/webm" | "video/quicktime";
}): Promise<CallToolResult>; };
```

## banger_upsert_contact

Add or update one contact in the selected product. Subscribing requires consent_confirmed=true on every call. Prior consent/source evidence and attributes are preserved; suppressed, bounced, or complained contacts cannot be resubscribed here. A stable idempotency key makes retries safe. Returns canonical contact read-back.

exec tool declaration:
```ts
declare const tools: { banger_upsert_contact(args: {
  attributes?: { [key: string]: unknown; };
  consent_confirmed?: boolean;
  consent_evidence?: { observed_at?: string; reference?: string; source?: string; statement?: string; };
  display_name?: string;
  email: string;
  idempotency_key: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  status: "subscribed" | "unsubscribed" | "bounced" | "complained";
}): Promise<CallToolResult>; };
```

## banger_validate_contact_import

Validate a proposed bulk contact import and report row errors and duplicates. Read-only; creates no contacts and queues no import. Subscribed rows require explicit consent confirmation.

exec tool declaration:
```ts
declare const tools: { banger_validate_contact_import(args: {
  consent_confirmed?: boolean;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id: string;
  rows: Array<{ attributes?: { [key: string]: unknown; }; consent_evidence?: { observed_at?: string; reference?: string; source?: string; statement?: string; }; display_name?: string; email: string; status: "subscribed" | "unsubscribed" | "bounced" | "complained"; }>;
}): Promise<CallToolResult>; };
```

## banger_verify_native_sending_domain

Recheck Banger and public DNS for a domain whose required records have been saved, and return Banger's statuses. Pending normally means propagation, not failure; the saved checkpoint can be verified again later.

exec tool declaration:
```ts
declare const tools: { banger_verify_native_sending_domain(args: {
  // Banger-native sending domain identifier.
  domain_id: string;
  // The product this call acts on, from the workspace's product list. Required for writes when the workspace has multiple active products.
  product_id?: string;
}): Promise<CallToolResult>; };
```


