Sequenzy email marketing MCP server: manage subscribers, campaigns, sequences, templates, and delivery stats.
Keys with access to multiple companies need a target company: get_account lists them, select_company chooses one, or companyId can be passed per call.
This connector carries the everyday email marketing tools. Some tool descriptions mention tools that are not in this list (A/B tests, sequence graph editing, integrations, landing pages and more); those are on the full Sequenzy MCP server at https://api.sequenzy.com/v1/mcp or in the Sequenzy dashboard, so tell the user where to do that instead of guessing another tool.
Discoverability
0/6 passed0 of 6 passed0/100
Client listings and public setup information.
mcp.json or server-card.json
Either mcp.json or an MCP Server Card declaring this endpoint passes.
No matching mcp.json manifest or MCP Server Card was found at the checked URLs.
How to fix: For ChatGPT submission, set one exact HTTPS origin such as "https://app.example.com" on every view via _meta.ui.domain (or openai/widgetDomain). Paths are not valid and all views in one app must share the origin.
How to fix: Use a ui:// URI and text/html;profile=mcp-app. For mcp-use v1, use widgetMetadata.metadata.widgetDescription; for v2, use the bound tool's view.description. The current description check reads _meta.ui.widgetDescription or _meta["openai/widgetDescription"] on resource contents or linked tools, not resource.description. Consequently, v2 view.description alone may leave this warning: report the checker compatibility gap instead of adding unsupported v1 fields or claiming the warning is fixed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Get your own Sequenzy account information (not your customers' B2B accounts; use list_accounts for those) including available companies, the current API key's permission scopes, and the API Keys management URL. Useful after a missing-scope error to inspect access and find the replacement-key settings. When the key has access to multiple companies, other tools need a target company: either one selected with select_company or a companyId passed in each call.
The response shows 'companies' (all available) and 'selectedCompanyId' (currently active). Subsequent operations use the selected company unless a companyId override is passed.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_account",
"description": "Get your own Sequenzy account information (not your customers' B2B accounts; use list_accounts for those) including available companies, the current API key's permission scopes, and the API Keys management URL. Useful after a missing-scope error to inspect access and find the replacement-key settings. When the key has access to multiple companies, other tools need a target company: either one selected with select_company or a companyId passed in each call.\n\nThe response shows 'companies' (all available) and 'selectedCompanyId' (currently active). Subsequent operations use the selected company unless a companyId override is passed.",
"inputSchema": {
"type": "object",
"properties": {}
},
"annotations": {
"title": "Get Account",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Select which company to operate on (for user-scoped API keys with access to multiple companies). Use get_account to see available companies. After selecting, all subsequent operations will use this company unless you pass a companyId override.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
companyId
The company ID to select (from get_account's companies list)
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "select_company",
"description": "Select which company to operate on (for user-scoped API keys with access to multiple companies). Use get_account to see available companies. After selecting, all subsequent operations will use this company unless you pass a companyId override.",
"inputSchema": {
"type": "object",
"required": [
"companyId"
],
"properties": {
"companyId": {
"type": "string",
"description": "The company ID to select (from get_account's companies list)"
}
}
},
"annotations": {
"title": "Select Company",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description91/100
Generate Sequenzy dashboard URLs for known resource IDs. Use this when the user asks where to review or edit a generated sequence, campaign, template, company settings, or subscription. The response always includes the canonical owner-facing subscription URL when a company is resolved. For compatibility, settingsTab billing or subscription also resolves to that Account page rather than a nonexistent Settings tab. If companyId is omitted, the selected/current company is used when available.
The description explains the capability, when to use it, and what to expect.
Inputs66/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If omitted, uses the selected/current company when available.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
campaignId
Campaign ID for the campaign editor URL.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
landingPageId
Landing page ID for the landing page editor URL.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sequenceId
Sequence ID for the sequence editor URL.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
templateId
Template/email ID for the email editor URL.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
emailId
Email ID for the email editor URL.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
transactionalId
Transactional email ID.
Explain the meaning of this value, not just its name.
emailSendId
Email send ID for the sent email detail URL.
Clear enough to supply this argument.
domainId
Sending domain ID.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
status
Status for campaign/sequence list URLs.
Explain the meaning of this value, not just its name.
settingsTab
Settings tab slug, e.g. integrations, domain, tracking, api-keys, team. The billing and subscription aliases return the canonical Account -> Subscription page.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_app_urls",
"description": "Generate Sequenzy dashboard URLs for known resource IDs. Use this when the user asks where to review or edit a generated sequence, campaign, template, company settings, or subscription. The response always includes the canonical owner-facing subscription URL when a company is resolved. For compatibility, settingsTab billing or subscription also resolves to that Account page rather than a nonexistent Settings tab. If companyId is omitted, the selected/current company is used when available.",
"inputSchema": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Status for campaign/sequence list URLs."
},
"emailId": {
"type": "string",
"description": "Email ID for the email editor URL."
},
"domainId": {
"type": "string",
"description": "Sending domain ID."
},
"companyId": {
"type": "string",
"description": "Company ID. If omitted, uses the selected/current company when available."
},
"campaignId": {
"type": "string",
"description": "Campaign ID for the campaign editor URL."
},
"sequenceId": {
"type": "string",
"description": "Sequence ID for the sequence editor URL."
},
"templateId": {
"type": "string",
"description": "Template/email ID for the email editor URL."
},
"emailSendId": {
"type": "string",
"description": "Email send ID for the sent email detail URL."
},
"settingsTab": {
"type": "string",
"description": "Settings tab slug, e.g. integrations, domain, tracking, api-keys, team. The billing and subscription aliases return the canonical Account -> Subscription page."
},
"landingPageId": {
"type": "string",
"description": "Landing page ID for the landing page editor URL."
},
"transactionalId": {
"type": "string",
"description": "Transactional email ID."
}
}
},
"annotations": {
"title": "Get App URLs",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Get company details, processing status, product info, brand colors, AI writing context, the default AI email style (emailStylePreference: visual, plain, or null when not chosen), the company category (websiteType: saas, content, ecommerce, offline, mobile_app, other or null) with websiteTypeSource (user when chosen, detected when set from the website), header and footer (emailPreset) and the footer style for new AI-designed emails (footerStyle: auto, classic, mono, band or editorial), the auto-added footer's resolved colors and copy (footerTheme; change it with update_company footerTheme), reply-tracking settings, effective email localization settings, and the read-only emailBranding entitlement. emailBranding says whether "Sent with Sequenzy" is visible, whether the owner subscription removes it, why, the current tier/status, the required upgrade or renewal action, and the canonical subscriptionUrl. Branding is injected at render/send time rather than stored in footer blocks, so a paid entitlement removes it from future sends by existing live sequences without editing their emails. Also returns darkModeLogoStatus (pending, outlined, not_needed or custom) and darkModeLogoUrl, the logo emails use so dark transparent logos stay visible in dark-mode inboxes; set your own with update_company darkModeLogoUrl. Also returns defaultSubscriberListIds - the workspace default lists new contacts join when nothing targets them explicitly. A JSON null means every current and future list, not an empty selection; [] means no list at all; an array means exactly those lists. Change it with update_company. Read it before connecting an integration whose provider has no per-integration list targeting (Dodo Payments, PostHog, Polar, Paddle, and similar), because its live contacts and payment-provider backfills land there. PostHog history imports are different: contacts created by that import have no list memberships. Send Time Optimization is not a company or sequence setting. It is campaign-only: audit with list_campaigns or get_campaign (sendTimeOptimization, sendTimeWindowHours, default 12h window). Change a draft with update_campaign, or apply it when calling schedule_campaign. Sequences use sendingWindow (allowed local hours/days), which is a shared gate, not per-subscriber predicted send times.
The description explains the capability, when to use it, and what to expect.
Inputs50/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
companyId
The company ID to check
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_company",
"description": "Get company details, processing status, product info, brand colors, AI writing context, the default AI email style (emailStylePreference: visual, plain, or null when not chosen), the company category (websiteType: saas, content, ecommerce, offline, mobile_app, other or null) with websiteTypeSource (user when chosen, detected when set from the website), header and footer (emailPreset) and the footer style for new AI-designed emails (footerStyle: auto, classic, mono, band or editorial), the auto-added footer's resolved colors and copy (footerTheme; change it with update_company footerTheme), reply-tracking settings, effective email localization settings, and the read-only emailBranding entitlement. emailBranding says whether \"Sent with Sequenzy\" is visible, whether the owner subscription removes it, why, the current tier/status, the required upgrade or renewal action, and the canonical subscriptionUrl. Branding is injected at render/send time rather than stored in footer blocks, so a paid entitlement removes it from future sends by existing live sequences without editing their emails. Also returns darkModeLogoStatus (pending, outlined, not_needed or custom) and darkModeLogoUrl, the logo emails use so dark transparent logos stay visible in dark-mode inboxes; set your own with update_company darkModeLogoUrl. Also returns defaultSubscriberListIds - the workspace default lists new contacts join when nothing targets them explicitly. A JSON null means every current and future list, not an empty selection; [] means no list at all; an array means exactly those lists. Change it with update_company. Read it before connecting an integration whose provider has no per-integration list targeting (Dodo Payments, PostHog, Polar, Paddle, and similar), because its live contacts and payment-provider backfills land there. PostHog history imports are different: contacts created by that import have no list memberships. Send Time Optimization is not a company or sequence setting. It is campaign-only: audit with list_campaigns or get_campaign (sendTimeOptimization, sendTimeWindowHours, default 12h window). Change a draft with update_campaign, or apply it when calling schedule_campaign. Sequences use sendingWindow (allowed local hours/days), which is a shared gate, not per-subscriber predicted send times.",
"inputSchema": {
"type": "object",
"required": [
"companyId"
],
"properties": {
"companyId": {
"type": "string",
"description": "The company ID to check"
}
}
},
"annotations": {
"title": "Get Company",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
List sender (From) profiles and reply-to profiles for the company, including which are the account defaults and whether each sender address has verified DNS plus a ready home transport. Use this to audit sending identity before scheduling, or to pick a valid senderProfileId/replyProfileId for create_campaign or update_campaign.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_sender_profiles",
"description": "List sender (From) profiles and reply-to profiles for the company, including which are the account defaults and whether each sender address has verified DNS plus a ready home transport. Use this to audit sending identity before scheduling, or to pick a valid senderProfileId/replyProfileId for create_campaign or update_campaign.",
"inputSchema": {
"type": "object",
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "List Sender Profiles",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Rename one sender (From) or reply-to profile in place, without changing which profile is the account default. Use this to standardize a display name across the several identities a mailbox may carry, e.g. renaming 'Viraj from SnapCount' to 'SnapCount'. Get IDs from list_sender_profiles. Only the display name changes: the address, its sending domain, and the account-wide default From/Reply-To selection are untouched, and existing campaigns and sequences pinned to this profile pick up the new name. To change which profile is the default instead, use update_company with senderProfileId/replyProfileId. A company cannot have two sender identities with the same name on one address, so a colliding rename is rejected and reports the ID already using that name. Requires the companies:manage scope.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
profileId
ID of the profile to rename, from list_sender_profiles. Sender profile IDs come from senderProfiles, reply-to IDs from replyProfiles.
Clear enough to supply this argument.
name
New display name, e.g. 'SnapCount'. Trimmed; must be non-empty and 255 characters or fewer.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
type
Which list profileId came from. Defaults to sender. Pass reply to rename a reply-to profile.
Clear enough to supply this argument.
companyId
Company ID. If not provided, uses the currently selected company.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_sender_profile",
"description": "Rename one sender (From) or reply-to profile in place, without changing which profile is the account default. Use this to standardize a display name across the several identities a mailbox may carry, e.g. renaming 'Viraj from SnapCount' to 'SnapCount'. Get IDs from list_sender_profiles. Only the display name changes: the address, its sending domain, and the account-wide default From/Reply-To selection are untouched, and existing campaigns and sequences pinned to this profile pick up the new name. To change which profile is the default instead, use update_company with senderProfileId/replyProfileId. A company cannot have two sender identities with the same name on one address, so a colliding rename is rejected and reports the ID already using that name. Requires the companies:manage scope.",
"inputSchema": {
"type": "object",
"required": [
"profileId",
"name"
],
"properties": {
"name": {
"type": "string",
"description": "New display name, e.g. 'SnapCount'. Trimmed; must be non-empty and 255 characters or fewer."
},
"type": {
"enum": [
"sender",
"reply"
],
"type": "string",
"description": "Which list profileId came from. Defaults to sender. Pass reply to rename a reply-to profile."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"profileId": {
"type": "string",
"description": "ID of the profile to rename, from list_sender_profiles. Sender profile IDs come from senderProfiles, reply-to IDs from replyProfiles."
}
}
},
"annotations": {
"title": "Update Sender Profile",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Check whether company-level email sending is active, paused, or suspended, and what it takes to restore it. Relevant whenever a send, test send, or sequence step fails for a reason that is not a validation error, and whenever the account reports a bounce or complaint rate problem.
Returns the pause reason and reason kind, when it was paused, the automated sender-health review state, whether the one-click resume is currently available (and if not, which gate is blocking it), the enforcement counts and thresholds for permanent bounces, temporary bounces, and complaints, and ordered remediation steps.
There is no rolling window and no expiry. Enforcement uses all-time totals counted from a reset watermark, so a paused rate does NOT decay over time. Waiting does not restore sending. The rate only changes as real (non-test) sends accumulate or when a resume moves the watermark. `metricsWindow` contains the exact watermark timestamps.
Requires the account:read scope, so a read-only key can diagnose a blocked account. resume_sending restores sending once the underlying problem is fixed.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_sending_status",
"description": "Check whether company-level email sending is active, paused, or suspended, and what it takes to restore it. Relevant whenever a send, test send, or sequence step fails for a reason that is not a validation error, and whenever the account reports a bounce or complaint rate problem.\n\nReturns the pause reason and reason kind, when it was paused, the automated sender-health review state, whether the one-click resume is currently available (and if not, which gate is blocking it), the enforcement counts and thresholds for permanent bounces, temporary bounces, and complaints, and ordered remediation steps.\n\nThere is no rolling window and no expiry. Enforcement uses all-time totals counted from a reset watermark, so a paused rate does NOT decay over time. Waiting does not restore sending. The rate only changes as real (non-test) sends accumulate or when a resume moves the watermark. `metricsWindow` contains the exact watermark timestamps.\n\nRequires the account:read scope, so a read-only key can diagnose a blocked account. resume_sending restores sending once the underlying problem is fixed.",
"inputSchema": {
"type": "object",
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "Get Sending Status",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Remix a public Sequenzy email gallery email into a new email template for this company. The new email keeps the example's exact layout and design; AI rewrites every piece of text for the company and its logo, brand color and links are swapped in. The example brand is never named and none of its copy, offers or claims are reused. Saved as an HTML template. Requires templates:write. Takes 5-20 seconds. Creates no template if generation fails (a company's first AI generation still saves its inferred email design direction); each successful call creates another template. Accepts a gallery email URL (https://sequenzy.com/email-examples/brands/{brand}/emails/{email}, or for an email in a sequence the sequence page URL ending in #email-{email}) or brand plus email slugs. For a whole sequence use create_sequence_from_example.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
url
Email gallery page URL. Provide either url, or brand plus the example slug; not both.
Clear enough to supply this argument.
brand
Gallery brand slug from the URL (/email-examples/brands/{brand}/...). Use with the example slug instead of url.
Clear enough to supply this argument.
brief
Optional direction, up to 1000 characters, such as an offer or feature to highlight. Takes priority over the example.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Optional name, up to 200 characters, for what is created.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
email
Gallery email slug from the URL (/emails/{email}). Use with brand instead of url.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_template_from_example",
"description": "Remix a public Sequenzy email gallery email into a new email template for this company. The new email keeps the example's exact layout and design; AI rewrites every piece of text for the company and its logo, brand color and links are swapped in. The example brand is never named and none of its copy, offers or claims are reused. Saved as an HTML template. Requires templates:write. Takes 5-20 seconds. Creates no template if generation fails (a company's first AI generation still saves its inferred email design direction); each successful call creates another template. Accepts a gallery email URL (https://sequenzy.com/email-examples/brands/{brand}/emails/{email}, or for an email in a sequence the sequence page URL ending in #email-{email}) or brand plus email slugs. For a whole sequence use create_sequence_from_example.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Email gallery page URL. Provide either url, or brand plus the example slug; not both."
},
"name": {
"type": "string",
"description": "Optional name, up to 200 characters, for what is created."
},
"brand": {
"type": "string",
"description": "Gallery brand slug from the URL (/email-examples/brands/{brand}/...). Use with the example slug instead of url."
},
"brief": {
"type": "string",
"description": "Optional direction, up to 1000 characters, such as an offer or feature to highlight. Takes priority over the example."
},
"email": {
"type": "string",
"description": "Gallery email slug from the URL (/emails/{email}). Use with brand instead of url."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "Create Template From Example",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Clone a public Sequenzy email gallery sequence into a draft sequence for this company, with the example's trigger family (signup, abandoned cart, order placed, or inactive tag) and send timing, up to 12 emails (the first 12 unless stepNumbers picks which; each kept email keeps its original timing from the trigger). AI then writes every email in the company's brand in the background (usually 30-60 seconds); poll get_sequence until enrichmentStatus is complete. If this tool returns enrichmentStatus not_queued with a warning, the draft exists but writing did not start: open it in the dashboard and do not call this tool again. The sequence stays a draft and sends nothing until enabled. Requires sequences:write. Each call creates another sequence. Accepts a gallery sequence URL (https://sequenzy.com/email-examples/brands/{brand}/sequences/{sequence}) or brand plus sequence slugs.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
url
Email gallery page URL. Provide either url, or brand plus the example slug; not both.
Clear enough to supply this argument.
brand
Gallery brand slug from the URL (/email-examples/brands/{brand}/...). Use with the example slug instead of url.
Clear enough to supply this argument.
brief
Optional direction, up to 1000 characters, such as an offer or feature to highlight. Takes priority over the example.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Optional name, up to 200 characters, for what is created.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sequence
Gallery sequence slug from the URL (/sequences/{sequence}). Use with brand instead of url.
Clear enough to supply this argument.
stepNumbers
Optional: which of the example's emails to clone, as 1-based positions in the gallery sequence (Email 1, Email 2, ...), 1 to 12 distinct positions. Defaults to the first 12. These are positions in the example, not the stepNumber of the created sequence's steps.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
emailStyle
Generated email style. Defaults to the company's email style preference.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_sequence_from_example",
"description": "Clone a public Sequenzy email gallery sequence into a draft sequence for this company, with the example's trigger family (signup, abandoned cart, order placed, or inactive tag) and send timing, up to 12 emails (the first 12 unless stepNumbers picks which; each kept email keeps its original timing from the trigger). AI then writes every email in the company's brand in the background (usually 30-60 seconds); poll get_sequence until enrichmentStatus is complete. If this tool returns enrichmentStatus not_queued with a warning, the draft exists but writing did not start: open it in the dashboard and do not call this tool again. The sequence stays a draft and sends nothing until enabled. Requires sequences:write. Each call creates another sequence. Accepts a gallery sequence URL (https://sequenzy.com/email-examples/brands/{brand}/sequences/{sequence}) or brand plus sequence slugs.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Email gallery page URL. Provide either url, or brand plus the example slug; not both."
},
"name": {
"type": "string",
"description": "Optional name, up to 200 characters, for what is created."
},
"brand": {
"type": "string",
"description": "Gallery brand slug from the URL (/email-examples/brands/{brand}/...). Use with the example slug instead of url."
},
"brief": {
"type": "string",
"description": "Optional direction, up to 1000 characters, such as an offer or feature to highlight. Takes priority over the example."
},
"sequence": {
"type": "string",
"description": "Gallery sequence slug from the URL (/sequences/{sequence}). Use with brand instead of url."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"emailStyle": {
"enum": [
"visual",
"plain"
],
"type": "string",
"description": "Generated email style. Defaults to the company's email style preference."
},
"stepNumbers": {
"type": "array",
"items": {
"type": "integer",
"minimum": 1
},
"description": "Optional: which of the example's emails to clone, as 1-based positions in the gallery sequence (Email 1, Email 2, ...), 1 to 12 distinct positions. Defaults to the first 12. These are positions in the example, not the stepNumber of the created sequence's steps."
}
}
},
"annotations": {
"title": "Create Sequence From Example",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description86/100
Add one subscriber. Status is only applied when creating a new contact; use update_subscriber to change an existing contact's status. The subscribers:write scope covers listIds in this call. Matching sequences enroll by default (REST enrollInSequences), including tag_added when tags are set in this call, without requiring a list; pass enrollInSequences false to skip, and automations:trigger is required for enrollment. For multiple contacts or CRM records, use create_subscriber_import instead of looping this tool. For an email-only batch going into one list, add_subscribers_to_list is also available.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID to add subscriber to. If not provided, uses the currently selected company.
Clear enough to supply this argument.
email
Subscriber email address. Optional when phone is provided - a contact created with only a phone becomes a phone-only (SMS) contact.
Clear enough to supply this argument.
externalId
Customer-owned subscriber ID. Provide this with email when creating, or instead of email for an existing subscriber.
Clear enough to supply this argument.
phone
Phone number in E.164 or national format, stored as a native profile field. With no email, creates or matches a phone-only (SMS) contact.
Clear enough to supply this argument.
phoneCountry
ISO 3166-1 alpha-2 country used to read a national-format phone number, such as IT or US. Defaults to US. Only send it together with phone; the stored country always comes from the parsed number.
Clear enough to supply this argument.
smsConsent
Set true only when express written SMS marketing consent was verified for this phone number. Never inferred from phone presence.
Clear enough to supply this argument.
firstName
Subscriber first name, stored as a native profile field.
Clear enough to supply this argument.
lastName
Subscriber last name, stored as a native profile field.
Clear enough to supply this argument.
timezone
IANA timezone identifier (e.g. America/New_York), stored as a native profile field. Enables recipient-local campaign delivery for this contact.
Clear enough to supply this argument.
attributes
Custom attributes (plan, company, etc.). Same field as REST customAttributes; provide one or the other. Use firstName/lastName for names instead of attributes. Values keep their JSON types, so send zip codes and IDs with leading zeros as strings; call list_subscriber_attributes to reuse existing names and types.
Clear enough to supply this argument.
customAttributes
REST name for attributes. Same custom-attribute map; provide attributes or customAttributes, not both.
Clear enough to supply this argument.
tags
Tags to apply to the subscriber
Clear enough to supply this argument.
listIds
List IDs to add subscriber to, covered by subscribers:write. Omit to let a contact this call creates follow the workspace default lists; an existing contact then keeps the memberships they already have. Pass [] to join no list.
Clear enough to supply this argument.
status
Initial subscriber status: active, unsubscribed, or bounced. Defaults to active and does not change an existing contact; use update_subscriber for existing contacts.
Clear enough to supply this argument.
optInMode
Consent mode: confirmed creates active immediately when consent is verified, double_opt_in sends a confirmation email before activation, and default obeys company double opt-in settings.
Clear enough to supply this argument.
enrollInSequences
Whether matching sequences may enroll this contact, including tag_added flows when tags are set in the same call. Same field as REST POST /api/v1/subscribers enrollInSequences. Defaults to true unless createdAt is supplied. Requires automations:trigger. Pass false to create and tag without enrollment. List membership is not required.
Clear enough to supply this argument.
createdAt
Original signup date (ISO 8601) when importing a contact from another platform. Preserves their real history so date-relative segments like 'added in the last 30 days' are correct immediately instead of treating every imported contact as brand new. An existing contact's date only ever moves earlier. Supplying this defaults sequence enrollment to false. New-subscriber account notifications remain eligible when the signup date is at most one hour old; older dates do not notify on creation. Double opt-in confirmation can notify even for imported contacts. Your notification preferences, double opt-in and the daily cap still apply.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "add_subscriber",
"description": "Add one subscriber. Status is only applied when creating a new contact; use update_subscriber to change an existing contact's status. The subscribers:write scope covers listIds in this call. Matching sequences enroll by default (REST enrollInSequences), including tag_added when tags are set in this call, without requiring a list; pass enrollInSequences false to skip, and automations:trigger is required for enrollment. For multiple contacts or CRM records, use create_subscriber_import instead of looping this tool. For an email-only batch going into one list, add_subscribers_to_list is also available.",
"inputSchema": {
"type": "object",
"required": [],
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags to apply to the subscriber"
},
"email": {
"type": "string",
"description": "Subscriber email address. Optional when phone is provided - a contact created with only a phone becomes a phone-only (SMS) contact."
},
"phone": {
"type": "string",
"description": "Phone number in E.164 or national format, stored as a native profile field. With no email, creates or matches a phone-only (SMS) contact."
},
"status": {
"enum": [
"active",
"unsubscribed",
"bounced"
],
"type": "string",
"description": "Initial subscriber status: active, unsubscribed, or bounced. Defaults to active and does not change an existing contact; use update_subscriber for existing contacts."
},
"listIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "List IDs to add subscriber to, covered by subscribers:write. Omit to let a contact this call creates follow the workspace default lists; an existing contact then keeps the memberships they already have. Pass [] to join no list."
},
"lastName": {
"type": "string",
"description": "Subscriber last name, stored as a native profile field."
},
"timezone": {
"type": "string",
"description": "IANA timezone identifier (e.g. America/New_York), stored as a native profile field. Enables recipient-local campaign delivery for this contact."
},
"companyId": {
"type": "string",
"description": "Company ID to add subscriber to. If not provided, uses the currently selected company."
},
"createdAt": {
"type": "string",
"description": "Original signup date (ISO 8601) when importing a contact from another platform. Preserves their real history so date-relative segments like 'added in the last 30 days' are correct immediately instead of treating every imported contact as brand new. An existing contact's date only ever moves earlier. Supplying this defaults sequence enrollment to false. New-subscriber account notifications remain eligible when the signup date is at most one hour old; older dates do not notify on creation. Double opt-in confirmation can notify even for imported contacts. Your notification preferences, double opt-in and the daily cap still apply."
},
"firstName": {
"type": "string",
"description": "Subscriber first name, stored as a native profile field."
},
"optInMode": {
"enum": [
"default",
"confirmed",
"double_opt_in"
],
"type": "string",
"description": "Consent mode: confirmed creates active immediately when consent is verified, double_opt_in sends a confirmation email before activation, and default obeys company double opt-in settings."
},
"attributes": {
"type": "object",
"description": "Custom attributes (plan, company, etc.). Same field as REST customAttributes; provide one or the other. Use firstName/lastName for names instead of attributes. Values keep their JSON types, so send zip codes and IDs with leading zeros as strings; call list_subscriber_attributes to reuse existing names and types.",
"additionalProperties": true
},
"externalId": {
"type": "string",
"description": "Customer-owned subscriber ID. Provide this with email when creating, or instead of email for an existing subscriber."
},
"smsConsent": {
"type": "boolean",
"description": "Set true only when express written SMS marketing consent was verified for this phone number. Never inferred from phone presence."
},
"phoneCountry": {
"type": "string",
"description": "ISO 3166-1 alpha-2 country used to read a national-format phone number, such as IT or US. Defaults to US. Only send it together with phone; the stored country always comes from the parsed number."
},
"customAttributes": {
"type": "object",
"description": "REST name for attributes. Same custom-attribute map; provide attributes or customAttributes, not both.",
"additionalProperties": true
},
"enrollInSequences": {
"type": "boolean",
"description": "Whether matching sequences may enroll this contact, including tag_added flows when tags are set in the same call. Same field as REST POST /api/v1/subscribers enrollInSequences. Defaults to true unless createdAt is supplied. Requires automations:trigger. Pass false to create and tag without enrollment. List membership is not required."
}
}
},
"annotations": {
"title": "Add Subscriber",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Queue one CRM-grade subscriber import with up to 5,000 full contact records. Supports names, external IDs, phones, statuses, tags, lists, and custom attributes. Prefer this over repeated add_subscriber calls. Returns an import ID for get_subscriber_import. Use optInMode='confirmed' only when the contacts already gave verified email consent. Rows are imported only after a list check, usually under a minute. When the list has too many addresses that don't exist or look risky (temporary inboxes, or mostly shared addresses like info@), nothing is imported and the finished import has listQuality (status 'needs_cleaning', with issues): relay listQuality.message and suggest cleaning the list (listQuality.cleaningUrl) and importing the cleaned list.
The description explains the capability, when to use it, and what to expect.
Inputs82/100
16 of 19 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
subscribers › items › email
Subscriber email address. Optional when the record has a phone - such rows import as phone-only (SMS) contacts.
Clear enough to supply this argument.
subscribers › items › externalId
Customer-owned subscriber ID
Clear enough to supply this argument.
subscribers › items › firstName
Not provided
Missing description. Explain what this value means and how to supply it.
subscribers › items › lastName
Not provided
Missing description. Explain what this value means and how to supply it.
subscribers › items › timezone
IANA timezone identifier (e.g. America/New_York) used for recipient-local campaign delivery. Rows with an invalid value import without it.
Clear enough to supply this argument.
subscribers › items › phone
Phone number. National-format values use the batch defaultPhoneCountry.
Clear enough to supply this argument.
subscribers › items › status
Email status from the source platform; defaults to active. Unsubscribed and bounced records never enroll in sequences or receive a double opt-in email. An active record never resubscribes an unsubscribed or bounced contact. With merge or overwrite, unsubscribed or bounced applies to an existing active contact. Send active for records the source marks not confirmed or pending (as the dashboard and CLI do), and bounced for cleaned addresses.
Clear enough to supply this argument.
subscribers › items › tags
Not provided
Missing description. Explain what this value means and how to supply it.
subscribers › items › customAttributes
CRM fields and other custom attributes. Values may be strings, numbers, booleans, arrays of those scalar values, or null.
Clear enough to supply this argument.
subscribers › items › createdAt
Original signup date (ISO 8601) from the source platform. Set this when migrating so date-relative segments are correct immediately rather than treating every imported contact as having joined today. An existing contact's date only ever moves earlier.
Clear enough to supply this argument.
duplicateStrategy
How existing contacts are handled. Defaults to skip. Merge fills missing fields; overwrite replaces public fields without reactivating unsubscribed contacts.
Clear enough to supply this argument.
fileName
Optional source label shown in import history, such as copper-export.csv.
Clear enough to supply this argument.
listIds
Lists to add every successfully imported active subscriber to. A nonempty array requires lists:write.
Clear enough to supply this argument.
enrollInSequences
Whether matching sequences may enroll imported contacts. Defaults to false and requires automations:trigger.
Clear enough to supply this argument.
defaultPhoneCountry
ISO 3166-1 alpha-2 country used for national-format phone numbers, such as SG or US.
Clear enough to supply this argument.
smsConsent
Set true only when express written SMS marketing consent was verified for every imported phone number.
Clear enough to supply this argument.
optInMode
Email consent mode. Default follows workspace settings and requires automations:trigger when any record is active or omits status. Confirmed creates active contacts immediately and must only be used for verified consent. Double_opt_in always requires automations:trigger.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
idempotencyKey
Caller-owned key (1-255 characters, not blank) that makes retrying this request safe. The key is scoped to the request content: resending the same request returns the already-queued import (deduplicated: true), while different content under the same key queues a new import. Use it whenever a timeout or retry loop could resend the same import. If two identical requests overlap, a transient 503 means to retry the same call shortly.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_subscriber_import",
"description": "Queue one CRM-grade subscriber import with up to 5,000 full contact records. Supports names, external IDs, phones, statuses, tags, lists, and custom attributes. Prefer this over repeated add_subscriber calls. Returns an import ID for get_subscriber_import. Use optInMode='confirmed' only when the contacts already gave verified email consent. Rows are imported only after a list check, usually under a minute. When the list has too many addresses that don't exist or look risky (temporary inboxes, or mostly shared addresses like info@), nothing is imported and the finished import has listQuality (status 'needs_cleaning', with issues): relay listQuality.message and suggest cleaning the list (listQuality.cleaningUrl) and importing the cleaned list.",
"inputSchema": {
"type": "object",
"required": [
"subscribers"
],
"properties": {
"listIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Lists to add every successfully imported active subscriber to. A nonempty array requires lists:write."
},
"fileName": {
"type": "string",
"description": "Optional source label shown in import history, such as copper-export.csv."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"optInMode": {
"enum": [
"default",
"confirmed",
"double_opt_in"
],
"type": "string",
"description": "Email consent mode. Default follows workspace settings and requires automations:trigger when any record is active or omits status. Confirmed creates active contacts immediately and must only be used for verified consent. Double_opt_in always requires automations:trigger."
},
"smsConsent": {
"type": "boolean",
"description": "Set true only when express written SMS marketing consent was verified for every imported phone number."
},
"subscribers": {
"type": "array",
"items": {
"type": "object",
"required": [],
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"email": {
"type": "string",
"description": "Subscriber email address. Optional when the record has a phone - such rows import as phone-only (SMS) contacts."
},
"phone": {
"type": "string",
"description": "Phone number. National-format values use the batch defaultPhoneCountry."
},
"status": {
"enum": [
"active",
"unsubscribed",
"bounced"
],
"type": "string",
"description": "Email status from the source platform; defaults to active. Unsubscribed and bounced records never enroll in sequences or receive a double opt-in email. An active record never resubscribes an unsubscribed or bounced contact. With merge or overwrite, unsubscribed or bounced applies to an existing active contact. Send active for records the source marks not confirmed or pending (as the dashboard and CLI do), and bounced for cleaned addresses."
},
"lastName": {
"type": "string"
},
"timezone": {
"type": "string",
"description": "IANA timezone identifier (e.g. America/New_York) used for recipient-local campaign delivery. Rows with an invalid value import without it."
},
"createdAt": {
"type": "string",
"description": "Original signup date (ISO 8601) from the source platform. Set this when migrating so date-relative segments are correct immediately rather than treating every imported contact as having joined today. An existing contact's date only ever moves earlier."
},
"firstName": {
"type": "string"
},
"externalId": {
"type": "string",
"description": "Customer-owned subscriber ID"
},
"customAttributes": {
"type": "object",
"description": "CRM fields and other custom attributes. Values may be strings, numbers, booleans, arrays of those scalar values, or null.",
"additionalProperties": true
}
},
"additionalProperties": false
},
"maxItems": 5000,
"minItems": 1,
"description": "Full subscriber records to import in one batch."
},
"idempotencyKey": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"description": "Caller-owned key (1-255 characters, not blank) that makes retrying this request safe. The key is scoped to the request content: resending the same request returns the already-queued import (deduplicated: true), while different content under the same key queues a new import. Use it whenever a timeout or retry loop could resend the same import. If two identical requests overlap, a transient 503 means to retry the same call shortly."
},
"duplicateStrategy": {
"enum": [
"skip",
"merge",
"overwrite"
],
"type": "string",
"description": "How existing contacts are handled. Defaults to skip. Merge fills missing fields; overwrite replaces public fields without reactivating unsubscribed contacts."
},
"enrollInSequences": {
"type": "boolean",
"description": "Whether matching sequences may enroll imported contacts. Defaults to false and requires automations:trigger."
},
"defaultPhoneCountry": {
"type": "string",
"description": "ISO 3166-1 alpha-2 country used for national-format phone numbers, such as SG or US."
}
}
},
"annotations": {
"title": "Create Subscriber Import",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Get progress, counts, skipped reasons, and failure summaries for a queued subscriber import. Every excluded row is explained: skippedReasons sums to skippedCount and failedReasons sums to failedCount, so a finished import can be reconciled without inspecting individual contacts. If the reason counts fall short of the totals, report it with the import ID rather than guessing what the missing rows were. listQuality is null unless the list needs cleaning; then nothing was imported (rows skipped as list_needs_cleaning) and you should relay its message and cleaningUrl. An import stays running until its list check finishes.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
importId
Import ID or batch ID returned by create_subscriber_import.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_subscriber_import",
"description": "Get progress, counts, skipped reasons, and failure summaries for a queued subscriber import. Every excluded row is explained: skippedReasons sums to skippedCount and failedReasons sums to failedCount, so a finished import can be reconciled without inspecting individual contacts. If the reason counts fall short of the totals, report it with the import ID rather than guessing what the missing rows were. listQuality is null unless the list needs cleaning; then nothing was imported (rows skipped as list_needs_cleaning) and you should relay its message and cleaningUrl. An import stays running until its list check finishes.",
"inputSchema": {
"type": "object",
"required": [
"importId"
],
"properties": {
"importId": {
"type": "string",
"description": "Import ID or batch ID returned by create_subscriber_import."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "Get Subscriber Import",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
Update an existing subscriber's profile, phone, status, attributes, or tags. Names and phones are native profile fields - set them here rather than as custom attributes. Setting status to unsubscribed suppresses the contact from all marketing, deactivates list memberships, and cancels active sequence enrollments while preserving the record and suppression history.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
email
Subscriber email address. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
externalId
Customer-owned subscriber ID. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
firstName
New first name, stored as a native profile field. Pass an empty string to clear it.
Clear enough to supply this argument.
lastName
New last name, stored as a native profile field. Pass an empty string to clear it.
Clear enough to supply this argument.
timezone
New IANA timezone identifier (e.g. America/New_York), stored as a native profile field. Pass an empty string to clear it. Enables recipient-local campaign delivery for this contact.
Clear enough to supply this argument.
phone
New phone number in E.164 or national format, stored as a native profile field. Pass an empty string to clear it, which is rejected for a phone-only (SMS) contact that has no email. Changing the number resets SMS consent unless smsConsent is sent in the same call.
Clear enough to supply this argument.
phoneCountry
ISO 3166-1 alpha-2 country used to read a national-format phone number, such as IT or US. Defaults to US. Only send it together with phone; the stored country always comes from the parsed number.
Clear enough to supply this argument.
smsConsent
Set true only when express written SMS marketing consent was verified for this phone number; false unsubscribes them from SMS. Omitting this leaves consent unchanged unless phone changes, which resets consent because it belonged to the old number. Consent is never inferred from phone presence.
Clear enough to supply this argument.
status
New global subscriber status. Use unsubscribed for compliance-grade suppression without deleting the record. Use bounced for an undeliverable address. Use complained when the contact reported spam: it records a company spam-complaint suppression, unsubscribes them and cancels their sequence enrollments, and the contact then reads as unsubscribed (the suppression shows in get_recipient_suppression). Use active only when the contact has valid consent to be resubscribed.
Clear enough to supply this argument.
attributes
Custom attributes to merge into the existing map. This is the legacy MCP spelling; provide attributes or customAttributes, not both. Use firstName/lastName for names instead of attributes. Values keep their JSON types; call list_subscriber_attributes to match existing names and types.
Clear enough to supply this argument.
customAttributes
REST spelling for custom attributes. Replaces the existing public custom-attribute map, matching REST PATCH semantics; provide attributes instead when you want to retain unspecified keys. Provide attributes or customAttributes, not both.
Clear enough to supply this argument.
addTags
Tags to add
Explain the meaning of this value, not just its name.
removeTags
Tags to remove
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_subscriber",
"description": "Update an existing subscriber's profile, phone, status, attributes, or tags. Names and phones are native profile fields - set them here rather than as custom attributes. Setting status to unsubscribed suppresses the contact from all marketing, deactivates list memberships, and cancels active sequence enrollments while preserving the record and suppression history.",
"inputSchema": {
"type": "object",
"required": [],
"properties": {
"email": {
"type": "string",
"description": "Subscriber email address. Provide email or externalId to identify the subscriber."
},
"phone": {
"type": "string",
"description": "New phone number in E.164 or national format, stored as a native profile field. Pass an empty string to clear it, which is rejected for a phone-only (SMS) contact that has no email. Changing the number resets SMS consent unless smsConsent is sent in the same call."
},
"status": {
"enum": [
"active",
"unsubscribed",
"bounced",
"complained"
],
"type": "string",
"description": "New global subscriber status. Use unsubscribed for compliance-grade suppression without deleting the record. Use bounced for an undeliverable address. Use complained when the contact reported spam: it records a company spam-complaint suppression, unsubscribes them and cancels their sequence enrollments, and the contact then reads as unsubscribed (the suppression shows in get_recipient_suppression). Use active only when the contact has valid consent to be resubscribed."
},
"addTags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags to add"
},
"lastName": {
"type": "string",
"description": "New last name, stored as a native profile field. Pass an empty string to clear it."
},
"timezone": {
"type": "string",
"description": "New IANA timezone identifier (e.g. America/New_York), stored as a native profile field. Pass an empty string to clear it. Enables recipient-local campaign delivery for this contact."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"firstName": {
"type": "string",
"description": "New first name, stored as a native profile field. Pass an empty string to clear it."
},
"attributes": {
"type": "object",
"description": "Custom attributes to merge into the existing map. This is the legacy MCP spelling; provide attributes or customAttributes, not both. Use firstName/lastName for names instead of attributes. Values keep their JSON types; call list_subscriber_attributes to match existing names and types.",
"additionalProperties": true
},
"externalId": {
"type": "string",
"description": "Customer-owned subscriber ID. Provide email or externalId to identify the subscriber."
},
"removeTags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags to remove"
},
"smsConsent": {
"type": "boolean",
"description": "Set true only when express written SMS marketing consent was verified for this phone number; false unsubscribes them from SMS. Omitting this leaves consent unchanged unless phone changes, which resets consent because it belonged to the old number. Consent is never inferred from phone presence."
},
"phoneCountry": {
"type": "string",
"description": "ISO 3166-1 alpha-2 country used to read a national-format phone number, such as IT or US. Defaults to US. Only send it together with phone; the stored country always comes from the parsed number."
},
"customAttributes": {
"type": "object",
"description": "REST spelling for custom attributes. Replaces the existing public custom-attribute map, matching REST PATCH semantics; provide attributes instead when you want to retain unspecified keys. Provide attributes or customAttributes, not both.",
"additionalProperties": true
}
}
},
"annotations": {
"title": "Update Subscriber",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description83/100
Unsubscribe a subscriber while preserving the record and suppression history. Only permanently deletes when hardDelete is true.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
email
Subscriber email address. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
externalId
Customer-owned subscriber ID. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
hardDelete
If true, permanently deletes the subscriber; usually within an hour their activity history and Sent emails records are erased and their delivery and engagement events anonymized, while bounce and spam-complaint suppressions keep the address. Defaults to false, which globally unsubscribes the contact, deactivates list memberships, and cancels active sequence enrollments.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "remove_subscriber",
"description": "Unsubscribe a subscriber while preserving the record and suppression history. Only permanently deletes when hardDelete is true.",
"inputSchema": {
"type": "object",
"required": [],
"properties": {
"email": {
"type": "string",
"description": "Subscriber email address. Provide email or externalId to identify the subscriber."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"externalId": {
"type": "string",
"description": "Customer-owned subscriber ID. Provide email or externalId to identify the subscriber."
},
"hardDelete": {
"type": "boolean",
"description": "If true, permanently deletes the subscriber; usually within an hour their activity history and Sent emails records are erased and their delivery and engagement events anonymized, while bounce and spam-complaint suppressions keep the address. Defaults to false, which globally unsubscribes the contact, deactivates list memberships, and cancels active sequence enrollments."
}
}
},
"annotations": {
"title": "Remove Subscriber",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Get the full subscriber profile, including tags, notes, list memberships, sequence enrollments, email stats, and recent activity. For commerce customers, customAttributes include nightly predictive analytics: predictedLtv (next-12-month spend), churnRisk (percent), expectedNextOrderAt, avgDaysBetweenOrders, and predictionConfidence.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
email
Subscriber email address. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
externalId
Customer-owned subscriber ID. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
includeMachineEngagement
If true, include machine-classified bot/scanner opens and clicks. Defaults to false, so metrics and activity are human-only.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List the custom attribute names in use across the account, each with its value type (string, number, or boolean), whether it holds a list (isArray), an example value, and how many of the sampled recent contacts carry it. Call this before add_subscriber or update_subscriber to reuse existing names and match their types, e.g. send a zip code as the string "02134" rather than a number. Names only older contacts carry are included with sampledContacts 0. mixedTypes is true when contacts hold different types for a key; valueType is then string. Always send values with leading zeros as strings, whatever valueType says.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
includeNested
Also list nested paths such as profile.tier. Defaults to false.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_subscriber_attributes",
"description": "List the custom attribute names in use across the account, each with its value type (string, number, or boolean), whether it holds a list (isArray), an example value, and how many of the sampled recent contacts carry it. Call this before add_subscriber or update_subscriber to reuse existing names and match their types, e.g. send a zip code as the string \"02134\" rather than a number. Names only older contacts carry are included with sampledContacts 0. mixedTypes is true when contacts hold different types for a key; valueType is then string. Always send values with leading zeros as strings, whatever valueType says.",
"inputSchema": {
"type": "object",
"required": [],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"includeNested": {
"type": "boolean",
"description": "Also list nested paths such as profile.tier. Defaults to false."
}
}
},
"annotations": {
"title": "List Subscriber Attributes",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description86/100
Emit a custom event for one subscriber, exactly as an integration or the public API would. This is the supported way to exercise event triggers, matching-field idempotency, branch conditions, and stop conditions end to end without waiting for real traffic. The event is recorded, sync rules apply, and matching event_received sequences enroll. Creates the subscriber if they do not exist. Use trigger_subscriber_events for several events on the same contact.
The description explains the capability, when to use it, and what to expect.
Inputs78/100
12 of 15 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
email
Subscriber email address. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
externalId
Customer-owned subscriber ID. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
event
Event name, such as saas.purchase or invoice.paid. The event definition is created if it does not exist.
Clear enough to supply this argument.
account › externalId
Customer-owned organization ID. Required for an object reference.
Clear enough to supply this argument.
account › role
owner, admin or member.
Explain what happens when this optional value is omitted.
account › name
Not provided
Missing description. Explain what this value means and how to supply it.
account › domain
Not provided
Missing description. Explain what this value means and how to supply it.
account › attributes
Not provided
Missing description. Explain what this value means and how to supply it.
Event properties. Include the sequence's matching field (for example order.id or invoice.id) when testing idempotency or cancellation by field value.
Clear enough to supply this argument.
firstName
First name applied to the subscriber profile.
Clear enough to supply this argument.
lastName
Last name applied to the subscriber profile.
Clear enough to supply this argument.
attributes
Custom attributes to set on the subscriber.
Clear enough to supply this argument.
occurredAt
When the event actually happened (ISO 8601). Omit for live events. If this is more than an hour in the past the event is recorded as history: it is stored with its real timestamp and counts for segments and the timeline, but no sequences enroll, no sync rules apply, no waiting steps resume, and no webhooks fire. A historical event also moves the contact's signup date back to when it occurred (never later), so imported contacts do not read as added today. Use this when backfilling from another platform - never to fake a live event, since the side effects you are testing will not run.
Clear enough to supply this argument.
eventId
Your own id for this event, used as an idempotency key on both paths. For a live event, re-sending an id this contact already has for this event name writes nothing, runs no side effects, and returns the existing event with duplicate: true. For a historical event, the response remains historical: true and reports the skipped row in duplicates instead. Live deduplication is best-effort for calls sent within about a second of each other, so a producer that needs a strict guarantee should also keep its own ledger.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "trigger_subscriber_event",
"description": "Emit a custom event for one subscriber, exactly as an integration or the public API would. This is the supported way to exercise event triggers, matching-field idempotency, branch conditions, and stop conditions end to end without waiting for real traffic. The event is recorded, sync rules apply, and matching event_received sequences enroll. Creates the subscriber if they do not exist. Use trigger_subscriber_events for several events on the same contact.",
"inputSchema": {
"type": "object",
"required": [
"event"
],
"properties": {
"email": {
"type": "string",
"description": "Subscriber email address. Provide email or externalId to identify the subscriber."
},
"event": {
"type": "string",
"description": "Event name, such as saas.purchase or invoice.paid. The event definition is created if it does not exist."
},
"account": {
"type": [
"string",
"object"
],
"properties": {
"name": {
"type": [
"string",
"null"
]
},
"role": {
"type": "string",
"description": "owner, admin or member."
},
"domain": {
"type": [
"string",
"null"
]
},
"attributes": {
"type": "object",
"additionalProperties": true
},
"externalId": {
"type": "string",
"description": "Customer-owned organization ID. Required for an object reference."
}
},
"description": "Organization (account) external ID or a reference object. Organizations are your customers' companies, not the Sequenzy account from get_account. Once the workspace has Organizations on, this creates the organization if missing, attaches this contact before the event, and supplies event.organization.* (and event.account.*) properties. Otherwise it is ignored and the result includes accountIgnored; create an account with upsert_account first. An object must contain externalId; role, name, domain and attributes are optional. Omit role to preserve existing membership roles."
},
"eventId": {
"type": "string",
"description": "Your own id for this event, used as an idempotency key on both paths. For a live event, re-sending an id this contact already has for this event name writes nothing, runs no side effects, and returns the existing event with duplicate: true. For a historical event, the response remains historical: true and reports the skipped row in duplicates instead. Live deduplication is best-effort for calls sent within about a second of each other, so a producer that needs a strict guarantee should also keep its own ledger."
},
"lastName": {
"type": "string",
"description": "Last name applied to the subscriber profile."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"firstName": {
"type": "string",
"description": "First name applied to the subscriber profile."
},
"attributes": {
"type": "object",
"description": "Custom attributes to set on the subscriber.",
"additionalProperties": true
},
"externalId": {
"type": "string",
"description": "Customer-owned subscriber ID. Provide email or externalId to identify the subscriber."
},
"occurredAt": {
"type": "string",
"description": "When the event actually happened (ISO 8601). Omit for live events. If this is more than an hour in the past the event is recorded as history: it is stored with its real timestamp and counts for segments and the timeline, but no sequences enroll, no sync rules apply, no waiting steps resume, and no webhooks fire. A historical event also moves the contact's signup date back to when it occurred (never later), so imported contacts do not read as added today. Use this when backfilling from another platform - never to fake a live event, since the side effects you are testing will not run."
},
"properties": {
"type": "object",
"description": "Event properties. Include the sequence's matching field (for example order.id or invoice.id) when testing idempotency or cancellation by field value.",
"additionalProperties": true
}
}
},
"annotations": {
"title": "Trigger Subscriber Event",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description78/100
Emit several custom events for one subscriber in order. Events are processed independently and sequentially, so a partial failure can still leave earlier events recorded.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs65/100
8 of 10 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
email
Subscriber email address. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
externalId
Customer-owned subscriber ID. Provide email or externalId to identify the subscriber.
Clear enough to supply this argument.
events › items › name
Event name
Explain the meaning of this value, not just its name.
events › items
Event properties
Explain the meaning of this value, not just its name.
events › items › occurredAt
When the event actually happened (ISO 8601). When every event in the batch is more than an hour old the batch is imported as history in one idempotent write, with no sequences, sync rules, waiting steps or webhooks; the contact's signup date also moves back to the earliest event in the batch (never later).
Clear enough to supply this argument.
events › items › eventId
Your own id for this event, making a re-run idempotent on both the live and historical paths.
Clear enough to supply this argument.
firstName
Not provided
Missing description. Explain what this value means and how to supply it.
lastName
Not provided
Missing description. Explain what this value means and how to supply it.
attributes
Custom attributes to set on the subscriber.
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "trigger_subscriber_events",
"description": "Emit several custom events for one subscriber in order. Events are processed independently and sequentially, so a partial failure can still leave earlier events recorded.",
"inputSchema": {
"type": "object",
"required": [
"events"
],
"properties": {
"email": {
"type": "string",
"description": "Subscriber email address. Provide email or externalId to identify the subscriber."
},
"events": {
"type": "array",
"items": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Event name"
},
"eventId": {
"type": "string",
"description": "Your own id for this event, making a re-run idempotent on both the live and historical paths."
},
"occurredAt": {
"type": "string",
"description": "When the event actually happened (ISO 8601). When every event in the batch is more than an hour old the batch is imported as history in one idempotent write, with no sequences, sync rules, waiting steps or webhooks; the contact's signup date also moves back to the earliest event in the batch (never later)."
},
"properties": {
"type": "object",
"description": "Event properties",
"additionalProperties": true
}
},
"additionalProperties": false
},
"maxItems": 500,
"minItems": 1,
"description": "Events to trigger, in order, for this subscriber."
},
"lastName": {
"type": "string"
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"firstName": {
"type": "string"
},
"attributes": {
"type": "object",
"description": "Custom attributes to set on the subscriber.",
"additionalProperties": true
},
"externalId": {
"type": "string",
"description": "Customer-owned subscriber ID. Provide email or externalId to identify the subscriber."
}
}
},
"annotations": {
"title": "Trigger Subscriber Events",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Add tags to up to 500 existing subscribers in one call, identified by emails, externalIds, or subscriberIds. Built for reconciling historical or derived tags: subscribers that do not exist are reported in notFound instead of being created, and tag automations do NOT run unless triggerAutomations is true. Needs the subscribers:tag scope; a tag name that does not exist yet also needs tags:write. The agent_safe key preset includes both. Use add_subscriber or update_subscriber for single-contact changes.
Describe the returned information so the agent knows whether it will answer the request.
Inputs79/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
tags
Tag names to add to every matched subscriber.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
emails
Subscriber emails to tag. Combine with externalIds/subscriberIds as needed; at least one identifier list is required.
Clear enough to supply this argument.
externalIds
Customer-owned subscriber IDs to tag.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
subscriberIds
Sequenzy subscriber IDs to tag.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
triggerAutomations
Whether tag_added sequences may enroll these contacts. Defaults to false, which is what backfills want. Requires the automations:trigger scope.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "bulk_add_subscriber_tags",
"description": "Add tags to up to 500 existing subscribers in one call, identified by emails, externalIds, or subscriberIds. Built for reconciling historical or derived tags: subscribers that do not exist are reported in notFound instead of being created, and tag automations do NOT run unless triggerAutomations is true. Needs the subscribers:tag scope; a tag name that does not exist yet also needs tags:write. The agent_safe key preset includes both. Use add_subscriber or update_subscriber for single-contact changes.",
"inputSchema": {
"type": "object",
"required": [
"tags"
],
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "Tag names to add to every matched subscriber."
},
"emails": {
"type": "array",
"items": {
"type": "string"
},
"description": "Subscriber emails to tag. Combine with externalIds/subscriberIds as needed; at least one identifier list is required."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"externalIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Customer-owned subscriber IDs to tag."
},
"subscriberIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Sequenzy subscriber IDs to tag."
},
"triggerAutomations": {
"type": "boolean",
"description": "Whether tag_added sequences may enroll these contacts. Defaults to false, which is what backfills want. Requires the automations:trigger scope."
}
}
},
"annotations": {
"title": "Bulk Add Subscriber Tags",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
Remove tags from up to 500 existing subscribers in one call, identified by emails, externalIds, or subscriberIds. Subscribers that do not exist are reported in notFound. Needs the subscribers:tag scope; the broader subscribers:write scope also satisfies it. Use this to roll back or reconcile a derived-tag backfill.
Describe the returned information so the agent knows whether it will answer the request.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
tags
Tag names to remove from every matched subscriber.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
emails
Subscriber emails to untag.
Clear enough to supply this argument.
externalIds
Customer-owned subscriber IDs to untag.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
subscriberIds
Sequenzy subscriber IDs to untag.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "bulk_remove_subscriber_tags",
"description": "Remove tags from up to 500 existing subscribers in one call, identified by emails, externalIds, or subscriberIds. Subscribers that do not exist are reported in notFound. Needs the subscribers:tag scope; the broader subscribers:write scope also satisfies it. Use this to roll back or reconcile a derived-tag backfill.",
"inputSchema": {
"type": "object",
"required": [
"tags"
],
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "Tag names to remove from every matched subscriber."
},
"emails": {
"type": "array",
"items": {
"type": "string"
},
"description": "Subscriber emails to untag."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"externalIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Customer-owned subscriber IDs to untag."
},
"subscriberIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Sequenzy subscriber IDs to untag."
}
}
},
"annotations": {
"title": "Bulk Remove Subscriber Tags",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
Search subscribers by free-text query, tags, list, segment, custom attribute, or opt-out date. Each subscriber carries unsubscribedAt, the date the contact opted out - use it rather than updatedAt, which any later tag or attribute write overwrites. If you omit limit, the tool fetches all pages and returns every match in one call - that is the fastest way to enumerate an audience. To walk a large audience in chunks instead, pass limit and then follow pagination.nextCursor (or pagination.nextOffset) until pagination.hasMore is false. Default searches are newest first; searches with attribute use stable subscriber-ID ascending order.
Describe the returned information so the agent knows whether it will answer the request.
Inputs93/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
query
Search query. A whole email address is matched exactly against the contact's email or external ID; anything shorter is a substring search across email, external ID, name, and tags. Prefer a whole address when you know it - it is an indexed lookup, while a partial term has to examine the entire audience.
Clear enough to supply this argument.
tags
Filter by tags
Explain the meaning of this value, not just its name.
list
Filter by subscriber list ID or exact list name. Prefer listId when known.
Clear enough to supply this argument.
listId
Filter by subscriber list ID.
Clear enough to supply this argument.
listName
Filter by exact subscriber list name when the list ID is not known.
Clear enough to supply this argument.
segmentId
Filter by segment ID
Explain the meaning of this value, not just its name.
status
Filter by subscriber status: active, unsubscribed, or bounced.
Clear enough to supply this argument.
unsubscribedAfter
Only return contacts whose opt-out is on or after this ISO 8601 date/datetime. Bare dates use UTC midnight; datetimes must include Z or an explicit offset. Contacts with no opt-out date are excluded: active contacts, and contacts imported as already unsubscribed.
Clear enough to supply this argument.
unsubscribedBefore
Only return contacts whose recorded opt-out is on or before this ISO 8601 date/datetime. Bare dates use UTC midnight; datetimes must include Z or an explicit offset. Combine with unsubscribedAfter to audit a window of opt-outs.
Clear enough to supply this argument.
attribute
Filter by custom attribute name, e.g. "plan". Pair with attributeValue and attributeOperator. The wire form "name:value" is also accepted. Cannot be combined with segmentId - use a saved segment for compound attribute filters.
Clear enough to supply this argument.
attributeValue
Value the custom attribute is compared against. Omit only when attributeOperator is is_not_empty.
Clear enough to supply this argument.
attributeOperator
How to compare the custom attribute. Defaults to is. Use is_not_empty to match every subscriber that has the attribute set to any value. For is_not, not_contains, or is_empty, create a segment and pass segmentId instead.
Clear enough to supply this argument.
limit
Maximum results to return. If omitted, the tool returns all matches across pages.
Clear enough to supply this argument.
offset
Number of matches to skip before returning results, up to 999999. Use with limit to page through a large audience; follow pagination.nextOffset from the previous response, then switch to nextCursor for deeper pagination.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
1-based page number, an alternative to offset. Requires limit, which defines the page size. Cannot be combined with offset.
Clear enough to supply this argument.
cursor
pagination.nextCursor from the previous response. The cheapest way to walk a large audience in chunks, because the server does not re-scan the rows already returned. Cannot be combined with offset or page.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "search_subscribers",
"description": "Search subscribers by free-text query, tags, list, segment, custom attribute, or opt-out date. Each subscriber carries unsubscribedAt, the date the contact opted out - use it rather than updatedAt, which any later tag or attribute write overwrites. If you omit limit, the tool fetches all pages and returns every match in one call - that is the fastest way to enumerate an audience. To walk a large audience in chunks instead, pass limit and then follow pagination.nextCursor (or pagination.nextOffset) until pagination.hasMore is false. Default searches are newest first; searches with attribute use stable subscriber-ID ascending order.",
"inputSchema": {
"type": "object",
"properties": {
"list": {
"type": "string",
"description": "Filter by subscriber list ID or exact list name. Prefer listId when known."
},
"page": {
"type": "number",
"description": "1-based page number, an alternative to offset. Requires limit, which defines the page size. Cannot be combined with offset."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Filter by tags"
},
"limit": {
"type": "number",
"minimum": 1,
"description": "Maximum results to return. If omitted, the tool returns all matches across pages."
},
"query": {
"type": "string",
"description": "Search query. A whole email address is matched exactly against the contact's email or external ID; anything shorter is a substring search across email, external ID, name, and tags. Prefer a whole address when you know it - it is an indexed lookup, while a partial term has to examine the entire audience."
},
"cursor": {
"type": "string",
"description": "pagination.nextCursor from the previous response. The cheapest way to walk a large audience in chunks, because the server does not re-scan the rows already returned. Cannot be combined with offset or page."
},
"listId": {
"type": "string",
"description": "Filter by subscriber list ID."
},
"offset": {
"type": "number",
"maximum": 999999,
"minimum": 0,
"description": "Number of matches to skip before returning results, up to 999999. Use with limit to page through a large audience; follow pagination.nextOffset from the previous response, then switch to nextCursor for deeper pagination."
},
"status": {
"type": "string",
"description": "Filter by subscriber status: active, unsubscribed, or bounced."
},
"listName": {
"type": "string",
"description": "Filter by exact subscriber list name when the list ID is not known."
},
"attribute": {
"type": "string",
"description": "Filter by custom attribute name, e.g. \"plan\". Pair with attributeValue and attributeOperator. The wire form \"name:value\" is also accepted. Cannot be combined with segmentId - use a saved segment for compound attribute filters."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"segmentId": {
"type": "string",
"description": "Filter by segment ID"
},
"attributeValue": {
"type": "string",
"description": "Value the custom attribute is compared against. Omit only when attributeOperator is is_not_empty."
},
"attributeOperator": {
"enum": [
"is",
"contains",
"gt",
"gte",
"lt",
"lte",
"is_not_empty"
],
"type": "string",
"description": "How to compare the custom attribute. Defaults to is. Use is_not_empty to match every subscriber that has the attribute set to any value. For is_not, not_contains, or is_empty, create a segment and pass segmentId instead."
},
"unsubscribedAfter": {
"type": "string",
"description": "Only return contacts whose opt-out is on or after this ISO 8601 date/datetime. Bare dates use UTC midnight; datetimes must include Z or an explicit offset. Contacts with no opt-out date are excluded: active contacts, and contacts imported as already unsubscribed."
},
"unsubscribedBefore": {
"type": "string",
"description": "Only return contacts whose recorded opt-out is on or before this ISO 8601 date/datetime. Bare dates use UTC midnight; datetimes must include Z or an explicit offset. Combine with unsubscribedAfter to audit a window of opt-outs."
}
}
},
"annotations": {
"title": "Search Subscribers",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
List all subscriber lists. Each list includes subscriberCount (current members of any status) and activeSubscriberCount (current members with status=active). Members who unsubscribed from the list are not counted. Use these fields for list audience size instead of paging search_subscribers.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID to list lists for. If not provided, uses the currently selected company.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_lists",
"description": "List all subscriber lists. Each list includes subscriberCount (current members of any status) and activeSubscriberCount (current members with status=active). Members who unsubscribed from the list are not counted. Use these fields for list audience size instead of paging search_subscribers.",
"inputSchema": {
"type": "object",
"properties": {
"companyId": {
"type": "string",
"description": "Company ID to list lists for. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "List Lists",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description82/100
Create a new subscriber list. Lists are public by default: public lists appear to subscribers in the email preference center, where they can join or leave them. Set isPrivate to keep the list internal.
The description explains the capability, when to use it, and what to expect.
Inputs80/100
Explain the meaning of this value, not just its name.
companyId
Company ID to create the list in. If not provided, uses the currently selected company.
Clear enough to supply this argument.
allowMemberUnsubscribe
Allow existing private-list members to unsubscribe in email preferences. Defaults false on creation; omission preserves on update, false disables. No effect on public lists. Does not allow joining or rejoining private lists.
Clear enough to supply this argument.
name
List name
Explain the meaning of this value, not just its name.
description
List description
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_list",
"description": "Create a new subscriber list. Lists are public by default: public lists appear to subscribers in the email preference center, where they can join or leave them. Set isPrivate to keep the list internal.",
"inputSchema": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "List name"
},
"companyId": {
"type": "string",
"description": "Company ID to create the list in. If not provided, uses the currently selected company."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the list is private. Defaults false."
},
"description": {
"type": "string",
"description": "List description"
},
"allowMemberUnsubscribe": {
"type": "boolean",
"description": "Allow existing private-list members to unsubscribe in email preferences. Defaults false on creation; omission preserves on update, false disables. No effect on public lists. Does not allow joining or rejoining private lists."
}
}
},
"annotations": {
"title": "Create List",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description81/100
Bulk add existing or new subscribers to a subscriber list from an email array. Existing subscribers are added to the list without requiring a per-subscriber update call.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs87/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
listId
Subscriber list ID to add subscribers to.
Clear enough to supply this argument.
emails
Email addresses to add to the list. Maximum 500 per call.
Clear enough to supply this argument.
duplicateStrategy
Duplicate strategy for existing subscribers: skip, merge, or overwrite. Defaults to skip.
Clear enough to supply this argument.
enrollInSequences
Whether newly created subscribers should enroll in matching sequences. Defaults to false.
Clear enough to supply this argument.
optInMode
Consent mode for newly created subscribers: default, confirmed, or double_opt_in. Defaults to default.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "add_subscribers_to_list",
"description": "Bulk add existing or new subscribers to a subscriber list from an email array. Existing subscribers are added to the list without requiring a per-subscriber update call.",
"inputSchema": {
"type": "object",
"required": [
"listId",
"emails"
],
"properties": {
"emails": {
"type": "array",
"items": {
"type": "string"
},
"description": "Email addresses to add to the list. Maximum 500 per call."
},
"listId": {
"type": "string",
"description": "Subscriber list ID to add subscribers to."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"optInMode": {
"type": "string",
"description": "Consent mode for newly created subscribers: default, confirmed, or double_opt_in. Defaults to default."
},
"duplicateStrategy": {
"type": "string",
"description": "Duplicate strategy for existing subscribers: skip, merge, or overwrite. Defaults to skip."
},
"enrollInSequences": {
"type": "boolean",
"description": "Whether newly created subscribers should enroll in matching sequences. Defaults to false."
}
}
},
"annotations": {
"title": "Add Subscribers To List",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Remove subscribers from a list by email address. Maximum 500 emails per call. Subscribers stay in the account; only the list membership is removed. Returns the removed count plus a notFound array of emails that did not match a subscriber.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
listId
Subscriber list ID to remove subscribers from.
Clear enough to supply this argument.
emails
Email addresses to remove from the list. Maximum 500 per call.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "remove_subscribers_from_list",
"description": "Remove subscribers from a list by email address. Maximum 500 emails per call. Subscribers stay in the account; only the list membership is removed. Returns the removed count plus a notFound array of emails that did not match a subscriber.",
"inputSchema": {
"type": "object",
"required": [
"listId",
"emails"
],
"properties": {
"emails": {
"type": "array",
"items": {
"type": "string"
},
"description": "Email addresses to remove from the list. Maximum 500 per call."
},
"listId": {
"type": "string",
"description": "Subscriber list ID to remove subscribers from."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "Remove Subscribers From List",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List the company's email bodies newest first, including per-locale localization sync status and each body's `emailPreset` Style > Format (branded or minimal; null for standalone raw HTML). Results include standalone templates plus the bodies behind campaigns and transactional emails. Returns 50 per call by default (100 max); page with offset while pagination.hasMore is true, and read pagination.total for the full count. You can also pass a campaign's emailId to get_template to fetch one body directly. Bodies are kept when their campaign or transactional email is deleted.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
label
Optional label name filter. Only templates assigned this label are returned.
Clear enough to supply this argument.
isTemplate
Filter to reusable master designs (true) or everything else (false). Dashboard sequence steps and campaigns can start from these designs as independent copies. MCP does not expose a standalone-template copy operation; create_campaign accepts templateId for campaign copies.
Clear enough to supply this argument.
limit
Templates per page, 1-100. Defaults to 50.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Templates to skip before returning results. Add pagination.count to the current offset to fetch the next page while pagination.hasMore is true.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_templates",
"description": "List the company's email bodies newest first, including per-locale localization sync status and each body's `emailPreset` Style > Format (branded or minimal; null for standalone raw HTML). Results include standalone templates plus the bodies behind campaigns and transactional emails. Returns 50 per call by default (100 max); page with offset while pagination.hasMore is true, and read pagination.total for the full count. You can also pass a campaign's emailId to get_template to fetch one body directly. Bodies are kept when their campaign or transactional email is deleted.",
"inputSchema": {
"type": "object",
"properties": {
"label": {
"type": "string",
"description": "Optional label name filter. Only templates assigned this label are returned."
},
"limit": {
"type": "number",
"description": "Templates per page, 1-100. Defaults to 50."
},
"offset": {
"type": "number",
"description": "Templates to skip before returning results. Add pagination.count to the current offset to fetch the next page while pagination.hasMore is true."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"isTemplate": {
"type": "boolean",
"description": "Filter to reusable master designs (true) or everything else (false). Dashboard sequence steps and campaigns can start from these designs as independent copies. MCP does not expose a standalone-template copy operation; create_campaign accepts templateId for campaign copies."
}
}
},
"annotations": {
"title": "List Templates",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description77/100
Get a template's details, content, and all localized variants with sync status. `emailPreset` reports the per-email Style > Format (branded or minimal; null when the whole email is standalone raw HTML) the same way get_sequence does per step.
The description explains the capability, when to use it, and what to expect.
Inputs66/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
templateId
Template ID
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_template",
"description": "Get a template's details, content, and all localized variants with sync status. `emailPreset` reports the per-email Style > Format (branded or minimal; null when the whole email is standalone raw HTML) the same way get_sequence does per step.",
"inputSchema": {
"type": "object",
"required": [
"templateId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"templateId": {
"type": "string",
"description": "Template ID"
}
}
},
"annotations": {
"title": "Get Template",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description76/100
Update an existing template. At least one of `name`, `subject`, `previewText`, `html`, `blocks`, `labels`, or `isTemplate` is required, and only those update fields are accepted. For the double opt-in email (`consent.doubleOptInEmailId` from `get_tracking_settings`), new `html` or `blocks` must keep `{{DOUBLE_OPT_IN_URL}}` or nothing is saved.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs88/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
templateId
Template ID
Explain the meaning of this value, not just its name.
name
Template name
Explain the meaning of this value, not just its name.
subject
Email subject line
Clear enough to supply this argument.
previewText
Inbox preview text. Send null to clear the existing preview text.
Clear enough to supply this argument.
html
Email HTML content. Mutually exclusive with `blocks`. Use this for imported provider templates. Raw HTML is stored as one opaque block. Sequenzy preserves that markup but does not add a company logo, branded native sections, or theme-driven block design. Use blocks for editor-native design, or a drafting prompt when you want Sequenzy to compose a new branded email. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes.
Clear enough to supply this argument.
blocks
Sequenzy email blocks. Use this for editor-compatible content, including conditional and repeat blocks. For provider-migrated HTML from another email platform, prefer the `html` field instead; Sequenzy stores it as one raw HTML block to preserve the original design. Use `styles` for per-block background, background opacity, text color, padding, border radius, border width, and border color. Recolor body copy with `styles.textColor` (or the top-level `textColor` alias), not with an inline `style` on `<p>` or `<span>`. Top-level style aliases such as `backgroundColor`, `backgroundOpacity`, `textColor`, `textAlign`, `borderColor`, `borderWidth`, and `borderRadius` are also accepted and saved under `styles`. Repeat blocks use { type: 'repeat', source: 'items', itemAlias: 'item', children: [...] }. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes. Any block accepts a `conditions` array so it only renders for matching recipients; conditions must all match unless the block sets `conditionsMatch: "any"`, and a numeric path segment reads one list item (`goals.0:bias`). To branch on a value passed in transactional `variables` or an automation `event` payload, use { "id": "c1", "field": "variable", "operator": "is", "value": "plan:pro" }; "attribute" uses the same "name:value" form, while "email"/"firstName"/"lastName" use a plain comparison value. Live subscriber fields are "status", "tag", "list", "segment", "event", "emailProvider", "phone", "phoneCountry", "smsStatus", "added", "stripeProduct", "stripeCurrentProduct", "stripeTrialProduct", "commerceProduct", "commerceCollection", "emailSent", "emailDelivered", "emailOpened", "emailClicked", "emailBounced", and "emailComplained". They use the same field-specific values and operators as segment filters, for example { "id": "c2", "field": "segment", "operator": "is", "value": "seg_123" }, { "id": "c3", "field": "tag", "operator": "contains", "value": "vip" }, or { "id": "c4", "field": "event", "operator": "at_least", "value": "purchase:3:30d" }. Supported operators across fields are is, is_not, contains, not_contains, starts_with, not_starts_with, gt, gte, lt, lte, less_than, more_than, at_least, less_than_count, is_empty, is_not_empty, is_temporary_bounce, and is_permanent_bounce; each field accepts only its segment-filter operators. Recipients without a stored subscriber match use the OTHERWISE branch or hide a conditionally displayed block. For if/else, use a { type: "conditional-group", conditions: [...], ifBranch: { children: [...] }, elseBranch: { children: [...] } } block. `styles` applies to the block's own container, not to an inner rendered element. On a button block, `styles.backgroundColor` colors the band behind the button and `styles.textColor` does not reach the label - set the top-level `buttonColor` and `buttonTextColor` fields instead, or leave them unset to inherit the email theme's primary color. Unsupported fields are discarded and reported in the response `warnings` array rather than rejected. Polls and NPS surveys use a native poll block. For answer buttons use { "type": "poll", "variant": "options", "question": "What did you think?", "options": [{ "label": "Loved it", "value": "loved" }, { "label": "Not for me", "value": "not_for_me" }], "attributeKey": "email_feedback" }. For NPS use { "type": "poll", "variant": "nps", "question": "How likely are you to recommend us?", "options": [], "attributeKey": "nps_score", "npsLowLabel": "Not likely", "npsHighLabel": "Very likely" }. `attributeKey` stores the latest response for segmentation. Set `allowMultiple: true` on a text-only options poll to let recipients pick several answers: answer links then open a hosted selection page where the recipient checks any number of options and saves them in one submit, and `attributeKey` stores the list of selected values (filter with attribute `contains`). Multi-select polls cannot use option images or configurations whose encoded signed links exceed the delivery-safe size limit. Optional `appearance` picks the answer style: "soft" (default), "pill", "outline", "filled", "pop" (hard-shadow boxes), "brutal" (square uppercase slabs), "quiz" (A/B/C letter badges), or "minimal" (bare ruled rows). `accentColor` recolors every appearance, including "brutal". `optionRadius` sets answer-button corners in px (0 is square) independently of `styles.borderRadius`, while `questionColor` recolors only the question. `fontFamily` applies to the poll; `optionFontSize`, `optionFontWeight`, `optionLetterSpacing`, and `optionTextTransform` style answers, and the matching `questionFontSize`, `questionFontWeight`, `questionLetterSpacing`, and `questionTextTransform` fields style the question. Sizes and spacing are px, weights are 100-900, and transforms are "none" or "uppercase". Optional `confirmationMessage` customizes the hosted thank-you page; set `redirectUrl` only when respondents should land on another page. For a new image, call `upload_image_asset` first and insert its returned `imageBlock`. A responsive fixed-height screenshot crop uses { "type": "image", "src": "https://...", "alt": "Product dashboard", "width": 100, "widthType": "percent", "height": 320, "objectFit": "cover", "align": "center" }. A YouTube video block can override its still with { "type": "video", "videoUrl": "https://www.youtube.com/watch?v=...", "thumbnailUrl": "https://cdn.example.com/cover.jpg", "alt": "Watch the product tour" }. Replacing the blocks array without `thumbnailUrl` restores YouTube's own thumbnail; the video destination remains `videoUrl`. Minimal valid core examples: {"type":"heading","content":"Title","level":1}; {"type":"text","content":"<p>Paragraph with <strong>bold</strong></p>","variant":"paragraph"}; {"type":"list","variant":"bullet","items":[{"content":"First point"},{"content":"Second point"}]}; {"type":"steps","variant":"timeline","items":[{"title":"Connect","description":"Link your account."},{"title":"Launch","description":"Send your first campaign."}]}; {"type":"button","text":"Click Me","url":"https://example.com","variant":"primary"}; {"type":"image","src":"https://...","alt":"Description","width":100,"widthType":"percent","height":240,"objectFit":"cover","href":"https://example.com","align":"center"}. Heading and text use `content`; button uses `text` but also accepts `content` as an alias and defaults `variant` to `primary`. Image `widthType` accepts `percent` or `px`. Lists are their own block type, never a text variant: `text` accepts only variant paragraph, lead, or html and never accepts `items`, so a numbered list is {"type":"list","variant":"numbered","items":[{"content":"First"}]} and a visual numbered walkthrough is {"type":"steps","variant":"numbered","items":[{"title":"Step one","description":"What happens"},{"title":"Step two","description":"What happens next"}]}. List items carry `content`; steps items carry `title` plus an optional `description`. Call `get_email_block_schema` for the required and optional fields of any other block type. If that tool is not in the MCP tool list, enable it on the Sequenzy connector rather than inferring fields from live HTML; the same reference is also at `sequenzy://email-blocks` (MCP resource), `GET /api/v1/email-blocks` (API), and `sequenzy blocks <type>` (CLI).
Clear enough to supply this argument.
labels
Replacement label names. Send an empty array to clear labels. Missing labels are created automatically.
Clear enough to supply this argument.
isTemplate
Mark (true) or unmark (false) this email as a reusable master design that sequence steps and campaigns can start from.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_template",
"description": "Update an existing template. At least one of `name`, `subject`, `previewText`, `html`, `blocks`, `labels`, or `isTemplate` is required, and only those update fields are accepted. For the double opt-in email (`consent.doubleOptInEmailId` from `get_tracking_settings`), new `html` or `blocks` must keep `{{DOUBLE_OPT_IN_URL}}` or nothing is saved.",
"inputSchema": {
"type": "object",
"required": [
"templateId"
],
"properties": {
"html": {
"type": "string",
"description": "Email HTML content. Mutually exclusive with `blocks`. Use this for imported provider templates. Raw HTML is stored as one opaque block. Sequenzy preserves that markup but does not add a company logo, branded native sections, or theme-driven block design. Use blocks for editor-native design, or a drafting prompt when you want Sequenzy to compose a new branded email. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes."
},
"name": {
"type": "string",
"description": "Template name"
},
"blocks": {
"type": "array",
"items": {
"type": "object"
},
"description": "Sequenzy email blocks. Use this for editor-compatible content, including conditional and repeat blocks. For provider-migrated HTML from another email platform, prefer the `html` field instead; Sequenzy stores it as one raw HTML block to preserve the original design. Use `styles` for per-block background, background opacity, text color, padding, border radius, border width, and border color. Recolor body copy with `styles.textColor` (or the top-level `textColor` alias), not with an inline `style` on `<p>` or `<span>`. Top-level style aliases such as `backgroundColor`, `backgroundOpacity`, `textColor`, `textAlign`, `borderColor`, `borderWidth`, and `borderRadius` are also accepted and saved under `styles`. Repeat blocks use { type: 'repeat', source: 'items', itemAlias: 'item', children: [...] }. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes. Any block accepts a `conditions` array so it only renders for matching recipients; conditions must all match unless the block sets `conditionsMatch: \"any\"`, and a numeric path segment reads one list item (`goals.0:bias`). To branch on a value passed in transactional `variables` or an automation `event` payload, use { \"id\": \"c1\", \"field\": \"variable\", \"operator\": \"is\", \"value\": \"plan:pro\" }; \"attribute\" uses the same \"name:value\" form, while \"email\"/\"firstName\"/\"lastName\" use a plain comparison value. Live subscriber fields are \"status\", \"tag\", \"list\", \"segment\", \"event\", \"emailProvider\", \"phone\", \"phoneCountry\", \"smsStatus\", \"added\", \"stripeProduct\", \"stripeCurrentProduct\", \"stripeTrialProduct\", \"commerceProduct\", \"commerceCollection\", \"emailSent\", \"emailDelivered\", \"emailOpened\", \"emailClicked\", \"emailBounced\", and \"emailComplained\". They use the same field-specific values and operators as segment filters, for example { \"id\": \"c2\", \"field\": \"segment\", \"operator\": \"is\", \"value\": \"seg_123\" }, { \"id\": \"c3\", \"field\": \"tag\", \"operator\": \"contains\", \"value\": \"vip\" }, or { \"id\": \"c4\", \"field\": \"event\", \"operator\": \"at_least\", \"value\": \"purchase:3:30d\" }. Supported operators across fields are is, is_not, contains, not_contains, starts_with, not_starts_with, gt, gte, lt, lte, less_than, more_than, at_least, less_than_count, is_empty, is_not_empty, is_temporary_bounce, and is_permanent_bounce; each field accepts only its segment-filter operators. Recipients without a stored subscriber match use the OTHERWISE branch or hide a conditionally displayed block. For if/else, use a { type: \"conditional-group\", conditions: [...], ifBranch: { children: [...] }, elseBranch: { children: [...] } } block. `styles` applies to the block's own container, not to an inner rendered element. On a button block, `styles.backgroundColor` colors the band behind the button and `styles.textColor` does not reach the label - set the top-level `buttonColor` and `buttonTextColor` fields instead, or leave them unset to inherit the email theme's primary color. Unsupported fields are discarded and reported in the response `warnings` array rather than rejected. Polls and NPS surveys use a native poll block. For answer buttons use { \"type\": \"poll\", \"variant\": \"options\", \"question\": \"What did you think?\", \"options\": [{ \"label\": \"Loved it\", \"value\": \"loved\" }, { \"label\": \"Not for me\", \"value\": \"not_for_me\" }], \"attributeKey\": \"email_feedback\" }. For NPS use { \"type\": \"poll\", \"variant\": \"nps\", \"question\": \"How likely are you to recommend us?\", \"options\": [], \"attributeKey\": \"nps_score\", \"npsLowLabel\": \"Not likely\", \"npsHighLabel\": \"Very likely\" }. `attributeKey` stores the latest response for segmentation. Set `allowMultiple: true` on a text-only options poll to let recipients pick several answers: answer links then open a hosted selection page where the recipient checks any number of options and saves them in one submit, and `attributeKey` stores the list of selected values (filter with attribute `contains`). Multi-select polls cannot use option images or configurations whose encoded signed links exceed the delivery-safe size limit. Optional `appearance` picks the answer style: \"soft\" (default), \"pill\", \"outline\", \"filled\", \"pop\" (hard-shadow boxes), \"brutal\" (square uppercase slabs), \"quiz\" (A/B/C letter badges), or \"minimal\" (bare ruled rows). `accentColor` recolors every appearance, including \"brutal\". `optionRadius` sets answer-button corners in px (0 is square) independently of `styles.borderRadius`, while `questionColor` recolors only the question. `fontFamily` applies to the poll; `optionFontSize`, `optionFontWeight`, `optionLetterSpacing`, and `optionTextTransform` style answers, and the matching `questionFontSize`, `questionFontWeight`, `questionLetterSpacing`, and `questionTextTransform` fields style the question. Sizes and spacing are px, weights are 100-900, and transforms are \"none\" or \"uppercase\". Optional `confirmationMessage` customizes the hosted thank-you page; set `redirectUrl` only when respondents should land on another page. For a new image, call `upload_image_asset` first and insert its returned `imageBlock`. A responsive fixed-height screenshot crop uses { \"type\": \"image\", \"src\": \"https://...\", \"alt\": \"Product dashboard\", \"width\": 100, \"widthType\": \"percent\", \"height\": 320, \"objectFit\": \"cover\", \"align\": \"center\" }. A YouTube video block can override its still with { \"type\": \"video\", \"videoUrl\": \"https://www.youtube.com/watch?v=...\", \"thumbnailUrl\": \"https://cdn.example.com/cover.jpg\", \"alt\": \"Watch the product tour\" }. Replacing the blocks array without `thumbnailUrl` restores YouTube's own thumbnail; the video destination remains `videoUrl`. Minimal valid core examples: {\"type\":\"heading\",\"content\":\"Title\",\"level\":1}; {\"type\":\"text\",\"content\":\"<p>Paragraph with <strong>bold</strong></p>\",\"variant\":\"paragraph\"}; {\"type\":\"list\",\"variant\":\"bullet\",\"items\":[{\"content\":\"First point\"},{\"content\":\"Second point\"}]}; {\"type\":\"steps\",\"variant\":\"timeline\",\"items\":[{\"title\":\"Connect\",\"description\":\"Link your account.\"},{\"title\":\"Launch\",\"description\":\"Send your first campaign.\"}]}; {\"type\":\"button\",\"text\":\"Click Me\",\"url\":\"https://example.com\",\"variant\":\"primary\"}; {\"type\":\"image\",\"src\":\"https://...\",\"alt\":\"Description\",\"width\":100,\"widthType\":\"percent\",\"height\":240,\"objectFit\":\"cover\",\"href\":\"https://example.com\",\"align\":\"center\"}. Heading and text use `content`; button uses `text` but also accepts `content` as an alias and defaults `variant` to `primary`. Image `widthType` accepts `percent` or `px`. Lists are their own block type, never a text variant: `text` accepts only variant paragraph, lead, or html and never accepts `items`, so a numbered list is {\"type\":\"list\",\"variant\":\"numbered\",\"items\":[{\"content\":\"First\"}]} and a visual numbered walkthrough is {\"type\":\"steps\",\"variant\":\"numbered\",\"items\":[{\"title\":\"Step one\",\"description\":\"What happens\"},{\"title\":\"Step two\",\"description\":\"What happens next\"}]}. List items carry `content`; steps items carry `title` plus an optional `description`. Call `get_email_block_schema` for the required and optional fields of any other block type. If that tool is not in the MCP tool list, enable it on the Sequenzy connector rather than inferring fields from live HTML; the same reference is also at `sequenzy://email-blocks` (MCP resource), `GET /api/v1/email-blocks` (API), and `sequenzy blocks <type>` (CLI)."
},
"labels": {
"type": "array",
"items": {
"type": "string"
},
"description": "Replacement label names. Send an empty array to clear labels. Missing labels are created automatically."
},
"subject": {
"type": "string",
"description": "Email subject line"
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"isTemplate": {
"type": "boolean",
"description": "Mark (true) or unmark (false) this email as a reusable master design that sequence steps and campaigns can start from."
},
"templateId": {
"type": "string",
"description": "Template ID"
},
"previewText": {
"type": [
"string",
"null"
],
"description": "Inbox preview text. Send null to clear the existing preview text."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Update Template",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Field reference for Sequenzy email blocks: which fields each block type requires, which are optional, the allowed values of every enum field, and the shape of nested item arrays and nested objects. Call this before authoring blocks for a type you have not written before, or after a block write is rejected. The `blocks` parameter on create_campaign, create_sequence, create_template, and update_sequence_node accepts any of these types, but is declared as a plain object array because the union is too large to inline. Without a blockType this lists every type with its required and optional fields; with one it returns that type's full reference plus a minimal valid example and authoring notes. `group` is a persisted structural type managed by the editor and is omitted by creatableOnly; request it by name when reading existing grouped content. Note that lists are their own block type rather than a text variant: a numbered list is {"type":"list","variant":"numbered","items":[{"content":"First"}]}, and a visual numbered walkthrough is {"type":"steps","variant":"numbered","items":[{"title":"Step one","description":"What happens"},{"title":"Step two","description":"What happens next"}]}. A `text` block only accepts variants paragraph, lead, and html, and never accepts `items`. Every block also takes a `conditions` array, and each condition field accepts only its own operators - a block's own `field` and `operator` enums pool every field's operators together, so they list `is` for `tag` even though a tag condition is rejected with it. The `conditionFields` table resolves that: the operators each condition field accepts, how its `value` string is shaped, and what render_email needs before it can evaluate the condition rather than rendering it as false. It comes back automatically when you list every type and when you ask for `conditional-group`; on any other single type pass conditionFields: true, since the table is several times the size of one block's reference.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
blockType
A single block type to describe, for example "list", "steps", "text", "hero", or the structural "group" type. Omit to list every block type.
Clear enough to supply this argument.
creatableOnly
Only list block types an author should hand-create, hiding structural types such as group that the editor manages. Ignored when blockType is set.
Clear enough to supply this argument.
conditionFields
Include the per-field condition table alongside a single blockType. Only needed when you are writing a `conditions` array on that type: listing every type already includes the table, and so does asking for `conditional-group`. Responses that omit it say so in `conditionFieldsHint`.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_email_block_schema",
"description": "Field reference for Sequenzy email blocks: which fields each block type requires, which are optional, the allowed values of every enum field, and the shape of nested item arrays and nested objects. Call this before authoring blocks for a type you have not written before, or after a block write is rejected. The `blocks` parameter on create_campaign, create_sequence, create_template, and update_sequence_node accepts any of these types, but is declared as a plain object array because the union is too large to inline. Without a blockType this lists every type with its required and optional fields; with one it returns that type's full reference plus a minimal valid example and authoring notes. `group` is a persisted structural type managed by the editor and is omitted by creatableOnly; request it by name when reading existing grouped content. Note that lists are their own block type rather than a text variant: a numbered list is {\"type\":\"list\",\"variant\":\"numbered\",\"items\":[{\"content\":\"First\"}]}, and a visual numbered walkthrough is {\"type\":\"steps\",\"variant\":\"numbered\",\"items\":[{\"title\":\"Step one\",\"description\":\"What happens\"},{\"title\":\"Step two\",\"description\":\"What happens next\"}]}. A `text` block only accepts variants paragraph, lead, and html, and never accepts `items`. Every block also takes a `conditions` array, and each condition field accepts only its own operators - a block's own `field` and `operator` enums pool every field's operators together, so they list `is` for `tag` even though a tag condition is rejected with it. The `conditionFields` table resolves that: the operators each condition field accepts, how its `value` string is shaped, and what render_email needs before it can evaluate the condition rather than rendering it as false. It comes back automatically when you list every type and when you ask for `conditional-group`; on any other single type pass conditionFields: true, since the table is several times the size of one block's reference.",
"inputSchema": {
"type": "object",
"required": [],
"properties": {
"blockType": {
"type": "string",
"description": "A single block type to describe, for example \"list\", \"steps\", \"text\", \"hero\", or the structural \"group\" type. Omit to list every block type."
},
"creatableOnly": {
"type": "boolean",
"description": "Only list block types an author should hand-create, hiding structural types such as group that the editor manages. Ignored when blockType is set."
},
"conditionFields": {
"type": "boolean",
"description": "Include the per-field condition table alongside a single blockType. Only needed when you are writing a `conditions` array on that type: listing every type already includes the table, and so does asking for `conditional-group`. Responses that omit it say so in `conditionFieldsHint`."
}
}
},
"annotations": {
"title": "Get Email Block Schema",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
List campaigns. Each item carries `emailPreset`, the linked email's Style > Format (branded or minimal; null for SMS campaigns and standalone raw HTML emails), so chrome can be compared across campaigns without one get_campaign call each. Each item also carries delivery pacing so an account-wide STO audit does not need one get_campaign call each: sendTimeOptimization, sendTimeWindowHours, spreadOverHours, sendInRecipientTimezone, and scheduledTimezone. STO is campaign-only; sequences use sendingWindow. Results are paginated: the default page size is 50 and limit is capped at 100. Always read the returned `pagination` object (`limit`, `offset`, `count`, `total`, `hasMore`) and keep paging with `offset` while `hasMore` is true - a single call does not necessarily return every campaign.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID to list campaigns for. If not provided, uses the currently selected company.
Clear enough to supply this argument.
status
Filter by status (draft, scheduled, sent, sending, cancelled, paused, waiting_approval, or rejected). Rejected campaign results include rejectionComment feedback when provided.
Clear enough to supply this argument.
label
Optional label name filter. Only campaigns assigned this label are returned.
Clear enough to supply this argument.
limit
Page size from 1 to 100. Defaults to 50.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Zero-based result offset. Defaults to 0.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_campaigns",
"description": "List campaigns. Each item carries `emailPreset`, the linked email's Style > Format (branded or minimal; null for SMS campaigns and standalone raw HTML emails), so chrome can be compared across campaigns without one get_campaign call each. Each item also carries delivery pacing so an account-wide STO audit does not need one get_campaign call each: sendTimeOptimization, sendTimeWindowHours, spreadOverHours, sendInRecipientTimezone, and scheduledTimezone. STO is campaign-only; sequences use sendingWindow. Results are paginated: the default page size is 50 and limit is capped at 100. Always read the returned `pagination` object (`limit`, `offset`, `count`, `total`, `hasMore`) and keep paging with `offset` while `hasMore` is true - a single call does not necessarily return every campaign.",
"inputSchema": {
"type": "object",
"properties": {
"label": {
"type": "string",
"description": "Optional label name filter. Only campaigns assigned this label are returned."
},
"limit": {
"type": "number",
"description": "Page size from 1 to 100. Defaults to 50."
},
"offset": {
"type": "number",
"description": "Zero-based result offset. Defaults to 0."
},
"status": {
"type": "string",
"description": "Filter by status (draft, scheduled, sent, sending, cancelled, paused, waiting_approval, or rejected). Rejected campaign results include rejectionComment feedback when provided."
},
"companyId": {
"type": "string",
"description": "Company ID to list campaigns for. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "List Campaigns",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Get campaign details and stats, including rejectionComment reviewer feedback for rejected campaigns. `emailId` is the campaign's linked email body - the same record returned by the templates tools - and can be passed as templateId to create_campaign to reuse the design; it is null for SMS campaigns. `emailPreset` reports that email's Style > Format the same way get_sequence does per step (branded or minimal; null for SMS campaigns and standalone raw HTML emails), so campaign chrome can be compared against sequence steps and transactional templates without rendering them - minimal suppresses the company logo at render time. `targetLists` holds the raw audience targeting (IDs only); call get_campaign_audience for resolved list/segment names and a recipient count. Note that `computedLists` is email personalization (product lists rendered inside the email), not audience targeting. For native sends, `sentAt` is stamped when the last recipient is handed off, so on a paced send it is the end of the delivery window; `spreadOverHours`, `sendTimeOptimization`, and `sendTimeWindowHours` report recorded pacing, and `maxRecipients` reports the recipient cap (null = whole audience). Change draft pacing or the cap with update_campaign, or apply them when calling schedule_campaign. Send Time Optimization is not a company or sequence setting. It is campaign-only: audit with list_campaigns or get_campaign (sendTimeOptimization, sendTimeWindowHours, default 12h window). Change a draft with update_campaign, or apply it when calling schedule_campaign. Sequences use sendingWindow (allowed local hours/days), which is a shared gate, not per-subscriber predicted send times. Imported campaigns may not include pacing metadata from their source provider, so absent pacing fields do not prove that delivery happened all at once.
The description explains the capability, when to use it, and what to expect.
Inputs71/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
campaignId
Campaign ID
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_campaign",
"description": "Get campaign details and stats, including rejectionComment reviewer feedback for rejected campaigns. `emailId` is the campaign's linked email body - the same record returned by the templates tools - and can be passed as templateId to create_campaign to reuse the design; it is null for SMS campaigns. `emailPreset` reports that email's Style > Format the same way get_sequence does per step (branded or minimal; null for SMS campaigns and standalone raw HTML emails), so campaign chrome can be compared against sequence steps and transactional templates without rendering them - minimal suppresses the company logo at render time. `targetLists` holds the raw audience targeting (IDs only); call get_campaign_audience for resolved list/segment names and a recipient count. Note that `computedLists` is email personalization (product lists rendered inside the email), not audience targeting. For native sends, `sentAt` is stamped when the last recipient is handed off, so on a paced send it is the end of the delivery window; `spreadOverHours`, `sendTimeOptimization`, and `sendTimeWindowHours` report recorded pacing, and `maxRecipients` reports the recipient cap (null = whole audience). Change draft pacing or the cap with update_campaign, or apply them when calling schedule_campaign. Send Time Optimization is not a company or sequence setting. It is campaign-only: audit with list_campaigns or get_campaign (sendTimeOptimization, sendTimeWindowHours, default 12h window). Change a draft with update_campaign, or apply it when calling schedule_campaign. Sequences use sendingWindow (allowed local hours/days), which is a shared gate, not per-subscriber predicted send times. Imported campaigns may not include pacing metadata from their source provider, so absent pacing fields do not prove that delivery happened all at once.",
"inputSchema": {
"type": "object",
"required": [
"campaignId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"campaignId": {
"type": "string",
"description": "Campaign ID"
}
}
},
"annotations": {
"title": "Get Campaign",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description100/100
Resolve exactly who a campaign will reach. Returns the targeting kind, resolved list and segment names (flagging references that no longer exist), filter conditions, individual include/exclude adjustments, a plain-language summary, and a live recipient count. Critically, it reports whether targeting is unset - an unset campaign falls back to every active subscriber when scheduled. Use this to verify a scheduled campaign's audience before it sends. This is a read-only resolved view, not the write shape: to change targeting, pass `targetLists` (e.g. {type:'lists', listIds:['list_123']}) or the `segmentId`/`listIds` shorthands to update_campaign or schedule_campaign.
The description explains the capability, when to use it, and what to expect.
Inputs72/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
campaignId
Campaign ID
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_campaign_audience",
"description": "Resolve exactly who a campaign will reach. Returns the targeting kind, resolved list and segment names (flagging references that no longer exist), filter conditions, individual include/exclude adjustments, a plain-language summary, and a live recipient count. Critically, it reports whether targeting is unset - an unset campaign falls back to every active subscriber when scheduled. Use this to verify a scheduled campaign's audience before it sends. This is a read-only resolved view, not the write shape: to change targeting, pass `targetLists` (e.g. {type:'lists', listIds:['list_123']}) or the `segmentId`/`listIds` shorthands to update_campaign or schedule_campaign.",
"inputSchema": {
"type": "object",
"required": [
"campaignId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"campaignId": {
"type": "string",
"description": "Campaign ID"
}
}
},
"annotations": {
"title": "Get Campaign Audience",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List and filter the recent sent-email delivery history shown in the dashboard. Search subject/title or recipient, filter by delivery status, email type, bounce type, source ID, recipient mailbox provider, or list membership, then pass a returned emailSendId to get_email_send for exact open/click timestamps and the complete event timeline. Each row carries recipientEmail, subscriberId, automationNodeId, abTestVariantId, and sent/delivered/opened/clicked timestamps, so rows join into a recipient-level delivery matrix without re-reading the raw event stream. Pass automationNodeId to list only the recipients of one sequence step. Delivery rows are retained for 14 days, so this is the wrong tool for send totals: read get_sequence_stats steps[] or list_email_metrics, which cover the full retained event window. Successful live-test and other test sends are omitted so they do not bury real deliveries; only failed, bounced, or suppressed test sends appear. Replies to those test sends show in list_conversations only when inbound reply capture is enabled; otherwise the send uses the original Reply-To and Sequenzy never sees the reply.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
search
Case-insensitive search across subject and recipient email.
Clear enough to supply this argument.
subject
Case-insensitive subject/title filter.
Clear enough to supply this argument.
recipient
Case-insensitive recipient email filter.
Clear enough to supply this argument.
status
Delivery status: pending, sent, delivered, opened, clicked, bounced, complained, failed, or suppressed. Opened includes clicked deliveries, matching the dashboard.
Clear enough to supply this argument.
emailType
Email type: campaign, transactional, or sequence.
Clear enough to supply this argument.
bounceType
Bounce type: Permanent, Transient, Soft, or Blocked. Transient is every temporary bounce; Blocked is the part the receiver refused on content, policy, or reputation grounds, and Soft is the rest.
Clear enough to supply this argument.
campaignId
Filter deliveries from one campaign.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
transactionalEmailId
Filter deliveries from one saved transactional email.
Clear enough to supply this argument.
automationId
Filter deliveries from one sequence/automation.
Clear enough to supply this argument.
automationNodeId
Filter deliveries from one email step of a sequence, using the nodeId from get_sequence_stats steps[] or get_sequence nodes.
Clear enough to supply this argument.
mailboxProvider
Recipient mailbox provider, with the same values and domain classification as the analytics mailboxProvider filter (e.g. gmail, microsoft, yahoo, icloud, orange). Use it to list the deliveries behind a provider's analytics numbers. `other` matches every domain outside the named providers.
Clear enough to supply this argument.
listId
Only deliveries to active subscribers currently on this list (list ID from list_lists), the same audience the analytics list filter uses.
Clear enough to supply this argument.
days
History window in days, from 1 to 14. Defaults to 14.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Page number starting at 1. Defaults to 1.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Results per page, from 1 to 100. Defaults to 20.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sortField
Sort field: recipientEmail, subject, status, eventAt, sentAt, or createdAt. Defaults to createdAt.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sortOrder
Sort order: asc or desc. Defaults to desc.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_email_sends",
"description": "List and filter the recent sent-email delivery history shown in the dashboard. Search subject/title or recipient, filter by delivery status, email type, bounce type, source ID, recipient mailbox provider, or list membership, then pass a returned emailSendId to get_email_send for exact open/click timestamps and the complete event timeline. Each row carries recipientEmail, subscriberId, automationNodeId, abTestVariantId, and sent/delivered/opened/clicked timestamps, so rows join into a recipient-level delivery matrix without re-reading the raw event stream. Pass automationNodeId to list only the recipients of one sequence step. Delivery rows are retained for 14 days, so this is the wrong tool for send totals: read get_sequence_stats steps[] or list_email_metrics, which cover the full retained event window. Successful live-test and other test sends are omitted so they do not bury real deliveries; only failed, bounced, or suppressed test sends appear. Replies to those test sends show in list_conversations only when inbound reply capture is enabled; otherwise the send uses the original Reply-To and Sequenzy never sees the reply.",
"inputSchema": {
"type": "object",
"properties": {
"days": {
"type": "number",
"description": "History window in days, from 1 to 14. Defaults to 14."
},
"page": {
"type": "number",
"description": "Page number starting at 1. Defaults to 1."
},
"limit": {
"type": "number",
"description": "Results per page, from 1 to 100. Defaults to 20."
},
"listId": {
"type": "string",
"description": "Only deliveries to active subscribers currently on this list (list ID from list_lists), the same audience the analytics list filter uses."
},
"search": {
"type": "string",
"description": "Case-insensitive search across subject and recipient email."
},
"status": {
"type": "string",
"description": "Delivery status: pending, sent, delivered, opened, clicked, bounced, complained, failed, or suppressed. Opened includes clicked deliveries, matching the dashboard."
},
"subject": {
"type": "string",
"description": "Case-insensitive subject/title filter."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"emailType": {
"type": "string",
"description": "Email type: campaign, transactional, or sequence."
},
"recipient": {
"type": "string",
"description": "Case-insensitive recipient email filter."
},
"sortField": {
"type": "string",
"description": "Sort field: recipientEmail, subject, status, eventAt, sentAt, or createdAt. Defaults to createdAt."
},
"sortOrder": {
"type": "string",
"description": "Sort order: asc or desc. Defaults to desc."
},
"bounceType": {
"type": "string",
"description": "Bounce type: Permanent, Transient, Soft, or Blocked. Transient is every temporary bounce; Blocked is the part the receiver refused on content, policy, or reputation grounds, and Soft is the rest."
},
"campaignId": {
"type": "string",
"description": "Filter deliveries from one campaign."
},
"automationId": {
"type": "string",
"description": "Filter deliveries from one sequence/automation."
},
"mailboxProvider": {
"type": "string",
"description": "Recipient mailbox provider, with the same values and domain classification as the analytics mailboxProvider filter (e.g. gmail, microsoft, yahoo, icloud, orange). Use it to list the deliveries behind a provider's analytics numbers. `other` matches every domain outside the named providers."
},
"automationNodeId": {
"type": "string",
"description": "Filter deliveries from one email step of a sequence, using the nodeId from get_sequence_stats steps[] or get_sequence nodes."
},
"transactionalEmailId": {
"type": "string",
"description": "Filter deliveries from one saved transactional email."
}
}
},
"annotations": {
"title": "List Email Sends",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Get an email delivery by emailSendId, including queued and test sends, delivery status, provider failure reason, stored HTML, effective Reply-To, copied-recipient identity and primary email send ID, and the ClickHouse event timeline. `type` is the legacy source category; use `emailType` on the send and `deliveryPolicy` on events for the actual marketing or transactional policy when known. Queue jobs are internal execution details and are not exposed.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_email_send",
"description": "Get an email delivery by emailSendId, including queued and test sends, delivery status, provider failure reason, stored HTML, effective Reply-To, copied-recipient identity and primary email send ID, and the ClickHouse event timeline. `type` is the legacy source category; use `emailType` on the send and `deliveryPolicy` on events for the actual marketing or transactional policy when known. Queue jobs are internal execution details and are not exposed.",
"inputSchema": {
"type": "object",
"required": [
"emailSendId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"emailSendId": {
"type": "string",
"description": "Durable email delivery ID to inspect."
}
}
},
"annotations": {
"title": "Get Email Send",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description84/100
Create a new campaign. Omit all content fields to create an empty draft. `prompt` generates net-new content from natural language. `blocks` are finished caller-supplied Sequenzy content and `html` is preserved/imported markup. Pass `emailPreset` with native blocks to set Style > Format (minimal or branded); `style` is a prompt-generation hint only. Defaults to draft; status 'sent' only archives an already-sent campaign.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID to create the campaign in. If not provided, uses the currently selected company.
Clear enough to supply this argument.
name
Campaign name
Clear enough to supply this argument.
subject
Email subject line. Optional when `prompt` is provided because the generated subject will be used.
Clear enough to supply this argument.
previewText
Email preview text. Optional when `prompt` is provided because the generated preview text will be used.
Clear enough to supply this argument.
trackingCode
Optional campaign tracking code for UTM templates. Use only when explicitly requested.
Clear enough to supply this argument.
status
Initial status: draft or sent. Defaults to draft. Use sent only for imported/already-sent campaigns; it does not send email or create delivery history.
Clear enough to supply this argument.
sentAt
ISO date-time for an imported/already-sent campaign. Only valid when status is sent; defaults to now if omitted.
Clear enough to supply this argument.
html
Email HTML content. Mutually exclusive with `blocks`. Use this for imported provider campaigns. Raw HTML is stored as one opaque block. Sequenzy preserves that markup but does not add a company logo, branded native sections, or theme-driven block design. Use blocks for editor-native design, or a drafting prompt when you want Sequenzy to compose a new branded email. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes.
Clear enough to supply this argument.
blocks
Sequenzy email blocks. Use this for editor-compatible content, including conditional and repeat blocks. For provider-migrated HTML from another email platform, prefer the `html` field instead; Sequenzy stores it as one raw HTML block to preserve the original design. Use `styles` for per-block background, background opacity, text color, padding, border radius, border width, and border color. Recolor body copy with `styles.textColor` (or the top-level `textColor` alias), not with an inline `style` on `<p>` or `<span>`. Top-level style aliases such as `backgroundColor`, `backgroundOpacity`, `textColor`, `textAlign`, `borderColor`, `borderWidth`, and `borderRadius` are also accepted and saved under `styles`. Repeat blocks use { type: 'repeat', source: 'items', itemAlias: 'item', children: [...] }. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes. Any block accepts a `conditions` array so it only renders for matching recipients; conditions must all match unless the block sets `conditionsMatch: "any"`, and a numeric path segment reads one list item (`goals.0:bias`). To branch on a value passed in transactional `variables` or an automation `event` payload, use { "id": "c1", "field": "variable", "operator": "is", "value": "plan:pro" }; "attribute" uses the same "name:value" form, while "email"/"firstName"/"lastName" use a plain comparison value. Live subscriber fields are "status", "tag", "list", "segment", "event", "emailProvider", "phone", "phoneCountry", "smsStatus", "added", "stripeProduct", "stripeCurrentProduct", "stripeTrialProduct", "commerceProduct", "commerceCollection", "emailSent", "emailDelivered", "emailOpened", "emailClicked", "emailBounced", and "emailComplained". They use the same field-specific values and operators as segment filters, for example { "id": "c2", "field": "segment", "operator": "is", "value": "seg_123" }, { "id": "c3", "field": "tag", "operator": "contains", "value": "vip" }, or { "id": "c4", "field": "event", "operator": "at_least", "value": "purchase:3:30d" }. Supported operators across fields are is, is_not, contains, not_contains, starts_with, not_starts_with, gt, gte, lt, lte, less_than, more_than, at_least, less_than_count, is_empty, is_not_empty, is_temporary_bounce, and is_permanent_bounce; each field accepts only its segment-filter operators. Recipients without a stored subscriber match use the OTHERWISE branch or hide a conditionally displayed block. For if/else, use a { type: "conditional-group", conditions: [...], ifBranch: { children: [...] }, elseBranch: { children: [...] } } block. `styles` applies to the block's own container, not to an inner rendered element. On a button block, `styles.backgroundColor` colors the band behind the button and `styles.textColor` does not reach the label - set the top-level `buttonColor` and `buttonTextColor` fields instead, or leave them unset to inherit the email theme's primary color. Unsupported fields are discarded and reported in the response `warnings` array rather than rejected. Polls and NPS surveys use a native poll block. For answer buttons use { "type": "poll", "variant": "options", "question": "What did you think?", "options": [{ "label": "Loved it", "value": "loved" }, { "label": "Not for me", "value": "not_for_me" }], "attributeKey": "email_feedback" }. For NPS use { "type": "poll", "variant": "nps", "question": "How likely are you to recommend us?", "options": [], "attributeKey": "nps_score", "npsLowLabel": "Not likely", "npsHighLabel": "Very likely" }. `attributeKey` stores the latest response for segmentation. Set `allowMultiple: true` on a text-only options poll to let recipients pick several answers: answer links then open a hosted selection page where the recipient checks any number of options and saves them in one submit, and `attributeKey` stores the list of selected values (filter with attribute `contains`). Multi-select polls cannot use option images or configurations whose encoded signed links exceed the delivery-safe size limit. Optional `appearance` picks the answer style: "soft" (default), "pill", "outline", "filled", "pop" (hard-shadow boxes), "brutal" (square uppercase slabs), "quiz" (A/B/C letter badges), or "minimal" (bare ruled rows). `accentColor` recolors every appearance, including "brutal". `optionRadius` sets answer-button corners in px (0 is square) independently of `styles.borderRadius`, while `questionColor` recolors only the question. `fontFamily` applies to the poll; `optionFontSize`, `optionFontWeight`, `optionLetterSpacing`, and `optionTextTransform` style answers, and the matching `questionFontSize`, `questionFontWeight`, `questionLetterSpacing`, and `questionTextTransform` fields style the question. Sizes and spacing are px, weights are 100-900, and transforms are "none" or "uppercase". Optional `confirmationMessage` customizes the hosted thank-you page; set `redirectUrl` only when respondents should land on another page. For a new image, call `upload_image_asset` first and insert its returned `imageBlock`. A responsive fixed-height screenshot crop uses { "type": "image", "src": "https://...", "alt": "Product dashboard", "width": 100, "widthType": "percent", "height": 320, "objectFit": "cover", "align": "center" }. A YouTube video block can override its still with { "type": "video", "videoUrl": "https://www.youtube.com/watch?v=...", "thumbnailUrl": "https://cdn.example.com/cover.jpg", "alt": "Watch the product tour" }. Replacing the blocks array without `thumbnailUrl` restores YouTube's own thumbnail; the video destination remains `videoUrl`. Minimal valid core examples: {"type":"heading","content":"Title","level":1}; {"type":"text","content":"<p>Paragraph with <strong>bold</strong></p>","variant":"paragraph"}; {"type":"list","variant":"bullet","items":[{"content":"First point"},{"content":"Second point"}]}; {"type":"steps","variant":"timeline","items":[{"title":"Connect","description":"Link your account."},{"title":"Launch","description":"Send your first campaign."}]}; {"type":"button","text":"Click Me","url":"https://example.com","variant":"primary"}; {"type":"image","src":"https://...","alt":"Description","width":100,"widthType":"percent","height":240,"objectFit":"cover","href":"https://example.com","align":"center"}. Heading and text use `content`; button uses `text` but also accepts `content` as an alias and defaults `variant` to `primary`. Image `widthType` accepts `percent` or `px`. Lists are their own block type, never a text variant: `text` accepts only variant paragraph, lead, or html and never accepts `items`, so a numbered list is {"type":"list","variant":"numbered","items":[{"content":"First"}]} and a visual numbered walkthrough is {"type":"steps","variant":"numbered","items":[{"title":"Step one","description":"What happens"},{"title":"Step two","description":"What happens next"}]}. List items carry `content`; steps items carry `title` plus an optional `description`. Call `get_email_block_schema` for the required and optional fields of any other block type. If that tool is not in the MCP tool list, enable it on the Sequenzy connector rather than inferring fields from live HTML; the same reference is also at `sequenzy://email-blocks` (MCP resource), `GET /api/v1/email-blocks` (API), and `sequenzy blocks <type>` (CLI).
Clear enough to supply this argument.
prompt
Generate campaign blocks from a prompt. Generated blocks include the company's logo and footer, and the created campaign inherits the company brand font. Mutually exclusive with `html`, `blocks`, and `templateId`.
Clear enough to supply this argument.
style
Prompt generation style. Only used with `prompt`; this is not Style > Format. Pass 'designed' or 'plain' to force the designed or plain-text email style; other values (minimal, branded, promotional) are freeform prompt guidance and the company's email style preference decides. Use `emailPreset` to set branded or minimal chrome on native blocks.
Clear enough to supply this argument.
tone
Prompt generation tone: professional, casual, friendly. Only used with `prompt`.
Clear enough to supply this argument.
emailPreset
Per-email Style > Format for native Sequenzy blocks, including emails with supported custom HTML blocks. Use minimal for a direct text-forward note without the company logo and with the simple footer, or branded for branded chrome. This does not change the company-wide default and is not `style`, which is a prompt-generation hint valid only with `prompt`. Not a lossless toggle: minimal deletes standalone logo blocks, so switching back to branded generates a new logo block with a new id and the company name as alt text - send the authored logo block in `blocks` alongside the branded update to keep it. A standalone raw HTML email does not support this field, and emailPreset must not be combined with html.
Clear enough to supply this argument.
templateId
Use a template instead of html
Clear enough to supply this argument.
segmentId
Shorthand for targeting one saved segment. Equivalent to targetLists {type:'segment', segmentId}. Mutually exclusive with `targetLists` and `listIds`.
Clear enough to supply this argument.
listIds
Shorthand for targeting one or more lists. Equivalent to targetLists {type:'lists', listIds}. Mutually exclusive with `targetLists` and `segmentId`.
Clear enough to supply this argument.
targetLists › type
Audience shape. all = every active subscriber; lists = subscribers on any of listIds; segment = one saved segment; filtered = ad-hoc subscriber filters; rules = combined include/exclude rules.
Clear enough to supply this argument.
targetLists › listIds
List IDs to target. Required when type is 'lists'.
Clear enough to supply this argument.
targetLists › segmentId
Saved segment ID. Required when type is 'segment'.
Clear enough to supply this argument.
targetLists › filters
Subscriber filter objects {id, field, operator, value}. Required when type is 'filtered'.
Clear enough to supply this argument.
targetLists › filterJoinOperator
How 'filtered' filters combine. Optional, defaults to 'and'.
Clear enough to supply this argument.
targetLists › include
Include rules. Required when type is 'rules'; an include rule or explicit includedSubscriberIds are needed to schedule. Each rule is {type:'all'} | {type:'lists', listIds:[...]} | {type:'segments', segmentIds:[...]} | {type:'filtered', filters:[...]}.
Clear enough to supply this argument.
targetLists › exclude
Exclude rules for type 'rules'. Optional. Same shapes as include except {type:'all'}.
Clear enough to supply this argument.
targetLists › includedSubscriberIds
Explicit selected contacts, including frozen groups from create_campaign_for_audience. An empty include array is allowed when these IDs are present.
Clear enough to supply this argument.
targetLists › excludedSubscriberIds
Individual contacts to exclude from the audience. Explicit includedSubscriberIds override exclusions; remove a contact from that array to exclude it from a frozen group.
Clear enough to supply this argument.
fromEmail
From address for this campaign. Its domain must be configured and verified; a sender profile is created when needed.
Clear enough to supply this argument.
fromName
Display name recipients see, e.g. 'Brennon at TradeTally'. Selects the sender identity of that name on fromEmail, creating it when the address has no identity by that name; the mailbox's other display names, and everything pinned to them, are untouched. Requires fromEmail; omit it when using senderProfileId, which already carries its own display name.
Clear enough to supply this argument.
senderProfileId
Existing sender profile ID (see list_sender_profiles). It already supplies both the From address and display name, so send it on its own and omit fromEmail and fromName.
Clear enough to supply this argument.
replyTo
Reply-To address for this campaign. A reply profile is created when needed.
Clear enough to supply this argument.
replyToName
Display name for the Reply-To address. Requires replyTo; omit it when using replyProfileId, which already carries its own display name. An address carries one Reply-To name company-wide: if replyTo already has a saved profile under a different name, that saved name is kept and the response `warnings` array says so. Rename it with update_sender_profile (type 'reply') to change it everywhere.
Clear enough to supply this argument.
replyProfileId
Existing reply profile ID (see list_sender_profiles). It already supplies both the Reply-To address and display name, so send it on its own and omit replyTo and replyToName.
Clear enough to supply this argument.
campaignData
Optional campaign-scoped JSON data for repeat blocks and personalization.
Clear enough to supply this argument.
computedLists
Optional computed list definitions derived from campaignData at send time.
Clear enough to supply this argument.
labels
Optional label names to assign. Missing labels are created automatically.
Clear enough to supply this argument.
attachments › items › filename
Name recipients see, such as report.pdf. Its extension sets the file type when contentType is omitted.
Clear enough to supply this argument.
attachments › items › content
Base64 file content. Sequenzy stores the file and returns a path. Provide content or path, not both.
Clear enough to supply this argument.
attachments › items › path
Public HTTP(S) URL fetched when the campaign starts sending. Provide content or path, not both.
Clear enough to supply this argument.
attachments › items › contentType
MIME type for Base64 content, such as application/pdf. PDF, Office, ZIP, image, audio, video and text files are accepted; HTML and SVG are not.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "create_campaign",
"description": "Create a new campaign. Omit all content fields to create an empty draft. `prompt` generates net-new content from natural language. `blocks` are finished caller-supplied Sequenzy content and `html` is preserved/imported markup. Pass `emailPreset` with native blocks to set Style > Format (minimal or branded); `style` is a prompt-generation hint only. Defaults to draft; status 'sent' only archives an already-sent campaign.",
"inputSchema": {
"type": "object",
"required": [
"name"
],
"properties": {
"html": {
"type": "string",
"description": "Email HTML content. Mutually exclusive with `blocks`. Use this for imported provider campaigns. Raw HTML is stored as one opaque block. Sequenzy preserves that markup but does not add a company logo, branded native sections, or theme-driven block design. Use blocks for editor-native design, or a drafting prompt when you want Sequenzy to compose a new branded email. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes."
},
"name": {
"type": "string",
"description": "Campaign name"
},
"tone": {
"type": "string",
"description": "Prompt generation tone: professional, casual, friendly. Only used with `prompt`."
},
"style": {
"type": "string",
"description": "Prompt generation style. Only used with `prompt`; this is not Style > Format. Pass 'designed' or 'plain' to force the designed or plain-text email style; other values (minimal, branded, promotional) are freeform prompt guidance and the company's email style preference decides. Use `emailPreset` to set branded or minimal chrome on native blocks."
},
"blocks": {
"type": "array",
"items": {
"type": "object"
},
"description": "Sequenzy email blocks. Use this for editor-compatible content, including conditional and repeat blocks. For provider-migrated HTML from another email platform, prefer the `html` field instead; Sequenzy stores it as one raw HTML block to preserve the original design. Use `styles` for per-block background, background opacity, text color, padding, border radius, border width, and border color. Recolor body copy with `styles.textColor` (or the top-level `textColor` alias), not with an inline `style` on `<p>` or `<span>`. Top-level style aliases such as `backgroundColor`, `backgroundOpacity`, `textColor`, `textAlign`, `borderColor`, `borderWidth`, and `borderRadius` are also accepted and saved under `styles`. Repeat blocks use { type: 'repeat', source: 'items', itemAlias: 'item', children: [...] }. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes. Any block accepts a `conditions` array so it only renders for matching recipients; conditions must all match unless the block sets `conditionsMatch: \"any\"`, and a numeric path segment reads one list item (`goals.0:bias`). To branch on a value passed in transactional `variables` or an automation `event` payload, use { \"id\": \"c1\", \"field\": \"variable\", \"operator\": \"is\", \"value\": \"plan:pro\" }; \"attribute\" uses the same \"name:value\" form, while \"email\"/\"firstName\"/\"lastName\" use a plain comparison value. Live subscriber fields are \"status\", \"tag\", \"list\", \"segment\", \"event\", \"emailProvider\", \"phone\", \"phoneCountry\", \"smsStatus\", \"added\", \"stripeProduct\", \"stripeCurrentProduct\", \"stripeTrialProduct\", \"commerceProduct\", \"commerceCollection\", \"emailSent\", \"emailDelivered\", \"emailOpened\", \"emailClicked\", \"emailBounced\", and \"emailComplained\". They use the same field-specific values and operators as segment filters, for example { \"id\": \"c2\", \"field\": \"segment\", \"operator\": \"is\", \"value\": \"seg_123\" }, { \"id\": \"c3\", \"field\": \"tag\", \"operator\": \"contains\", \"value\": \"vip\" }, or { \"id\": \"c4\", \"field\": \"event\", \"operator\": \"at_least\", \"value\": \"purchase:3:30d\" }. Supported operators across fields are is, is_not, contains, not_contains, starts_with, not_starts_with, gt, gte, lt, lte, less_than, more_than, at_least, less_than_count, is_empty, is_not_empty, is_temporary_bounce, and is_permanent_bounce; each field accepts only its segment-filter operators. Recipients without a stored subscriber match use the OTHERWISE branch or hide a conditionally displayed block. For if/else, use a { type: \"conditional-group\", conditions: [...], ifBranch: { children: [...] }, elseBranch: { children: [...] } } block. `styles` applies to the block's own container, not to an inner rendered element. On a button block, `styles.backgroundColor` colors the band behind the button and `styles.textColor` does not reach the label - set the top-level `buttonColor` and `buttonTextColor` fields instead, or leave them unset to inherit the email theme's primary color. Unsupported fields are discarded and reported in the response `warnings` array rather than rejected. Polls and NPS surveys use a native poll block. For answer buttons use { \"type\": \"poll\", \"variant\": \"options\", \"question\": \"What did you think?\", \"options\": [{ \"label\": \"Loved it\", \"value\": \"loved\" }, { \"label\": \"Not for me\", \"value\": \"not_for_me\" }], \"attributeKey\": \"email_feedback\" }. For NPS use { \"type\": \"poll\", \"variant\": \"nps\", \"question\": \"How likely are you to recommend us?\", \"options\": [], \"attributeKey\": \"nps_score\", \"npsLowLabel\": \"Not likely\", \"npsHighLabel\": \"Very likely\" }. `attributeKey` stores the latest response for segmentation. Set `allowMultiple: true` on a text-only options poll to let recipients pick several answers: answer links then open a hosted selection page where the recipient checks any number of options and saves them in one submit, and `attributeKey` stores the list of selected values (filter with attribute `contains`). Multi-select polls cannot use option images or configurations whose encoded signed links exceed the delivery-safe size limit. Optional `appearance` picks the answer style: \"soft\" (default), \"pill\", \"outline\", \"filled\", \"pop\" (hard-shadow boxes), \"brutal\" (square uppercase slabs), \"quiz\" (A/B/C letter badges), or \"minimal\" (bare ruled rows). `accentColor` recolors every appearance, including \"brutal\". `optionRadius` sets answer-button corners in px (0 is square) independently of `styles.borderRadius`, while `questionColor` recolors only the question. `fontFamily` applies to the poll; `optionFontSize`, `optionFontWeight`, `optionLetterSpacing`, and `optionTextTransform` style answers, and the matching `questionFontSize`, `questionFontWeight`, `questionLetterSpacing`, and `questionTextTransform` fields style the question. Sizes and spacing are px, weights are 100-900, and transforms are \"none\" or \"uppercase\". Optional `confirmationMessage` customizes the hosted thank-you page; set `redirectUrl` only when respondents should land on another page. For a new image, call `upload_image_asset` first and insert its returned `imageBlock`. A responsive fixed-height screenshot crop uses { \"type\": \"image\", \"src\": \"https://...\", \"alt\": \"Product dashboard\", \"width\": 100, \"widthType\": \"percent\", \"height\": 320, \"objectFit\": \"cover\", \"align\": \"center\" }. A YouTube video block can override its still with { \"type\": \"video\", \"videoUrl\": \"https://www.youtube.com/watch?v=...\", \"thumbnailUrl\": \"https://cdn.example.com/cover.jpg\", \"alt\": \"Watch the product tour\" }. Replacing the blocks array without `thumbnailUrl` restores YouTube's own thumbnail; the video destination remains `videoUrl`. Minimal valid core examples: {\"type\":\"heading\",\"content\":\"Title\",\"level\":1}; {\"type\":\"text\",\"content\":\"<p>Paragraph with <strong>bold</strong></p>\",\"variant\":\"paragraph\"}; {\"type\":\"list\",\"variant\":\"bullet\",\"items\":[{\"content\":\"First point\"},{\"content\":\"Second point\"}]}; {\"type\":\"steps\",\"variant\":\"timeline\",\"items\":[{\"title\":\"Connect\",\"description\":\"Link your account.\"},{\"title\":\"Launch\",\"description\":\"Send your first campaign.\"}]}; {\"type\":\"button\",\"text\":\"Click Me\",\"url\":\"https://example.com\",\"variant\":\"primary\"}; {\"type\":\"image\",\"src\":\"https://...\",\"alt\":\"Description\",\"width\":100,\"widthType\":\"percent\",\"height\":240,\"objectFit\":\"cover\",\"href\":\"https://example.com\",\"align\":\"center\"}. Heading and text use `content`; button uses `text` but also accepts `content` as an alias and defaults `variant` to `primary`. Image `widthType` accepts `percent` or `px`. Lists are their own block type, never a text variant: `text` accepts only variant paragraph, lead, or html and never accepts `items`, so a numbered list is {\"type\":\"list\",\"variant\":\"numbered\",\"items\":[{\"content\":\"First\"}]} and a visual numbered walkthrough is {\"type\":\"steps\",\"variant\":\"numbered\",\"items\":[{\"title\":\"Step one\",\"description\":\"What happens\"},{\"title\":\"Step two\",\"description\":\"What happens next\"}]}. List items carry `content`; steps items carry `title` plus an optional `description`. Call `get_email_block_schema` for the required and optional fields of any other block type. If that tool is not in the MCP tool list, enable it on the Sequenzy connector rather than inferring fields from live HTML; the same reference is also at `sequenzy://email-blocks` (MCP resource), `GET /api/v1/email-blocks` (API), and `sequenzy blocks <type>` (CLI)."
},
"labels": {
"type": "array",
"items": {
"type": "string"
},
"description": "Optional label names to assign. Missing labels are created automatically."
},
"prompt": {
"type": "string",
"description": "Generate campaign blocks from a prompt. Generated blocks include the company's logo and footer, and the created campaign inherits the company brand font. Mutually exclusive with `html`, `blocks`, and `templateId`."
},
"sentAt": {
"type": "string",
"description": "ISO date-time for an imported/already-sent campaign. Only valid when status is sent; defaults to now if omitted."
},
"status": {
"type": "string",
"description": "Initial status: draft or sent. Defaults to draft. Use sent only for imported/already-sent campaigns; it does not send email or create delivery history."
},
"listIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Shorthand for targeting one or more lists. Equivalent to targetLists {type:'lists', listIds}. Mutually exclusive with `targetLists` and `segmentId`."
},
"replyTo": {
"type": "string",
"description": "Reply-To address for this campaign. A reply profile is created when needed."
},
"subject": {
"type": "string",
"description": "Email subject line. Optional when `prompt` is provided because the generated subject will be used."
},
"fromName": {
"type": "string",
"description": "Display name recipients see, e.g. 'Brennon at TradeTally'. Selects the sender identity of that name on fromEmail, creating it when the address has no identity by that name; the mailbox's other display names, and everything pinned to them, are untouched. Requires fromEmail; omit it when using senderProfileId, which already carries its own display name."
},
"companyId": {
"type": "string",
"description": "Company ID to create the campaign in. If not provided, uses the currently selected company."
},
"fromEmail": {
"type": "string",
"description": "From address for this campaign. Its domain must be configured and verified; a sender profile is created when needed."
},
"segmentId": {
"type": "string",
"description": "Shorthand for targeting one saved segment. Equivalent to targetLists {type:'segment', segmentId}. Mutually exclusive with `targetLists` and `listIds`."
},
"templateId": {
"type": "string",
"description": "Use a template instead of html"
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"required": [
"filename"
],
"properties": {
"path": {
"type": "string",
"description": "Public HTTP(S) URL fetched when the campaign starts sending. Provide content or path, not both."
},
"content": {
"type": "string",
"description": "Base64 file content. Sequenzy stores the file and returns a path. Provide content or path, not both."
},
"filename": {
"type": "string",
"description": "Name recipients see, such as report.pdf. Its extension sets the file type when contentType is omitted."
},
"contentType": {
"type": "string",
"description": "MIME type for Base64 content, such as application/pdf. PDF, Office, ZIP, image, audio, video and text files are accepted; HTML and SVG are not."
}
}
},
"maxItems": 10,
"description": "Files attached to every recipient's email, including CC/BCC copies and test sends: up to 10 files and 5MB in total. Each item has a filename plus Base64 `content` or a public `path` URL. Inline images (contentId) are not supported on campaigns. If a file cannot be fetched or is too large when sending starts, nothing is sent and the campaign returns to draft."
},
"emailPreset": {
"enum": [
"branded",
"minimal"
],
"type": "string",
"description": "Per-email Style > Format for native Sequenzy blocks, including emails with supported custom HTML blocks. Use minimal for a direct text-forward note without the company logo and with the simple footer, or branded for branded chrome. This does not change the company-wide default and is not `style`, which is a prompt-generation hint valid only with `prompt`. Not a lossless toggle: minimal deletes standalone logo blocks, so switching back to branded generates a new logo block with a new id and the company name as alt text - send the authored logo block in `blocks` alongside the branded update to keep it. A standalone raw HTML email does not support this field, and emailPreset must not be combined with html."
},
"previewText": {
"type": [
"string",
"null"
],
"description": "Email preview text. Optional when `prompt` is provided because the generated preview text will be used."
},
"replyToName": {
"type": "string",
"description": "Display name for the Reply-To address. Requires replyTo; omit it when using replyProfileId, which already carries its own display name. An address carries one Reply-To name company-wide: if replyTo already has a saved profile under a different name, that saved name is kept and the response `warnings` array says so. Rename it with update_sender_profile (type 'reply') to change it everywhere."
},
"targetLists": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"all",
"lists",
"segment",
"filtered",
"rules"
],
"type": "string",
"description": "Audience shape. all = every active subscriber; lists = subscribers on any of listIds; segment = one saved segment; filtered = ad-hoc subscriber filters; rules = combined include/exclude rules."
},
"exclude": {
"type": "array",
"items": {
"type": "object"
},
"description": "Exclude rules for type 'rules'. Optional. Same shapes as include except {type:'all'}."
},
"filters": {
"type": "array",
"items": {
"type": "object"
},
"description": "Subscriber filter objects {id, field, operator, value}. Required when type is 'filtered'."
},
"include": {
"type": "array",
"items": {
"type": "object"
},
"description": "Include rules. Required when type is 'rules'; an include rule or explicit includedSubscriberIds are needed to schedule. Each rule is {type:'all'} | {type:'lists', listIds:[...]} | {type:'segments', segmentIds:[...]} | {type:'filtered', filters:[...]}."
},
"listIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "List IDs to target. Required when type is 'lists'."
},
"segmentId": {
"type": [
"string",
"null"
],
"description": "Saved segment ID. Required when type is 'segment'."
},
"filterJoinOperator": {
"enum": [
"and",
"or"
],
"type": "string",
"description": "How 'filtered' filters combine. Optional, defaults to 'and'."
},
"excludedSubscriberIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Individual contacts to exclude from the audience. Explicit includedSubscriberIds override exclusions; remove a contact from that array to exclude it from a frozen group."
},
"includedSubscriberIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Explicit selected contacts, including frozen groups from create_campaign_for_audience. An empty include array is allowed when these IDs are present."
}
},
"description": "Campaign audience, saved on the draft. Omit to leave targeting unset and set it later with `update_campaign` or `schedule_campaign`. Examples: {type:'all'}, {type:'lists', listIds:['list_123']}, {type:'segment', segmentId:'seg_123'}, {type:'filtered', filters:[...], filterJoinOperator:'and'}, or {type:'rules', include:[{type:'lists', listIds:['list_123']}], exclude:[{type:'segments', segmentIds:['seg_123']}]}. Use this to send straight to a list without creating a segment first. Mutually exclusive with `segmentId` and `listIds`.",
"additionalProperties": true
},
"campaignData": {
"type": "object",
"description": "Optional campaign-scoped JSON data for repeat blocks and personalization."
},
"trackingCode": {
"type": "string",
"description": "Optional campaign tracking code for UTM templates. Use only when explicitly requested."
},
"computedLists": {
"type": "array",
"items": {
"type": "object"
},
"description": "Optional computed list definitions derived from campaignData at send time."
},
"replyProfileId": {
"type": "string",
"description": "Existing reply profile ID (see list_sender_profiles). It already supplies both the Reply-To address and display name, so send it on its own and omit replyTo and replyToName."
},
"senderProfileId": {
"type": "string",
"description": "Existing sender profile ID (see list_sender_profiles). It already supplies both the From address and display name, so send it on its own and omit fromEmail and fromName."
}
}
},
"annotations": {
"title": "Create Campaign",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description85/100
Update a draft campaign's content, audience, sending identity, labels, Style > Format, delivery pacing, or recipient limit. Pass emailPreset to change Style > Format on native blocks without rewriting copy. sendTimeOptimization, sendTimeWindowHours and maxRecipients persist on the draft and are used when the campaign is later scheduled unless schedule_campaign overrides them. Send Time Optimization is not a company or sequence setting. It is campaign-only: audit with list_campaigns or get_campaign (sendTimeOptimization, sendTimeWindowHours, default 12h window). Change a draft with update_campaign, or apply it when calling schedule_campaign. Sequences use sendingWindow (allowed local hours/days), which is a shared gate, not per-subscriber predicted send times.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs91/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
campaignId
Campaign ID
Explain the meaning of this value, not just its name.
name
Campaign name
Clear enough to supply this argument.
subject
Email subject line
Clear enough to supply this argument.
trackingCode
Optional campaign tracking code for UTM templates. Use only when explicitly requested. Send an empty string to clear it.
Clear enough to supply this argument.
html
Email HTML content. Mutually exclusive with `blocks`. Use this for imported provider campaigns. Raw HTML is stored as one opaque block. Sequenzy preserves that markup but does not add a company logo, branded native sections, or theme-driven block design. Use blocks for editor-native design, or a drafting prompt when you want Sequenzy to compose a new branded email. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes.
Clear enough to supply this argument.
blocks
Sequenzy email blocks. Use this for editor-compatible content, including conditional and repeat blocks. For provider-migrated HTML from another email platform, prefer the `html` field instead; Sequenzy stores it as one raw HTML block to preserve the original design. Use `styles` for per-block background, background opacity, text color, padding, border radius, border width, and border color. Recolor body copy with `styles.textColor` (or the top-level `textColor` alias), not with an inline `style` on `<p>` or `<span>`. Top-level style aliases such as `backgroundColor`, `backgroundOpacity`, `textColor`, `textAlign`, `borderColor`, `borderWidth`, and `borderRadius` are also accepted and saved under `styles`. Repeat blocks use { type: 'repeat', source: 'items', itemAlias: 'item', children: [...] }. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes. Any block accepts a `conditions` array so it only renders for matching recipients; conditions must all match unless the block sets `conditionsMatch: "any"`, and a numeric path segment reads one list item (`goals.0:bias`). To branch on a value passed in transactional `variables` or an automation `event` payload, use { "id": "c1", "field": "variable", "operator": "is", "value": "plan:pro" }; "attribute" uses the same "name:value" form, while "email"/"firstName"/"lastName" use a plain comparison value. Live subscriber fields are "status", "tag", "list", "segment", "event", "emailProvider", "phone", "phoneCountry", "smsStatus", "added", "stripeProduct", "stripeCurrentProduct", "stripeTrialProduct", "commerceProduct", "commerceCollection", "emailSent", "emailDelivered", "emailOpened", "emailClicked", "emailBounced", and "emailComplained". They use the same field-specific values and operators as segment filters, for example { "id": "c2", "field": "segment", "operator": "is", "value": "seg_123" }, { "id": "c3", "field": "tag", "operator": "contains", "value": "vip" }, or { "id": "c4", "field": "event", "operator": "at_least", "value": "purchase:3:30d" }. Supported operators across fields are is, is_not, contains, not_contains, starts_with, not_starts_with, gt, gte, lt, lte, less_than, more_than, at_least, less_than_count, is_empty, is_not_empty, is_temporary_bounce, and is_permanent_bounce; each field accepts only its segment-filter operators. Recipients without a stored subscriber match use the OTHERWISE branch or hide a conditionally displayed block. For if/else, use a { type: "conditional-group", conditions: [...], ifBranch: { children: [...] }, elseBranch: { children: [...] } } block. `styles` applies to the block's own container, not to an inner rendered element. On a button block, `styles.backgroundColor` colors the band behind the button and `styles.textColor` does not reach the label - set the top-level `buttonColor` and `buttonTextColor` fields instead, or leave them unset to inherit the email theme's primary color. Unsupported fields are discarded and reported in the response `warnings` array rather than rejected. Polls and NPS surveys use a native poll block. For answer buttons use { "type": "poll", "variant": "options", "question": "What did you think?", "options": [{ "label": "Loved it", "value": "loved" }, { "label": "Not for me", "value": "not_for_me" }], "attributeKey": "email_feedback" }. For NPS use { "type": "poll", "variant": "nps", "question": "How likely are you to recommend us?", "options": [], "attributeKey": "nps_score", "npsLowLabel": "Not likely", "npsHighLabel": "Very likely" }. `attributeKey` stores the latest response for segmentation. Set `allowMultiple: true` on a text-only options poll to let recipients pick several answers: answer links then open a hosted selection page where the recipient checks any number of options and saves them in one submit, and `attributeKey` stores the list of selected values (filter with attribute `contains`). Multi-select polls cannot use option images or configurations whose encoded signed links exceed the delivery-safe size limit. Optional `appearance` picks the answer style: "soft" (default), "pill", "outline", "filled", "pop" (hard-shadow boxes), "brutal" (square uppercase slabs), "quiz" (A/B/C letter badges), or "minimal" (bare ruled rows). `accentColor` recolors every appearance, including "brutal". `optionRadius` sets answer-button corners in px (0 is square) independently of `styles.borderRadius`, while `questionColor` recolors only the question. `fontFamily` applies to the poll; `optionFontSize`, `optionFontWeight`, `optionLetterSpacing`, and `optionTextTransform` style answers, and the matching `questionFontSize`, `questionFontWeight`, `questionLetterSpacing`, and `questionTextTransform` fields style the question. Sizes and spacing are px, weights are 100-900, and transforms are "none" or "uppercase". Optional `confirmationMessage` customizes the hosted thank-you page; set `redirectUrl` only when respondents should land on another page. For a new image, call `upload_image_asset` first and insert its returned `imageBlock`. A responsive fixed-height screenshot crop uses { "type": "image", "src": "https://...", "alt": "Product dashboard", "width": 100, "widthType": "percent", "height": 320, "objectFit": "cover", "align": "center" }. A YouTube video block can override its still with { "type": "video", "videoUrl": "https://www.youtube.com/watch?v=...", "thumbnailUrl": "https://cdn.example.com/cover.jpg", "alt": "Watch the product tour" }. Replacing the blocks array without `thumbnailUrl` restores YouTube's own thumbnail; the video destination remains `videoUrl`. Minimal valid core examples: {"type":"heading","content":"Title","level":1}; {"type":"text","content":"<p>Paragraph with <strong>bold</strong></p>","variant":"paragraph"}; {"type":"list","variant":"bullet","items":[{"content":"First point"},{"content":"Second point"}]}; {"type":"steps","variant":"timeline","items":[{"title":"Connect","description":"Link your account."},{"title":"Launch","description":"Send your first campaign."}]}; {"type":"button","text":"Click Me","url":"https://example.com","variant":"primary"}; {"type":"image","src":"https://...","alt":"Description","width":100,"widthType":"percent","height":240,"objectFit":"cover","href":"https://example.com","align":"center"}. Heading and text use `content`; button uses `text` but also accepts `content` as an alias and defaults `variant` to `primary`. Image `widthType` accepts `percent` or `px`. Lists are their own block type, never a text variant: `text` accepts only variant paragraph, lead, or html and never accepts `items`, so a numbered list is {"type":"list","variant":"numbered","items":[{"content":"First"}]} and a visual numbered walkthrough is {"type":"steps","variant":"numbered","items":[{"title":"Step one","description":"What happens"},{"title":"Step two","description":"What happens next"}]}. List items carry `content`; steps items carry `title` plus an optional `description`. Call `get_email_block_schema` for the required and optional fields of any other block type. If that tool is not in the MCP tool list, enable it on the Sequenzy connector rather than inferring fields from live HTML; the same reference is also at `sequenzy://email-blocks` (MCP resource), `GET /api/v1/email-blocks` (API), and `sequenzy blocks <type>` (CLI).
Clear enough to supply this argument.
emailPreset
Per-email Style > Format for native Sequenzy blocks, including emails with supported custom HTML blocks. Use minimal for a direct text-forward note without the company logo and with the simple footer, or branded for branded chrome. This does not change the company-wide default and is not `style`, which is a prompt-generation hint valid only with `prompt`. Not a lossless toggle: minimal deletes standalone logo blocks, so switching back to branded generates a new logo block with a new id and the company name as alt text - send the authored logo block in `blocks` alongside the branded update to keep it. A standalone raw HTML email does not support this field, and emailPreset must not be combined with html.
Clear enough to supply this argument.
replyTo
Set reply-to using an existing reply profile email address for this company.
Clear enough to supply this argument.
replyProfileId
Set reply-to using a reply profile ID for this company (see list_sender_profiles). It already supplies both the Reply-To address and display name, so send it on its own and omit replyTo and replyToName.
Clear enough to supply this argument.
replyToName
Display name for the Reply-To address. Requires replyTo; omit it when using replyProfileId, which already carries its own display name. An address carries one Reply-To name company-wide: if replyTo already has a saved profile under a different name, that saved name is kept and the response `warnings` array says so. Rename it with update_sender_profile (type 'reply') to change it everywhere.
Clear enough to supply this argument.
fromEmail
Set this campaign's From address. Its domain must be configured and verified.
Clear enough to supply this argument.
fromName
Display name recipients see, e.g. 'Brennon at TradeTally'. Selects the sender identity of that name on fromEmail, creating it when the address has no identity by that name; the mailbox's other display names, and everything pinned to them, are untouched. Requires fromEmail; omit it when using senderProfileId, which already carries its own display name.
Clear enough to supply this argument.
senderProfileId
Set an existing sender profile (see list_sender_profiles). It already supplies both the From address and display name, so send it on its own and omit fromEmail and fromName.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
ccEmails
Addresses CC'd on every recipient's campaign email (max 10). Send an empty array or null to clear them; omit to leave unchanged.
Clear enough to supply this argument.
bccEmails
Addresses BCC'd on every recipient's campaign email (max 10). Send an empty array or null to clear them; omit to leave unchanged.
Clear enough to supply this argument.
campaignData
Set campaign-scoped JSON data for repeat blocks and personalization.
Clear enough to supply this argument.
computedLists
Set computed list definitions derived from campaignData at send time.
Clear enough to supply this argument.
targetLists › type
Audience shape. all = every active subscriber; lists = subscribers on any of listIds; segment = one saved segment; filtered = ad-hoc subscriber filters; rules = combined include/exclude rules.
Clear enough to supply this argument.
targetLists › listIds
List IDs to target. Required when type is 'lists'.
Clear enough to supply this argument.
targetLists › segmentId
Saved segment ID. Required when type is 'segment'.
Clear enough to supply this argument.
targetLists › filters
Subscriber filter objects {id, field, operator, value}. Required when type is 'filtered'.
Clear enough to supply this argument.
targetLists › filterJoinOperator
How 'filtered' filters combine. Optional, defaults to 'and'.
Clear enough to supply this argument.
targetLists › include
Include rules. Required when type is 'rules'; an include rule or explicit includedSubscriberIds are needed to schedule. Each rule is {type:'all'} | {type:'lists', listIds:[...]} | {type:'segments', segmentIds:[...]} | {type:'filtered', filters:[...]}.
Clear enough to supply this argument.
targetLists › exclude
Exclude rules for type 'rules'. Optional. Same shapes as include except {type:'all'}.
Clear enough to supply this argument.
targetLists › includedSubscriberIds
Explicit selected contacts, including frozen groups from create_campaign_for_audience. An empty include array is allowed when these IDs are present.
Clear enough to supply this argument.
targetLists › excludedSubscriberIds
Individual contacts to exclude from the audience. Explicit includedSubscriberIds override exclusions; remove a contact from that array to exclude it from a frozen group.
Clear enough to supply this argument.
segmentId
Shorthand for retargeting the draft at one saved segment. Equivalent to targetLists {type:'segment', segmentId}. Mutually exclusive with `targetLists` and `listIds`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
listIds
Shorthand for retargeting the draft at one or more lists. Equivalent to targetLists {type:'lists', listIds}. Mutually exclusive with `targetLists` and `segmentId`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
labels
Replacement label names. Send an empty array to clear labels. Missing labels are created automatically.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sendTimeOptimization
Deliver each recipient at their predicted best open hour within sendTimeWindowHours of scheduledAt (default 12h). Campaign-only: there is no company or sequence STO toggle. Sequences use sendingWindow instead. spreadOverHours takes precedence and turns STO off; sendInRecipientTimezone also turns it off.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sendTimeWindowHours
STO delivery window in hours from scheduledAt (integer 1-24, default 12). Only used when sendTimeOptimization is true. Recipients whose predicted hour falls outside the window are snapped to the nearest edge. Sequences have no equivalent.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
maxRecipients
Send to at most this many audience members: an integer from 1 to 10,000,000, or null to remove the limit. The first N matching subscribers (by subscriber id) receive the campaign after every audience and suppression rule is applied, and recipients already reached count against the cap when a paused send resumes. Use it to ramp up a new domain or to soft-launch an offer; duplicate the campaign and exclude contacts who already received it to send the next batch. Applies to email campaigns.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
attachments › items › filename
Name recipients see, such as report.pdf. Its extension sets the file type when contentType is omitted.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
attachments › items › content
Base64 file content. Sequenzy stores the file and returns a path. Provide content or path, not both.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
attachments › items › path
Public HTTP(S) URL fetched when the campaign starts sending. Provide content or path, not both.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
attachments › items › contentType
MIME type for Base64 content, such as application/pdf. PDF, Office, ZIP, image, audio, video and text files are accepted; HTML and SVG are not.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "update_campaign",
"description": "Update a draft campaign's content, audience, sending identity, labels, Style > Format, delivery pacing, or recipient limit. Pass emailPreset to change Style > Format on native blocks without rewriting copy. sendTimeOptimization, sendTimeWindowHours and maxRecipients persist on the draft and are used when the campaign is later scheduled unless schedule_campaign overrides them. Send Time Optimization is not a company or sequence setting. It is campaign-only: audit with list_campaigns or get_campaign (sendTimeOptimization, sendTimeWindowHours, default 12h window). Change a draft with update_campaign, or apply it when calling schedule_campaign. Sequences use sendingWindow (allowed local hours/days), which is a shared gate, not per-subscriber predicted send times.",
"inputSchema": {
"type": "object",
"required": [
"campaignId"
],
"properties": {
"html": {
"type": "string",
"description": "Email HTML content. Mutually exclusive with `blocks`. Use this for imported provider campaigns. Raw HTML is stored as one opaque block. Sequenzy preserves that markup but does not add a company logo, branded native sections, or theme-driven block design. Use blocks for editor-native design, or a drafting prompt when you want Sequenzy to compose a new branded email. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes."
},
"name": {
"type": "string",
"description": "Campaign name"
},
"blocks": {
"type": "array",
"items": {
"type": "object"
},
"description": "Sequenzy email blocks. Use this for editor-compatible content, including conditional and repeat blocks. For provider-migrated HTML from another email platform, prefer the `html` field instead; Sequenzy stores it as one raw HTML block to preserve the original design. Use `styles` for per-block background, background opacity, text color, padding, border radius, border width, and border color. Recolor body copy with `styles.textColor` (or the top-level `textColor` alias), not with an inline `style` on `<p>` or `<span>`. Top-level style aliases such as `backgroundColor`, `backgroundOpacity`, `textColor`, `textAlign`, `borderColor`, `borderWidth`, and `borderRadius` are also accepted and saved under `styles`. Repeat blocks use { type: 'repeat', source: 'items', itemAlias: 'item', children: [...] }. Merge tags resolve in this content but are always HTML-escaped; prefix a tag with 'html.' - e.g. {{html.subscriber.body_html}} - to insert a trusted subscriber attribute or variable holding prebuilt HTML unescaped. Injected HTML is sanitized (scripts, event handlers, and dangerous URLs stripped), must be final HTML, and renders raw only in HTML text position, never inside attributes. Any block accepts a `conditions` array so it only renders for matching recipients; conditions must all match unless the block sets `conditionsMatch: \"any\"`, and a numeric path segment reads one list item (`goals.0:bias`). To branch on a value passed in transactional `variables` or an automation `event` payload, use { \"id\": \"c1\", \"field\": \"variable\", \"operator\": \"is\", \"value\": \"plan:pro\" }; \"attribute\" uses the same \"name:value\" form, while \"email\"/\"firstName\"/\"lastName\" use a plain comparison value. Live subscriber fields are \"status\", \"tag\", \"list\", \"segment\", \"event\", \"emailProvider\", \"phone\", \"phoneCountry\", \"smsStatus\", \"added\", \"stripeProduct\", \"stripeCurrentProduct\", \"stripeTrialProduct\", \"commerceProduct\", \"commerceCollection\", \"emailSent\", \"emailDelivered\", \"emailOpened\", \"emailClicked\", \"emailBounced\", and \"emailComplained\". They use the same field-specific values and operators as segment filters, for example { \"id\": \"c2\", \"field\": \"segment\", \"operator\": \"is\", \"value\": \"seg_123\" }, { \"id\": \"c3\", \"field\": \"tag\", \"operator\": \"contains\", \"value\": \"vip\" }, or { \"id\": \"c4\", \"field\": \"event\", \"operator\": \"at_least\", \"value\": \"purchase:3:30d\" }. Supported operators across fields are is, is_not, contains, not_contains, starts_with, not_starts_with, gt, gte, lt, lte, less_than, more_than, at_least, less_than_count, is_empty, is_not_empty, is_temporary_bounce, and is_permanent_bounce; each field accepts only its segment-filter operators. Recipients without a stored subscriber match use the OTHERWISE branch or hide a conditionally displayed block. For if/else, use a { type: \"conditional-group\", conditions: [...], ifBranch: { children: [...] }, elseBranch: { children: [...] } } block. `styles` applies to the block's own container, not to an inner rendered element. On a button block, `styles.backgroundColor` colors the band behind the button and `styles.textColor` does not reach the label - set the top-level `buttonColor` and `buttonTextColor` fields instead, or leave them unset to inherit the email theme's primary color. Unsupported fields are discarded and reported in the response `warnings` array rather than rejected. Polls and NPS surveys use a native poll block. For answer buttons use { \"type\": \"poll\", \"variant\": \"options\", \"question\": \"What did you think?\", \"options\": [{ \"label\": \"Loved it\", \"value\": \"loved\" }, { \"label\": \"Not for me\", \"value\": \"not_for_me\" }], \"attributeKey\": \"email_feedback\" }. For NPS use { \"type\": \"poll\", \"variant\": \"nps\", \"question\": \"How likely are you to recommend us?\", \"options\": [], \"attributeKey\": \"nps_score\", \"npsLowLabel\": \"Not likely\", \"npsHighLabel\": \"Very likely\" }. `attributeKey` stores the latest response for segmentation. Set `allowMultiple: true` on a text-only options poll to let recipients pick several answers: answer links then open a hosted selection page where the recipient checks any number of options and saves them in one submit, and `attributeKey` stores the list of selected values (filter with attribute `contains`). Multi-select polls cannot use option images or configurations whose encoded signed links exceed the delivery-safe size limit. Optional `appearance` picks the answer style: \"soft\" (default), \"pill\", \"outline\", \"filled\", \"pop\" (hard-shadow boxes), \"brutal\" (square uppercase slabs), \"quiz\" (A/B/C letter badges), or \"minimal\" (bare ruled rows). `accentColor` recolors every appearance, including \"brutal\". `optionRadius` sets answer-button corners in px (0 is square) independently of `styles.borderRadius`, while `questionColor` recolors only the question. `fontFamily` applies to the poll; `optionFontSize`, `optionFontWeight`, `optionLetterSpacing`, and `optionTextTransform` style answers, and the matching `questionFontSize`, `questionFontWeight`, `questionLetterSpacing`, and `questionTextTransform` fields style the question. Sizes and spacing are px, weights are 100-900, and transforms are \"none\" or \"uppercase\". Optional `confirmationMessage` customizes the hosted thank-you page; set `redirectUrl` only when respondents should land on another page. For a new image, call `upload_image_asset` first and insert its returned `imageBlock`. A responsive fixed-height screenshot crop uses { \"type\": \"image\", \"src\": \"https://...\", \"alt\": \"Product dashboard\", \"width\": 100, \"widthType\": \"percent\", \"height\": 320, \"objectFit\": \"cover\", \"align\": \"center\" }. A YouTube video block can override its still with { \"type\": \"video\", \"videoUrl\": \"https://www.youtube.com/watch?v=...\", \"thumbnailUrl\": \"https://cdn.example.com/cover.jpg\", \"alt\": \"Watch the product tour\" }. Replacing the blocks array without `thumbnailUrl` restores YouTube's own thumbnail; the video destination remains `videoUrl`. Minimal valid core examples: {\"type\":\"heading\",\"content\":\"Title\",\"level\":1}; {\"type\":\"text\",\"content\":\"<p>Paragraph with <strong>bold</strong></p>\",\"variant\":\"paragraph\"}; {\"type\":\"list\",\"variant\":\"bullet\",\"items\":[{\"content\":\"First point\"},{\"content\":\"Second point\"}]}; {\"type\":\"steps\",\"variant\":\"timeline\",\"items\":[{\"title\":\"Connect\",\"description\":\"Link your account.\"},{\"title\":\"Launch\",\"description\":\"Send your first campaign.\"}]}; {\"type\":\"button\",\"text\":\"Click Me\",\"url\":\"https://example.com\",\"variant\":\"primary\"}; {\"type\":\"image\",\"src\":\"https://...\",\"alt\":\"Description\",\"width\":100,\"widthType\":\"percent\",\"height\":240,\"objectFit\":\"cover\",\"href\":\"https://example.com\",\"align\":\"center\"}. Heading and text use `content`; button uses `text` but also accepts `content` as an alias and defaults `variant` to `primary`. Image `widthType` accepts `percent` or `px`. Lists are their own block type, never a text variant: `text` accepts only variant paragraph, lead, or html and never accepts `items`, so a numbered list is {\"type\":\"list\",\"variant\":\"numbered\",\"items\":[{\"content\":\"First\"}]} and a visual numbered walkthrough is {\"type\":\"steps\",\"variant\":\"numbered\",\"items\":[{\"title\":\"Step one\",\"description\":\"What happens\"},{\"title\":\"Step two\",\"description\":\"What happens next\"}]}. List items carry `content`; steps items carry `title` plus an optional `description`. Call `get_email_block_schema` for the required and optional fields of any other block type. If that tool is not in the MCP tool list, enable it on the Sequenzy connector rather than inferring fields from live HTML; the same reference is also at `sequenzy://email-blocks` (MCP resource), `GET /api/v1/email-blocks` (API), and `sequenzy blocks <type>` (CLI)."
},
"labels": {
"type": "array",
"items": {
"type": "string"
},
"description": "Replacement label names. Send an empty array to clear labels. Missing labels are created automatically."
},
"listIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Shorthand for retargeting the draft at one or more lists. Equivalent to targetLists {type:'lists', listIds}. Mutually exclusive with `targetLists` and `segmentId`."
},
"replyTo": {
"type": "string",
"description": "Set reply-to using an existing reply profile email address for this company."
},
"subject": {
"type": "string",
"description": "Email subject line"
},
"ccEmails": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"maxItems": 10,
"description": "Addresses CC'd on every recipient's campaign email (max 10). Send an empty array or null to clear them; omit to leave unchanged."
},
"fromName": {
"type": "string",
"description": "Display name recipients see, e.g. 'Brennon at TradeTally'. Selects the sender identity of that name on fromEmail, creating it when the address has no identity by that name; the mailbox's other display names, and everything pinned to them, are untouched. Requires fromEmail; omit it when using senderProfileId, which already carries its own display name."
},
"bccEmails": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"maxItems": 10,
"description": "Addresses BCC'd on every recipient's campaign email (max 10). Send an empty array or null to clear them; omit to leave unchanged."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"fromEmail": {
"type": "string",
"description": "Set this campaign's From address. Its domain must be configured and verified."
},
"segmentId": {
"type": "string",
"description": "Shorthand for retargeting the draft at one saved segment. Equivalent to targetLists {type:'segment', segmentId}. Mutually exclusive with `targetLists` and `listIds`."
},
"campaignId": {
"type": "string",
"description": "Campaign ID"
},
"attachments": {
"type": [
"array",
"null"
],
"items": {
"type": "object",
"required": [
"filename"
],
"properties": {
"path": {
"type": "string",
"description": "Public HTTP(S) URL fetched when the campaign starts sending. Provide content or path, not both."
},
"content": {
"type": "string",
"description": "Base64 file content. Sequenzy stores the file and returns a path. Provide content or path, not both."
},
"filename": {
"type": "string",
"description": "Name recipients see, such as report.pdf. Its extension sets the file type when contentType is omitted."
},
"contentType": {
"type": "string",
"description": "MIME type for Base64 content, such as application/pdf. PDF, Office, ZIP, image, audio, video and text files are accepted; HTML and SVG are not."
}
}
},
"maxItems": 10,
"description": "Files attached to every recipient's email, including CC/BCC copies and test sends: up to 10 files and 5MB in total. Each item has a filename plus Base64 `content` or a public `path` URL. Inline images (contentId) are not supported on campaigns. If a file cannot be fetched or is too large when sending starts, nothing is sent and the campaign returns to draft. Replaces the saved list; send an empty array or null to remove every attachment, or omit to leave them unchanged."
},
"emailPreset": {
"enum": [
"branded",
"minimal"
],
"type": "string",
"description": "Per-email Style > Format for native Sequenzy blocks, including emails with supported custom HTML blocks. Use minimal for a direct text-forward note without the company logo and with the simple footer, or branded for branded chrome. This does not change the company-wide default and is not `style`, which is a prompt-generation hint valid only with `prompt`. Not a lossless toggle: minimal deletes standalone logo blocks, so switching back to branded generates a new logo block with a new id and the company name as alt text - send the authored logo block in `blocks` alongside the branded update to keep it. A standalone raw HTML email does not support this field, and emailPreset must not be combined with html."
},
"replyToName": {
"type": "string",
"description": "Display name for the Reply-To address. Requires replyTo; omit it when using replyProfileId, which already carries its own display name. An address carries one Reply-To name company-wide: if replyTo already has a saved profile under a different name, that saved name is kept and the response `warnings` array says so. Rename it with update_sender_profile (type 'reply') to change it everywhere."
},
"targetLists": {
"type": [
"object",
"null"
],
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"all",
"lists",
"segment",
"filtered",
"rules"
],
"type": "string",
"description": "Audience shape. all = every active subscriber; lists = subscribers on any of listIds; segment = one saved segment; filtered = ad-hoc subscriber filters; rules = combined include/exclude rules."
},
"exclude": {
"type": "array",
"items": {
"type": "object"
},
"description": "Exclude rules for type 'rules'. Optional. Same shapes as include except {type:'all'}."
},
"filters": {
"type": "array",
"items": {
"type": "object"
},
"description": "Subscriber filter objects {id, field, operator, value}. Required when type is 'filtered'."
},
"include": {
"type": "array",
"items": {
"type": "object"
},
"description": "Include rules. Required when type is 'rules'; an include rule or explicit includedSubscriberIds are needed to schedule. Each rule is {type:'all'} | {type:'lists', listIds:[...]} | {type:'segments', segmentIds:[...]} | {type:'filtered', filters:[...]}."
},
"listIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "List IDs to target. Required when type is 'lists'."
},
"segmentId": {
"type": [
"string",
"null"
],
"description": "Saved segment ID. Required when type is 'segment'."
},
"filterJoinOperator": {
"enum": [
"and",
"or"
],
"type": "string",
"description": "How 'filtered' filters combine. Optional, defaults to 'and'."
},
"excludedSubscriberIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Individual contacts to exclude from the audience. Explicit includedSubscriberIds override exclusions; remove a contact from that array to exclude it from a frozen group."
},
"includedSubscriberIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Explicit selected contacts, including frozen groups from create_campaign_for_audience. An empty include array is allowed when these IDs are present."
}
},
"description": "Replace the draft's saved audience, using the same shapes as `create_campaign`, e.g. {type:'lists', listIds:['list_123']}. Send null to clear it and choose the audience in `schedule_campaign` instead; omit to leave it unchanged. Mutually exclusive with `segmentId` and `listIds`.",
"additionalProperties": true
},
"campaignData": {
"type": "object",
"description": "Set campaign-scoped JSON data for repeat blocks and personalization."
},
"trackingCode": {
"type": "string",
"description": "Optional campaign tracking code for UTM templates. Use only when explicitly requested. Send an empty string to clear it."
},
"computedLists": {
"type": "array",
"items": {
"type": "object"
},
"description": "Set computed list definitions derived from campaignData at send time."
},
"maxRecipients": {
"type": [
"number",
"null"
],
"description": "Send to at most this many audience members: an integer from 1 to 10,000,000, or null to remove the limit. The first N matching subscribers (by subscriber id) receive the campaign after every audience and suppression rule is applied, and recipients already reached count against the cap when a paused send resumes. Use it to ramp up a new domain or to soft-launch an offer; duplicate the campaign and exclude contacts who already received it to send the next batch. Applies to email campaigns."
},
"replyProfileId": {
"type": "string",
"description": "Set reply-to using a reply profile ID for this company (see list_sender_profiles). It already supplies both the Reply-To address and display name, so send it on its own and omit replyTo and replyToName."
},
"senderProfileId": {
"type": "string",
"description": "Set an existing sender profile (see list_sender_profiles). It already supplies both the From address and display name, so send it on its own and omit fromEmail and fromName."
},
"sendTimeWindowHours": {
"type": "number",
"description": "STO delivery window in hours from scheduledAt (integer 1-24, default 12). Only used when sendTimeOptimization is true. Recipients whose predicted hour falls outside the window are snapped to the nearest edge. Sequences have no equivalent."
},
"sendTimeOptimization": {
"type": "boolean",
"description": "Deliver each recipient at their predicted best open hour within sendTimeWindowHours of scheduledAt (default 12h). Campaign-only: there is no company or sequence STO toggle. Sequences use sendingWindow instead. spreadOverHours takes precedence and turns STO off; sendInRecipientTimezone also turns it off."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Update Campaign",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Schedule a draft or already scheduled campaign as a one-off send or on a repeating weekly/monthly cadence via `recurringInterval`. The campaign must have a non-empty subject, at least one content block, and at least one audience include rule or an explicit selected contact. Use `recurringInterval` for newsletters that go out on a fixed schedule instead of creating one campaign per issue. Send Time Optimization (sendTimeOptimization) delivers each recipient at their predicted best hour within sendTimeWindowHours of scheduledAt (default 12h, max 24); it is campaign-only and is not available on sequences. spreadOverHours takes precedence and turns STO off; sendInRecipientTimezone also turns it off. Returns dashboard edit and preview URLs; validation errors explain what must be fixed before retrying. Only draft or scheduled campaigns can be scheduled, so a repeat call replaces the schedule and cannot send the campaign twice. Check `status` in the result: `waiting_approval` means the campaign is held for safety review (new senders get an automated screen that can take up to about two minutes; flagged content waits for a person). That is a normal outcome, not an error: report it and poll get_campaign for `scheduled` or `rejected` (with rejectionComment) instead of scheduling again, which does not clear the hold.
The description explains the capability, when to use it, and what to expect.
Inputs84/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
campaignId
Campaign ID
Explain the meaning of this value, not just its name.
scheduledAt
Future ISO 8601 timestamp for the send, for example 2026-06-01T14:00:00Z.
Clear enough to supply this argument.
targetLists › type
Audience shape. all = every active subscriber; lists = subscribers on any of listIds; segment = one saved segment; filtered = ad-hoc subscriber filters; rules = combined include/exclude rules.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
targetLists › listIds
List IDs to target. Required when type is 'lists'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
targetLists › segmentId
Saved segment ID. Required when type is 'segment'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
targetLists › filters
Subscriber filter objects {id, field, operator, value}. Required when type is 'filtered'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
targetLists › filterJoinOperator
How 'filtered' filters combine. Optional, defaults to 'and'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
targetLists › include
Include rules. Required when type is 'rules'; an include rule or explicit includedSubscriberIds are needed to schedule. Each rule is {type:'all'} | {type:'lists', listIds:[...]} | {type:'segments', segmentIds:[...]} | {type:'filtered', filters:[...]}.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
targetLists › exclude
Exclude rules for type 'rules'. Optional. Same shapes as include except {type:'all'}.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
targetLists › includedSubscriberIds
Explicit selected contacts, including frozen groups from create_campaign_for_audience. An empty include array is allowed when these IDs are present.
Clear enough to supply this argument.
targetLists › excludedSubscriberIds
Individual contacts to exclude from the audience. Explicit includedSubscriberIds override exclusions; remove a contact from that array to exclude it from a frozen group.
Clear enough to supply this argument.
listIds
Shorthand for sending to one or more lists. Equivalent to targetLists {type:'lists', listIds}. Mutually exclusive with `targetLists`.
Clear enough to supply this argument.
sendTimeOptimization
Deliver each recipient at their predicted best open hour within sendTimeWindowHours of scheduledAt (default 12h). Campaign-only: there is no company or sequence STO toggle. Sequences use sendingWindow instead. spreadOverHours takes precedence and turns STO off; sendInRecipientTimezone also turns it off.
Clear enough to supply this argument.
sendTimeWindowHours
STO delivery window in hours from scheduledAt (integer 1-24, default 12). Only used when sendTimeOptimization is true. Recipients whose predicted hour falls outside the window are snapped to the nearest edge. Sequences have no equivalent.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
spreadOverHours
Spread delivery over an integer number of hours from 1 to 72. When set, spread delivery takes precedence over send-time optimization. With an A/B test the spread sets one sending rate for the whole audience: the test sample and the winner are each spread over their share of the window, with the test duration in between. If the account has a minimum spread, a lower or missing value is raised to it and send-time optimization is turned off.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
maxRecipients
Send to at most this many audience members: an integer from 1 to 10,000,000, or null to remove the limit. The first N matching subscribers (by subscriber id) receive the campaign after every audience and suppression rule is applied, and recipients already reached count against the cap when a paused send resumes. Use it to ramp up a new domain or to soft-launch an offer; duplicate the campaign and exclude contacts who already received it to send the next batch. Applies to email campaigns. Omit to keep the draft's saved cap. For A/B tests, allow at least one recipient per variant plus one for the winner; smaller limits are rejected before scheduling.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sendInRecipientTimezone
Deliver at scheduledAt's wall-clock time in each recipient's own timezone ('send when it's 8pm for the customer'). Requires `scheduledTimezone`; contacts without a stored timezone receive the campaign at scheduledAt itself. Not combinable with `recurringInterval` or `spreadOverHours`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
scheduledTimezone
IANA timezone the scheduledAt wall-clock time refers to, for example America/New_York. Required with `sendInRecipientTimezone`.
Clear enough to supply this argument.
recurringInterval
Repeat this campaign on a cadence starting at scheduledAt. The campaign becomes a recurring template: each run is duplicated and sent automatically, re-evaluating audience membership every time. Omit for a one-shot send; scheduling again without it stops the recurrence.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "schedule_campaign",
"description": "Schedule a draft or already scheduled campaign as a one-off send or on a repeating weekly/monthly cadence via `recurringInterval`. The campaign must have a non-empty subject, at least one content block, and at least one audience include rule or an explicit selected contact. Use `recurringInterval` for newsletters that go out on a fixed schedule instead of creating one campaign per issue. Send Time Optimization (sendTimeOptimization) delivers each recipient at their predicted best hour within sendTimeWindowHours of scheduledAt (default 12h, max 24); it is campaign-only and is not available on sequences. spreadOverHours takes precedence and turns STO off; sendInRecipientTimezone also turns it off. Returns dashboard edit and preview URLs; validation errors explain what must be fixed before retrying. Only draft or scheduled campaigns can be scheduled, so a repeat call replaces the schedule and cannot send the campaign twice. Check `status` in the result: `waiting_approval` means the campaign is held for safety review (new senders get an automated screen that can take up to about two minutes; flagged content waits for a person). That is a normal outcome, not an error: report it and poll get_campaign for `scheduled` or `rejected` (with rejectionComment) instead of scheduling again, which does not clear the hold.",
"inputSchema": {
"type": "object",
"required": [
"campaignId",
"scheduledAt"
],
"properties": {
"listIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Shorthand for sending to one or more lists. Equivalent to targetLists {type:'lists', listIds}. Mutually exclusive with `targetLists`."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"campaignId": {
"type": "string",
"description": "Campaign ID"
},
"scheduledAt": {
"type": "string",
"description": "Future ISO 8601 timestamp for the send, for example 2026-06-01T14:00:00Z."
},
"targetLists": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"all",
"lists",
"segment",
"filtered",
"rules"
],
"type": "string",
"description": "Audience shape. all = every active subscriber; lists = subscribers on any of listIds; segment = one saved segment; filtered = ad-hoc subscriber filters; rules = combined include/exclude rules."
},
"exclude": {
"type": "array",
"items": {
"type": "object"
},
"description": "Exclude rules for type 'rules'. Optional. Same shapes as include except {type:'all'}."
},
"filters": {
"type": "array",
"items": {
"type": "object"
},
"description": "Subscriber filter objects {id, field, operator, value}. Required when type is 'filtered'."
},
"include": {
"type": "array",
"items": {
"type": "object"
},
"description": "Include rules. Required when type is 'rules'; an include rule or explicit includedSubscriberIds are needed to schedule. Each rule is {type:'all'} | {type:'lists', listIds:[...]} | {type:'segments', segmentIds:[...]} | {type:'filtered', filters:[...]}."
},
"listIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "List IDs to target. Required when type is 'lists'."
},
"segmentId": {
"type": [
"string",
"null"
],
"description": "Saved segment ID. Required when type is 'segment'."
},
"filterJoinOperator": {
"enum": [
"and",
"or"
],
"type": "string",
"description": "How 'filtered' filters combine. Optional, defaults to 'and'."
},
"excludedSubscriberIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Individual contacts to exclude from the audience. Explicit includedSubscriberIds override exclusions; remove a contact from that array to exclude it from a frozen group."
},
"includedSubscriberIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Explicit selected contacts, including frozen groups from create_campaign_for_audience. An empty include array is allowed when these IDs are present."
}
},
"description": "Optional campaign targeting object. Omit to use saved targeting - or, when none is saved, ALL active subscribers. Examples: {type:'all'}, {type:'lists', listIds:['list_123']}, {type:'segment', segmentId:'seg_123'}, {type:'filtered', filters:[...], filterJoinOperator:'and'}, or {type:'rules', include:[{type:'lists', listIds:['list_123']}], exclude:[{type:'segments', segmentIds:['seg_123']}]}. Rules audiences require at least one include rule or a nonempty includedSubscriberIds array. Mutually exclusive with `listIds`.",
"additionalProperties": true
},
"maxRecipients": {
"type": [
"number",
"null"
],
"description": "Send to at most this many audience members: an integer from 1 to 10,000,000, or null to remove the limit. The first N matching subscribers (by subscriber id) receive the campaign after every audience and suppression rule is applied, and recipients already reached count against the cap when a paused send resumes. Use it to ramp up a new domain or to soft-launch an offer; duplicate the campaign and exclude contacts who already received it to send the next batch. Applies to email campaigns. Omit to keep the draft's saved cap. For A/B tests, allow at least one recipient per variant plus one for the winner; smaller limits are rejected before scheduling."
},
"spreadOverHours": {
"type": "number",
"description": "Spread delivery over an integer number of hours from 1 to 72. When set, spread delivery takes precedence over send-time optimization. With an A/B test the spread sets one sending rate for the whole audience: the test sample and the winner are each spread over their share of the window, with the test duration in between. If the account has a minimum spread, a lower or missing value is raised to it and send-time optimization is turned off."
},
"recurringInterval": {
"enum": [
"weekly",
"monthly"
],
"type": "string",
"description": "Repeat this campaign on a cadence starting at scheduledAt. The campaign becomes a recurring template: each run is duplicated and sent automatically, re-evaluating audience membership every time. Omit for a one-shot send; scheduling again without it stops the recurrence."
},
"scheduledTimezone": {
"type": "string",
"description": "IANA timezone the scheduledAt wall-clock time refers to, for example America/New_York. Required with `sendInRecipientTimezone`."
},
"sendTimeWindowHours": {
"type": "number",
"description": "STO delivery window in hours from scheduledAt (integer 1-24, default 12). Only used when sendTimeOptimization is true. Recipients whose predicted hour falls outside the window are snapped to the nearest edge. Sequences have no equivalent."
},
"sendTimeOptimization": {
"type": "boolean",
"description": "Deliver each recipient at their predicted best open hour within sendTimeWindowHours of scheduledAt (default 12h). Campaign-only: there is no company or sequence STO toggle. Sequences use sendingWindow instead. spreadOverHours takes precedence and turns STO off; sendInRecipientTimezone also turns it off."
},
"sendInRecipientTimezone": {
"type": "boolean",
"description": "Deliver at scheduledAt's wall-clock time in each recipient's own timezone ('send when it's 8pm for the customer'). Requires `scheduledTimezone`; contacts without a stored timezone receive the campaign at scheduledAt itself. Not combinable with `recurringInterval` or `spreadOverHours`."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Schedule Campaign",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Queue a campaign test email to a single address. Returns a durable emailSendId; pass it to get_email_send for delivery status and failure details. Each successful call queues another test email.
The description explains the capability, when to use it, and what to expect.
Inputs79/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
campaignId
Campaign ID to test
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "send_test_email",
"description": "Queue a campaign test email to a single address. Returns a durable emailSendId; pass it to get_email_send for delivery status and failure details. Each successful call queues another test email.",
"inputSchema": {
"type": "object",
"required": [
"campaignId",
"to"
],
"properties": {
"to": {
"type": "string",
"description": "Email address to send test to"
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"campaignId": {
"type": "string",
"description": "Campaign ID to test"
}
}
},
"annotations": {
"title": "Send Test Email",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Return a scheduled campaign to an editable draft. Removes its pending send and recurrence without permanently cancelling it, so it can be edited and scheduled again.
Describe the returned information so the agent knows whether it will answer the request.
Inputs85/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "unschedule_campaign",
"description": "Return a scheduled campaign to an editable draft. Removes its pending send and recurrence without permanently cancelling it, so it can be edited and scheduled again.",
"inputSchema": {
"type": "object",
"required": [
"campaignId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"campaignId": {
"type": "string",
"description": "Scheduled campaign ID to return to draft."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Unschedule Campaign",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Cancel a campaign. Stops scheduled and sending campaigns (also works for paused and approval-pending ones). Remaining emails will not be sent and the campaign cannot be restarted - this cannot be undone.
The description explains the capability, when to use it, and what to expect.
Inputs78/100
Clarify ID sources, units, or usage conventions not already expressed in the schema.
companyId
Company ID. If not provided, uses the currently selected company.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "cancel_campaign",
"description": "Cancel a campaign. Stops scheduled and sending campaigns (also works for paused and approval-pending ones). Remaining emails will not be sent and the campaign cannot be restarted - this cannot be undone.",
"inputSchema": {
"type": "object",
"required": [
"campaignId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"campaignId": {
"type": "string",
"description": "Campaign ID to cancel."
}
}
},
"annotations": {
"title": "Cancel Campaign",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "pause_campaign",
"description": "Pause a campaign that is currently sending. Only campaigns in sending status can be paused. Use resume_campaign to continue delivery later.",
"inputSchema": {
"type": "object",
"required": [
"campaignId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"campaignId": {
"type": "string",
"description": "Campaign ID to pause."
}
}
},
"annotations": {
"title": "Pause Campaign",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description80/100
Resume a paused campaign. Only campaigns in paused status can be resumed. Optionally spread the remaining delivery over a number of hours.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs86/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
campaignId
Campaign ID to resume.
Clear enough to supply this argument.
spreadOverHours
Spread the remaining delivery over an integer number of hours from 1 to 72. With an A/B test this sets the sending rate for the remaining recipients of the current phase. If the account has a minimum spread, a lower, missing or null value is raised to it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "resume_campaign",
"description": "Resume a paused campaign. Only campaigns in paused status can be resumed. Optionally spread the remaining delivery over a number of hours.",
"inputSchema": {
"type": "object",
"required": [
"campaignId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"campaignId": {
"type": "string",
"description": "Campaign ID to resume."
},
"spreadOverHours": {
"type": "number",
"description": "Spread the remaining delivery over an integer number of hours from 1 to 72. With an A/B test this sets the sending rate for the remaining recipients of the current phase. If the account has a minimum spread, a lower, missing or null value is raised to it."
}
}
},
"annotations": {
"title": "Resume Campaign",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description86/100
Duplicate a campaign as a new draft. mode 'campaign' (default) copies the campaign and its email, 'ab_test' also duplicates the campaign's A/B test with all variants, and 'variant' copies a single variant's content as the new campaign email (requires variantId).
Describe the returned information so the agent knows whether it will answer the request.
Inputs81/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
campaignId
Campaign ID to duplicate.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
mode
Duplication mode. Defaults to campaign.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
variantId
A/B test variant ID whose content becomes the new campaign email. Required when mode is variant.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "duplicate_campaign",
"description": "Duplicate a campaign as a new draft. mode 'campaign' (default) copies the campaign and its email, 'ab_test' also duplicates the campaign's A/B test with all variants, and 'variant' copies a single variant's content as the new campaign email (requires variantId).",
"inputSchema": {
"type": "object",
"required": [
"campaignId"
],
"properties": {
"mode": {
"enum": [
"campaign",
"ab_test",
"variant"
],
"type": "string",
"description": "Duplication mode. Defaults to campaign."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"variantId": {
"type": "string",
"description": "A/B test variant ID whose content becomes the new campaign email. Required when mode is variant."
},
"campaignId": {
"type": "string",
"description": "Campaign ID to duplicate."
}
}
},
"annotations": {
"title": "Duplicate Campaign",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Upload an image to the selected company's shared media library and return a hosted URL plus a ready-to-insert Sequenzy image block. When an email needs a new image, call this before create/update campaign, sequence, template, or transactional tools, then place the returned imageBlock in the target blocks array. Provide either filePath (local stdio MCP only) or imageBase64 (works with remote MCP when the client can supply attachment bytes), not both. PNG, JPEG, GIF, and WebP are supported up to 10MB. cropHeight with objectFit:'cover' provides a precise centered screenshot crop while displayWidthPercent keeps the image responsive.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
filePath
Local path to a PNG, JPEG, GIF, or WebP image. Available only when the MCP server runs locally. Provide filePath or imageBase64, not both.
Clear enough to supply this argument.
imageBase64
Raw base64 image bytes or a base64 data URL. Use this for remote MCP clients that can access attachment bytes. Provide imageBase64 or filePath, not both.
Clear enough to supply this argument.
filename
File name including extension. Required with imageBase64; optional override with filePath.
Clear enough to supply this argument.
contentType
Image MIME type when it cannot be inferred from filename, such as image/png.
Clear enough to supply this argument.
altText
Accessible description stored with the asset and returned as imageBlock.alt. Use an empty string only for a decorative image.
Clear enough to supply this argument.
sourceWidth
Optional intrinsic source width in pixels. Provide sourceWidth and sourceHeight together when known.
Clear enough to supply this argument.
sourceHeight
Optional intrinsic source height in pixels. Provide sourceWidth and sourceHeight together when known.
Clear enough to supply this argument.
displayWidthPercent
Responsive image width as a percentage of the email content area. Defaults to 100.
Clear enough to supply this argument.
cropHeight
Optional fixed display height in pixels. With objectFit:'cover', the image is centered and cropped to this height.
Clear enough to supply this argument.
objectFit
How the image fits cropHeight. Defaults to cover when cropHeight is provided. Only valid with cropHeight.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "upload_image_asset",
"description": "Upload an image to the selected company's shared media library and return a hosted URL plus a ready-to-insert Sequenzy image block. When an email needs a new image, call this before create/update campaign, sequence, template, or transactional tools, then place the returned imageBlock in the target blocks array. Provide either filePath (local stdio MCP only) or imageBase64 (works with remote MCP when the client can supply attachment bytes), not both. PNG, JPEG, GIF, and WebP are supported up to 10MB. cropHeight with objectFit:'cover' provides a precise centered screenshot crop while displayWidthPercent keeps the image responsive.",
"inputSchema": {
"type": "object",
"properties": {
"align": {
"enum": [
"left",
"center",
"right"
],
"type": "string",
"description": "Image alignment. Defaults to center."
},
"altText": {
"type": "string",
"description": "Accessible description stored with the asset and returned as imageBlock.alt. Use an empty string only for a decorative image."
},
"filePath": {
"type": "string",
"description": "Local path to a PNG, JPEG, GIF, or WebP image. Available only when the MCP server runs locally. Provide filePath or imageBase64, not both."
},
"filename": {
"type": "string",
"description": "File name including extension. Required with imageBase64; optional override with filePath."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"objectFit": {
"enum": [
"cover",
"contain"
],
"type": "string",
"description": "How the image fits cropHeight. Defaults to cover when cropHeight is provided. Only valid with cropHeight."
},
"cropHeight": {
"type": "integer",
"maximum": 2000,
"minimum": 1,
"description": "Optional fixed display height in pixels. With objectFit:'cover', the image is centered and cropped to this height."
},
"contentType": {
"type": "string",
"description": "Image MIME type when it cannot be inferred from filename, such as image/png."
},
"imageBase64": {
"type": "string",
"description": "Raw base64 image bytes or a base64 data URL. Use this for remote MCP clients that can access attachment bytes. Provide imageBase64 or filePath, not both."
},
"sourceWidth": {
"type": "integer",
"maximum": 20000,
"minimum": 1,
"description": "Optional intrinsic source width in pixels. Provide sourceWidth and sourceHeight together when known."
},
"sourceHeight": {
"type": "integer",
"maximum": 20000,
"minimum": 1,
"description": "Optional intrinsic source height in pixels. Provide sourceWidth and sourceHeight together when known."
},
"displayWidthPercent": {
"type": "number",
"maximum": 100,
"minimum": 1,
"description": "Responsive image width as a percentage of the email content area. Defaults to 100."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Upload Image Asset",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description79/100
List all email sequences (automations). Read effectiveStatus (draft, live, enrollment_paused, paused, archived) to know whether a sequence is running: status alone reads `active` even when new enrollments are paused, and the legacy triggerConfig.active flag is not used by the runtime.
Describe the returned information so the agent knows whether it will answer the request.
Inputs79/100
Resolve the mismatch between this description and its schema constraints.
companyId
Company ID to list sequences for. If not provided, uses the currently selected company.
Clear enough to supply this argument.
status
Optional dashboard status filter.
Resolve the mismatch between this description and its schema constraints.
search
Case-insensitive search across sequence name and description.
Clear enough to supply this argument.
labels
Return sequences assigned any of these dashboard label names.
Clear enough to supply this argument.
limit
Page size from 1 to 100. When limit and offset are both omitted, every sequence is returned.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_sequences",
"description": "List all email sequences (automations). Read effectiveStatus (draft, live, enrollment_paused, paused, archived) to know whether a sequence is running: status alone reads `active` even when new enrollments are paused, and the legacy triggerConfig.active flag is not used by the runtime.",
"inputSchema": {
"type": "object",
"properties": {
"limit": {
"type": "number",
"description": "Page size from 1 to 100. When limit and offset are both omitted, every sequence is returned."
},
"labels": {
"type": "array",
"items": {
"type": "string"
},
"description": "Return sequences assigned any of these dashboard label names."
},
"offset": {
"type": "number",
"description": "Zero-based result offset."
},
"search": {
"type": "string",
"description": "Case-insensitive search across sequence name and description."
},
"status": {
"enum": [
"draft",
"active",
"paused",
"archived"
],
"type": "string",
"description": "Optional dashboard status filter."
},
"companyId": {
"type": "string",
"description": "Company ID to list sequences for. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "List Sequences",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Get sequence details, editable step content, and graph topology. Read effectiveStatus (draft, live, enrollment_paused, paused, archived) to know whether a sequence is running: status alone reads `active` even when new enrollments are paused, and the legacy triggerConfig.active flag is not used by the runtime. Each sequence.nodes item includes id, nodeType, current config, updatedAt, and updateHints with its editable/managed fields and ready-to-return expectedUpdatedAt token for update_sequence_node/update_sequence_nodes. The response also includes sequence.edges and graphRevision for safe edit_sequence_graph calls, plus sequence.emails with each email step's nodeId, nodeType, linked emailId, subject, previewText, emailPreset (the per-email Style > Format for native blocks, including emails with supported custom HTML blocks; null when the entire email is standalone raw HTML), and blocks. sequence.emails includes action_ab_test steps, whose copy lives on the A/B test variants rather than on the node: their subject/previewText/blocks are control variant A only. With ab_tests:read, each carries abTest with the test id, status, and one entry per variant including that variant's full blocks, so a sequence read is enough to audit CTA/promo/review copy; without that scope, test-record fields are redacted and variants is empty while the configured id and editing guidance remain available. To change the copy of an A/B step, edit each variant with update_ab_test_variant - if that tool is not in the tool list, enable it on the Sequenzy connector rather than writing through update_template or update_sequence_node. Rebuilding the step as a plain email node to reach the copy destroys the test. get_ab_test remains the dedicated A/B read for settings, localization, and stats. Send Time Optimization is not a company or sequence setting. It is campaign-only: audit with list_campaigns or get_campaign (sendTimeOptimization, sendTimeWindowHours, default 12h window). Change a draft with update_campaign, or apply it when calling schedule_campaign. Sequences use sendingWindow (allowed local hours/days), which is a shared gate, not per-subscriber predicted send times.
The description explains the capability, when to use it, and what to expect.
Inputs66/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
sequenceId
Sequence ID
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_sequence",
"description": "Get sequence details, editable step content, and graph topology. Read effectiveStatus (draft, live, enrollment_paused, paused, archived) to know whether a sequence is running: status alone reads `active` even when new enrollments are paused, and the legacy triggerConfig.active flag is not used by the runtime. Each sequence.nodes item includes id, nodeType, current config, updatedAt, and updateHints with its editable/managed fields and ready-to-return expectedUpdatedAt token for update_sequence_node/update_sequence_nodes. The response also includes sequence.edges and graphRevision for safe edit_sequence_graph calls, plus sequence.emails with each email step's nodeId, nodeType, linked emailId, subject, previewText, emailPreset (the per-email Style > Format for native blocks, including emails with supported custom HTML blocks; null when the entire email is standalone raw HTML), and blocks. sequence.emails includes action_ab_test steps, whose copy lives on the A/B test variants rather than on the node: their subject/previewText/blocks are control variant A only. With ab_tests:read, each carries abTest with the test id, status, and one entry per variant including that variant's full blocks, so a sequence read is enough to audit CTA/promo/review copy; without that scope, test-record fields are redacted and variants is empty while the configured id and editing guidance remain available. To change the copy of an A/B step, edit each variant with update_ab_test_variant - if that tool is not in the tool list, enable it on the Sequenzy connector rather than writing through update_template or update_sequence_node. Rebuilding the step as a plain email node to reach the copy destroys the test. get_ab_test remains the dedicated A/B read for settings, localization, and stats. Send Time Optimization is not a company or sequence setting. It is campaign-only: audit with list_campaigns or get_campaign (sendTimeOptimization, sendTimeWindowHours, default 12h window). Change a draft with update_campaign, or apply it when calling schedule_campaign. Sequences use sendingWindow (allowed local hours/days), which is a shared gate, not per-subscriber predicted send times.",
"inputSchema": {
"type": "object",
"required": [
"sequenceId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"sequenceId": {
"type": "string",
"description": "Sequence ID"
}
},
"additionalProperties": false
},
"annotations": {
"title": "Get Sequence",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Dry-run a sequence without sending mail or enrolling anyone. Requires sequences:read and subscribers:read because results include contact samples. Activation does not enroll existing matches unless audienceAutoEnroll is saved. Without a subscriber this reports who currently matches (existing list/tag/segment matches are not auto-enrolled) and activation readiness errors and warnings (for example, an email reading {{webhooks.KEY}} or {{ai.KEY}} that no earlier step saves). Frequency and inactivity current-match counts are unavailable because the hourly worker evaluates them. Pass subscriberId or email to also walk that stored contact's branch path - use this to check whether a specific contact would receive a given step. Call this before enable_sequence.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
sequenceId
Sequence ID to simulate.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
subscriberId
Optional stored subscriber to walk through the graph. Do not pass with email.
Clear enough to supply this argument.
email
Optional stored subscriber email to walk through the graph. Do not pass with subscriberId.
Clear enough to supply this argument.
limit
Maximum currently matching contacts to include in the sample. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "simulate_sequence",
"description": "Dry-run a sequence without sending mail or enrolling anyone. Requires sequences:read and subscribers:read because results include contact samples. Activation does not enroll existing matches unless audienceAutoEnroll is saved. Without a subscriber this reports who currently matches (existing list/tag/segment matches are not auto-enrolled) and activation readiness errors and warnings (for example, an email reading {{webhooks.KEY}} or {{ai.KEY}} that no earlier step saves). Frequency and inactivity current-match counts are unavailable because the hourly worker evaluates them. Pass subscriberId or email to also walk that stored contact's branch path - use this to check whether a specific contact would receive a given step. Call this before enable_sequence.",
"inputSchema": {
"type": "object",
"required": [
"sequenceId"
],
"properties": {
"email": {
"type": "string",
"description": "Optional stored subscriber email to walk through the graph. Do not pass with subscriberId."
},
"limit": {
"type": "integer",
"maximum": 25,
"minimum": 1,
"description": "Maximum currently matching contacts to include in the sample. Defaults to 10."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"sequenceId": {
"type": "string",
"description": "Sequence ID to simulate."
},
"subscriberId": {
"type": "string",
"description": "Optional stored subscriber to walk through the graph. Do not pass with email."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Simulate Sequence",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Change a sequence's emails with AI in one request, like the Emails view in the sequence editor: the prompt says what to change, in any language ("make the background cream", "remove the header", "new structure for email 2"). Without emailIds the prompt decides which emails: every email, unless it names some. A look change (background, colors, fonts) is made identical across the emails it touches, down to each kind of block's style. "Make them all look like email 1" copies that email's style exactly without AI, keeping each email's words. For design variations of an email use generate_sequence_email_variations: such a prompt returns 400 here. An email written in HTML is edited as HTML and keeps its theme. A/B test steps, steps without an email and steps that send the same email as an earlier step are skipped and listed in skipped. Each email succeeds or fails on its own: emails[].status is changed, unchanged (summary says why) or failed; changed emails are saved (saved:true) unless dryRun is true. Saved changes apply to the next sends of an active sequence. Runs synchronously and can take up to a minute; one request edits up to 12 emails, so pass emailIds in batches for longer sequences. A 503 means the AI could not tell which emails the prompt means and nothing changed: retry or pass emailIds. An email saved elsewhere meanwhile comes back with saved:false and an error instead of being overwritten. If the call times out, read get_sequence before retrying: changes may already be saved. To set exact values instead of asking the AI, use update_sequence_nodes.
Describe the returned information so the agent knows whether it will answer the request.
Inputs79/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
sequenceId
Sequence ID.
Explain the meaning of this value, not just its name.
prompt
What should change, any language, up to 2000 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
emailIds
Only change these emails (emailId from get_sequence.sequence.emails). Omit to let the prompt decide.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sectionIds
Only change these top-level block ids. Needs exactly one emailId.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dryRun
Return the new content without saving it. Defaults to false.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "edit_sequence_emails",
"description": "Change a sequence's emails with AI in one request, like the Emails view in the sequence editor: the prompt says what to change, in any language (\"make the background cream\", \"remove the header\", \"new structure for email 2\"). Without emailIds the prompt decides which emails: every email, unless it names some. A look change (background, colors, fonts) is made identical across the emails it touches, down to each kind of block's style. \"Make them all look like email 1\" copies that email's style exactly without AI, keeping each email's words. For design variations of an email use generate_sequence_email_variations: such a prompt returns 400 here. An email written in HTML is edited as HTML and keeps its theme. A/B test steps, steps without an email and steps that send the same email as an earlier step are skipped and listed in skipped. Each email succeeds or fails on its own: emails[].status is changed, unchanged (summary says why) or failed; changed emails are saved (saved:true) unless dryRun is true. Saved changes apply to the next sends of an active sequence. Runs synchronously and can take up to a minute; one request edits up to 12 emails, so pass emailIds in batches for longer sequences. A 503 means the AI could not tell which emails the prompt means and nothing changed: retry or pass emailIds. An email saved elsewhere meanwhile comes back with saved:false and an error instead of being overwritten. If the call times out, read get_sequence before retrying: changes may already be saved. To set exact values instead of asking the AI, use update_sequence_nodes.",
"inputSchema": {
"type": "object",
"required": [
"sequenceId",
"prompt"
],
"properties": {
"dryRun": {
"type": "boolean",
"description": "Return the new content without saving it. Defaults to false."
},
"prompt": {
"type": "string",
"description": "What should change, any language, up to 2000 characters."
},
"emailIds": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 12,
"minItems": 1,
"description": "Only change these emails (emailId from get_sequence.sequence.emails). Omit to let the prompt decide."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"sectionIds": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 50,
"description": "Only change these top-level block ids. Needs exactly one emailId."
},
"sequenceId": {
"type": "string",
"description": "Sequence ID."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Edit Sequence Emails",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Enable/activate a sequence so it starts processing its triggers. Sequences are created disabled so their content can be reviewed before activation; this tool is intended for user-requested activation. simulate_sequence shows who currently matches and whether the sequence is ready. Activation does not enroll existing matches unless audienceAutoEnroll is saved. Relay any response `warnings` to the user, such as a contact_added trigger with no list, which enrolls every new contact.
The description explains the capability, when to use it, and what to expect.
Inputs66/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
sequenceId
Sequence ID
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "enable_sequence",
"description": "Enable/activate a sequence so it starts processing its triggers. Sequences are created disabled so their content can be reviewed before activation; this tool is intended for user-requested activation. simulate_sequence shows who currently matches and whether the sequence is ready. Activation does not enroll existing matches unless audienceAutoEnroll is saved. Relay any response `warnings` to the user, such as a contact_added trigger with no list, which enrolls every new contact.",
"inputSchema": {
"type": "object",
"required": [
"sequenceId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"sequenceId": {
"type": "string",
"description": "Sequence ID"
}
}
},
"annotations": {
"title": "Enable Sequence",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Disable/freeze a sequence. This blocks new enrollments and holds current recipients until the sequence is enabled again. To only stop new enrollments while current recipients continue, use pause_sequence_enrollments.
Explain mutations, irreversible effects, or prerequisites that matter before calling this tool.
Inputs61/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
sequenceId
Sequence ID
Explain the meaning of this value, not just its name.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "disable_sequence",
"description": "Disable/freeze a sequence. This blocks new enrollments and holds current recipients until the sequence is enabled again. To only stop new enrollments while current recipients continue, use pause_sequence_enrollments.",
"inputSchema": {
"type": "object",
"required": [
"sequenceId"
],
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"sequenceId": {
"type": "string",
"description": "Sequence ID"
}
}
},
"annotations": {
"title": "Disable Sequence",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Manually enroll subscribers in a sequence by email address or subscriber ID. Maximum 500 total targets per call across emails and subscriberIds. Only active subscribers are enrolled: unknown emails are returned in `notFound`, while inactive, unavailable, and already actively enrolled subscribers are counted in `skipped`. By default enrollment starts at the first step after the trigger; pass targetNodeId to start at a specific step.
Describe the returned information so the agent knows whether it will answer the request.
Inputs80/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
sequenceId
Sequence ID to enroll subscribers in.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
emails
Email addresses of subscribers to enroll. Combined with subscriberIds, maximum 500 total targets per call.
Clear enough to supply this argument.
subscriberIds
Subscriber IDs to enroll. Combined with emails, maximum 500 total targets per call.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
targetNodeId
Optional node ID to start enrollment at. Use a non-trigger nodeId from get_sequence. Defaults to the first step after the trigger.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "enroll_subscribers_in_sequence",
"description": "Manually enroll subscribers in a sequence by email address or subscriber ID. Maximum 500 total targets per call across emails and subscriberIds. Only active subscribers are enrolled: unknown emails are returned in `notFound`, while inactive, unavailable, and already actively enrolled subscribers are counted in `skipped`. By default enrollment starts at the first step after the trigger; pass targetNodeId to start at a specific step.",
"inputSchema": {
"type": "object",
"required": [
"sequenceId"
],
"properties": {
"emails": {
"type": "array",
"items": {
"type": "string"
},
"description": "Email addresses of subscribers to enroll. Combined with subscriberIds, maximum 500 total targets per call."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"sequenceId": {
"type": "string",
"description": "Sequence ID to enroll subscribers in."
},
"targetNodeId": {
"type": "string",
"description": "Optional node ID to start enrollment at. Use a non-trigger nodeId from get_sequence. Defaults to the first step after the trigger."
},
"subscriberIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "Subscriber IDs to enroll. Combined with emails, maximum 500 total targets per call."
}
}
},
"annotations": {
"title": "Enroll Subscribers In Sequence",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
List transactional email templates with subjects, delivery metrics, API slugs, and dashboard URLs. Each item also carries `emailPreset`, the per-email Style > Format (branded or minimal, null for a standalone raw HTML email), so a chrome drift check across templates does not need one get_transactional_email call each. `managedBy` is `code` for emails created by `send_email` with `trackAs`: their content is a snapshot of recent sends and they cannot be sent by `templateId`. Search by name, slug, or email title; filter active state; and sort by sends, opens, open rate, clicks, or CTR.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
labels
Filter by label names; matches any supplied name.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
search
Case-insensitive search across template name, API slug, and linked email subject/title.
Clear enough to supply this argument.
status
Template status: all, active, or disabled.
Clear enough to supply this argument.
sort
Sort field: date, sends, opens, open-rate, clicks, or ctr. Defaults to date.
Clear enough to supply this argument.
order
Sort order: asc or desc. Defaults to desc.
Clear enough to supply this argument.
includeMachineEngagement
Include bot, scanner, and privacy-proxy engagement in open and click metrics. Defaults to false.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_transactional_emails",
"description": "List transactional email templates with subjects, delivery metrics, API slugs, and dashboard URLs. Each item also carries `emailPreset`, the per-email Style > Format (branded or minimal, null for a standalone raw HTML email), so a chrome drift check across templates does not need one get_transactional_email call each. `managedBy` is `code` for emails created by `send_email` with `trackAs`: their content is a snapshot of recent sends and they cannot be sent by `templateId`. Search by name, slug, or email title; filter active state; and sort by sends, opens, open rate, clicks, or CTR.",
"inputSchema": {
"type": "object",
"properties": {
"sort": {
"type": "string",
"description": "Sort field: date, sends, opens, open-rate, clicks, or ctr. Defaults to date."
},
"order": {
"type": "string",
"description": "Sort order: asc or desc. Defaults to desc."
},
"labels": {
"type": "array",
"items": {
"type": "string"
},
"description": "Filter by label names; matches any supplied name."
},
"search": {
"type": "string",
"description": "Case-insensitive search across template name, API slug, and linked email subject/title."
},
"status": {
"type": "string",
"description": "Template status: all, active, or disabled."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"includeMachineEngagement": {
"type": "boolean",
"description": "Include bot, scanner, and privacy-proxy engagement in open and click metrics. Defaults to false."
}
},
"additionalProperties": false
},
"annotations": {
"title": "List Transactional Emails",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
Get a transactional email by ID or slug, including subject, preview text, blocks, variables, and linked dashboard URLs. `emailPreset` reports the per-email Style > Format the same way get_sequence does per step (branded or minimal; null when the whole email is standalone raw HTML), so it can be compared against sequence steps and campaigns without rendering them - minimal suppresses the company logo at render time.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
idOrSlug
Transactional email ID or API slug, for example `welcome-email`.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_transactional_email",
"description": "Get a transactional email by ID or slug, including subject, preview text, blocks, variables, and linked dashboard URLs. `emailPreset` reports the per-email Style > Format the same way get_sequence does per step (branded or minimal; null when the whole email is standalone raw HTML), so it can be compared against sequence steps and campaigns without rendering them - minimal suppresses the company logo at render time.",
"inputSchema": {
"type": "object",
"required": [
"idOrSlug"
],
"properties": {
"idOrSlug": {
"type": "string",
"description": "Transactional email ID or API slug, for example `welcome-email`."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "Get Transactional Email",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Queue one email using either a saved transactional email API slug (`templateId`) or direct `subject` and `html` content. Add `trackAs` to a direct send to track it under one code-managed transactional email for per-email stats. Always provide a stable `idempotencyKey` when an agent or workflow may retry, and reuse it for the same logical email; Sequenzy returns the original send for 14 days and rejects different content under the same key. The default delivery policy is transactional. A transactional send delivers one email to several people at once: `to` takes up to 50 addresses and `cc`/`bcc` take up to 50 each, so everyone sees the same shared recipient list instead of receiving separate copies. Addresses repeated across the fields are dropped from the lower-priority one (to beats cc beats bcc). When the recipient matches a subscriber, saved first and last names fill omitted name variables; explicit variables take precedence. Set `emailType` to `marketing` to add subscriber suppression, a marketing footer, and RFC 8058 one-click unsubscribe; marketing sends take exactly one `to` recipient and no `cc` or `bcc`. When no identity override is provided, a template send keeps its saved From and Reply-To identities, while a direct send uses the company defaults. To send as a non-default verified brand, pass `fromEmail` (and `fromName` if that address has several identities) plus optional `replyTo`/`replyToName`; you do not need profile IDs. `senderProfileId`/`replyProfileId` from `list_sender_profiles` remain available when you already have them. These fields look up existing identities and do not create profiles. `{{viewInBrowserUrl}}` is replaced with a hosted copy URL. Attach up to 10 files with Base64 `content` or a public `path`; `contentId` embeds a CID image referenced by the HTML. When `trackingSettings` is omitted, the company's Transactional API defaults apply. Set `clickTracking` or `openTracking` to `false` to opt out for this send only; these fields cannot enable tracking disabled by account settings. Use `headers` for extra email headers, such as your own one-click `List-Unsubscribe` on a transactional send. Returns a durable emailSendId, the accepted emailType, the deduplicated recipient lists, and `ignoredHeaders` when some headers were not applied; pass the ID to get_email_send for delivery status and failure details.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
21 of 26 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
to
Primary recipient email address, or an array of up to 50 addresses that share one email and see each other in the To header. Marketing sends accept exactly one address.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cc
Carbon-copy email address, or an array of up to 50, visible to every recipient. Transactional sends only. Addresses already in `to` are dropped.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
bcc
Blind-carbon-copy email address, or an array of up to 50, hidden from the other recipients. Transactional sends only. Addresses already in `to` or `cc` are dropped.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
idempotencyKey
Caller-owned retry key for this logical email (maximum 255 characters). Reuse the same key with the same arguments to get the original emailSendId for 14 days. Never reuse a key for different content.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
subject
Email subject line. Required with `html` when `templateId` is omitted.
Clear enough to supply this argument.
html
Direct-send HTML body. Required with `subject` when `templateId` is omitted; the MCP server maps this to the transactional API `body` field. Use `{{viewInBrowserUrl}}` for a hosted copy link generated at send time.
Clear enough to supply this argument.
templateId
Saved transactional email API slug, for example `welcome-email`. The field name is retained for MCP compatibility and is mapped to the transactional API `slug` field.
Clear enough to supply this argument.
trackAs
Direct `subject`/`html` sends only. Names the email type, for example `weekly-report` (up to 255 ASCII letters, digits, spaces and `. _ - : /`), so every send with the same value is tracked under one code-managed transactional email with its own stats. The first send creates it (`managedBy: code` in list_transactional_emails); later sends link to it. Use a stable name, never per-recipient values: a workspace can have at most 100. Fails if the value matches a dashboard template's slug or the code-managed email is disabled. Code-managed emails cannot be sent with `templateId`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
variables
Variables for template personalization. Nested objects and arrays are supported for repeat blocks, for example { items: [...] }. When the recipient matches a subscriber, saved first and last names fill omitted name variables; explicit values, including blanks, take precedence. Variables are HTML-escaped; a template can prefix a tag with 'html.' ({{html.prerenderedHtml}}) to insert a trusted, sanitized HTML value unescaped.
Clear enough to supply this argument.
subscriberExternalId
Customer-owned subscriber ID for attaching analytics, localization, and saved-name personalization on single-recipient sends. Maximum length: 255 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
emailType
Delivery policy: `transactional` (default) or `marketing`. Marketing mode supports exactly one `to` recipient, rejects `cc` and `bcc`, and automatically applies subscriber suppression, the standard unsubscribe footer, and RFC 8058 headers. Both modes use the Send API and require the `transactional:send` scope; a personal key held by a `marketer` cannot use this tool in either mode (see `roleRestrictedScopes` on get_account) and should send through campaigns or sequences instead.
Clear enough to supply this argument.
replyTo
Optional Reply-To address, formatted as `[email protected]` or `Name <[email protected]>`. Pair a bare address with `replyToName` instead of embedding the name. Mutually exclusive with `replyProfileId`. When omitted, the saved template or company default is used.
Clear enough to supply this argument.
replyToName
Display name for `replyTo`. Requires a bare `replyTo` address. Mutually exclusive with `replyProfileId`. Does not create a reply profile.
Clear enough to supply this argument.
senderProfileId
Existing sender profile ID (see list_sender_profiles). It already supplies both the From address and display name, so send it on its own and omit fromEmail and fromName. Mutually exclusive with fromEmail. When omitted, a template send keeps its saved sender and a direct send uses the company default.
Clear enough to supply this argument.
fromEmail
From address of an existing verified sender profile (see list_sender_profiles). Mutually exclusive with senderProfileId. If the address has several identities, pass fromName to choose one. Does not create a new sender profile.
Clear enough to supply this argument.
fromName
Display name of an existing verified sender identity on fromEmail, e.g. StudyBoost vs StudyBoost News. Requires fromEmail. Mutually exclusive with senderProfileId. Does not create a new sender profile.
Clear enough to supply this argument.
replyProfileId
Existing reply profile ID (see list_sender_profiles). It already supplies both the Reply-To address and display name, so send it on its own and omit replyTo and replyToName. Mutually exclusive with replyTo.
Clear enough to supply this argument.
attachments › items › filename
Not provided
Missing description. Explain what this value means and how to supply it.
attachments › items › content
Not provided
Missing description. Explain what this value means and how to supply it.
attachments › items › path
Not provided
Missing description. Explain what this value means and how to supply it.
attachments › items › contentId
Not provided
Missing description. Explain what this value means and how to supply it.
attachments › items › contentType
Not provided
Missing description. Explain what this value means and how to supply it.
trackingSettings › clickTracking
Set to `false` to skip click-link rewriting for this send only, which helps when tracking redirects break universal or deep links.
Clear enough to supply this argument.
trackingSettings › openTracking
Set to `false` to skip the open-tracking pixel for this send only.
Clear enough to supply this argument.
headers
Extra email headers as `{ "Header-Name": "value" }`, up to 50. Names use letters, digits, and hyphens; values are one line of printable ASCII. A transactional send can carry the caller's own `List-Unsubscribe` and `List-Unsubscribe-Post: List-Unsubscribe=One-Click`. Marketing sends always use Sequenzy's signed unsubscribe headers, so those two plus `Precedence` and `Feedback-ID` are not applied. Headers Sequenzy manages (for example From, To, Subject, Reply-To, Message-ID, Content-Type, and `X-Sequenzy-*`) are never applied. Values must be strings. Headers the API does not apply do not fail the send; they are listed in the response `ignoredHeaders` with a reason.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "send_email",
"description": "Queue one email using either a saved transactional email API slug (`templateId`) or direct `subject` and `html` content. Add `trackAs` to a direct send to track it under one code-managed transactional email for per-email stats. Always provide a stable `idempotencyKey` when an agent or workflow may retry, and reuse it for the same logical email; Sequenzy returns the original send for 14 days and rejects different content under the same key. The default delivery policy is transactional. A transactional send delivers one email to several people at once: `to` takes up to 50 addresses and `cc`/`bcc` take up to 50 each, so everyone sees the same shared recipient list instead of receiving separate copies. Addresses repeated across the fields are dropped from the lower-priority one (to beats cc beats bcc). When the recipient matches a subscriber, saved first and last names fill omitted name variables; explicit variables take precedence. Set `emailType` to `marketing` to add subscriber suppression, a marketing footer, and RFC 8058 one-click unsubscribe; marketing sends take exactly one `to` recipient and no `cc` or `bcc`. When no identity override is provided, a template send keeps its saved From and Reply-To identities, while a direct send uses the company defaults. To send as a non-default verified brand, pass `fromEmail` (and `fromName` if that address has several identities) plus optional `replyTo`/`replyToName`; you do not need profile IDs. `senderProfileId`/`replyProfileId` from `list_sender_profiles` remain available when you already have them. These fields look up existing identities and do not create profiles. `{{viewInBrowserUrl}}` is replaced with a hosted copy URL. Attach up to 10 files with Base64 `content` or a public `path`; `contentId` embeds a CID image referenced by the HTML. When `trackingSettings` is omitted, the company's Transactional API defaults apply. Set `clickTracking` or `openTracking` to `false` to opt out for this send only; these fields cannot enable tracking disabled by account settings. Use `headers` for extra email headers, such as your own one-click `List-Unsubscribe` on a transactional send. Returns a durable emailSendId, the accepted emailType, the deduplicated recipient lists, and `ignoredHeaders` when some headers were not applied; pass the ID to get_email_send for delivery status and failure details.",
"inputSchema": {
"type": "object",
"required": [
"to"
],
"properties": {
"cc": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
},
"maxItems": 50,
"description": "Carbon-copy email address, or an array of up to 50, visible to every recipient. Transactional sends only. Addresses already in `to` are dropped."
},
"to": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
},
"maxItems": 50,
"minItems": 1,
"description": "Primary recipient email address, or an array of up to 50 addresses that share one email and see each other in the To header. Marketing sends accept exactly one address."
},
"bcc": {
"type": [
"string",
"array"
],
"items": {
"type": "string"
},
"maxItems": 50,
"description": "Blind-carbon-copy email address, or an array of up to 50, hidden from the other recipients. Transactional sends only. Addresses already in `to` or `cc` are dropped."
},
"html": {
"type": "string",
"description": "Direct-send HTML body. Required with `subject` when `templateId` is omitted; the MCP server maps this to the transactional API `body` field. Use `{{viewInBrowserUrl}}` for a hosted copy link generated at send time."
},
"headers": {
"type": "object",
"description": "Extra email headers as `{ \"Header-Name\": \"value\" }`, up to 50. Names use letters, digits, and hyphens; values are one line of printable ASCII. A transactional send can carry the caller's own `List-Unsubscribe` and `List-Unsubscribe-Post: List-Unsubscribe=One-Click`. Marketing sends always use Sequenzy's signed unsubscribe headers, so those two plus `Precedence` and `Feedback-ID` are not applied. Headers Sequenzy manages (for example From, To, Subject, Reply-To, Message-ID, Content-Type, and `X-Sequenzy-*`) are never applied. Values must be strings. Headers the API does not apply do not fail the send; they are listed in the response `ignoredHeaders` with a reason.",
"additionalProperties": {
"type": "string"
}
},
"replyTo": {
"type": "string",
"description": "Optional Reply-To address, formatted as `[email protected]` or `Name <[email protected]>`. Pair a bare address with `replyToName` instead of embedding the name. Mutually exclusive with `replyProfileId`. When omitted, the saved template or company default is used."
},
"subject": {
"type": "string",
"description": "Email subject line. Required with `html` when `templateId` is omitted."
},
"trackAs": {
"type": "string",
"maxLength": 255,
"description": "Direct `subject`/`html` sends only. Names the email type, for example `weekly-report` (up to 255 ASCII letters, digits, spaces and `. _ - : /`), so every send with the same value is tracked under one code-managed transactional email with its own stats. The first send creates it (`managedBy: code` in list_transactional_emails); later sends link to it. Use a stable name, never per-recipient values: a workspace can have at most 100. Fails if the value matches a dashboard template's slug or the code-managed email is disabled. Code-managed emails cannot be sent with `templateId`."
},
"fromName": {
"type": "string",
"description": "Display name of an existing verified sender identity on fromEmail, e.g. StudyBoost vs StudyBoost News. Requires fromEmail. Mutually exclusive with senderProfileId. Does not create a new sender profile."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"emailType": {
"type": "string",
"description": "Delivery policy: `transactional` (default) or `marketing`. Marketing mode supports exactly one `to` recipient, rejects `cc` and `bcc`, and automatically applies subscriber suppression, the standard unsubscribe footer, and RFC 8058 headers. Both modes use the Send API and require the `transactional:send` scope; a personal key held by a `marketer` cannot use this tool in either mode (see `roleRestrictedScopes` on get_account) and should send through campaigns or sequences instead."
},
"fromEmail": {
"type": "string",
"description": "From address of an existing verified sender profile (see list_sender_profiles). Mutually exclusive with senderProfileId. If the address has several identities, pass fromName to choose one. Does not create a new sender profile."
},
"variables": {
"type": "object",
"description": "Variables for template personalization. Nested objects and arrays are supported for repeat blocks, for example { items: [...] }. When the recipient matches a subscriber, saved first and last names fill omitted name variables; explicit values, including blanks, take precedence. Variables are HTML-escaped; a template can prefix a tag with 'html.' ({{html.prerenderedHtml}}) to insert a trusted, sanitized HTML value unescaped."
},
"templateId": {
"type": "string",
"description": "Saved transactional email API slug, for example `welcome-email`. The field name is retained for MCP compatibility and is mapped to the transactional API `slug` field."
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"required": [
"filename"
],
"properties": {
"path": {
"type": "string"
},
"content": {
"type": "string"
},
"filename": {
"type": "string"
},
"contentId": {
"type": "string"
},
"contentType": {
"type": "string"
}
},
"additionalProperties": false
},
"maxItems": 10,
"description": "Files to attach (15MB total). Each item needs `filename` and exactly one of Base64 `content` or public HTTP(S) `path`. Set `contentId` to embed it as a CID image referenced from HTML, and optionally set `contentType` to override MIME detection."
},
"replyToName": {
"type": "string",
"description": "Display name for `replyTo`. Requires a bare `replyTo` address. Mutually exclusive with `replyProfileId`. Does not create a reply profile."
},
"idempotencyKey": {
"type": "string",
"description": "Caller-owned retry key for this logical email (maximum 255 characters). Reuse the same key with the same arguments to get the original emailSendId for 14 days. Never reuse a key for different content."
},
"replyProfileId": {
"type": "string",
"description": "Existing reply profile ID (see list_sender_profiles). It already supplies both the Reply-To address and display name, so send it on its own and omit replyTo and replyToName. Mutually exclusive with replyTo."
},
"senderProfileId": {
"type": "string",
"description": "Existing sender profile ID (see list_sender_profiles). It already supplies both the From address and display name, so send it on its own and omit fromEmail and fromName. Mutually exclusive with fromEmail. When omitted, a template send keeps its saved sender and a direct send uses the company default."
},
"trackingSettings": {
"type": "object",
"properties": {
"openTracking": {
"type": "boolean",
"description": "Set to `false` to skip the open-tracking pixel for this send only."
},
"clickTracking": {
"type": "boolean",
"description": "Set to `false` to skip click-link rewriting for this send only, which helps when tracking redirects break universal or deep links."
}
},
"description": "Per-send tracking opt-outs. Each field defaults to `true`, meaning the account tracking settings apply; set a field to `false` to disable that tracking for this send only. These fields cannot enable tracking the account has disabled.",
"additionalProperties": false
},
"subscriberExternalId": {
"type": "string",
"description": "Customer-owned subscriber ID for attaching analytics, localization, and saved-name personalization on single-recipient sends. Maximum length: 255 characters."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Send Email",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Get overview statistics for a time period, including reply count and reply rate. Counts form a funnel over the sends made inside the period: opened and clicked are unique per email send (not total open events) and include engagement that arrives after the period ends, so they never exceed sent. Rates divide by rateDenominator (delivered, falling back to sent), reported alongside rateDenominatorBasis. Set emailType to transactional for Send API and transactional SMTP open/click rates, including both direct and saved-template sends. Also returns top-level subscriberCount (every stored contact) and activeSubscriberCount (status=active) as a live audience snapshot, independent of period; use these for 'how many subscribers do I have' instead of search_subscribers pagination.total. When no emailType filter is used and a background-computed snapshot is available, the response also includes a top-level commerceForecast with predicted AOV, 12-month customer value, 90-day revenue, confidence, and data-eligibility reasons.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
period
Time period: 7d, 30d, or 90d (default: 7d)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
emailType
Optional structural email type filter: campaign, transactional, or sequence. Use transactional for Send API and transactional SMTP traffic.
Clear enough to supply this argument.
start
ISO 8601 range start; needs end. Max 90 days.
Clear enough to supply this argument.
end
ISO 8601 range end; needs start.
Clear enough to supply this argument.
mailboxProvider
Mailbox provider filter, e.g. gmail or microsoft.
Clear enough to supply this argument.
recipientDomain
Recipient domain filter, e.g. gmail.com.
Clear enough to supply this argument.
source
Source filter <type>:<id> with type campaign, sequence, sequence_step or transactional.
Clear enough to supply this argument.
outcome
Only sends that bounced this way or drew a spam complaint. With get_stats_breakdown by=email it shows which emails the bounces or complaints came from. Filtered stats report replies as 0.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
includeMachineEngagement
If true, include machine-classified bot/scanner opens and clicks. Defaults to false, so metrics and activity are human-only.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_stats",
"description": "Get overview statistics for a time period, including reply count and reply rate. Counts form a funnel over the sends made inside the period: opened and clicked are unique per email send (not total open events) and include engagement that arrives after the period ends, so they never exceed sent. Rates divide by rateDenominator (delivered, falling back to sent), reported alongside rateDenominatorBasis. Set emailType to transactional for Send API and transactional SMTP open/click rates, including both direct and saved-template sends. Also returns top-level subscriberCount (every stored contact) and activeSubscriberCount (status=active) as a live audience snapshot, independent of period; use these for 'how many subscribers do I have' instead of search_subscribers pagination.total. When no emailType filter is used and a background-computed snapshot is available, the response also includes a top-level commerceForecast with predicted AOV, 12-month customer value, 90-day revenue, confidence, and data-eligibility reasons.",
"inputSchema": {
"type": "object",
"properties": {
"end": {
"type": "string",
"description": "ISO 8601 range end; needs start."
},
"start": {
"type": "string",
"description": "ISO 8601 range start; needs end. Max 90 days."
},
"period": {
"type": "string",
"description": "Time period: 7d, 30d, or 90d (default: 7d)"
},
"source": {
"type": "string",
"description": "Source filter <type>:<id> with type campaign, sequence, sequence_step or transactional."
},
"outcome": {
"enum": [
"permanent_bounce",
"temporary_bounce",
"blocked",
"complaint"
],
"type": "string",
"description": "Only sends that bounced this way or drew a spam complaint. With get_stats_breakdown by=email it shows which emails the bounces or complaints came from. Filtered stats report replies as 0."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"emailType": {
"type": "string",
"description": "Optional structural email type filter: campaign, transactional, or sequence. Use transactional for Send API and transactional SMTP traffic."
},
"mailboxProvider": {
"type": "string",
"description": "Mailbox provider filter, e.g. gmail or microsoft."
},
"recipientDomain": {
"type": "string",
"description": "Recipient domain filter, e.g. gmail.com."
},
"includeMachineEngagement": {
"type": "boolean",
"description": "If true, include machine-classified bot/scanner opens and clicks. Defaults to false, so metrics and activity are human-only."
}
}
},
"annotations": {
"title": "Get Stats",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description81/100
Funnel per email, sequence, email_type, mailbox_provider or recipient_domain, most sends first, with rates and attributed revenue. Drill in by passing a row's filter values to get_stats or another breakdown. Defaults: 30d, 25 rows.
Describe the returned information so the agent knows whether it will answer the request.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
by
Dimension: email (default), sequence, email_type, mailbox_provider, or recipient_domain.
Clear enough to supply this argument.
period
Time period: 1h, 24h, 7d, 30d, or 90d. Defaults to 30d.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
emailType
Optional structural email type filter: campaign, transactional, or sequence.
Clear enough to supply this argument.
start
ISO 8601 range start; needs end. Max 90 days.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
end
ISO 8601 range end; needs start.
Clear enough to supply this argument.
mailboxProvider
Mailbox provider filter, e.g. gmail or microsoft.
Clear enough to supply this argument.
recipientDomain
Recipient domain filter, e.g. gmail.com.
Clear enough to supply this argument.
source
Source filter <type>:<id> with type campaign, sequence, sequence_step or transactional.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
outcome
Only sends that bounced this way or drew a spam complaint. With get_stats_breakdown by=email it shows which emails the bounces or complaints came from. Filtered stats report replies as 0.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Rows to return, 1 to 100. Defaults to 25.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
includeMachineEngagement
If true, include machine-classified bot/scanner opens and clicks. Defaults to false, so metrics and activity are human-only.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Get detailed statistics for a campaign, including replies and reply rate (list who replied with list_campaign_replies), attributed conversions, revenue (revenueCents), attached campaign conversion goals in the top-level goals array (sent → opened → clicked → each named goal), product recommendation funnel metrics, a per-link click breakdown in the top-level clickedLinks array, and any Poll or NPS survey summaries in the top-level polls array.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
campaignId
Campaign ID
Explain the meaning of this value, not just its name.
period
Time period: 1h, 24h, 7d, 30d, or 90d
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
start
Custom range start as an ISO 8601 timestamp; provide end too
Clear enough to supply this argument.
end
Custom range end as an ISO 8601 timestamp; provide start too
Clear enough to supply this argument.
includeMachineEngagement
If true, include machine-classified bot/scanner opens and clicks. Defaults to false, so metrics and activity are human-only.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_campaign_stats",
"description": "Get detailed statistics for a campaign, including replies and reply rate (list who replied with list_campaign_replies), attributed conversions, revenue (revenueCents), attached campaign conversion goals in the top-level goals array (sent → opened → clicked → each named goal), product recommendation funnel metrics, a per-link click breakdown in the top-level clickedLinks array, and any Poll or NPS survey summaries in the top-level polls array.",
"inputSchema": {
"type": "object",
"required": [
"campaignId"
],
"properties": {
"end": {
"type": "string",
"description": "Custom range end as an ISO 8601 timestamp; provide start too"
},
"start": {
"type": "string",
"description": "Custom range start as an ISO 8601 timestamp; provide end too"
},
"period": {
"type": "string",
"description": "Time period: 1h, 24h, 7d, 30d, or 90d"
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"campaignId": {
"type": "string",
"description": "Campaign ID"
},
"includeMachineEngagement": {
"type": "boolean",
"description": "If true, include machine-classified bot/scanner opens and clicks. Defaults to false, so metrics and activity are human-only."
}
}
},
"annotations": {
"title": "Get Campaign Stats",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Get statistics for a sequence. The steps array is the per-step breakdown: one entry per email step in graph order with its step number, automation nodeId, subject, and its own sent, delivered, bounced, opened, clicked, replies, and unsubscribed counts plus rates - so this is where you read how many of Email 4 went out, without reconstructing anything from list_sequence_events. Step counts come from the retained event stream, not the 14-day delivery history behind list_email_sends, so they stay answerable for old sends. Also returns the aggregate funnel across every step, attributed conversions and revenue (revenueCents), product recommendation funnel metrics, per-step failed subscribers and failure reasons, per-step Poll and NPS summaries in steps[].polls (lifetime, same shape as get_campaign_stats polls), and enrollmentSkipped counts for trigger matches where the contact could not be enrolled (unsubscribed/bounced). Pass period or start/end to use one explicit window for every historical metric; without them, step and aggregate counts are all-time and enrollmentSkipped defaults to the last 30 days. The enrollmentCounts field is a live snapshot of active and waiting enrollments grouped by current node, so it is not limited by period or start/end; contacts held by pause_sequence_subscribers are counted separately in pausedEnrollments. To compare the same step across many sequences in one call, use list_email_metrics instead.
The description explains the capability, when to use it, and what to expect.
Inputs79/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
sequenceId
Sequence ID
Explain the meaning of this value, not just its name.
period
Optional sliding window: 1h, 24h, 7d, 30d, or 90d. Ignored when start and end are provided.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
start
Optional ISO 8601 custom range start. Must be provided with end.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
end
Optional ISO 8601 custom range end. Must be provided with start; maximum range is 90 days.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
includeMachineEngagement
If true, include machine-classified bot/scanner opens and clicks. Defaults to false, so metrics and activity are human-only.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_sequence_stats",
"description": "Get statistics for a sequence. The steps array is the per-step breakdown: one entry per email step in graph order with its step number, automation nodeId, subject, and its own sent, delivered, bounced, opened, clicked, replies, and unsubscribed counts plus rates - so this is where you read how many of Email 4 went out, without reconstructing anything from list_sequence_events. Step counts come from the retained event stream, not the 14-day delivery history behind list_email_sends, so they stay answerable for old sends. Also returns the aggregate funnel across every step, attributed conversions and revenue (revenueCents), product recommendation funnel metrics, per-step failed subscribers and failure reasons, per-step Poll and NPS summaries in steps[].polls (lifetime, same shape as get_campaign_stats polls), and enrollmentSkipped counts for trigger matches where the contact could not be enrolled (unsubscribed/bounced). Pass period or start/end to use one explicit window for every historical metric; without them, step and aggregate counts are all-time and enrollmentSkipped defaults to the last 30 days. The enrollmentCounts field is a live snapshot of active and waiting enrollments grouped by current node, so it is not limited by period or start/end; contacts held by pause_sequence_subscribers are counted separately in pausedEnrollments. To compare the same step across many sequences in one call, use list_email_metrics instead.",
"inputSchema": {
"type": "object",
"required": [
"sequenceId"
],
"properties": {
"end": {
"type": "string",
"description": "Optional ISO 8601 custom range end. Must be provided with start; maximum range is 90 days."
},
"start": {
"type": "string",
"description": "Optional ISO 8601 custom range start. Must be provided with end."
},
"period": {
"type": "string",
"description": "Optional sliding window: 1h, 24h, 7d, 30d, or 90d. Ignored when start and end are provided."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"sequenceId": {
"type": "string",
"description": "Sequence ID"
},
"includeMachineEngagement": {
"type": "boolean",
"description": "If true, include machine-classified bot/scanner opens and clicks. Defaults to false, so metrics and activity are human-only."
}
}
},
"annotations": {
"title": "Get Sequence Stats",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Get the email address anyone (a person, a service, or another agent) can write to so the message lands in this company's Sequenzy inbox. Also returns the default address, the branded address (customAddress, with status active or pending), whether receiving is on, whether attachments are stored, and how many days messages are kept. Replies to Sequenzy emails arrive in the same inbox automatically.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Input documentation gives an agent enough context to populate the arguments.
companyId
Company ID. If not provided, uses the currently selected company.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "get_inbox_address",
"description": "Get the email address anyone (a person, a service, or another agent) can write to so the message lands in this company's Sequenzy inbox. Also returns the default address, the branded address (customAddress, with status active or pending), whether receiving is on, whether attachments are stored, and how many days messages are kept. Replies to Sequenzy emails arrive in the same inbox automatically.",
"inputSchema": {
"type": "object",
"properties": {
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "Get Inbox Address",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
List inbox conversations: replies to campaigns, sequences and transactional email, plus email sent to the inbox address (context.type inbox; recipientAddress says which address). Filter by status, search, unread, spam (only listed with spam true) or recipient, with pagination. Each conversation includes lastMessagePreview: a short plain-text preview of the latest subscriber or team reply (quoted history removed), or null.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
status
Filter by conversation status. Defaults to all.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
search
Free-text search across conversation subjects and participants.
Clear enough to supply this argument.
unread
Set true to only return conversations with unread messages.
Clear enough to supply this argument.
spam
Set true to list the Spam folder instead.
Clear enough to supply this argument.
recipient
Only conversations that started at this inbox address.
Clear enough to supply this argument.
page
Page number. Defaults to 1.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Results per page, from 1 to 100. Defaults to 20.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "list_conversations",
"description": "List inbox conversations: replies to campaigns, sequences and transactional email, plus email sent to the inbox address (context.type inbox; recipientAddress says which address). Filter by status, search, unread, spam (only listed with spam true) or recipient, with pagination. Each conversation includes lastMessagePreview: a short plain-text preview of the latest subscriber or team reply (quoted history removed), or null.",
"inputSchema": {
"type": "object",
"properties": {
"page": {
"type": "number",
"description": "Page number. Defaults to 1."
},
"spam": {
"type": "boolean",
"description": "Set true to list the Spam folder instead."
},
"limit": {
"type": "number",
"description": "Results per page, from 1 to 100. Defaults to 20."
},
"search": {
"type": "string",
"description": "Free-text search across conversation subjects and participants."
},
"status": {
"enum": [
"open",
"closed",
"all"
],
"type": "string",
"description": "Filter by conversation status. Defaults to all."
},
"unread": {
"type": "boolean",
"description": "Set true to only return conversations with unread messages."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"recipient": {
"type": "string",
"description": "Only conversations that started at this inbox address."
}
}
},
"annotations": {
"title": "List Conversations",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description86/100
Get a conversation with its full message history, subscriber details, and context. Message attachments include a downloadUrl (signed, valid for one hour) when the file is stored.
The description explains the capability, when to use it, and what to expect.
Inputs67/100
Explain the meaning of this value, not just its name.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
conversationId
Conversation ID.
Explain the meaning of this value, not just its name.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
Send a reply in a conversation, or add an internal note. type 'outbound' (default) emails the subscriber and requires bodyText or bodyHtml; type 'note' adds a private team-only note. When the conversation has a recipientAddress (the inbox address it was sent to), list the sender profiles first and, if one's email equals that address, reply from it with senderProfileId. Replying to a closed conversation reopens it. Each successful outbound call sends another email, so after a timeout check the conversation with get_conversation before retrying.
Describe the returned information so the agent knows whether it will answer the request.
Inputs83/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
conversationId
Conversation ID to reply in.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
type
Message type: outbound emails the subscriber, note is internal-only. Defaults to outbound.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
subject
Optional subject override. Defaults to the conversation subject.
Clear enough to supply this argument.
bodyText
Plain-text message body.
Explain what happens when this optional value is omitted.
bodyHtml
HTML message body.
Clear enough to supply this argument.
senderProfileId
Optional sender profile to reply from (outbound only; its domain must be verified). Get IDs from list_sender_profiles. Omit to send from the API key owner's email address.
Clear enough to supply this argument.
attachments › items › filename
File name.
Explain the meaning of this value, not just its name.
attachments › items › content
Base64-encoded file content.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
attachments › items › contentType
Optional MIME type. Inferred from the file name when omitted.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "reply_to_conversation",
"description": "Send a reply in a conversation, or add an internal note. type 'outbound' (default) emails the subscriber and requires bodyText or bodyHtml; type 'note' adds a private team-only note. When the conversation has a recipientAddress (the inbox address it was sent to), list the sender profiles first and, if one's email equals that address, reply from it with senderProfileId. Replying to a closed conversation reopens it. Each successful outbound call sends another email, so after a timeout check the conversation with get_conversation before retrying.",
"inputSchema": {
"type": "object",
"required": [
"conversationId"
],
"properties": {
"type": {
"enum": [
"outbound",
"note"
],
"type": "string",
"description": "Message type: outbound emails the subscriber, note is internal-only. Defaults to outbound."
},
"subject": {
"type": "string",
"description": "Optional subject override. Defaults to the conversation subject."
},
"bodyHtml": {
"type": "string",
"description": "HTML message body."
},
"bodyText": {
"type": "string",
"description": "Plain-text message body."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"required": [
"filename",
"content"
],
"properties": {
"content": {
"type": "string",
"maxLength": 20971520,
"description": "Base64-encoded file content."
},
"filename": {
"type": "string",
"description": "File name."
},
"contentType": {
"type": "string",
"description": "Optional MIME type. Inferred from the file name when omitted."
}
}
},
"maxItems": 10,
"description": "Optional files to attach (max 10, 15 MB total). Requires attachment storage; see attachmentsAvailable from get_inbox_address."
},
"conversationId": {
"type": "string",
"description": "Conversation ID to reply in."
},
"senderProfileId": {
"type": "string",
"description": "Optional sender profile to reply from (outbound only; its domain must be verified). Get IDs from list_sender_profiles. Omit to send from the API key owner's email address."
}
}
},
"annotations": {
"title": "Reply To Conversation",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Generate email blocks from a prompt. Returns a draft and does not create or send an email; the first generation for a company also saves its inferred email design direction, which later generations reuse. Generated blocks include the company's branding chrome (logo, footer with company name/address/unsubscribe) by default, matching emails created in the dashboard.
Describe the returned information so the agent knows whether it will answer the request.
Inputs95/100
Explain what happens when this optional value is omitted.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
prompt
Description of the email to generate
Clear enough to supply this argument.
style
Style guidance. Pass 'designed' or 'plain' to force the designed or plain-text email style; other values (minimal, branded, promotional) are freeform prompt guidance. Defaults to the company's email style preference.
Clear enough to supply this argument.
tone
Tone: professional, casual, friendly
Explain what happens when this optional value is omitted.
applyBranding
Wrap the generated content with company branding (logo + footer). Defaults to true; set false to get raw content blocks only.
Clear enough to supply this argument.
emailType
Email type. Transactional emails get a footer without the unsubscribe link. Defaults to marketing.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "generate_email",
"description": "Generate email blocks from a prompt. Returns a draft and does not create or send an email; the first generation for a company also saves its inferred email design direction, which later generations reuse. Generated blocks include the company's branding chrome (logo, footer with company name/address/unsubscribe) by default, matching emails created in the dashboard.",
"inputSchema": {
"type": "object",
"required": [
"prompt"
],
"properties": {
"tone": {
"type": "string",
"description": "Tone: professional, casual, friendly"
},
"style": {
"type": "string",
"description": "Style guidance. Pass 'designed' or 'plain' to force the designed or plain-text email style; other values (minimal, branded, promotional) are freeform prompt guidance. Defaults to the company's email style preference."
},
"prompt": {
"type": "string",
"description": "Description of the email to generate"
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"emailType": {
"enum": [
"marketing",
"transactional"
],
"type": "string",
"description": "Email type. Transactional emails get a footer without the unsubscribe link. Defaults to marketing."
},
"applyBranding": {
"type": "boolean",
"description": "Wrap the generated content with company branding (logo + footer). Defaults to true; set false to get raw content blocks only."
}
}
},
"annotations": {
"title": "Generate Email",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description91/100
[DEPRECATED compatibility alias - use create_sequence] Create and persist a disabled AI-generated email sequence draft from a goal. The saved draft appears in list_sequences. The name defaults to the goal and the trigger defaults to contact_added; optionally pass listId to scope it. Review before enabling.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
companyId
Company ID. If not provided, uses the currently selected company.
Clear enough to supply this argument.
goal
Goal of the sequence (e.g., 'onboard new SaaS trial users')
Clear enough to supply this argument.
name
Optional sequence name. Defaults to the goal.
Clear enough to supply this argument.
emailCount
Number of emails in the sequence (default: 5, max: 10)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
durationDays
Total duration in days (default: 14)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
listId
Optional list ID. When provided, only contacts added to this list trigger the sequence.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "generate_sequence",
"description": "[DEPRECATED compatibility alias - use create_sequence] Create and persist a disabled AI-generated email sequence draft from a goal. The saved draft appears in list_sequences. The name defaults to the goal and the trigger defaults to contact_added; optionally pass listId to scope it. Review before enabling.",
"inputSchema": {
"type": "object",
"required": [
"goal"
],
"properties": {
"goal": {
"type": "string",
"description": "Goal of the sequence (e.g., 'onboard new SaaS trial users')"
},
"name": {
"type": "string",
"description": "Optional sequence name. Defaults to the goal."
},
"listId": {
"type": "string",
"description": "Optional list ID. When provided, only contacts added to this list trigger the sequence."
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
},
"emailCount": {
"type": "number",
"description": "Number of emails in the sequence (default: 5, max: 10)"
},
"durationDays": {
"type": "number",
"description": "Total duration in days (default: 14)"
}
}
},
"annotations": {
"title": "Generate Sequence",
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Generate subject line variants for an A/B test from a prompt. Returns suggestions only and does not create or change a test; the first generation for a company also saves its inferred email design direction, which later generations reuse.
Describe the returned information so the agent knows whether it will answer the request.
Inputs83/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
companyId
Company ID. If not provided, uses the currently selected company.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "generate_subject_lines",
"description": "Generate subject line variants for an A/B test from a prompt. Returns suggestions only and does not create or change a test; the first generation for a company also saves its inferred email design direction, which later generations reuse.",
"inputSchema": {
"type": "object",
"required": [
"topic"
],
"properties": {
"count": {
"type": "number",
"description": "Number of variants to generate (default: 5)"
},
"topic": {
"type": "string",
"description": "Topic or context for the subject lines"
},
"companyId": {
"type": "string",
"description": "Company ID. If not provided, uses the currently selected company."
}
}
},
"annotations": {
"title": "Generate Subject Lines",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
Loading score analytics…
Put your MCP to the test
A few tasks worth trying with this server, chosen from its reviewed tools. These have not been run.
01Get SubscriberGet the full subscriber profile, including tags, notes, list memberships, sequence enrollments, email stats, and recent activity.
02Search SubscribersSearch subscribers by free-text query, tags, list, segment, custom attribute, or opt-out date.
03Get Subscriber ActivityGet recent activity, email stats, and current sequence enrollments for a subscriber.
04List ConversationsList inbox conversations: replies to campaigns, sequences and transactional email, plus email sent to the inbox address (context.type inbox; recipientAddress…
05List SequencesList all email sequences (automations).
Want to run these tasks against your MCP server with us?
sequenzy setup, tools, quality score, publishing readiness, and alternatives.
How do I add sequenzy to Claude, ChatGPT, or Cursor?
Add sequenzy to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://api.sequenzy.com/v1/mcp/muse.
Is sequenzy MCP ready for ChatGPT and Claude?
As of November 10, 2026, sequenzy scores 91/100 on Manufact's MCP publishing checklist. The scan does not yet meet ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is sequenzy's MCP tool documentation?
As of November 10, 2026, sequenzy scores 83/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 70 of 70 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What are the best alternatives to sequenzy?
As of November 10, 2026, alternatives to sequenzy in marketing-seo on the Manufact MCP leaderboard include Refluenced, The Prompting Company MCP, Buzzfy, Indexing Dispatch, and Brave URL Submitter.
How can sequenzy improve its MCP documentation?
create_tag is the lowest-scoring reviewed tool at 74/100. No output schema is declared. Add one for structured results so clients can interpret returned fields. Open its review for feedback and a copyable fix prompt, then rerun the documentation review after updating your tool metadata.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.