Flodesk MCP Server
A Flodesk MCP server and CLI exposing 32 shared tools—16 reads and 16 confirmed operations—over the native public REST API, with local guard, review and private-file helpers.
Read campaigns, custom fields, segments, segment colors, subscribers, webhooks and workflows (paginated, with native filters/statuses).
Create/update a subscriber, or batch upsert up to 50 subscribers with custom fields, segment IDs and opt-in data.
Add or remove a subscriber's segment membership, and unsubscribe them from all lists.
Enroll subscribers in workflows or remove them, subject to native re-entry and abandoned-cart restrictions.
Manage custom fields: create one, list paginated, or list all.
Manage segments: create, and retrieve one; list all segment colors.
Manage webhooks: create, update, delete, get and list.
Publish reviewed Canva bundle URLs or Studio HTML exports as draft campaigns (no send/schedule).
Inspect Canva design state to auto-select a campaign.
Preview and then submit an exact, hash-bound batch of 1–20 ordered subscriber/segment/workflow/custom-field tasks, stopping on first failure.
Save one subscriber page to an exclusive private JSON file instead of streaming records to the console.
List configured account profiles (labels/default/auth type only, no secrets) and read OAuth UserInfo for an externally minted Bearer token.
Inspect the reviewed local method/path/schema provenance of any native operation via get_operation_schema.
Require explicit confirmation for all mutations and writes; support read-only mode, per-account credential isolation and audit logging.
Integrates with Canva to publish email designs as draft campaigns and retrieve the latest Canva design state for auto-selecting campaigns.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Flodesk MCP Serveradd jane@example.com to my subscribers and tag her as VIP"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Flodesk MCP Server & CLI
Flodesk MCP server and CLI for Codex and AI agents. 32 shared tools for current subscribers, draft campaigns, workflows, custom fields and webhooks, private account profiles and exact reviewed subscriber batches.
One package provides a task CLI, local stdio MCP and versioned desktop bundle. Built and maintained by Navid Moazzez. Built on Slipway, which turns one definition of each tool into the MCP server and the CLI. Complete setup: navid.me.
The terminal illustrates actual commands, not a recorded provider account session. Node 22+ is required for manual installs; private account API access, subscription eligibility and audience permissions remain separate.
Two ways to use it
Command line
A terminal or shell agent calls only the requested task.
npx -y --package @thenavidm/flodesk-mcp-cli@latest flodesk-cli list-accounts --agentMCP server, for your AI app
Register the same stdio package with private user settings.
codex mcp add flodesk --env FLODESK_TOKEN_FILE=/absolute/private/flodesk.txt -- npx -y @thenavidm/flodesk-mcp-cli@latestWhich one
Use task-specific CLI help/compact output for terminal automation, or local MCP for your AI client. Both enforce the exact same handlers and policy. Complete setup is in INSTALL.md.
Related MCP server: Arsel MCP Server
Features
Current native 50-subscriber upsert and complete current subscriber/segment arguments.
Correct native DELETE JSON, workflow enrollment/removal and actual draft-campaign exports.
Native custom-field and webhook management with explicit approval.
Shared read-only/direct-call guard, isolated Basic/Bearer profiles and exact ordered reviews.
Full client/OS/desktop setup, native terminal, version history, accurate official comparison and 20 FAQ accordions.
Contents
Section | What it covers |
What you can ask it | |
Quick install | |
Set up Flodesk access | |
Connect your client | |
Check it works | |
Output, flags and exit codes | |
MCP or CLI and token cost | |
Every tool and argument | |
Subscriber, draft and automation workflows | |
Exact reviewed batches and pagination | |
Several private accounts | |
Writing safely | |
How the two surfaces work | |
Your data | |
Environment variables | |
Updates and removal | |
Troubleshooting | |
API coverage and comparisons | |
Versions and migration | |
FAQ |
1. What you can ask it
Read the intended account's subscribers, current native statuses and one exact subscriber.
Create/update only approved subscriber data, native batch upserts and segment membership.
Inspect workflows, enroll/remove exactly requested subscribers and account for email side effects.
Manage requested custom fields and webhook configuration with native arguments.
Publish a reviewed Canva/Studio export as a draft campaign, without sending it.
Review ordered subscriber operations and save a requested single audience page privately.
Actual shared discovery exposes 32 tools: 16 reads and 16 confirmed operations. All 20 legacy tool names remain. Six current REST additions and six helper/account/file/batch tasks complete the shared catalogue. See actual native arguments, major migrations and current official comparison below. The official hosted MCP has separate analytics and cohort capabilities this package does not invent.
2. Quick install
npm install -g @thenavidm/flodesk-mcp-cli@latest
flodesk-cli --version
flodesk-cli tools
flodesk-cli schema batch-create-or-update-subscribers
flodesk-cli loginNode 22+ for manual CLI/local MCP. INSTALL.md has Codex first and full client/OS setup, including the versioned desktop bundle.
3. Set up Flodesk access
Private integration API key
Sign into the intended Flodesk account. Open Account → Integrations → API, or the API key settings. Check which account owns the audience before creating/copying a key.
Use a private integration API key for your own account. The native docs describe full API access; this package does not invent per-operation key scopes or guarantee provider read-only keys. Local read-only policy is a separate control.
Save FLODESK_API_KEY only in private user/client environment settings, or use FLODESK_TOKEN_FILE as an absolute token-only file outside repositories. On macOS/Linux use a private 0700 directory and owner-private 0600 regular non-symlink file, at most 64 KiB. On Windows restrict file/parent ACLs to yourself; POSIX mode checks do not establish Windows ACLs.
Run flodesk-cli doctor for local settings. Deliberately run doctor --network to read one subscriber page with per_page=1; output reports only count, not the subscriber record. That verifies one read, not account-owner identity, campaign/webhook access or all native permissions.
Inspect exact native fields and IDs, then approve only requested work. Double opt-in, segment additions and workflow enrollment can trigger actual messages. Do not create subscribers, opt-ins, workflow entries, drafts or webhooks merely to test installation.
The API key is an HTTP Basic username, with an empty password. The client constructs Authorization: Basic base64(key:), sends a descriptive User-Agent and uses only the allowlisted https://api.flodesk.com origin. No API key goes into a URL, prompt, Git file or log. It refuses redirects and unknown routes.
Externally minted partner OAuth
Native partner OAuth requires a provider-approved integration with its own client ID/secret and redirect flow. This package accepts an externally minted FLODESK_ACCESS_TOKEN or named access_token profile as Authorization: Bearer. It does not register an app, start login, exchange authorization codes, refresh tokens or import official connector sessions.
Access tokens are documented as 24 hours; refresh tokens are single-use and rotate. Refreshing belongs to your approved private integration and must store its newly issued refresh token securely. This runtime never holds that client secret/refresh token. Restart after replacing its access token. get_oauth_userinfo makes only the fixed /oauth2/userinfo GET and refuses API-key profiles before any request.
For a token file containing an OAuth access token, set FLODESK_AUTH_TYPE=oauth for a direct profile, or auth_type:"oauth" in that named profile. File credentials otherwise default to API key. Never configure api_key and access_token together. A selected file overrides only its own profile's inline credential; profiles never inherit a global key/token or another account.
Several private accounts
FLODESK_ACCOUNTS is a private JSON array of unique {name,api_key,access_token,token_file,auth_type} entries. Choose exactly one credential type in each. FLODESK_DEFAULT_ACCOUNT and --account select exact labels. Labels and review hashes are not verified provider ownership. Token files cache until process restart. list_accounts returns only labels/default/auth type/credential source, without token paths or provider reads.
Official MCP connection
Flodesk already supplies its official MCP and setup help. Its production field reference currently lists 35 tools, including email/form/checkout/workflow analytics, cohort filters, subscriber actions, CSV export and bulk archive/unarchive/segment changes. Its previews issue single-use confirmation tokens expiring after 120 seconds. Those capabilities and safeguards already exist.
The September 11 help article describes an earlier 24-tool/individual-action phase and says bulk work is upcoming; the current production catalog describes 35 tools and bulk workflows. Treat that as documented source drift. Marketing's broad future-control examples do not establish current send/schedule support. This local public-REST package does not call private MCP-only analytics/cohort routes or accept the hosted connector's confirmation tokens.
Quotas and effects
The AGPL wrapper is free; Flodesk subscription/API eligibility and account policies remain separate. Native REST limits are 100 requests/minute normally and 20/minute for POST /subscribers/batch, up to 50 subscribers per request. X-Fd-RateLimit headers report remaining capacity. Our process spacing defaults 650 ms, plus a separate 3100 ms batch window. Other processes/apps share account quota; local pacing is not provider enforcement or a guaranteed distributed limiter.
No automatic retries, including reads, 429, 5xx, redirects or timeouts. A failed write can leave an unknown result, duplicate webhook/segment or triggered message. Inspect provider state before deliberately repeating. JSON requests cap 1 MiB and responses 5 MiB. Each native list returns one page with its own meta/page semantics, not an all-pages backup. Workflow statuses use native CSV and perPage; campaign query names retain native capitalization.
Canva and Studio publish draft campaign exports, not send/schedule emails. Subscriber upsert can create or update by id/email; up to 50 segment IDs are supported. double_optin applies only to newly created subscribers and can send a confirmation message. Workflow re-entry needs prior completion and Allow repeat subscribers; abandoned-cart workflows cannot be enrolled through this route. Unsubscribe changes subscription state without pretending to delete the record. Removing segment membership is distinct and sends the required native DELETE JSON body.
Revocation and retained data
Revoke the intended key at Flodesk, replace private settings/files and restart. Revoke partner OAuth/official connector authorization separately. Package/client removal does not undo audience changes, sent opt-ins/workflow effects, drafts, webhooks or private audience-page files. Retain receipts and investigate unknown outcomes before explicitly requested cleanup.
4. Connect your client
INSTALL.md covers Codex, Claude Code, Claude Desktop bundle/manual stdio, Cursor, VS Code/Copilot, Windsurf, Zed, Gemini CLI, Cline, Docker and other local stdio clients on macOS/Windows/Linux. No Claude Code installation is needed for Codex. GUI/remote runtimes need their own private settings and accessible file paths; restart/reconnect after changes.
This owned package is local stdio. Official hosted connectors use their own authentication/settings. Manual/client configurations must keep credentials outside project Git; optional SKILL.md is not installed automatically by npm.
codex mcp add flodesk --env FLODESK_TOKEN_FILE=/absolute/private/flodesk.txt -- npx -y @thenavidm/flodesk-mcp-cli@latest5. Check it works
flodesk-cli --version
flodesk-cli tools
flodesk-cli list-accounts --agent
flodesk-cli doctor
flodesk-cli doctor --network
flodesk-cli list-subscribers --per-page 1 --agent --select meta,data.idThe release validates shared full/read-only discovery and native request fixtures. Actual authenticated provider reads/writes, desktop GUI installation and matched successful Codex task/token measurements require their own evidence. doctor without --network checks local configuration only. One successful subscriber read does not prove ownership or every permission; never trigger opt-ins/workflows to test installation.
6. Output, flags and exit codes
Native provider JSON/meta is preserved after recognized credential redaction. Audience records, draft HTML and emails can still contain private data. --select filters only the needed fields locally. save_subscriber_page writes one confirmed page exclusively into a private JSON file and returns saved-file metadata, not customer rows.
Native batch upserts can return HTTP 200 with successes and failures. Inspect both arrays; a 2xx transport status is not complete success. Workflow enrollment returns native acceptance/data; it does not prove messages completed. All requests happen once; provider state must resolve unknown outcomes before any repeat.
Use --payload or an absolute private --payload-file for full native bodies, mutually exclusive with flat body flags and each other. Primitive array flags repeat one value at a time; --subscribers and --tasks repeat individual JSON objects. The house bridge derives flag names from actual schema, including native campaign query capitalization and workflow perPage.
flodesk-cli list-subscribers --per-page 5 --agent --select meta,data.id
flodesk-cli list-workflows --help
flodesk-cli schema publish-studio-emailFlag | Behavior |
--agent | Compact JSON and no prompts; never confirms a write |
--confirm | Explicit requested-operation approval |
--account LABEL | Exact private key/token profile |
--select a,b.c | Local field selection |
--payload / --payload-file | Complete exclusive native body input |
--subscribers JSON | Repeat native batch-upsert item objects |
--tasks JSON | Repeat ordered local review objects |
--review-sha256 HASH | Exact matching ordered preview hash |
--output-file PATH | New exclusive private page file |
Exit | Meaning |
0 | Handler/receipt success; still inspect partial native failures |
1 | Unexpected error |
2 | Invalid arguments, a refused or unapproved operation, an unknown command or a hidden write |
3 | Not found |
4 | Auth/permission |
5 | API/network/unknown write outcome |
7 | Provider rate limit |
10 | Missing/invalid private configuration |
7. MCP or CLI and token cost
Both surfaces are built by Slipway from the exact same real tool catalogue, handlers, argument validation and write guard. CLI discovery/task-specific help can expose only requested command information; MCP clients determine their own discovery/loading strategy. No statement here assumes every client sends every schema on every turn.
Measured on 2026-10-05 against 2.0.2, with Claude Code 2.1.286 on Claude Opus 5.5 (one short prompt with and without the server connected, the difference read from the API's own usage figures) and Codex 0.159.3 on gpt-6.1-sol:
Cost | 2.0.2 | 3.0.0 |
Claude Code, every tool loaded, every message | 13,410 | 12,750 |
Claude Code's default, tool search, every message | 949 | 950 |
| 1,232 | 1,289 |
Codex over the CLI, one task, median of five | 126,029 | 82,830 |
Codex over MCP, the same task, median of five | 48,151 | 48,158 |
The task was "find the command that adds a subscriber to a segment, and the flags it requires". Every tool loaded costs less because a subscriber batch and the double opt-in switch, each written out twice as their own arguments and inside payload, are now written once and referred to. Over the CLI, four of five 2.0.2 runs tried a command that failed, a bare schema or one that does not exist, then read the whole command list, because 2.0.2's help never said how to list commands; every extra step carries the whole conversation forward. Every 3.0.0 run asked which and read one command's help. Over MCP, Codex prints its own TypeScript rendering of the tool list and keeps its first and last 20,000 characters or so: the whole rendering is 182 tokens shorter on 3.0.0, but the part Codex keeps holds about 43 more, which each later request carries. SKILL.md costs 57 more because it now says how approval works over MCP and lists every exit code.
Evidence | Current status |
Actual shared full/read-only discovery | Verified release checks |
Local mutation/read-only/account/partial-request behavior | Verified fixtures, no provider side effects |
Official hosted authenticated task comparison | Not measured; documentation scope only |
Tool-list bytes or characters divided by four are not API usage, and no other offering was measured.
8. Every tool and argument
list_campaigns
List campaigns.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
| No; body/guard requirements still apply | string | Exact native query parameter. |
| No; body/guard requirements still apply | string | Exact native query parameter. |
| No; body/guard requirements still apply | string | Exact native query parameter. |
| No; body/guard requirements still apply | string | Exact native query parameter. enum: |
| No; body/guard requirements still apply | boolean | Exact native query parameter. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
publish_canva_email
Publish a Canva email design as a draft campaign.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.payload
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
get_canva_design_state
Get the latest Canva design state for auto-selecting campaigns.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
publish_studio_email
Publish a Studio email export as a draft campaign.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.payload
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
list_custom_fields
List all custom fields (pagination).
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
create_custom_field
Create a custom field.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | A friendly display label of the custom field. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.payload
Argument | Required | Type | Details |
| Yes | string | A friendly display label of the custom field. |
list_all_custom_fields
List all custom fields.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
list_segments
List all segments.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
create_segment
Create a segment.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | The color of the segment using a hex code. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.payload
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| No; body/guard requirements still apply | string | The color of the segment using a hex code. |
list_segment_colors
List all segment colors.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
get_segment
Retrieve a segment.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
list_subscribers
List all subscribers.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
| No; body/guard requirements still apply | string | Optional. The subscriber's status. |
| No; body/guard requirements still apply | string | Optional. The segment's id. When included, returns only subscribers who were added to the given segment. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
create_or_update_subscriber
Create or update a subscriber.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's first name. |
| No; body/guard requirements still apply | string | The subscriber's last name. |
| No; body/guard requirements still apply | object | An object containing custom field data. E.g. |
| No; body/guard requirements still apply | array | The segments this subscriber will be added to. Cap at |
| No; body/guard requirements still apply | boolean | Whether or not to require the subscriber to confirm subscription via email. This option is only available to set with new subscriber creation. Default to |
| No; body/guard requirements still apply | string | IP address from which the subscriber confirmed their opt-in. |
| No; body/guard requirements still apply | string | The date and time the subscribers confirmed their opt-in in ISO 8601 format. E.g. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.custom_fields
input.custom_fields.{key}
Native JSON value; inspect the full schema for validation.
input.segment_ids
input.segment_ids[]
Native JSON value; inspect the full schema for validation.
input.payload
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's first name. |
| No; body/guard requirements still apply | string | The subscriber's last name. |
| No; body/guard requirements still apply | object | An object containing custom field data. E.g. |
| No; body/guard requirements still apply | array | The segments this subscriber will be added to. Cap at |
| No; body/guard requirements still apply | boolean | Whether or not to require the subscriber to confirm subscription via email. This option is only available to set with new subscriber creation. Default to |
| No; body/guard requirements still apply | string | IP address from which the subscriber confirmed their opt-in. |
| No; body/guard requirements still apply | string | The date and time the subscribers confirmed their opt-in in ISO 8601 format. E.g. |
input.payload.custom_fields
input.payload.custom_fields.{key}
Native JSON value; inspect the full schema for validation.
input.payload.segment_ids
input.payload.segment_ids[]
Native JSON value; inspect the full schema for validation.
batch_create_or_update_subscribers
Create or update up to 50 subscribers in a single request.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | array | List of subscribers to create or update. Maximum 50 items. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.subscribers
input.subscribers[]
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's first name. |
| No; body/guard requirements still apply | string | The subscriber's last name. |
| No; body/guard requirements still apply | object | An object containing custom field data. E.g. |
| No; body/guard requirements still apply | array | The segments this subscriber will be added to. Cap at |
| No; body/guard requirements still apply | boolean | Whether or not to require the subscriber to confirm subscription via email. This option is only available to set with new subscriber creation. Default to |
| No; body/guard requirements still apply | string | IP address from which the subscriber confirmed their opt-in. |
| No; body/guard requirements still apply | string | The date and time the subscribers confirmed their opt-in in ISO 8601 format. E.g. |
input.subscribers[].custom_fields
input.subscribers[].custom_fields.{key}
Native JSON value; inspect the full schema for validation.
input.subscribers[].segment_ids
input.subscribers[].segment_ids[]
Native JSON value; inspect the full schema for validation.
input.payload
Argument | Required | Type | Details |
| Yes | array | List of subscribers to create or update. Maximum 50 items. |
input.payload.subscribers
input.payload.subscribers[]
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's first name. |
| No; body/guard requirements still apply | string | The subscriber's last name. |
| No; body/guard requirements still apply | object | An object containing custom field data. E.g. |
| No; body/guard requirements still apply | array | The segments this subscriber will be added to. Cap at |
| No; body/guard requirements still apply | boolean | Whether or not to require the subscriber to confirm subscription via email. This option is only available to set with new subscriber creation. Default to |
| No; body/guard requirements still apply | string | IP address from which the subscriber confirmed their opt-in. |
| No; body/guard requirements still apply | string | The date and time the subscribers confirmed their opt-in in ISO 8601 format. E.g. |
input.payload.subscribers[].custom_fields
input.payload.subscribers[].custom_fields.{key}
Native JSON value; inspect the full schema for validation.
input.payload.subscribers[].segment_ids
input.payload.subscribers[].segment_ids[]
Native JSON value; inspect the full schema for validation.
get_subscriber
Retrieve a subscriber.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
remove_subscriber_from_segments
Remove the subscriber from segments.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | array | An array of identifiers of the segments. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.segment_ids
input.segment_ids[]
Native JSON value; inspect the full schema for validation.
input.payload
Argument | Required | Type | Details |
| Yes | array | An array of identifiers of the segments. |
input.payload.segment_ids
input.payload.segment_ids[]
Native JSON value; inspect the full schema for validation.
add_subscriber_to_segments
Add the subscriber to segments.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | array | An array of identifiers of the segments. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.segment_ids
input.segment_ids[]
Native JSON value; inspect the full schema for validation.
input.payload
Argument | Required | Type | Details |
| Yes | array | An array of identifiers of the segments. |
input.payload.segment_ids
input.payload.segment_ids[]
Native JSON value; inspect the full schema for validation.
unsubscribe
Unsubscribe from all lists.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
list_webhooks
List all webhooks.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
create_webhook
Create a webhook.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | The webhook name. |
| No; body/guard requirements still apply | string | The url that the webhook will post to. |
| No; body/guard requirements still apply | array | An array specifying which events are enabled for webhook notifications. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.events
input.events[]
Native JSON value; inspect the full schema for validation.
input.payload
Argument | Required | Type | Details |
| Yes | string | The webhook name. |
| Yes | string | The url that the webhook will post to. |
| Yes | array | An array specifying which events are enabled for webhook notifications. |
input.payload.events
input.payload.events[]
Native JSON value; inspect the full schema for validation.
delete_webhook
Delete a webhook.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
get_webhook
Retrieve a webhook.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
update_webhook
Update a webhook.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | string | The webhook name. |
| No; body/guard requirements still apply | string | The url that the webhook will post to. |
| No; body/guard requirements still apply | array | An array specifying which events are enabled for webhook notifications. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.events
input.events[]
Native JSON value; inspect the full schema for validation.
input.payload
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | The webhook name. |
| No; body/guard requirements still apply | string | The url that the webhook will post to. |
| No; body/guard requirements still apply | array | An array specifying which events are enabled for webhook notifications. |
input.payload.events
input.payload.events[]
Native JSON value; inspect the full schema for validation.
list_workflows
List workflows.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | array | filter by workflow statuses e.g. statuses=active,paused. Default is all statuses |
| No; body/guard requirements still apply | integer | Default = 1 minimum: |
| No; body/guard requirements still apply | integer | Default = 10 Local positive integer validation; perPage has a local 100-item cap. minimum: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
input.statuses
input.statuses[]
Native JSON value; inspect the full schema for validation.
add_subscriber_to_workflow
Notes:
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | string |
|
| No; body/guard requirements still apply | string |
|
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| No; body/guard requirements still apply | object | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. |
| No; body/guard requirements still apply | string | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. minLength: |
input.payload
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string |
|
| No; body/guard requirements still apply | string |
|
remove_subscriber_from_workflow
Remove a subscriber from workflow.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| Yes | string | Exact native path parameter. minLength: |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
list_accounts
Local profile labels/default/auth method only. No keys, token paths, provider identity or network request.
Kind: Read. Native account permissions and local semantics still apply.
Native JSON value; inspect the full schema for validation.
get_operation_schema
Local reviewed method/path/query/body schema and provenance for one native tool. No credentials or provider request.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | string | Exact native tool name, e.g. batch_create_or_update_subscribers or publish_studio_email. enum: |
get_oauth_userinfo
One fixed UserInfo GET for an explicitly selected externally minted OAuth access token. API keys refuse; no refresh, OAuth login or fallback.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | Exact selected private account profile; binds label, not key ownership. |
preview_subscriber_batch
Local validation and SHA-256 of exact ordered subscriber/segment/workflow/custom-field work, selected profile label and reviewed schema. No provider reads, key load, identity check, price or rollback guarantee.
Kind: Read. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | array | One to twenty exact ordered supported subscriber/segment/workflow/custom-field operations. Native batch upserts may affect up to50 subscribers per task; not a20-person budget. minItems: |
| No; body/guard requirements still apply | string | Exact selected private account profile; binds label, not key ownership. |
input.tasks
input.tasks[]
Argument | Required | Type | Details |
| Yes | string | Native field; use the reviewed provider reference. enum: |
| Yes | object | Actual native tool arguments without account, confirm, payload_file or output_file. |
submit_subscriber_batch
Confirmed one-to-twenty ordered subscriber/segment/workflow/custom-field tasks. Prevalidate all and verify exact hash before first request. Stop on first failure with known results/failed index/unattempted indices; no retries, rollback or implicit continuation.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| Yes | array | One to twenty exact ordered supported subscriber/segment/workflow/custom-field operations. Native batch upserts may affect up to50 subscribers per task; not a20-person budget. minItems: |
| No; body/guard requirements still apply | string | Exact selected private account profile; binds label, not key ownership. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| Yes | string | Exact preview_subscriber_batch hash for identical requests, profile label, schema and order. pattern: |
input.tasks
input.tasks[]
Argument | Required | Type | Details |
| Yes | string | Native field; use the reviewed provider reference. enum: |
| Yes | object | Actual native tool arguments without account, confirm, payload_file or output_file. |
save_subscriber_page
Confirmed one-page GET saved only to an exclusive new0600 JSON file. No CSV/cohort export, all-pages loop, overwrite, automatic upload or browser preview.
Kind: Confirmed operation. Native account permissions and local semantics still apply.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
| No; body/guard requirements still apply | string | Optional. The subscriber's status. |
| No; body/guard requirements still apply | string | Optional. The segment's id. When included, returns only subscribers who were added to the given segment. |
| No; body/guard requirements still apply | string | Exact configured private account profile label; not a tenant or provider account ID. |
| No; body/guard requirements still apply | boolean | Set true only when the user asked for exactly this action. |
| Yes | string | Absolute new file in an existing private directory. Restrict Windows ACLs separately. minLength: |
Native list_campaigns: GET /campaigns
List campaigns.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
| No; body/guard requirements still apply | string | Exact native query parameter. |
| No; body/guard requirements still apply | string | Exact native query parameter. |
| No; body/guard requirements still apply | string | Exact native query parameter. |
| No; body/guard requirements still apply | string | Exact native query parameter. enum: |
| No; body/guard requirements still apply | boolean | Exact native query parameter. |
No JSON body.
Native publish_canva_email: POST /campaigns/canva
Publish a Canva email design as a draft campaign.
Native JSON value; inspect the full schema for validation.
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| bundle_url | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| title | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| design_token | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| page_id | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| campaign_id | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
Native get_canva_design_state: GET /campaigns/canva/design-state
Get the latest Canva design state for auto-selecting campaigns.
Native JSON value; inspect the full schema for validation.
No JSON body.
Native publish_studio_email: POST /campaigns/studio
Publish a Studio email export as a draft campaign.
Native JSON value; inspect the full schema for validation.
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| html | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| title | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| campaign_id | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| asset_id | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
Native list_custom_fields: GET /custom-fields
List all custom fields (pagination).
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
No JSON body.
Native create_custom_field: POST /custom-fields
Create a custom field.
Native JSON value; inspect the full schema for validation.
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| label | Yes | string | A friendly display label of the custom field. |
Native list_all_custom_fields: GET /custom-fields/all
List all custom fields.
Native JSON value; inspect the full schema for validation.
No JSON body.
Native list_segments: GET /segments
List all segments.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
No JSON body.
Native create_segment: POST /segments
Create a segment.
Native JSON value; inspect the full schema for validation.
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| name | No; body/guard requirements still apply | string | Native field; use the reviewed provider reference. |
| color | No; body/guard requirements still apply | string | The color of the segment using a hex code. Use GET List all segment colors. to view available colors. |
Native list_segment_colors: GET /segments/colors
List all segment colors.
Native JSON value; inspect the full schema for validation.
No JSON body.
Native get_segment: GET /segments/{id}
Retrieve a segment.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
No JSON body.
Native list_subscribers: GET /subscribers
List all subscribers.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
| No; body/guard requirements still apply | string | Optional. The subscriber's status. |
| No; body/guard requirements still apply | string | Optional. The segment's id. When included, returns only subscribers who were added to the given segment. |
No JSON body.
Native create_or_update_subscriber: POST /subscribers
Create or update a subscriber.
Native JSON value; inspect the full schema for validation.
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| id | No; body/guard requirements still apply | string | The subscriber's id. Either email or id must be included. |
| email | No; body/guard requirements still apply | string | The subscriber's email. Either email or id must be included. |
| first_name | No; body/guard requirements still apply | string | The subscriber's first name. |
| last_name | No; body/guard requirements still apply | string | The subscriber's last name. |
| custom_fields | No; body/guard requirements still apply | object | An object containing custom field data. E.g. "favorite_color": "Lavender". |
| segment_ids | No; body/guard requirements still apply | array | The segments this subscriber will be added to. Cap at 50. |
| double_optin | No; body/guard requirements still apply | boolean | Whether or not to require the subscriber to confirm subscription via email. This option is only available to set with new subscriber creation. Default to false if not indicated. |
| optin_ip | No; body/guard requirements still apply | string | IP address from which the subscriber confirmed their opt-in. |
| optin_timestamp | No; body/guard requirements still apply | string | The date and time the subscribers confirmed their opt-in in ISO 8601 format. E.g. 2023-01-02T15:04:05.999Z. |
input.custom_fields
input.custom_fields.{key}
Native JSON value; inspect the full schema for validation.
input.segment_ids
input.segment_ids[]
Native JSON value; inspect the full schema for validation.
Native batch_create_or_update_subscribers: POST /subscribers/batch
Create or update up to 50 subscribers in a single request.
Native JSON value; inspect the full schema for validation.
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| subscribers | Yes | array | List of subscribers to create or update. Maximum 50 items. |
input.subscribers
input.subscribers[]
Argument | Required | Type | Details |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's |
| No; body/guard requirements still apply | string | The subscriber's first name. |
| No; body/guard requirements still apply | string | The subscriber's last name. |
| No; body/guard requirements still apply | object | An object containing custom field data. E.g. |
| No; body/guard requirements still apply | array | The segments this subscriber will be added to. Cap at |
| No; body/guard requirements still apply | boolean | Whether or not to require the subscriber to confirm subscription via email. This option is only available to set with new subscriber creation. Default to |
| No; body/guard requirements still apply | string | IP address from which the subscriber confirmed their opt-in. |
| No; body/guard requirements still apply | string | The date and time the subscribers confirmed their opt-in in ISO 8601 format. E.g. |
input.subscribers[].custom_fields
input.subscribers[].custom_fields.{key}
Native JSON value; inspect the full schema for validation.
input.subscribers[].segment_ids
input.subscribers[].segment_ids[]
Native JSON value; inspect the full schema for validation.
Native get_subscriber: GET /subscribers/{id_or_email}
Retrieve a subscriber.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
No JSON body.
Native remove_subscriber_from_segments: DELETE /subscribers/{id_or_email}/segments
Remove the subscriber from segments.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| segment_ids | Yes | array | An array of identifiers of the segments. |
input.segment_ids
input.segment_ids[]
Native JSON value; inspect the full schema for validation.
Native add_subscriber_to_segments: POST /subscribers/{id_or_email}/segments
Add the subscriber to segments.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| segment_ids | Yes | array | An array of identifiers of the segments. |
input.segment_ids
input.segment_ids[]
Native JSON value; inspect the full schema for validation.
Native unsubscribe: POST /subscribers/{id_or_email}/unsubscribe
Unsubscribe from all lists.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
No JSON body.
Native list_webhooks: GET /webhooks
List all webhooks.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | integer | The page number. Defaults to 1. minimum: |
| No; body/guard requirements still apply | integer | The number of records to be returned on each page. Defaults to 20. Maximum 100. minimum: |
No JSON body.
Native create_webhook: POST /webhooks
Create a webhook.
Native JSON value; inspect the full schema for validation.
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| name | Yes | string | The webhook name. |
| post_url | Yes | string | The url that the webhook will post to. |
| events | Yes | array | An array specifying which events are enabled for webhook notifications. |
input.events
input.events[]
Native JSON value; inspect the full schema for validation.
Native delete_webhook: DELETE /webhooks/{id}
Delete a webhook.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
No JSON body.
Native get_webhook: GET /webhooks/{id}
Retrieve a webhook.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
No JSON body.
Native update_webhook: PUT /webhooks/{id}
Update a webhook.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| name | No; body/guard requirements still apply | string | The webhook name. |
| post_url | No; body/guard requirements still apply | string | The url that the webhook will post to. |
| events | No; body/guard requirements still apply | array | An array specifying which events are enabled for webhook notifications. |
input.events
input.events[]
Native JSON value; inspect the full schema for validation.
Native list_workflows: GET /workflows
List workflows.
Argument | Required | Type | Details |
| No; body/guard requirements still apply | array | filter by workflow statuses e.g. statuses=active,paused. Default is all statuses |
| No; body/guard requirements still apply | integer | Default = 1 minimum: |
| No; body/guard requirements still apply | integer | Default = 10 Local positive integer validation; perPage has a local 100-item cap. minimum: |
input.statuses
input.statuses[]
Native JSON value; inspect the full schema for validation.
No JSON body.
Native add_subscriber_to_workflow: POST /workflows/{workflow_id}/subscribers
Notes:
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
Native body: | Argument | Required | Type | Details |
| --- | --- | --- | --- |
| id | No; body/guard requirements still apply | string | id is required if email is not present |
| email | No; body/guard requirements still apply | string | email is required if id is not present |
Native remove_subscriber_from_workflow: DELETE /workflows/{workflow_id}/subscribers/{id_or_email}
Remove a subscriber from workflow.
Argument | Required | Type | Details |
| Yes | string | Exact native path parameter. minLength: |
| Yes | string | Exact native path parameter. minLength: |
No JSON body.
9. Subscriber, draft and automation workflows
Start with one intended account and exact IDs. Read current subscriber status/membership, segment colors and available workflow IDs before approving changes. Do not infer consent or enroll all matching rows from a display name. Native upsert accepts id or email; optional optin_ip/optin_timestamp preserve supplied provenance rather than inventing it. Its status filter now includes unconfirmed, cleaned and archived.
Use native batch upsert for 1–50 explicit subscribers. It is distinct from the official MCP's dynamic-cohort archive/export actions. Inspect every successes/failures item and repeat only an explicitly reviewed correction after resolving unknown outcomes.
Segment removal changes membership and retains the subscriber record; unsubscribe changes subscription state. Workflow addition can trigger real automation messages and is refused until confirmed. Provider re-entry/completion/abandoned-cart restrictions still apply; the wrapper does not circumvent them.
Create a webhook only for the explicitly chosen HTTPS receiver and requested native events. No receiver is called by this local client. Event delivery is provider behavior after configuration; a creation response is not a receiver/test-delivery success. Native public REST does not expose a signing-key creation/rotation endpoint, and none is invented.
Publish reviewed native HTML via publish_studio_email, or an approved exported bundle_url via publish_canva_email. These create/update draft campaigns; sending/scheduling remains outside this API. The old blanket statement that no campaign creation exists is corrected. Never treat a returned draft URL as a sent campaign receipt.
flodesk-cli get-subscriber --id-or-email YOUR_SUBSCRIBER_ID --account work --agent
flodesk-cli list-workflows --agent
flodesk-cli get-operation-schema --operation publish_studio_email --agent
flodesk-cli create-or-update-subscriber --help
flodesk-cli save-subscriber-page --per-page 1 --output-file /absolute/private/page-001.json --account work --confirm --agent10. Exact reviewed batches and pagination
preview_subscriber_batch is fully local: validate 1–20 ordered subscriber/segment/workflow/custom-field tasks against current packaged schemas and native semantics. It loads no key/file and makes no provider read. SHA-256 binds ordered exact requests/tasks, selected profile label/auth type and snapshot. It is not a real-cohort preview, final recipient count, cryptographic approval, current provider-state lock or verified account ownership. A changed key can keep the same label.
submit_subscriber_batch requires explicit confirmation and the matching hash. Every task is validated before the first request. Native batch-upsert tasks may each affect 50 subscribers:20 tasks is not a 20-recipient budget. Stop on first failure, partial native HTTP 200 result or incomplete native receipt, returning knownResults/failedIndex/unattemptedIndices without automatic retry, replay, rollback or implicit continuation. Earlier subscriber/workflow effects can persist.
Official preview_bulk_change and preview_segment_count already count real filtered audiences, issue single-use 120-second tokens and validate cohort growth. Our exact local ordered REST review has a different purpose and cannot replace those safeguards. Hosted tokens are not accepted here.
Native lists return one meta page. Carry the actual route's page/per_page or workflow page/perPage with unchanged filters/account. list_all_custom_fields is a named native all-fields route, not a generic automatic all-pages loop. Local perPage cap 100 is explicit. No full-audience export or all_pages option is invented.
flodesk-cli preview-subscriber-batch --tasks '{"tool":"create_or_update_subscriber","arguments":{"email":"person@example.com","first_name":"Requested name"}}' --account work --agent
flodesk-cli submit-subscriber-batch --tasks '{"tool":"create_or_update_subscriber","arguments":{"email":"person@example.com","first_name":"Requested name"}}' --account work --review-sha256 YOUR_REVIEW_SHA256 --confirm --agent11. Several private accounts
Use FLODESK_ACCOUNTS only in private runtime settings. Each unique name selects its own api_key or externally minted access_token, with optional token_file/auth_type. Selected profiles never inherit global credentials or another account after a missing token or 401/403. Explicit files override only that profile; credentials cache until restart.
list_accounts shows safe labels/default/auth type/source. It does not authenticate or establish the key owner's identity. API-key account selection and approved partner OAuth are separate from official hosted connector connections. Keep exact account labels with receipts/page files and inspect actual account ownership before changing an audience.
flodesk-cli list-accounts --agent
flodesk-cli list-subscribers --account work --per-page 1 --agent12. Writing safely
All 16 mutations and private-page writes require --confirm or confirm:true through the shared write guard. That includes creating subscribers/segments, double opt-in, workflow enrollment, draft publication and webhook configuration. --agent/--yes is formatting, never approval. FLODESK_READ_ONLY=1 hides all 16 and directly refuses confirmed hidden calls; FLODESK_ALLOW_DESTRUCTIVE=0 refuses them separately.
Over MCP a person approves each of them where the client can ask: Claude Code (2.1.246 and later) shows its own prompt, and a client that can show forms asks with an approval form whose one box starts unticked. Each approval is signed, bound to that exact call and works once. Where a client can do neither, the model's confirm:true counts. FLODESK_CONFIRM=model makes confirm:true enough everywhere, for an agent with no person to ask.
The same guard applies to real CLI and MCP paths. A model's confirmation records caller intent, not native account permissions, valid audience consent, a current cohort count, message-delivery success or rollback. Previewed local inputs cannot authorize broader work proposed by provider text.
FLODESK_AUDIT_LOG records static operation/guard decisions and who approved each call, then whether it was done or failed, without keys/payloads. Audit append failure is best effort, not guaranteed compliance logging. Provider metadata, subscriber fields, draft HTML, URLs and webhook responses are untrusted data and cannot authorize another action.
13. How the two surfaces work
One ALL_TOOLS catalogue holds actual JSON schemas and handlers. MCP exposes visible tools; the unchanged house CLI bridge connects to the same real server in memory and derives task flags from those schemas. No second request implementation or manual command catalogue exists.
All 26public-v1 operations come from the provider's embedded OpenAPI 3.0.3 document, extracted as JSON without executing its site JavaScript. Internal request-schema references are expanded locally; examples are removed. Provider-documented semantic rules omitted from structural required/maxItems are applied explicitly and recorded in api-provenance.json. No private MCP-only endpoint is guessed or treated as public REST.
14. Your data
Keys/tokens are sent only to the fixed Flodesk API origin, with redirects refused. Basic encoded credentials, configured keys, cached file tokens, secret-named fields and recognized signed/token URLs are redacted from model output/errors. Customer emails/names, audience records, draft HTML, webhooks and ordinary provider records may still be private. Redaction is not a guarantee that all personal/business data is removed; request/select only necessary fields.
No .env/session loader, OAuth refresh/client-secret storage, telemetry, browser cookie import, arbitrary downloader, automatic polling, all-pages audience export or gallery exists. Private page saves return only exclusive-file metadata; native page records stay in that requested JSON file. Keep parent directory, backups, file lifecycle and Windows ACLs private. Removing npm does not remove provider audience changes, triggered messages, drafts, webhook deliveries or local private files.
Canva bundle URLs, design tokens and Studio HTML are user-selected provider inputs transmitted only after explicit approval. The local client does not fetch those URLs itself. API-native subscriber opt-in data is not fabricated. Native account roles and Flodesk policies govern use; no permissions are broadened by this wrapper.
15. Environment variables
Setting | Effect |
| Private integration Basic username key; empty password. No fallback with named profiles. |
| Externally minted partner Bearer token, never alongside api_key; no refresh. |
| Absolute owner-private regular token-only file overriding only selected direct credential. |
| oauth for Bearer token files; blank infers inline credential or defaults file to api_key. |
| Private unique {name,api_key,access_token,token_file,auth_type} profiles. |
| Exact selected private profile label, not provider owner proof. |
| 1/true hides and directly refuses all 16confirmed operations. |
| 0/false refuses confirmed operations too. |
| Optional best-effort static guard log without payload/key. |
| Default 30000; allowed 100–300000; no automatic retries. |
| Default 650; allowed 0–10000; process-wide ordinary spacing. |
|
|
|
|
| Give up on any tool after this long |
| For |
| Comma-separated browser origins allowed to call |
|
|
| Default 3100; allowed 0–60000; separate native batch-upsert window. |
16. Updates and removal
Use npx -y @thenavidm/flodesk-mcp-cli@latest for fresh process launches and restart/reconnect existing clients. Global installs require npm update -g; versioned desktop bundles require a new bundle installation. Read major changes first and preserve intended account configuration.
Remove only the requested MCP registration, skill/global package or desktop extension. Revoke private keys/partner OAuth/official connector access separately, and review provider webhooks/workflows/private audience files. Uninstalling does not unsend opt-in/automation messages or undo subscriber/draft changes.
npm update -g @thenavidm/flodesk-mcp-cli
flodesk-cli --version
# Removal only when requested
codex mcp remove flodesk
npm uninstall -g @thenavidm/flodesk-mcp-cli17. Troubleshooting
Symptom | Check and resolution |
Node/binary missing | Node 22+ and npm executable PATH; reopen terminal, npm.cmd if Windows policy needs it. |
Mixed key/token config | Choose one api_key or access_token per profile. |
File treated as Basic | Explicit auth_type:oauth/FLODESK_AUTH_TYPE=oauth for a Bearer token file. |
401/403 | Check intended key/token/account access; expired OAuth requires private partner renewal and process restart. |
429 | Respect 100/minute standard and 20/minute native-batch limits; other clients share quota. |
Empty upsert or workflow identity | Provide nonempty id/email and exact requested native fields. |
Segment removal fails | Use actual id_or_email/segment_ids; required JSON body is sent on DELETE. |
Native batch HTTP 200 failures | Inspect successes and failures individually, without replaying successes. |
Workflow enrollment rejected | Check completed/repeat-subscriber setting and abandoned-cart restriction. |
Review mismatch | Preview exact inputs/order/profile label/auth type/snapshot again. |
Unknown write outcome | Inspect provider state before any explicit retry. |
Existing page file | Choose a new absolute file; no overwrite. |
Analytics/archive/export missing | Those are official MCP-only tools, outside current public REST. |
Draft URL but no sent mail | Canva/Studio publication creates a draft; no send/schedule endpoint is provided. |
GUI/remote environment differs | Configure private settings/files/Node in that actual runtime and restart. |
18. API coverage and comparisons
Offering | Current reviewed evidence | Capabilities and boundaries |
Production field reference 35 tools, format 3, catalog 7c6870e8b9c66a4d366fc4c0abc53504721dd7c85cf3de9e3c5a202ef50d05f0, checked 2026-10-03 | Analytics, campaign content/performance, audience engagement/cohort filters, forms/checkouts/workflows, CSV export and bulk archive/unarchive/segment actions. Previews already have exact compiled-filter bindings, single-use 120-second tokens and cohort-growth checks. Public docs count is not authenticated tools/list or a tested account outcome. | |
Updated September 11, 2026; earlier individual-action phase | Documents OAuth connections and destructive-operation confirmation. It still says bulk actions are unavailable; current production catalog documents them. Read current field reference rather than using old absence as our advantage. | |
OpenAPI 3.0.3, API 1.0.0, 26 operations, 19 paths | API keys or approved partner OAuth; subscriber batch upsert, native workflow enrollment/removal, custom fields, webhook CRUD and Canva/Studio draft publication. This public API does not expose the official MCP's analytics/cohort/export/archive routes. | |
Pinned main source, checked 2026-10-03 | The repository description advertises Rails, OAuth 2.1 and encrypted per-user keys, but this public main tree contains only a five-line Gemfile. No implemented tools/client/README are available at this revision, so advertised functionality is unverified; no runtime account test was run. | |
Pinned source checked 2026-10-03, package 0.0.0/private | Its actual server declares Authless Calculator with only add and calculate. No Flodesk API client or subscriber workflow exists in this revision. No runtime deployment was tested. | |
This owned companion | Shared local stdio MCP, task CLI and versioned desktop bundle | 32 tasks: 16 reads, 16 confirmed operations. All 26 public-v1 native routes, OAuth UserInfo, local profile/schema helpers, exact ordered subscriber review and exclusive private single-page files. Native REST draft/custom-field/webhook/workflow operations and repeatable terminal automation add useful scope. No hosted analytics/cohort filter engine, CSV export, native archive/unarchive or OAuth login/refresh. Token costs are measured against this package's own 2.0.2 in README section 7, not against the hosted server. |
No official task CLI is identified in the reviewed vendor docs/current registry results. That is a scoped research finding, not proof that no CLI exists anywhere. Provider @flodesk/grain is a component/design package, not a task CLI. A command spelling or 32 versus 35 tools does not establish superiority.
Build criterion: useful repeatable terminal/local-stdio access to native public REST work absent from the current 35-tool hosted catalog, including draft exports, custom-field management, webhook CRUD, explicit workflow enrollment/removal and 50-subscriber upsert. Verified local guards and exact ordered request review support that companion. Official analytics, engagement, cohort counting and two-minute provider-side confirmation tokens remain strengths; our local preview is not an equivalent real-cohort count or replacement for their safeguards.
19. Versions and migration
Component | Reviewed version |
Package/desktop manifest | 3.0.0 |
Node runtime | >=22 |
Slipway | 0.1.17 |
MCP TypeScript SDK, through Slipway | 2.3.0 |
Ajv / formats | 8.20.0 / 3.0.1 |
TypeScript / Vitest | 7.0.2 / 5.0.3 |
Desktop builder | 2.1.2 |
Native API snapshot | OpenAPI 3.0.3/API1.0.0;26operations checked 2026-10-03 |
Official MCP production catalog | Format 3; 35 listed tools, checked 2026-10-03 |
2.0.0 is a major refresh of the private 1.0 MCP. All 20legacy names remain. Added batch_create_or_update_subscribers, list_campaigns, publish_canva_email, get_canva_design_state, publish_studio_email and list_all_custom_fields. Legacy segment/workflow/webhook aliases keep their tool names but use exact current native fields: get_segment/get_webhook/delete_webhook/update_webhook use id, enrollment accepts id or email, webhook configuration uses post_url, workflows use perPage and statuses CSV. The old server omitted DELETE bodies and misnamed some fields; these are corrected rather than keeping broken requests.
Subscriber statuses now include unconfirmed/cleaned/archived; upserts accept native id/email, optin_ip/optin_timestamp and 50 segment IDs. Native upsert permits 50 subscribers and preserves partial successes/failures. All mutations/private-page files require approval and isolated credentials. Mixed private credential types fail instead of silently prioritizing Bearer/global values. All automatic/inherited auth fallbacks, source-saved credentials and thin clone-only setup are removed. The complete CLI/MCP/desktop/client framework, policy, current comparison and dated update history ships together.
Private legacy history/settings remain separate and are never imported into public history. See CHANGELOG.md, api-provenance.json and RELEASE-CHECKLIST.md.
20. FAQ
A shared 32-task CLI, local stdio MCP and versioned desktop extension for current public Flodesk REST operations, exact ordered reviews and private account files.
Yes. Its current production field reference lists 35 tools with useful analytics, cohort filters, subscriber actions, CSV export and bulk controls. This companion does not replace those capabilities.
Yes. preview_bulk_change/preview_segment_count bind real filtered audiences to single-use confirmation tokens that expire after 120 seconds. Local exact REST request review has a different purpose.
Repeatable terminal/local-stdio workflows cover native custom fields, webhook CRUD, explicit workflow enrollment/removal,50-subscriber upsert and Canva/Studio draft exports absent from the reviewed hosted catalog.
Node 22+ CLI/local stdio on macOS, Windows and Linux. INSTALL covers Codex, Claude Code/Desktop, Cursor, VS Code, Windsurf, Zed, Gemini, Cline and Docker; each runtime needs its private settings.
No. Codex registers the same npm package directly. Section 7 has both clients' measured costs.
No. Current native Canva/Studio publish routes create/update drafts. No public send/schedule endpoint is invented or called.
Yes. A new-subscriber double opt-in can send confirmation, and workflow/segment actions can trigger automation. They require approval and are unsuitable installation smoke tests.
It accepts 1–50 explicit id/email records. HTTP 200 may contain successes and failures; inspect each. Native batch limits are separate from ordinary REST quota.
All 20remain, with major native argument corrections: id,post_url,id/email enrollment, perPage and statuses CSV. The dropped DELETE segment-removal body is fixed.
Private integrations use the API key as a Basic username with an empty password. Approved partner integrations may supply externally minted Bearer tokens. Choose exactly one per profile; no OAuth login/refresh occurs here.
Yes. Unique private profiles select only their own key/token/file, with exact labels and no global/cross-account fallback. A label is not authenticated owner proof.
API key by default; set FLODESK_AUTH_TYPE=oauth or profile auth_type:"oauth" for a Bearer token file. The file overrides only that selected profile and caches until restart.
Exact ordered inputs/requests, packaged schemas and selected profile label/auth type. It reads no provider data and does not establish current cohort size, real ownership, final side effects or cryptographic human approval.
Execution stops with knownResults,failedIndex and unattemptedIndices. Earlier changes/messages may persist; no retry, replay, rollback or automatic continuation occurs.
Yes. FLODESK_READ_ONLY hides all 16confirmed operations and the shared guard directly refuses confirmed calls. --agent/--yes never approve work.
One selected subscriber page is written exclusively into a new private JSON file. It is not a CSV/cohort/all-pages export; console output contains file metadata rather than customer records.
No. Known credentials are redacted, but names/emails/HTML/native records can still be private. Select only necessary fields and keep private files/parents/Windows ACLs restricted.
Yes, for this package against its own 2.0.2. In Claude Code the CLI costs nothing until it is used, plus about 1,290 tokens for SKILL.md once, where the server costs about 950 tokens a message with tool search and 12,750 with every tool loaded. In Codex, finding the command that adds a subscriber to a segment and its flags took a median of 82,830 input tokens over the CLI and 48,158 over MCP. Section 7 has how each was measured.
Reconnect/restart npm@latest processes; update global installs and desktop bundles explicitly. Remove only the requested registration, then revoke exact keys/OAuth separately and review retained files/provider effects.
Questions
Open a sanitized issue. Use SECURITY.md for private reports.
About the author
Navid Moazzez is a leading AI business strategist, and the host of the AI Creator Summit, watched by 100,000+ creators. He helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life. He creates useful free tools, MCP servers and CLIs that creators and founders can use in their own workflows.
Links
Personal website: navid.me
Link in bio: navid.bio
Navid Media: navid.media
YouTube: @thenavidm and @thenavidai
X: @thenavidm
Instagram: @thenavidm
LinkedIn: thenavidm
If this is useful, star the repo and come say hi on X.
Dependencies
Runtime: Slipway, which brings the MCP TypeScript SDK, plus Ajv and ajv-formats. Development: TypeScript, Vitest, Vite and MCPB. Exact locked versions appear above. Packaging tools are excluded from desktop runtime.
License
Preserves AGPL-3.0 and existing private legacy history. Read THIRD_PARTY_NOTICES.md. Flodesk service terms and trademarks remain separate.
© 2026 Navid Media. Made with ❤️ by Navid Moazzez.
Available Tools
32 toolsadd_subscriber_to_segmentsAdd the subscriber to segments.CDestructive
Add the subscriber to segments.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| id_or_email | Yes | Exact native path parameter. | |
| segment_ids | No | An array of identifiers of the segments. | |
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose the important traits: readOnlyHint=false, destructiveHint=true, idempotentHint=false, openWorldHint=true. The description adds nothing beyond that profile — no statement about whether re-adding a subscriber to an existing segment is a no-op, whether segment IDs must already exist, what happens on partial failure, or what the response contains. It neither contradicts nor enriches the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single sentence is short and front-loaded, but it does not earn its place: it duplicates the tool name exactly, so the text could be removed with no loss of information. Brevity here reflects under-specification rather than disciplined concision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a six-parameter, nested-object, destructive write operation with no output schema, and the description supplies no operational context whatsoever. The annotations at least signal that it is a non-idempotent write, so an agent is not entirely blind, but nothing about segment prerequisites, account scoping, or result handling is covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline would be 3, but the description contributes zero parameter semantics. More importantly, the schema itself presents an unresolved ambiguity — a top-level 'segment_ids' array alongside 'payload.segment_ids', plus mutually exclusive 'payload' vs 'payload_file' — and the description does nothing to explain which form to use. The one sentence offered adds no value over the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as remove_subscriber_from_segments or add_subscriber_to_workflow. The only signal an agent gets is the verb 'add', which is already in the name. No exclusions or conditions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_subscriber_to_workflowAdd a subscriber to workflow.ADestructive
Notes:
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | `id` is required if `email` is not present | |
| No | `email` is required if `id` is not present | ||
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| workflow_id | Yes | Exact native path parameter. | |
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false, and openWorldHint=true, so the safety profile is covered. The description adds non-duplicated context: the workflow must not currently have the subscriber active and abandoned-cart workflows reject this call. That explains why the operation is non-idempotent and where it fails, which is meaningful beyond the annotations. It still says nothing about success/return behavior or permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The content is two tight bullets with no filler, and the most consequential constraint (repeat-subscriber precondition) is listed first. The HTML markup (br, ul, li) is noisy overhead but the underlying text is lean. No wasted sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, nested-body, destructive mutation, the description supplies the failure constraints that the schema and annotations cannot express, and the 100%-covered schema plus explicit annotations carry the rest. No output schema exists, but for an add-to-workflow call the return surface is trivial. Adequate; only the absence of any permission/account-scoping note keeps it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (id/email alternatives, account, confirm, payload, payload_file, workflow_id) is already documented in the schema. The description names no parameters and adds no semantics beyond it. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The tool name and title state a specific verb+resource (add a subscriber to a workflow), and the sibling set contains unambiguous counterparts (remove_subscriber_from_workflow, add_subscriber_to_segments) that make the resource separable. However, the description body itself never states the purpose and opens directly with 'Notes', so it contributes no purpose statement of its own. Clear in practice, but the description adds no sibling differentiation beyond the name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The two bullets give real usage conditions: the repeat-subscriber preconditions (must have completed the workflow, 'Allow repeat subscribers' must be on) and an explicit exclusion (abandoned cart workflows cannot use this endpoint). This tells the agent when the call will fail, which is above-average guidance. It stops short of naming alternatives for the excluded case, so it is not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_create_or_update_subscribersBatch create or update subscribers.CDestructive
Create or update up to 50 subscribers in a single request.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| subscribers | No | ||
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true, idempotentHint=false, and openWorldHint=true, so the safety profile is partly covered. The description adds nothing about what a destructive update actually overwrites, how partial failures in a 50-item batch are handled, or whether duplicates are matched by id or email. The only added fact (the 50 cap) is already in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence with the key constraint front-loaded and no filler. It is efficient, though arguably too terse for a destructive 5-parameter batch tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-idempotent batch mutation with nested objects and no output schema, the description should address partial success, matching semantics, and the confirm/payload_file interplay. None of that is present, leaving an agent under-informed about consequences of a 50-record write.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 80%, so the schema already documents account, confirm, payload, subscribers, and payload_file. The description adds no meaning beyond the existing 50-item maximum, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair (create or update) plus resource (subscribers) and adds the batch scope ('up to 50 subscribers in a single request'), which implicitly distinguishes it from the singular create_or_update_subscriber sibling. It never names that sibling or the related preview_subscriber_batch/submit_subscriber_batch tools, so differentiation stays inferential rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to prefer this over create_or_update_subscriber for a single record, or over preview_subscriber_batch to validate before committing. No mention of preconditions, rate limits, or the confirm flag's role.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_custom_fieldCreate a custom field.CDestructive
Create a custom field.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | A friendly display label of the custom field. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=false and openWorldHint=true, so the safety profile is fully covered by structured data. The description adds nothing about the required confirmation flow, permission/account scoping, or what the destructive write affects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single sentence with zero padding, so there is nothing to trim, but that brevity comes from under-specification rather than disciplined editing. There is no structure or front-loaded context to evaluate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive create with a nested payload object, a confirm flag, and no output schema, the description omits the write semantics, confirmation requirement, and account scoping that the schema only partially conveys. The annotations cover safety but the description leaves real gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema itself documents label, account, confirm, payload and payload_file with meaningful text. Per the rubric this establishes a baseline of 3 when the schema does the heavy lifting; the description contributes no additional parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool, when not to, or which alternative to pick. An agent must infer everything from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_or_update_subscriberCreate or update a subscriber.DDestructive
Create or update a subscriber.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | The subscriber's `id`. Either `email` or `id` must be included. | |
| No | The subscriber's `email`. Either `email` or `id` must be included. | ||
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| optin_ip | No | IP address from which the subscriber confirmed their opt-in. | |
| last_name | No | The subscriber's last name. | |
| first_name | No | The subscriber's first name. | |
| segment_ids | No | The segments this subscriber will be added to. Cap at `50`. | |
| double_optin | No | ||
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. | |
| custom_fields | No | An object containing custom field data. E.g. ``` "favorite_color": "Lavender" ```. | |
| optin_timestamp | No | The date and time the subscribers confirmed their opt-in in ISO 8601 format. E.g. `2023-01-02T15:04:05.999Z`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false, and openWorldHint=true, so the safety profile is covered structurally. The description adds nothing beyond that — it does not explain upsert resolution (which fields update vs create), merge vs overwrite behavior, or the meaning of the confirm flag. With annotations carrying the burden, a low 2 is fair for a description that contributes zero behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is short but that brevity is under-specification rather than conciseness — a single sentence that duplicates the title and earns no place. There is no front-loading of substance because there is no substance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter mutation tool with nested objects, a payload-or-flags exclusivity model, no output schema, and destructive/idempotent annotations, this one-line restatement is wholly inadequate. Nothing about upsert semantics, the confirm gate, or account scoping is addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 92%, so the schema already documents nearly all 13 parameters, including the payload/payload_file exclusivity rules and the double_optin constraint. Baseline 3 applies; the description adds no parameter meaning whatsoever.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no named alternatives. An agent cannot tell from this text whether to call this versus batch_create_or_update_subscribers or add_subscriber_to_segments, nor when an update path vs a create path is taken.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_segmentCreate a segment.CDestructive
Create a segment.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| color | No | The color of the segment using a hex code. `Use GET List all segment colors`. to view available colors. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=false and openWorldHint=true, so the safety profile is known. The description adds nothing beyond that — no mention of the confirm flag's gate, duplicate-name behavior, or what happens on repeated calls. No contradiction with annotations, but zero added value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence with no filler, but this is under-specification rather than conciseness — the brevity leaves a destructive, six-parameter tool with nested objects entirely undescribed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a non-idempotent, destructive create operation with six parameters, nested payload structures, and no output schema, the description provides none of the context an agent needs (payload vs payload_file exclusivity, confirm gating, account label semantics). It is wholly inadequate for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 83%, so the schema already documents color, account, confirm, payload, and payload_file. The description contributes no parameter meaning at all; baseline 3 applies because the schema carries the load, though the undocumented name field and nested payload.name remain unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives such as add_subscriber_to_segments or list_segments, nor any prerequisites or exclusions. Usage must be entirely inferred from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_webhookCreate a webhook.DDestructive
Create a webhook.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | The webhook name. | |
| events | No | An array specifying which events are enabled for webhook notifications. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| post_url | No | The url that the webhook will post to. | |
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, destructive, non-idempotent, open-world mutation, so the safety bar is partially met by structured fields. However, the description adds nothing on top — no mention of the confirm flag requirement, the payload/payload_file/body-flag mutual exclusion, account scoping, or that creating a webhook is irreversible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
At four words it is not bloated, but it is under-specified rather than concise — the single sentence carries no load and repeats the title. Nothing is front-loaded because nothing is stated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter destructive mutation with a nested object body, mutually exclusive input modes (payload vs. body flags vs. payload_file), a confirm safeguard, and no output schema, a title-only description is completely inadequate. An agent cannot safely invoke this tool from the definition alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all seven parameters (including the nested payload body, confirm, account, and payload_file) are documented in the schema itself. The description contributes zero additional meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as update_webhook for modifying an existing webhook. The agent must infer everything from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_webhookDelete a webhook.CDestructive
Delete a webhook.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Exact native path parameter. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false, readOnlyHint=false, and openWorldHint=true, so the safety profile is covered structurally. The description adds nothing on top of that — no statement of irreversibility, no warning about the confirm flag, no note on what happens to a missing webhook — so it contributes no behavioral value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence with no wasted words, but the brevity comes from under-specification rather than disciplined conciseness — the entire content is a duplication of the title, so nothing in it earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-idempotent mutation with no output schema, the description supplies none of the context an agent would want (reversibility, the role of the confirm flag, scoping via account). The annotations and a fully-covered schema carry most of the load, but the description itself is far from complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so id, account, and confirm are all documented in the schema itself (including the meaningful confirm='only when the user asked for exactly this action' semantics). The description adds nothing beyond the schema, which lands at the baseline of 3 for fully documented parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as update_webhook or get_webhook. The agent gets no help deciding when deletion is the right call versus modifying a webhook instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_canva_design_stateGet the latest Canva design state for auto-selecting campaigns.CRead-onlyIdempotent
Get the latest Canva design state for auto-selecting campaigns.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact configured private account profile label; not a tenant or provider account ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, idempotentHint=true, destructiveHint=false, openWorldHint=true), so the description's only obligation is to add context. It adds nothing — no statement of whether the returned state is cached, whether it reflects unpublished or published designs, or what happens if no design exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence with no bloat, which is structurally fine, but the conciseness comes at the cost of zero substance — it repeats the title rather than front-loading useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read tool with an optional parameter and no output schema, the description should at minimum explain what the 'design state' comprises and how it feeds campaign auto-selection. Neither is addressed, leaving the agent unable to predict the result or the trigger conditions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With a single parameter and 100% schema description coverage, the schema already documents the 'account' label semantics precisely (exact configured private account profile label). The description contributes no additional parameter meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives. The phrase 'for auto-selecting campaigns' hints at a workflow purpose but does not tell the agent which conditions should trigger this call versus other campaign tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_oauth_userinfoRead OAuth identityARead-onlyIdempotent
One fixed UserInfo GET for an explicitly selected externally minted OAuth access token. API keys refuse; no refresh, OAuth login or fallback.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact selected private account profile; binds label, not key ownership. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive and open-world traits. The description adds value beyond them: it is a single fixed request, it will not refresh tokens, and it rejects API keys — real behavioral constraints not present in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences with zero filler; the core action and the credential requirement are both front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple no-argument read, the description covers invocation constraints (auth type, no fallback, no refresh) adequately. With no output schema, it says nothing about what UserInfo fields come back, which is the one remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single optional 'account' param is fully documented in the schema. The description gestures at 'explicitly selected' account/token but adds no syntax or format detail beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (GET) and resource (UserInfo) and constrains the credential type to an 'externally minted OAuth access token.' It is clear on what the tool does, but does not differentiate it from any sibling (which are Mailchimp-style subscriber/campaign tools), leaving the agent to infer placement from the name alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'API keys refuse; no refresh, OAuth login or fallback' is an explicit when-not condition, telling the agent this only works with a pre-minted OAuth token and that there is no alternative auth path. It stops short of naming an alternative tool to use instead, but the credential precondition is stated plainly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_operation_schemaInspect a current native operationARead-onlyIdempotent
Local reviewed method/path/query/body schema and provenance for one native tool. No credentials or provider request.
| Name | Required | Description | Default |
|---|---|---|---|
| operation | Yes | Exact native tool name, e.g. batch_create_or_update_subscribers or publish_studio_email. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent, non-destructive and closed-world behavior, so the bar is lower. The description still adds real value beyond them by declaring that the lookup is local and requires no credentials and issues no provider request, and that the returned schema is 'reviewed' with provenance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with no filler, and the payload description is front-loaded. The first sentence is a dense noun phrase rather than a full clause and the second is clipped, which costs a little readability without wasting space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter introspection tool with no output schema and no nested objects, the description adequately sketches what comes back (method, path, query, body schema and provenance). It would be stronger if it indicated the return format or how the schema should be consumed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'operation' parameter already carries an enum and a description, so the schema does the heavy lifting. The description only reinforces that the value is a 'native tool' name, adding no format or selection guidance beyond the enum.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (inspect/get) and resource (the reviewed method/path/query/body schema plus provenance for a single named native operation), which is clearly distinct from the sibling tools that actually perform those operations. It stops short of explicitly contrasting itself with those siblings, but the 'one native tool' scoping makes the target unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: 'No credentials or provider request' hints that this is a safe introspection step rather than an actual provider call, but there is no explicit 'use this before invoking X' instruction or named alternative. An agent can infer the intent, yet nothing states when this tool should be preferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_segmentRetrieve a segment.CRead-onlyIdempotent
Retrieve a segment.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Exact native path parameter. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond that baseline – no note on behavior when the id is not found, no indication of what is returned, and no mention of the account resolution semantics. It contributes zero behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence and thus technically concise, but this is under-specification rather than effective brevity. Nothing is front-loaded beyond the tool name, and the sentence earns no informational value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with a fully documented 2-parameter schema and annotations covering safety, the description still leaves key gaps: what a segment contains, how id and account interact, and what happens on a missing or unauthorized segment. No output schema exists to fill these in.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the id parameter is documented as an "Exact native path parameter" and account as an "Exact configured private account profile label." The description adds no parameter meaning at all, so the baseline 3 applies when the schema does all the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives. An agent cannot tell from the description why it would call get_segment rather than list_segments or list_segment_colors, and no prerequisites (e.g. needing an existing segment id) are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_subscriberRetrieve a subscriber.CRead-onlyIdempotent
Retrieve a subscriber.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| id_or_email | Yes | Exact native path parameter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is fully covered without the description. The description contributes nothing beyond that — no note on whether a missing subscriber errors or returns empty, and no auth or lookup-scope context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence, so it is not verbose, but that brevity comes from under-specification rather than discipline. The one sentence merely duplicates the title and earns no place beyond it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description should ideally indicate what a retrieved subscriber contains or what happens when the id_or_email does not resolve. With no annotations gap to fill and no return-value guidance, the definition is too thin for a lookup tool in a crowded subscriber-tool family.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (account and id_or_email) are already documented in the schema, including the caveat that account is a profile label and not a tenant/provider ID. The description adds no syntax, format, or disambiguation beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of prerequisites, and no reference to alternatives such as list_subscribers for bulk retrieval or create_or_update_subscriber for writes. The agent must guess the boundary between this tool and its many sibling subscriber tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_webhookRetrieve a webhook.CRead-onlyIdempotent
Retrieve a webhook.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Exact native path parameter. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is fully covered by structured data. The description adds nothing on top — no error/not-found behavior, no noting that this is a safe repeatable read, no scoping caveats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence, so there is no waste, but it is under-specified rather than concise — it conveys only what the title already does. Front-loaded yes, but no substantive content follows.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with full annotation coverage and a fully documented schema, the minimum is met, but there is no output schema, so the description could reasonably state what is returned or what happens when the webhook id is unknown. It leaves all of that unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the two parameters (id, account) are fully documented in the schema, including the nuance that 'account' is a profile label rather than a tenant/provider ID. The description contributes nothing further, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this versus list_webhooks (for enumeration) or the create/update/delete webhook siblings. The verb 'retrieve' weakly implies 'fetch one webhook by id', which is the only inferred usage signal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_accountsList configured accountsBRead-onlyIdempotent
Local profile labels/default/auth method only. No keys, token paths, provider identity or network request.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so safety is covered. The description adds genuine context beyond that: output is limited to local profile labels/defaults/auth method and deliberately excludes keys, token paths, and provider identity, telling the agent the result is safe to surface.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is very short (two fragments) and wastes no words, but it is telegraphic and front-loads a qualifier rather than the core action. The terseness borders on under-specification rather than disciplined conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only listing tool with no output schema and strong annotations, the description covers the essential safety and scope facts. However, it never plainly states what the tool does or what the returned list contains beyond field-level exclusions, leaving the purpose inferable only from the title.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter semantics for the description to carry. Baseline of 4 applies; nothing is missing on this dimension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description never states a verb or resource — it only describes the scope of what is returned ("Local profile labels/default/auth method only"). The title supplies the actual purpose, so the agent can infer this lists local accounts, but the description itself is vague about the action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance and no named alternative among the numerous list_* siblings (list_customers, list_partners, list_domains, etc.). The agent must infer that this tool is for enumerating locally configured account profiles rather than any remote data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_all_custom_fieldsList all custom fields.CRead-onlyIdempotent
List all custom fields.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact configured private account profile label; not a tenant or provider account ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is fully covered by structured data. The description adds nothing on top of that — no pagination behavior, no return shape, no mention of what "all" spans.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single sentence is compact and front-loaded with no wasted words, but its brevity stems from under-specification rather than disciplined concision. It reads as a restated title rather than an earning sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with no output schema the bar is low, but the description still omits the one thing an agent needs: how this differs from the near-identical sibling list_custom_fields and whether the account parameter scopes the result. Nothing is provided beyond the name.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'account' parameter is clearly documented in the schema as a private account profile label. The description adds no parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus list_custom_fields, create_custom_field, or any other sibling. No context, no exclusions, no prerequisites are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_campaignsList campaigns.CRead-onlyIdempotent
List campaigns.
| Name | Required | Description | Default |
|---|---|---|---|
| Sort | No | Exact native query parameter. | |
| page | No | The page number. Defaults to 1. | |
| Search | No | Exact native query parameter. | |
| Status | No | Exact native query parameter. | |
| OrderBy | No | Exact native query parameter. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| per_page | No | The number of records to be returned on each page. Defaults to 20. Maximum 100. | |
| SharedAsTemplate | No | Exact native query parameter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds nothing on top of that: no pagination behavior, no note that results may be filtered by account, no indication of what happens with an empty result set.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single four-word sentence with no wasted words, but it is under-specified rather than concise: there is no front-loaded scope, no filtering summary, and nothing to orient the agent before it reads the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 8 optional parameters, an enum status filter, a paginated result shape and no output schema, the description leaves the agent to infer everything about filtering and result handling. Annotations cover the safety profile, but the description is far too thin for a list tool with this much surface area.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema itself documents page/per_page defaults and the Status enum. Per the baseline rule for high coverage, 3 is the ceiling here since the description contributes zero parameter meaning of its own (e.g. it never clarifies the 'account' profile label or the opaque Sort/OrderBy/Search native query parameters).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of alternatives, and no exclusions. An agent cannot tell from the description whether this is the right tool versus any other listing endpoint, nor what the eight query parameters are for.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_custom_fieldsList all custom fields (pagination).CRead-onlyIdempotent
List all custom fields (pagination).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | The page number. Defaults to 1. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| per_page | No | The number of records to be returned on each page. Defaults to 20. Maximum 100. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond the parenthetical '(pagination)', which the schema already conveys via page/per_page parameters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence with no padding, so it is structurally clean. However, that sentence merely duplicates the title and does no work of its own, so brevity here reflects under-specification rather than efficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a paginated list tool with no output schema, the description should at least characterize what a custom field is or what the response contains. With zero content beyond the title, an agent gets no completeness value from the description, though annotations and the full schema partly compensate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: page, per_page, and account are each documented in the schema, including defaults and the max-100 cap. The description contributes no additional meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus alternatives. The presence of a near-identical sibling, 'list_all_custom_fields', makes this omission actively confusing rather than merely absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_segment_colorsList all segment colors.CRead-onlyIdempotent
List all segment colors.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact configured private account profile label; not a tenant or provider account ID. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is fully covered structurally. The description adds nothing beyond that — no note on whether the account parameter is required for multi-account setups or what the listing contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short, front-loaded sentence with zero filler or repetition. It is efficiently sized, though its brevity reflects under-specification rather than disciplined concision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a trivial read-only list operation with no output schema and full schema coverage, the minimum is arguably met by the name plus annotations. However, the description contributes nothing about what a 'segment color' is or how the optional account scoping affects results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single optional 'account' parameter is well documented in the schema itself (exact private account profile label, not a tenant/provider ID). The description adds no parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of the related list_segments/get_segment tools, and no statement about when an account argument is needed versus omitted. The agent is left to infer everything from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_segmentsList all segments.CRead-onlyIdempotent
List all segments.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | The page number. Defaults to 1. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| per_page | No | The number of records to be returned on each page. Defaults to 20. Maximum 100. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is fully covered without the description. The description adds nothing beyond that — no pagination behavior, no result-set size, no sorting, no account-scoping semantics, all of which would be valuable for a list endpoint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is short, but this is under-specification rather than conciseness — the single sentence duplicates the title and earns no additional place. There is no front-loaded scope or constraint because there is no substantive content at all.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with page, per_page, and account each documented directly in the schema, including defaults and the max of 100. The description adds no parameter meaning on top of that, so the baseline 3 for high-coverage schemas applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as get_segment for fetching a single segment or list_segment_colors. The agent must infer that this is the bulk-listing counterpart of get_segment entirely on its own.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_subscribersList all subscribers.CRead-onlyIdempotent
List all subscribers.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | The page number. Defaults to 1. | |
| status | No | Optional. The subscriber's status. `active`: The subscriber is currently active to receive marketing emails. `unsubscribed`: The subscriber has opted out of marketing emails. `unconfirmed`: The subscriber is pending for double opt-in confirmation. `bounced`: The subscriber's address is undeliverable due to a hard bounce. `complained`: The subscriber marked an email as spam. `cleaned`: The subscriber was cleaned, learn more [here](https://help.flodesk.com/en/articles/4747969#how_can_i_find_out_which_email_addresses_have_been_cleaned). `archived`: The subscriber was archived. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| per_page | No | The number of records to be returned on each page. Defaults to 20. Maximum 100. | |
| segment_id | No | Optional. The segment's id. When included, returns only subscribers who were added to the given segment. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered without the description. The description adds nothing beyond that — no pagination behavior, no note on whether filtered lists are returned, no account-scoping semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence with no padding, which is structurally clean. But the sentence merely echoes the title and therefore does not earn its place as a distinct piece of content — brevity here reflects under-specification, not disciplined concision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A five-parameter, filterable list tool with no output schema needs the description to convey filtering and pagination behavior, and it conveys none of it. Saying "all subscribers" is actively incomplete given that status and segment_id exist to narrow the result set.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the five parameters (page, per_page, status with a full enum, account, segment_id) are already fully documented in the schema and the baseline is 3. The description contributes no additional parameter meaning, so it does not exceed the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not-to-use guidance and no named alternative. An agent cannot tell from this text when to call list_subscribers versus get_subscriber or list_segments. The phrase "all subscribers" even obscures that status/segment filtering exists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_webhooksList all webhooks.CRead-onlyIdempotent
List all webhooks.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | The page number. Defaults to 1. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| per_page | No | The number of records to be returned on each page. Defaults to 20. Maximum 100. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=true, so the safety profile is fully covered elsewhere. The description contributes nothing on top of them — no mention of pagination behavior, result ordering, or account scoping introduced by the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One short sentence with zero padding, so nothing is wasted. However, it is too thin to be front-loaded with anything useful — brevity here reflects under-specification rather than disciplined concision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an open-world list tool with no output schema, the description should at least gesture at return shape or pagination expectations given the page/per_page params. Annotations cover safety, but the agent still lacks any signal about what enumeration yields or how it pairs with get_webhook.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so page, per_page and account are each documented in the schema with defaults and bounds; baseline 3 applies. The description adds no parameter meaning beyond that (for example, why account is a profile label rather than a tenant ID).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance whatsoever: nothing says when to prefer this over get_webhook, or that it is the collection-level read after create_webhook/update_webhook. The agent must infer usage entirely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_workflowsList workflows.CRead-onlyIdempotent
List workflows.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Default = 1 | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| perPage | No | Default = 10 Local positive integer validation; perPage has a local 100-item cap. | |
| statuses | No | filter by workflow statuses e.g. statuses=active,paused. Default is all statuses |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds nothing beyond that: no ordering, no scope (workspace/account context), no pagination behavior notes. With annotations carrying the burden, the description still contributes essentially zero additional context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single sentence is short but earns nothing — it conveys no information beyond the tool name. This is under-specification, not effective conciseness, mirroring the LOW calibration case where a bare restatement scores 2 on this dimension.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, parameterless-required read-only list tool, the complete schema and the safety annotations mean an agent could still call it correctly. However, the description supplies no guidance on sibling selection or result scope, leaving a real but modest gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with page, perPage, account, and statuses all documented inline (including defaults, the 100-item cap, and the 'not a tenant or provider account ID' clarification). Per the rubric, full schema coverage sets a baseline of 3; the description adds no parameter meaning beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of the sibling list_* tools, and no exclusions or prerequisites. The agent must infer everything from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_subscriber_batchReview exact ordered subscriber tasksBRead-onlyIdempotent
Local validation and SHA-256 of exact ordered subscriber/segment/workflow/custom-field work, selected profile label and reviewed schema. No provider reads, key load, identity check, price or rollback guarantee.
| Name | Required | Description | Default |
|---|---|---|---|
| tasks | Yes | One to twenty exact ordered supported subscriber/segment/workflow/custom-field operations. Native batch upserts may affect up to50 subscribers per task; not a20-person budget. | |
| account | No | Exact selected private account profile; binds label, not key ownership. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), and the description adds real context on top: it is purely local, performs SHA-256, and explicitly touches no provider, no key, no identity check. It stops short of explaining what the digest is used for or what the preview returns.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences that lead with the action and follow with the boundary list. Dense jargon ('selected profile label and reviewed schema') costs a little readability, but nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only preview tool with full schema coverage this is adequate, but it omits the one thing the agent most needs: that this is the pre-flight for submit_subscriber_batch and what to do with the SHA-256 result. With no output schema, the return value's role goes unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented, including the ordering, the 'exact native arguments' note, and the 1-20 maxItems clarification. The description restates 'exact ordered... work' and 'selected profile label' without adding syntax or new constraint detail, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource: 'Local validation and SHA-256 of exact ordered subscriber/segment/workflow/custom-field work'. An agent can tell this is a dry-run validation pass, not an executor. It does not, however, name the sibling submit_subscriber_batch it obviously pairs with, so sibling differentiation is only implied by the schema's tool enum.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not guidance and no routing to the alternative. The negative clauses ('No provider reads, key load...') imply a safe pre-flight step, but the agent is never told this precedes submit_subscriber_batch or that the same tasks should be submitted on success.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_canva_emailPublish a Canva email design as a draft campaign.DDestructive
Publish a Canva email design as a draft campaign.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| page_id | No | ||
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| bundle_url | No | ||
| campaign_id | No | ||
| design_token | No | ||
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=false and openWorldHint=true, so the description would need to add context such as side effects or auth needs to earn credit. It adds nothing, and notably never mentions the schema's confirm gate ('Set true only when the user asked for exactly this action'), which is critical safety behavior for a destructive, non-idempotent call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single efficient sentence with no filler, which satisfies the 'no waste' test. But for a 9-parameter, destructive, open-world tool, one sentence is under-scaled rather than appropriately sized; nothing is front-loaded that an agent actually needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 9 optional parameters, a nested payload object, no output schema, and destructive annotations, the description leaves essentially every operational question unanswered: required confirmation, ID/URL sources, error behavior, and return value. It is not close to sufficient for this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 44% across 9 parameters, including an undocumented nested payload object and bare fields like title, page_id, bundle_url, campaign_id and design_token, so the description is required to compensate. It supplies zero parameter meaning, not even the distinction between payload and payload_file or the title/account semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use, when-not-to-use, or prerequisite guidance of any kind. The phrase 'draft campaign' faintly implies this does not send mail, but nothing tells the agent when to pick this over publish_studio_email or get_canva_design_state.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_studio_emailPublish a Studio email export as a draft campaign.DDestructive
Publish a Studio email export as a draft campaign.
| Name | Required | Description | Default |
|---|---|---|---|
| html | No | ||
| title | No | ||
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| asset_id | No | ||
| campaign_id | No | ||
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false, and openWorldHint=true, so the safety profile is partly covered. The description adds nothing beyond the title: it does not explain the confirm requirement, account scoping, rate/auth constraints, or what the destructive behavior actually affects (existing drafts, campaigns).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is one short sentence with nothing wasted, but that brevity is under-specification rather than economy — the whole sentence is the title restated, so no informational content is front-loaded for the agent to use.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a non-idempotent, destructive, open-world mutation tool with a nested payload object, 8 parameters, and mutually exclusive body encodings, a single title sentence is wholly inadequate; no output schema exists to offload return-value explanation either.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 50% across 8 parameters including a nested object. The description never mentions html, title, asset_id, campaign_id, payload, payload_file, or the confirm guardrail, so it does not compensate for the undocumented half of the parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use or when-not-to-use guidance is given, and no alternative is named. The presence of publish_canva_email as a sibling makes this omission meaningful, and the mandatory-ish 'confirm' semantics implied by the schema are never mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_subscriber_from_segmentsRemove the subscriber from segments.CDestructive
Remove the subscriber from segments.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| id_or_email | Yes | Exact native path parameter. | |
| segment_ids | No | An array of identifiers of the segments. | |
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false, and readOnlyHint=false, so the safety profile is covered externally. The description adds nothing on top: it never says the removal is irreversible, never explains the 'confirm' flag's intent, and never states auth or account-scoping requirements, which is a notable omission for a destructive mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single sentence is short but is a pure restatement of the title, so it does not earn its place as description content. Brevity here reflects under-specification rather than effective concision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter destructive tool with nested objects, an alternate body-passing mechanism (payload vs payload_file vs body flags), and no output schema, the description is far too thin. The rich schema and destructive annotation cover some ground, but an agent still gets no explanation of how the redundant segment_ids/payload fields interact or what 'confirm' gates.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters, including the payload/segment_ids duplication and the payload_file alternative. The description supplies no additional parameter meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of the obvious alternative add_subscriber_to_segments. The agent gets zero routing help beyond what the tool name already implies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_subscriber_from_workflowRemove a subscriber from workflow.CDestructive
Remove a subscriber from workflow.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| id_or_email | Yes | Exact native path parameter. | |
| workflow_id | Yes | Exact native path parameter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, idempotentHint=false, and openWorldHint=true, so the safety profile is covered. The description adds nothing further — no note on reversibility, effect on the subscriber, or partial-failure behavior — which is a real gap for a destructive operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence, but it is under-specified rather than concise — it merely echoes the tool name and earns no place. Short does not mean efficient here.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive mutation tool with no output schema, the description should at least say what gets removed and any consequences. Given that annotations and the 100%-covered schema carry the structured details, the description still leaves the action's semantics and side effects unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all four parameters (including the notable 'confirm' gating flag). The description adds no syntax, format, or meaning beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus obvious alternatives such as add_subscriber_to_workflow, unsubscribe, or remove_subscriber_from_segments. No preconditions or exclusions are stated, leaving the agent to infer usage entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_subscriber_pageSave one private subscriber pageADestructive
Confirmed one-page GET saved only to an exclusive new0600 JSON file. No CSV/cohort export, all-pages loop, overwrite, automatic upload or browser preview.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | The page number. Defaults to 1. | |
| status | No | Optional. The subscriber's status. `active`: The subscriber is currently active to receive marketing emails. `unsubscribed`: The subscriber has opted out of marketing emails. `unconfirmed`: The subscriber is pending for double opt-in confirmation. `bounced`: The subscriber's address is undeliverable due to a hard bounce. `complained`: The subscriber marked an email as spam. `cleaned`: The subscriber was cleaned, learn more [here](https://help.flodesk.com/en/articles/4747969#how_can_i_find_out_which_email_addresses_have_been_cleaned). `archived`: The subscriber was archived. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| per_page | No | The number of records to be returned on each page. Defaults to 20. Maximum 100. | |
| segment_id | No | Optional. The segment's id. When included, returns only subscribers who were added to the given segment. | |
| output_file | Yes | Absolute new file in an existing private directory. Restrict Windows ACLs separately. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, idempotentHint=false, but the description adds concrete behavior they don't cover: output is an exclusive, newly created 0600 JSON file with no overwrite, no automatic upload, and no browser preview. This meaningfully tells the agent what side effects occur and what safeguards exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences with zero filler; the core action is front-loaded and the scope exclusions follow. Nothing is repeated or padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter destructive write with no output schema, the description covers the key behavioral facts an agent needs (file-only output, exclusive creation, no overwrite/upload). It could say more about what the saved file contains or what happens if the target file already exists, but with annotations and a fully documented schema the coverage is largely adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents page, status, account, confirm, per_page, segment_id and output_file in detail. The description only loosely echoes 'Confirmed' (confirm) and the new JSON file (output_file perms), adding little beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific action (a single-page GET written to a new JSON file) and the title pins the resource to subscriber pages, so the agent knows this is a save/export tool rather than a list or preview. It is distinguishable from siblings like list_subscribers and preview_subscriber_batch, though the phrasing 'Confirmed one-page GET' is jargon-y and assumes the reader maps it to subscribers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The negative list (no CSV/cohort export, all-pages loop, overwrite, upload, preview) implicitly scopes usage and tells the agent what this tool will not do, which is useful. However it never states when to pick this over list_subscribers or preview_subscriber_batch, so routing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_subscriber_batchExecute reviewed subscriber tasksADestructive
Confirmed one-to-twenty ordered subscriber/segment/workflow/custom-field tasks. Prevalidate all and verify exact hash before first request. Stop on first failure with known results/failed index/unattempted indices; no retries, rollback or implicit continuation.
| Name | Required | Description | Default |
|---|---|---|---|
| tasks | Yes | One to twenty exact ordered supported subscriber/segment/workflow/custom-field operations. Native batch upserts may affect up to50 subscribers per task; not a20-person budget. | |
| account | No | Exact selected private account profile; binds label, not key ownership. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| review_sha256 | Yes | Exact preview_subscriber_batch hash for identical requests, profile label, schema and order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only state destructive, non-idempotent, openWorld. The description adds substantial execution semantics beyond that: prevalidation, exact-hash verification before the first request, stop-on-first-failure behavior, and explicitly no retries, no rollback, no implicit continuation. It even names the failure payload shape (known results / failed index / unattempted indices).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the scope and the confirmation/hash gate before the failure semantics. No filler. Slightly telegraphic ('Confirmed one-to-twenty ordered ... tasks') but every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-idempotent batch executor with no output schema, the description covers the critical concerns: gating (confirm + hash), failure behavior, and partial-completion reporting. It does not describe the success return shape, but the failure contract is the higher-risk gap and it is covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents tasks, account, confirm and review_sha256. The description restates the ordering and the 1-20 bound and the hash requirement, but adds no format or syntax detail beyond the structured fields, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and scope: executing 1-20 ordered subscriber/segment/workflow/custom-field tasks that were already reviewed. The verb is implicit (submit/execute) but the hash-verification requirement makes it distinguishable from preview_subscriber_batch. It is clear, though it never names the sibling that produces the hash.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied — this runs a batch that was previously previewed and confirmed — but the description never explicitly says 'use after preview_subscriber_batch' or when to prefer it over calling the individual sibling tools directly. The routing hint lives only in the schema's review_sha256 description, not the tool description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsubscribeUnsubscribe from all lists.CDestructive
Unsubscribe from all lists.
| Name | Required | Description | Default |
|---|---|---|---|
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| id_or_email | Yes | Exact native path parameter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false, and openWorldHint=true, so the safety profile is covered by structured data. The description adds no behavioral context of its own: it does not say the action is irreversible, that it affects every list at once, or what happens on partial failure. It adds zero value beyond the name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single short sentence with nothing extraneous, so it is not bloated. But it is duplicated directly from the title, meaning no sentence earns its place beyond the name itself.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an irreversible, bulk destructive mutation with no output schema, the description leaves critical questions unanswered: what counts as "all lists", whether this is scoped to a subscriber, and whether confirmation is required. Annotations cover the safety flag but not the scope semantics an agent needs before invoking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with 'account', 'confirm', and 'id_or_email' all documented in the schema, so the schema does the heavy lifting and baseline 3 applies. The description contributes no additional parameter meaning, but none is required given full coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus narrower removal siblings such as remove_subscriber_from_segments or remove_subscriber_from_workflow, nor any prerequisite or confirmation context. The only hint of usage is the schema's 'confirm' parameter description, which is not part of the tool description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_webhookUpdate a webhook.DDestructive
Update a webhook.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Exact native path parameter. | |
| name | No | The webhook name. | |
| events | No | An array specifying which events are enabled for webhook notifications. | |
| account | No | Exact configured private account profile label; not a tenant or provider account ID. | |
| confirm | No | Set true only when the user asked for exactly this action. | |
| payload | No | Complete native JSON body; do not mix with body flags or payload_file. Arrays use repeated JSON object flags or a whole native array in a private file. | |
| post_url | No | The url that the webhook will post to. | |
| payload_file | No | Absolute regular non-symlink JSON body file, at most 1 MiB. Cannot mix with payload/body flags. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=false, and openWorldHint=true, so the safety profile is conveyed structurally. The description adds nothing beyond that – no mention of which fields are replaceable, whether omitted fields are cleared, or what happens to existing settings.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single sentence is short but this reflects under-specification rather than conciseness. Nothing is front-loaded because there is nothing to front-load.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, non-idempotent mutation with 8 parameters, a nested payload object, mutually exclusive body options (payload vs payload_file), and no output schema, a three-word description is wholly inadequate. An agent cannot determine scope, replacement semantics, or the payload/body-flag conflict from this text.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% across all 8 parameters, so the schema itself documents id, name, events, account, confirm, payload, post_url, and payload_file. The description contributes no additional parameter meaning, which is the baseline 3 when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Tautological: description restates name/title.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance whatsoever on when to use this tool versus create_webhook, delete_webhook, or get_webhook, nor any prerequisite or context information. The agent is left to infer everything from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
22 tool updates
v3.0.0- Changed
add_subscriber_to_segments1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
add_subscriber_to_workflow1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
batch_create_or_update_subscribers10 fields changed- added
Input schema / $defsAdded value: +{ + "subscribers": { + "description": "List of subscribers to create or update. Maximum 50 items.", + "items": { + "properties": { + "custom_fields": { + "additionalProperties": { + "type": "string" + }, + "description": "An object containing custom field data.\nE.g. ``` \"favorite_color\": \"Lavender\" ```.", + "type": "object" + }, + "double_optin": { + "description": "Whether or not to require the subscriber to confirm subscription via email.\n\nThis option is only available to set with new subscriber creation. Default to `false` if not indicated.", + "type": "boolean" + }, + "email": { + "description": "The subscriber's `email`. Either `email` or `id` must be included.", + "type": "string" + }, + "first_name": { + "description": "The subscriber's first name.", + "type": "string" + }, + "id": { + "description": "The subscriber's `id`. Either `email` or `id` must be included.", + "type": "string" + }, + "last_name": { + "description": "The subscriber's last name.", + "type": "string" + }, + "optin_ip": { + "description": "IP address from which the subscriber confirmed their opt-in.", + "type": "string" + }, + "optin_timestamp": { + "description": "The date and time the subscribers confirmed their opt-in in ISO 8601 format.\nE.g. `2023-01-02T15:04:05.999Z`.", + "type": "string" + }, + "segment_ids": { + "description": "The segments this subscriber will be added to. Cap at `50`.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "title": "CreateOrUpdateSubscriberItem represents a single subscriber payload.", + "type": "object" + }, + "type": "array" + } +} - changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action." - added
Input schema / properties / payload / properties / subscribers / $refAdded value: +"#/$defs/subscribers" - removed
Input schema / properties / payload / properties / subscribers / descriptionRemoved value: -"List of subscribers to create or update. Maximum 50 items." - removed
Input schema / properties / payload / properties / subscribers / itemsRemoved value: -{ - "properties": { - "custom_fields": { - "additionalProperties": { - "type": "string" - }, - "description": "An object containing custom field data.\nE.g. ``` \"favorite_color\": \"Lavender\" ```.", - "type": "object" - }, - "double_optin": { - "description": "Whether or not to require the subscriber to confirm subscription via email.\n\nThis option is only available to set with new subscriber creation. Default to `false` if not indicated.", - "type": "boolean" - }, - "email": { - "description": "The subscriber's `email`. Either `email` or `id` must be included.", - "type": "string" - }, - "first_name": { - "description": "The subscriber's first name.", - "type": "string" - }, - "id": { - "description": "The subscriber's `id`. Either `email` or `id` must be included.", - "type": "string" - }, - "last_name": { - "description": "The subscriber's last name.", - "type": "string" - }, - "optin_ip": { - "description": "IP address from which the subscriber confirmed their opt-in.", - "type": "string" - }, - "optin_timestamp": { - "description": "The date and time the subscribers confirmed their opt-in in ISO 8601 format.\nE.g. `2023-01-02T15:04:05.999Z`.", - "type": "string" - }, - "segment_ids": { - "description": "The segments this subscriber will be added to. Cap at `50`.", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "title": "CreateOrUpdateSubscriberItem represents a single subscriber payload.", - "type": "object" -} - removed
Input schema / properties / payload / properties / subscribers / typeRemoved value: -"array" - added
Input schema / properties / subscribers / $refAdded value: +"#/$defs/subscribers" - removed
Input schema / properties / subscribers / descriptionRemoved value: -"List of subscribers to create or update. Maximum 50 items." - removed
Input schema / properties / subscribers / itemsRemoved value: -{ - "properties": { - "custom_fields": { - "additionalProperties": { - "type": "string" - }, - "description": "An object containing custom field data.\nE.g. ``` \"favorite_color\": \"Lavender\" ```.", - "type": "object" - }, - "double_optin": { - "description": "Whether or not to require the subscriber to confirm subscription via email.\n\nThis option is only available to set with new subscriber creation. Default to `false` if not indicated.", - "type": "boolean" - }, - "email": { - "description": "The subscriber's `email`. Either `email` or `id` must be included.", - "type": "string" - }, - "first_name": { - "description": "The subscriber's first name.", - "type": "string" - }, - "id": { - "description": "The subscriber's `id`. Either `email` or `id` must be included.", - "type": "string" - }, - "last_name": { - "description": "The subscriber's last name.", - "type": "string" - }, - "optin_ip": { - "description": "IP address from which the subscriber confirmed their opt-in.", - "type": "string" - }, - "optin_timestamp": { - "description": "The date and time the subscribers confirmed their opt-in in ISO 8601 format.\nE.g. `2023-01-02T15:04:05.999Z`.", - "type": "string" - }, - "segment_ids": { - "description": "The segments this subscriber will be added to. Cap at `50`.", - "items": { - "type": "string" - }, - "type": "array" - } - }, - "title": "CreateOrUpdateSubscriberItem represents a single subscriber payload.", - "type": "object" -} - removed
Input schema / properties / subscribers / typeRemoved value: -"array"
- Changed
create_custom_field1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
create_or_update_subscriber8 fields changed- added
Input schema / $defsAdded value: +{ + "double_optin": { + "description": "Whether or not to require the subscriber to confirm subscription via email.\n\nThis option is only available to set with new subscriber creation. Default to `false` if not indicated.", + "type": "boolean" + } +} - changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action." - added
Input schema / properties / double_optin / $refAdded value: +"#/$defs/double_optin" - removed
Input schema / properties / double_optin / descriptionRemoved value: -"Whether or not to require the subscriber to confirm subscription via email.\n\nThis option is only available to set with new subscriber creation. Default to `false` if not indicated." - removed
Input schema / properties / double_optin / typeRemoved value: -"boolean" - added
Input schema / properties / payload / properties / double_optin / $refAdded value: +"#/$defs/double_optin" - removed
Input schema / properties / payload / properties / double_optin / descriptionRemoved value: -"Whether or not to require the subscriber to confirm subscription via email.\n\nThis option is only available to set with new subscriber creation. Default to `false` if not indicated." - removed
Input schema / properties / payload / properties / double_optin / typeRemoved value: -"boolean"
- Changed
create_segment1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
create_webhook1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
delete_webhook1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
list_campaigns1 field changed- removed
Input schema / properties / page / maximumRemoved value: -9007199254740991
- Changed
list_custom_fields1 field changed- removed
Input schema / properties / page / maximumRemoved value: -9007199254740991
- Changed
list_segments1 field changed- removed
Input schema / properties / page / maximumRemoved value: -9007199254740991
- Changed
list_subscribers1 field changed- removed
Input schema / properties / page / maximumRemoved value: -9007199254740991
- Changed
list_webhooks1 field changed- removed
Input schema / properties / page / maximumRemoved value: -9007199254740991
- Changed
list_workflows1 field changed- removed
Input schema / properties / page / maximumRemoved value: -9007199254740991
- Changed
publish_canva_email1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
publish_studio_email1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
remove_subscriber_from_segments1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
remove_subscriber_from_workflow1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
save_subscriber_page2 fields changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Explicit approval for this exact requested ordered batch."New value: +"Set true only when the user asked for exactly this action." - removed
Input schema / properties / page / maximumRemoved value: -9007199254740991
- Changed
submit_subscriber_batch1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Explicit approval for this exact requested ordered batch."New value: +"Set true only when the user asked for exactly this action."
- Changed
unsubscribe1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
- Changed
update_webhook1 field changed- changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true for the requested mutation or exclusive private output file."New value: +"Set true only when the user asked for exactly this action."
32 tool updates
v2.0.0- First observed
add_subscriber_to_segments - First observed
add_subscriber_to_workflow - First observed
batch_create_or_update_subscribers - First observed
create_custom_field - First observed
create_or_update_subscriber - First observed
create_segment - First observed
create_webhook - First observed
delete_webhook - First observed
get_canva_design_state - First observed
get_oauth_userinfo - First observed
get_operation_schema - First observed
get_segment - First observed
get_subscriber - First observed
get_webhook - First observed
list_accounts - First observed
list_all_custom_fields - First observed
list_campaigns - First observed
list_custom_fields - First observed
list_segment_colors - First observed
list_segments - First observed
list_subscribers - First observed
list_webhooks - First observed
list_workflows - First observed
preview_subscriber_batch - First observed
publish_canva_email - First observed
publish_studio_email - First observed
remove_subscriber_from_segments - First observed
remove_subscriber_from_workflow - First observed
save_subscriber_page - First observed
submit_subscriber_batch - First observed
unsubscribe - First observed
update_webhook
TDQS
Scored across 32 tools
Most tools target distinct resources, but list_custom_fields and list_all_custom_fields appear to do the same thing, and preview_subscriber_batch, submit_subscriber_batch, and batch_create_or_update_subscribers have blurry boundaries around batch subscriber operations. The Canva/Studio publish pair is also similar, though distinguishable by source.
Nearly all names follow a predictable verb_noun snake_case pattern (get_subscriber, list_webhooks, create_webhook, add_subscriber_to_segments). Minor deviations like get_oauth_userinfo and the noun-heavy _batch/_page variants keep it just short of perfect.
At 32 tools this is on the heavy side for a single server, exceeding the typical 3-15 sweet spot. The domain (subscribers, campaigns, segments, workflows, webhooks, custom fields, publishing) is broad enough to justify many, but several meta/utility tools (get_operation_schema, list_accounts, get_oauth_userinfo, preview_subscriber_batch) add weight.
Coverage is uneven: webhooks have full CRUD and subscribers are richly handled, but campaigns only support listing (no get/create/update/delete), and segments and custom fields lack update/delete operations. These notable gaps would leave agents at dead ends for common lifecycle tasks.
Maintenance
Related MCP Connectors
Project-scoped marketing ops for agents: Bearer dpk_/dpa_ or OAuth, read and supervised write.
Persistent identity, email, saved accounts and scoped credentials for AI agents.
Multiple Gmail accounts, editable Google Sheets & Docs for AI agents. Deny-by-default access rules.
Hosted CRM and email desk for AI agents: key per agent, audit log, one-click undo, opt-in approval.
Related MCP Servers
AlicenseAqualityAmaintenanceEnables AI agents to author and manage workflows, agents, tools, skills, policies, and reference docs in an Axonity tenant via the public REST API, with guardrails preventing direct publishing and secret exposure.10099 npmMIT
Arsel MCP Serverofficial
AlicenseBqualityBmaintenanceEnables AI agents to read and manage contacts, lists, tags, events, templates, campaigns and message logs in an Arsel organization, and to draft email, SMS, push and in-app campaigns for review. It is read-and-draft only, so agents can create and update records but cannot send, schedule or delete anything.59MIT- AlicenseBqualityAmaintenanceEnables AI clients to discover current fal.ai model schemas and pricing, submit only approved generation batches, manage assets, collections, tags, characters, and CDN access settings, and use isolated private account profiles through shared validated tools.6645 npmAGPL 3.0
- AlicenseBqualityBmaintenanceEnables AI agents and terminal workflows to read FluentCRM contacts, campaigns and automations, FluentCommunity spaces, feeds, comments and member analytics, and Fluent Forms definitions, submissions and stats, while applying only reviewed native changes. It supports multiple isolated private site profiles authenticated with WordPress Application Passwords, and provides approval-gated cross-plugin batches plus bounded, privately stored snapshots.5416 npmAGPL 3.0