listmonk-mcp-ts
Provides tools for interacting with a Listmonk instance, enabling AI agents to manage subscribers, mailing lists, campaigns (including body editing via plain-text, regex and batch replace), templates, media, and to send transactional email.
Listmonk MCP Server

An MCP server for Listmonk, the self-hosted newsletter and mailing list manager. It lets AI agents (Claude Code, Claude Desktop, Cursor, Cline, VS Code and others) manage subscribers, mailing lists, campaigns, templates and media, and send transactional email through your Listmonk instance.
TypeScript port of rhnvrm/listmonk-mcp by Rohan Verma, extended with file-based templates, campaign body editing and hardened file access.
Written in TypeScript, runs on Bun.
Features
Subscribers: add, update, delete, change status, search with Listmonk SQL queries, look up by ID or email.
Mailing lists: create, update, delete, list, list members.
Campaigns: create, update, preview, send now, schedule. Edit the body with plain-text, regex and batch replace.
Templates: create, update, delete, read. Large HTML bodies (for example MJML exports) can be loaded straight from a file.
Transactional email: send a
txtemplate to one recipient with custom data.Media: upload, rename, delete, list.
Related MCP server: sendook-mcp
Requirements
Bun 1.1 or newer.
Listmonk with an API user. In the Listmonk admin, open Users, create a user of type API and copy its token. Give it a role with only the permissions the agent needs.
Quick start
One-click install (then replace the placeholder URL, user and token in the client's MCP settings):
Claude Code
claude mcp add --transport stdio --scope user \
--env LISTMONK_MCP_URL=https://listmonk.example.com \
--env LISTMONK_MCP_USERNAME=api_user \
--env LISTMONK_MCP_PASSWORD=your-api-token \
listmonk -- bunx listmonk-mcp-tsClaude Desktop, Cursor, Cline and other clients
Add the server to the client's MCP config (mcpServers section):
{
"mcpServers": {
"listmonk": {
"command": "bunx",
"args": ["listmonk-mcp-ts"],
"env": {
"LISTMONK_MCP_URL": "https://listmonk.example.com",
"LISTMONK_MCP_USERNAME": "api_user",
"LISTMONK_MCP_PASSWORD": "your-api-token",
"LISTMONK_MCP_FILES_DIR": "/path/to/email-templates"
}
}
}
}Where the config file lives for each client: Claude Desktop, Cursor and Windsurf, Cline, VS Code.
The server is started by the client when a session opens and stops with it. You do not need to keep it running.
Configuration
Variable | Required | Default | Description |
| yes | Listmonk base URL, | |
| yes | API user name | |
| yes | API user token | |
| no | Directory the file tools may read from. File tools are disabled when it is not set | |
| no |
| HTTP timeout, seconds |
| no |
| Retries on network errors. Only GET requests are retried |
| no |
| Server name reported to the client |
Variables can also come from a .env file in the working directory, or from a file passed with --config /path/to/.env.
CLI options: -c, --config <file> loads an env file, -v, --version prints the version.
Tools
Area | Tools |
Health |
|
Subscribers |
|
Mailing lists |
|
Campaigns |
|
Campaign body |
|
Templates |
|
Transactional |
|
Media |
|
Templates from a file
Passing a large HTML body inline through a tool call is slow and the model can change it while copying. create_template_from_file and update_template_from_file read the body from a file instead, so the stored template matches the file byte for byte. subject is required for tx templates.
The file path can be absolute or relative to LISTMONK_MCP_FILES_DIR.
Security
File access is limited to
LISTMONK_MCP_FILES_DIR.create_template_from_file,update_template_from_fileandupload_media_filerefuse any path outside it, symlinks included, and are disabled when it is not set. Subscriber names, campaign bodies and other data read from Listmonk may contain instructions written by strangers (prompt injection). Without this limit such text could make the agent read~/.sshor.envand email it out.Keep approval on for sending tools.
send_campaign,schedule_campaignandsend_transactional_emailsend real email. Do not auto-approve them in your client.Use a dedicated API user with a role limited to what the agent needs, not an admin account.
Keep the token out of shared files. If your MCP config is committed or synced, pass the token through the environment instead.
Development
git clone https://github.com/tecspda/listmonk-mcp-ts.git
cd listmonk-mcp-ts
bun install
cp .env.example .env # fill in your Listmonk details
bun run start # run the server
bun run dev # run with reload on change
bun run check # type check
bun test # testsTo run a local checkout from an MCP client, use "command": "bun", "args": ["run", "/path/to/listmonk-mcp-ts/src/index.ts"].
Need a Listmonk instance for testing? See Docker setup.
License
Available Tools
36 toolsadd_subscriberA
Create a new subscriber and optionally subscribe them to mailing lists. Fails if a subscriber with the same email already exists. Returns the new subscriber ID. To change an existing subscriber use update_subscriber.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Subscriber name | |
| Yes | Subscriber email | ||
| lists | No | IDs of the mailing lists to subscribe them to (see get_mailing_lists); empty means no lists | |
| status | No | enabled (can receive mail), disabled, or blocklisted (never mailed) | enabled |
| attributes | No | Free-form JSON object stored with the subscriber, e.g. {"city": "Berlin"} | |
| preconfirm | No | If true, subscriptions to double opt-in lists are marked confirmed and no confirmation email is sent |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-read-only, non-idempotent, non-destructive, so the safety profile is covered. The description adds context beyond that: duplicate-email failure semantics and the returned subscriber ID. It omits that confirmation emails may be sent for double opt-in lists by default, which is a real side effect an agent should anticipate.
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?
Four short sentences, front-loaded with the primary action, then failure mode, return value, and the disambiguation hint. Nothing is repeated or wasted.
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 no output schema, the description usefully states what is returned (the new subscriber ID), and annotations handle the mutation profile. The one meaningful gap is the email-sending side effect for double opt-in lists, which is only discoverable by reading the preconfirm parameter description.
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 including the nested attributes object and the preconfirm flag is already documented in the schema. The description mentions subscribing to lists but adds no format, default, or constraint detail beyond that, making the baseline 3 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?
States a specific verb and resource ('Create a new subscriber') plus the optional side effect ('optionally subscribe them to mailing lists'). It also explicitly distinguishes itself from the sibling update_subscriber, leaving no ambiguity about which tool handles which case.
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?
Gives a clear routing rule: use this to create, use update_subscriber to change an existing subscriber, and note that a duplicate email causes failure. It doesn't spell out what to do on that failure (e.g., fall back to update_subscriber or get_subscriber_by_email), but the alternative is named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_replace_in_campaign_bodyADestructive
Apply several literal search and replace pairs to a campaign's body in the given order, then save once. Later pairs see the result of earlier ones, and empty search texts are skipped. Nothing is saved if no pair matches.
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | Yes | Campaign ID | |
| replacements | Yes | Search/replace pairs applied in order; each search is a literal, case-sensitive text |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag the tool as destructive and non-idempotent, so the description's job is to add detail, which it does: pairs are applied sequentially so later pairs see earlier results, empty search strings are skipped, the body is saved only once, and nothing is written if no pair matches. That effectively softens the destructive hint into a conditional-write guarantee. It stops short of saying the original body text is overwritten irreversibly or what permissions/lookup failures look like.
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 with zero filler. The core action and its ordering guarantee lead, and the edge-case behavior (empty searches skipped, no-match means no save) follows — appropriately 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 two-parameter mutation with no output schema, the description covers behavior, ordering, and conditional saving well. The remaining gap is the return value: with no output schema, the agent cannot know whether it gets a count of applied replacements, the resulting body, or a no-op indicator — worth one sentence.
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%, so the baseline is 3; the description earns above that by adding execution semantics the schema does not convey — cross-pair ordering effects (later pairs operate on earlier results) and the skip rule for empty search values, which is invisible in the schema since 'search' is just a required string.
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 (apply literal search/replace pairs), the target resource (a campaign's body), and the scope (several pairs, applied in order, saved once) — enough to distinguish it from the sibling replace_in_campaign_body. It does not, however, name the single-pair or regex siblings as alternatives, so the differentiation is implicit 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?
The batched, ordered nature implies when to use it (multiple literal edits in one save), and the empty-search skipping rule is stated. But there is no explicit guidance to use replace_in_campaign_body for a single pair or regex_replace_in_campaign_body for pattern matching, and no preconditions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
change_subscriber_statusADestructiveIdempotent
Change only a subscriber's status to enabled, disabled or blocklisted. Blocklisted subscribers are excluded from all campaigns. Use remove_subscriber to delete the record instead.
| Name | Required | Description | Default |
|---|---|---|---|
| status | Yes | New status (enabled, disabled, blocklisted) | |
| subscriber_id | Yes | Subscriber ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover idempotency and destructiveness, and the description adds a genuine consequence beyond them: blocklisted subscribers are excluded from all campaigns. It does not explain the side effects of the 'disabled' state or whether the call fails on an unknown subscriber ID, leaving some behavioral gaps 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?
Three short sentences, front-loaded with the action and constraints, then the blocklist side effect, then the sibling redirect. Nothing is redundant 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 two-parameter mutation with full schema coverage and annotations declaring idempotency and destructiveness, the description covers purpose, allowed values, and semantic consequences. Only the response/error behavior and the effect of the 'disabled' status are unaddressed, and no output schema exists to cover them.
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 and the status enum are already documented structurally. The description repeats the three status values without adding format, validation, or ID-source guidance, 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 and resource ('Change ... a subscriber's status') plus the exact enum of allowed values. The word 'only' scopes it against update_subscriber, and remove_subscriber is named outright, so an agent can differentiate it from siblings without opening any schema.
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?
Explicitly routes deletion to remove_subscriber, and the phrase 'Change only a subscriber's status' implies other field edits belong to update_subscriber. It stops short of naming update_subscriber as the alternative for name/email/attribute changes, so the routing is clear but not fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_listmonk_healthARead-only
Check that the Listmonk server is reachable and responding, and return its health data. Makes a single request with no retries. Use it first when other tools fail with connection errors.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds genuinely useful behavior beyond that—a single request with no retries, indicating fast, non-idempotent-retry failure semantics—though it stops short of saying whether failures raise an error or return a status payload.
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?
Three short sentences with the core purpose first, followed by execution behavior, then the routing hint. Every sentence earns its place and 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 zero-parameter read-only health probe with no output schema, the description covers purpose, execution behavior, and usage routing. The only soft gap is that 'health data' is not itemized, but the shape of a health response is not critical to invoking this correctly.
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 nothing for the description to disambiguate; the entry schema is empty and the baseline of 4 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 (check) and resource (Listmonk server) plus what it returns (health data). Among 35+ sibling tools focused on subscribers, campaigns, templates, and media, it is unmistakably the diagnostic endpoint.
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?
Gives an explicit trigger: 'Use it first when other tools fail with connection errors.' That tells the agent both when to use it and how it relates to the rest of the toolset, with no inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_campaignA
Create a campaign in draft status; nothing is sent yet. body is the message content and template_id selects the layout template that wraps it. Returns the new campaign ID. Next, review it with get_campaign_preview, then start it with send_campaign or schedule_campaign.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | Message content in the chosen content_type; can also be added later with update_campaign | |
| name | Yes | Campaign name | |
| tags | No | Labels for organising campaigns | |
| type | No | regular (normal campaign) or optin (asks subscribers to confirm a double opt-in subscription) | regular |
| lists | Yes | IDs of the mailing lists to send to, at least one (see get_mailing_lists) | |
| subject | Yes | Email subject | |
| template_id | No | Layout template that wraps the body (see get_templates); omit to use the default campaign template | |
| content_type | No | Format of body: richtext, html, markdown or plain | richtext |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-read-only, non-destructive, non-idempotent; the description adds real value by confirming the campaign is created in draft and 'nothing is sent yet', which tells the agent this mutation is inert until a separate send call. It also states the return value (new campaign ID). It omits that repeated calls create duplicate campaigns (relevant given idempotentHint=false).
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?
Three short sentences, front-loaded with the state outcome and then the workflow. No filler and no repetition of the parameter list.
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 8-parameter creation tool with no output schema, the description covers the draft semantics, the return value, and the downstream workflow. Remaining gaps (duplicate-creation risk, whether a required sender/list setup must exist) are minor since all parameters are fully documented in the schema.
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%, so the baseline is 3. The description's note that body is the message content and template_id selects the wrapping layout template rephrases what the schema already says in nearly the same words, adding little beyond the structured fields.
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 and resource plus the crucial scope qualifier: 'Create a campaign in draft status; nothing is sent yet.' This immediately separates it from send_campaign and schedule_campaign among the siblings.
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?
Explicitly prescribes the follow-on workflow: create, then get_campaign_preview, then send_campaign or schedule_campaign. The when-to-use path is fully spelled out with named alternatives rather than left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_mailing_listA
Create a mailing list and return its ID, which other tools use to subscribe people and target campaigns. A list is public or private and uses single or double opt-in.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | List name | |
| tags | No | Labels for organising lists | |
| type | No | public (can appear on subscription forms) or private (internal only) | public |
| optin | No | single (subscribed at once) or double (subscriber must confirm by email) | single |
| description | No | Short description of the list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false and destructiveHint=false, so the safety profile is covered. The description adds only the return-ID fact; it does not state the meaningful consequence of idempotentHint=false (repeated calls with the same name create duplicate lists) or any naming/uniqueness or permission constraints. Useful but thin beyond what structured fields already give.
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 short sentences, front-loaded with the create action and the returned ID. The second sentence about list visibility and opt-in is largely redundant with the schema and slightly dilutes the focus, but nothing is padded excessively.
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 no output schema, the description correctly tells the agent the call returns an ID, and all five parameters are fully covered by the schema. The main gap is behavioral: nothing about duplicate-name handling or whether the new list is immediately usable in campaigns, which would matter for a non-idempotent create.
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 five parameters — including the public/private and single/double opt-in semantics — are already fully documented in the schema with the same parenthetical explanations. The description's second sentence merely restates that schema content, adding no new 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?
States a specific verb and resource ('Create a mailing list') plus what it returns ('its ID'), which immediately separates it from get_mailing_lists, update_mailing_list and delete_mailing_list. It even names the downstream consumers of the returned ID, so an agent knows this is the entry point of the list lifecycle.
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 reference to 'other tools use to subscribe people and target campaigns' implies this is a prerequisite step before add_subscriber or create_campaign, but it never states when to create versus reuse an existing list, nor any prerequisites or exclusions. Usage is implied rather than prescribed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_templateA
Create a template and return its ID. Type 'campaign' is a layout that wraps campaign bodies; type 'tx' is a transactional email template that needs a subject and is sent with send_transactional_email. For large HTML bodies prefer create_template_from_file.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | Full template HTML. A 'campaign' template must contain {{ template "content" . }} where the campaign body goes | |
| name | Yes | Template name | |
| type | No | Template type: 'campaign' or 'tx' (transactional) | campaign |
| subject | No | Subject line (required for 'tx' transactional templates) | |
| is_default | No | Whether this is default |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false and destructiveHint=false, so the write/safety profile is covered. The description adds two useful facts, that the new template's ID is returned and that 'tx' templates require a subject, but it does not warn about non-idempotent duplicate creation (e.g. whether name must be unique or what happens on repeat calls).
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?
Three short sentences, front-loaded with the core action and return value, then type semantics, then the sibling alternative. Every sentence carries information an agent needs, with no filler.
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 no output schema, the description compensates by stating that the ID is returned, and it covers both template types and the large-body alternative. It stops short of addressing naming/uniqueness behavior or validation failures, which would matter for a non-idempotent create.
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%, so the body placeholder requirement, the type default and the subject requirement are already documented in the schema. The description reinforces the type/subject relationship and the meaning of 'campaign' vs 'tx', but adds no formatting or constraint detail beyond that. 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 and resource ("Create a template") and immediately names the return value ("return its ID"). It also distinguishes this tool from its sibling create_template_from_file, so an agent can pick correctly without opening either schema.
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?
Explicitly routes the agent: use create_template_from_file for large HTML bodies, and 'tx' templates are sent with send_transactional_email. This names alternatives and the conditions that select them, which is exactly the routing help missing from most definitions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_template_from_fileA
Create a template whose HTML body is read from a UTF-8 file inside LISTMONK_MCP_FILES_DIR, so large bodies such as MJML exports are stored byte for byte. Otherwise identical to create_template. Fails if LISTMONK_MCP_FILES_DIR is not set or the path is outside it.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Template name | |
| type | No | Template type: 'campaign' or 'tx' (transactional) | campaign |
| subject | No | Subject line (required for 'tx' transactional templates) | |
| file_path | Yes | Path to the template HTML file inside LISTMONK_MCP_FILES_DIR (absolute or relative to it) | |
| is_default | No | Whether this is default |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses important behavior: the body is read as UTF-8 from a restricted directory, stored byte for byte, and the call fails if LISTMONK_MCP_FILES_DIR is missing or the path escapes it. This adds useful file-system and error context, though it does not describe return behavior or duplicate-name handling.
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?
Three tightly packed sentences: purpose first, use case and sibling comparison second, failure conditions third. Every sentence adds actionable information with no filler.
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 file-backed mutation tool, the description covers purpose, the inline alternative, file location constraints, encoding, and major failure modes. It lacks return-value information, but with rich schema descriptions and annotations the definition is otherwise sufficient 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%, so the schema already documents all five parameters thoroughly. The description adds only limited semantic detail about file_path and encoding, which is useful but does not materially expand parameter meaning beyond 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?
The description states a specific verb and resource ('Create a template') plus the defining mechanism ('HTML body is read from a UTF-8 file'). It also distinguishes this from the sibling create_template with 'Otherwise identical to create_template,' so an agent can tell exactly what this tool does differently.
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?
It gives a clear use case ('large bodies such as MJML exports') and names create_template as the equivalent alternative. It also states prerequisites/failure conditions, but does not explicitly say when to prefer create_template over this file-based variant.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_mailing_listADestructiveIdempotent
Permanently delete a mailing list and its subscriptions. The subscribers themselves are kept and only leave this list. This cannot be undone.
| Name | Required | Description | Default |
|---|---|---|---|
| list_id | Yes | List ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false, so the safety profile is covered. The description still earns credit for disclosing the cascade behavior — subscriptions are removed while subscriber records survive — which annotations cannot express; 'cannot be undone' reinforces rather than contradicts the hints.
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?
Three short sentences, front-loaded with the action and its permanence, followed immediately by the non-obvious consequence for subscribers. No filler.
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 destructive tool, the definition covers action, permanence, and side effects on subscriber data; no output schema exists and none is needed to call it. It only stops short of mentioning error conditions or how to obtain list_id.
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?
There is a single required parameter with 100% schema description coverage, so the schema carries the semantics. The description does not add anything about list_id format, valid ranges, or how to discover an ID (e.g., via get_mailing_lists), which would have been the only way to 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?
States a specific verb (delete) and resource (mailing list) plus the destructive scope (its subscriptions), and clarifies that subscriber records are not deleted — a distinction that separates it from remove_subscriber and update_mailing_list.
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 intent is implied clearly enough (permanent removal of a list), but the description never states when to prefer alternatives such as update_mailing_list or unsubscribing members individually, nor any prerequisites like list ownership or existence checks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_media_fileADestructiveIdempotent
Permanently delete a media file. Campaigns or templates that still link to its URL will show a broken file. This cannot be undone.
| Name | Required | Description | Default |
|---|---|---|---|
| media_id | Yes | Media ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is known. The description adds real context beyond that: the deletion is permanent, irreversible, and leaves dependent campaigns/templates with broken file URLs. It does not say whether the call errors when the media is in use, but the stated consequence implies it proceeds.
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?
Three short sentences, front-loaded with the action and followed by the consequence and irreversibility. No filler.
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 destructive tool with annotations and no output schema, this covers the essentials: what is deleted, that it is irreversible, and the downstream impact. Only a note on failure behavior when referenced assets exist would improve it.
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?
There is a single parameter with 100% schema description coverage, so the schema does the work and the baseline is 3. The description adds no meaning about media_id (e.g., where to obtain it) beyond 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?
States a specific verb and resource ('Permanently delete a media file'), and the resource cleanly separates it from sibling deletes like delete_template or delete_mailing_list. An agent can identify the operation without opening the schema.
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 implied by the destructive framing and the broken-link warning, which helps an agent decide, but there is no explicit when-to-use/when-not guidance or reference to alternatives such as rename_media or get_media_list for verification.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_templateADestructiveIdempotent
Permanently delete a template by ID. This cannot be undone. Check get_templates first so you do not delete one that is still needed.
| Name | Required | Description | Default |
|---|---|---|---|
| template_id | Yes | Template ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the description is not carrying the safety burden alone. It nonetheless reinforces irreversibility ('This cannot be undone') and adds a concrete pre-check workflow, which is real value beyond the annotations; it doesn't mention effects on campaigns referencing the template.
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 short sentences, zero filler, with the destructive scope front-loaded ahead of the safety advice. Every clause 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 single-parameter destructive tool with full annotation coverage and no output schema, the description supplies the two things an agent needs: irreversibility and a lookup-first safeguard. It stops short of saying what happens to campaigns that reference the template or what the response returns.
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 a single well-typed required parameter (positive number), so the schema does the work. The description only restates 'by ID' and adds no format or constraint detail beyond it, matching 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?
States a specific verb plus resource ('Permanently delete a template') and the selector ('by ID'), which cleanly distinguishes it from the other delete siblings (delete_media_file, delete_mailing_list, remove_subscriber). An agent can select it without opening the schema.
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?
Gives an explicit pre-flight instruction ('Check get_templates first') and the reason for it (avoid deleting something still needed), which routes the agent to a sibling before acting. No explicit when-not-to-use condition or named alternative for the deletion itself, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_campaignARead-only
Get one campaign by ID: name, subject, status, type, template, target lists, send progress, view and click counts, and the full body (which can be large).
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | Yes | Campaign ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read. The description adds useful payload context (send progress, view/click counts, full body that may be large), but says nothing about behavior for a missing/invalid ID or response shape beyond field names.
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 sentence, front-loaded with the verb and retrieval key, then a compact field list. The size caveat is a single parenthetical and every element 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?
With no output schema, the description must convey what comes back, and it enumerates the key fields and flags that the body is large. Only error/missing-campaign behavior is left uncovered, which is minor for a read-only lookup.
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?
There is a single parameter and schema coverage is 100%, with the schema documenting campaign_id (numeric, > 0). The description only restates 'by ID', adding no format or constraint detail 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?
States a specific verb and resource ('Get one campaign by ID') and enumerates the returned fields, which distinguishes it from the sibling list tool get_campaigns and from get_campaign_preview by including the full body. It stops short of explicitly naming those siblings.
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: 'Get one campaign by ID' plus the parenthetical that the body 'can be large' hints that get_campaign_preview is the lighter alternative, but no alternative is named and no when-not guidance is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_campaign_previewARead-only
Render a preview of the campaign as the HTML subscribers would see. Read-only: nothing is sent. Use it to check a campaign before send_campaign or schedule_campaign.
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | Yes | Campaign ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true; the description reinforces this with 'nothing is sent,' which is meaningful for an agent worried about triggering a real send. It also implicitly characterizes the return value as rendered HTML, though it omits any note on rendering failures, caching, or size limits.
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 short sentences with no waste; the purpose comes first and the safety/workflow note follows. Every clause 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 one-parameter read tool with no output schema, the description covers what it produces (subscriber-view HTML) and that it is side-effect free. Minor gap: no mention of what happens for unsent/draft campaigns or whether personalization is resolved.
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% with a single required campaign_id (number, exclusiveMinimum 0), so the schema carries the parameter burden. The description adds no further constraint such as whether the ID must refer to an existing draft — 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 and resource ('Render a preview of the campaign') plus the exact output form ('as the HTML subscribers would see'). This clearly distinguishes it from get_campaign (metadata retrieval) and get_templates.
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?
Explicitly names the moment to use it — checking a campaign before send_campaign or schedule_campaign — which routes the agent to the right sibling tools at the right workflow stage. No ambiguity about when this tool applies.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_campaignsARead-only
List campaigns, one page at a time, with ID, name, status, sent/total progress and target list IDs. Optionally filter by status. Use get_campaign for one campaign's full details and body.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, starting at 1 | |
| status | No | Only campaigns with this status: draft, scheduled, running, paused, cancelled or finished. Omit for all | |
| per_page | No | Campaigns per page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so safety is covered, and the description adds behavior the annotations do not: results come back 'one page at a time' and enumerate the returned fields, which is valuable given there is no output schema. It stops short of explaining whether pagination metadata (total count, next page) is returned, leaving a minor gap.
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 sentences, both front-loaded: the capability and return fields come first, the sibling disambiguation second. No filler or redundant restatement of 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?
For a paginated read tool with no output schema, the description compensates by listing returned fields and noting the one-page-at-a-time behavior. It doesn't state whether the response includes total counts or a next-page indicator, which an agent paginating results would want.
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%, so page, per_page and status are already fully documented including defaults and allowed status values. The description only restates that status filtering is optional, adding essentially no semantics 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?
States a specific verb and resource ('List campaigns') and enumerates the returned fields (ID, name, status, sent/total progress, target list IDs), which tells the agent exactly what it gets. It also explicitly names the sibling it is not ('get_campaign for one campaign's full details'), so the two are easily separated.
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?
Gives the selection rule against the obvious alternative: use get_campaign when you need one campaign's full details and body, otherwise use this tool. The optional status filter is framed as optional ('Optionally filter by status'), matching the schema's 'Omit for all' guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_list_by_idARead-only
Get one mailing list by ID: name, type, opt-in mode, subscriber count, tags, description and timestamps.
| Name | Required | Description | Default |
|---|---|---|---|
| list_id | Yes | List ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes that this is a safe read operation. The description adds useful detail about which fields are returned, but does not mention behavior on invalid or missing list IDs, so the behavioral picture is adequate but not rich.
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 definition is a single front-loaded sentence with zero waste. It states the action, scope, and returned fields immediately.
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 read tool with readOnlyHint and no output schema, the description is nearly sufficient: it tells the agent what fields the response contains. The only meaningful gap is the absence of not-found or error behavior.
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 input schema has 100% description coverage for the single list_id parameter, so the schema already carries parameter documentation. The description restates the concept of fetching by ID without adding validation, format, or error semantics beyond 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?
The description states a specific verb and resource: retrieving a single mailing list by ID. It enumerates the returned fields, distinguishing it implicitly from the plural sibling get_mailing_lists, though it does not name that sibling explicitly.
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 description implies usage when the caller has a list ID and needs full details for one list. It does not explicitly state when to prefer get_mailing_lists or get_list_subscribers_tool instead, leaving the alternative choice partly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_list_subscribers_toolARead-only
List the subscribers of one mailing list, one page at a time, with name, email and status, plus the list's total subscriber count. Use get_mailing_lists to find list IDs.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, starting at 1 | |
| list_id | Yes | List ID | |
| per_page | No | Subscribers per page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read, so the bar is lower, yet the description still adds useful context: results are paginated one page at a time and include a total subscriber count. It stops short of stating ordering, page-size limits, or behavior beyond the last page.
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: the primary capability and returned fields come first, the prerequisite routing hint second. No filler, nothing redundant with structured fields.
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 no output schema and annotation only covering read-only safety, the description correctly spends its words on what is returned (name, email, status, total count) and on pagination, which is what an agent needs before calling. Missing only secondary details like sort order and page-boundary behavior.
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% with defaults and constraints documented for `page`, `per_page`, and `list_id`, so the schema carries the parameter semantics. The description only hints at pagination ('one page at a time') and adds no format or range detail beyond the schema; 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?
Specific verb+resource+scope: lists subscribers of one mailing list, one page at a time, and names the returned fields. It is distinguishable from most siblings, but it never distinguishes itself from the near-identically named sibling `list_subscribers`, leaving genuine ambiguity that only a schema comparison could resolve.
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?
Gives one concrete prerequisite: use `get_mailing_lists` to find list IDs, which is real routing help. However, it offers no when-not guidance and does not address how this differs from the sibling `list_subscribers`, which appears to do the same job.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_mailing_listsARead-only
List mailing lists with ID, type, subscriber count and tags. Use it to find the list IDs required by add_subscriber, create_campaign and other tools.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already covers the safety profile, and the description adds value by disclosing the returned fields (ID, type, subscriber count, tags) even though no output schema exists. It doesn't mention pagination or whether all lists are returned in one call, which is the remaining gap.
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 short sentences, zero waste: the first defines the output, the second gives the motivating use case. Front-loaded and easy to scan.
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-param, read-only lookup with no output schema, the description covers what comes back and why to call it. Minor omissions (pagination behavior, ordering, whether filtering is possible) keep 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?
The tool takes no parameters, so there is no parameter semantics to explain; the baseline for a zero-param tool is 4. The description correctly implies the call needs no arguments.
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 and resource ('List mailing lists') and enumerates what each entry contains (ID, type, subscriber count, tags). It doesn't explicitly distinguish itself from nearby readers like get_list_by_id or list_subscribers, but the 'list all lists' scope is 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?
Explicitly states the use case: finding list IDs needed by add_subscriber, create_campaign and others, which is exactly the precondition an agent needs. It doesn't say when to prefer get_list_by_id or get_list_subscribers_tool instead, so it stops short of full alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_media_listARead-only
List uploaded media files with ID, filename, title, size, creation date and public URL. The URL can be used in campaign and template HTML.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes this is a safe read, and the description's field list adds useful context about the shape of what comes back. However, it says nothing about whether results are paginated, capped, ordered, or scoped to the current user/workspace – meaningful gaps for a list operation that could return a large collection.
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. The core capability is front-loaded, and the secondary sentence earns its place by telling the agent what the URL field is for.
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 no parameters, no output schema and a readOnlyHint annotation, the definition is nearly self-sufficient, and the field enumeration partly substitutes for the missing output schema. The remaining gap is absent detail on result volume, ordering and pagination for a list tool.
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 and the schema is empty at 100% coverage, so there is nothing for the description to disambiguate. Baseline 4 applies; the mention of returned fields is value-add but does not bear on parameter 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?
The description pairs a specific verb ('List') with a specific resource ('uploaded media files') and enumerates the returned fields (ID, filename, title, size, creation date, public URL), which clearly separates it from sibling mutations like upload_media_file, rename_media and delete_media_file.
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 only usage cue is 'The URL can be used in campaign and template HTML', which explains what the returned URL is good for but not when an agent should call this tool versus other lookup tools. Usage is implied rather than stated, and no exclusion or alternative is named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_subscriber_by_emailARead-only
Look up one subscriber by exact email address and return the same details as get_subscriber_by_id. Returns a not-found error if no subscriber has that address.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | Subscriber email |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds genuinely new behavior: exact (non-fuzzy) matching and a not-found error when no subscriber matches. It does not cover case sensitivity or whether the lookup is rate-limited, but the safety and failure profile is largely disclosed.
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 sentences, zero filler, with the lookup scope front-loaded and the error contract as a closing clause. Every sentence carries information an agent 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?
For a one-parameter read tool with no output schema, the description covers input scope, return-shape (by reference to get_subscriber_by_id), and failure mode. The only gap is that the actual returned fields are only available indirectly via that sibling reference.
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 parameter is trivially documented, so the baseline is 3. The description earns an extra point by clarifying that the email must match exactly, which is real semantic information the schema's format=email does not convey.
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 and resource ("look up one subscriber") with a scoping constraint ("by exact email address") and explicitly names the sibling whose output shape it mirrors (get_subscriber_by_id). An agent can distinguish it from get_subscriber_by_id and list_subscribers without opening any schema.
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 exact-match requirement plus the pointer to get_subscriber_by_id implicitly establish when to use which tool (you have an email vs. an ID). No explicit exclusion or prerequisite is spelled out, so it falls short of a full when/when-not statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_subscriber_by_idARead-only
Get one subscriber by numeric ID: email, name, status, timestamps, list memberships and custom attributes. Returns an error if the ID does not exist. Use get_subscriber_by_email when you only know the address.
| Name | Required | Description | Default |
|---|---|---|---|
| subscriber_id | Yes | Subscriber ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes the safety profile, so the bar is lower; the description adds real context by disclosing the failure mode ('returns an error if the ID does not exist') and the shape of the payload. It omits anything about permissions or error structure, but nothing it says conflicts with the annotation.
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?
Three short sentences, front-loaded with the payload description, then the error behavior, then the alternative. Every sentence carries distinct information with no repetition of the name or 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?
For a one-parameter read tool with no output schema, the description compensates well by naming the returned fields and the not-found error. Only the absence of any detail on how the error surfaces or how large list memberships are returned keeps it from being fully 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?
With a single parameter at 100% schema description coverage, the schema already documents subscriber_id as a positive number. The description reinforces 'numeric ID' but adds no format, range, or sourcing hints beyond that. 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+resource (get one subscriber) scoped by numeric ID, and enumerates what comes back (email, name, status, timestamps, list memberships, custom attributes). It explicitly distinguishes itself from the sibling get_subscriber_by_email, so an agent can pick between them without opening either schema.
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?
Gives a clear routing rule: use this when you have the numeric ID, and use get_subscriber_by_email when you only have the address. That covers the primary ambiguity in this sibling cluster, though it says nothing about related operations like list_subscribers when no ID is known.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_templateARead-only
Get one template by ID: name, type (campaign or tx), default flag, subject (tx only), update time and the full HTML body, which can be large.
| Name | Required | Description | Default |
|---|---|---|---|
| template_id | Yes | Template ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds real operational context beyond that: the response includes the full HTML body, which 'can be large' — a useful payload-size warning absent from any structured field.
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 front-loaded sentence that names the key, the discriminator ('one'), and the payload caveat with no wasted words.
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 no output schema, the description steps in to list the returned fields, including the type enum values (campaign or tx) and the tx-only subject, which is genuinely needed context. Minor gap: no mention of behavior for an invalid or missing ID.
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% for the single template_id parameter, so the schema already documents it fully. The description adds no format, constraint, or lookup semantics beyond what the schema provides; 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 and resource ('Get one template by ID') and enumerates the fields returned, so the agent knows exactly what it gets. The word 'one' implicitly separates it from the sibling get_templates, though that sibling is never named.
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 by the name and the 'by ID' phrasing; the description never says when to call this versus get_templates or when not to fetch the full body. An agent can infer the split but must do the work itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_templatesARead-only
List all templates (campaign layouts and transactional) with ID, name, type and default flag. Use the IDs with create_campaign, send_transactional_email or update_template.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already declares the safety profile, so the bar is lower. The description adds that the result includes ID, name, type and default flag, effectively documenting the return shape. It omits any mention of result volume or pagination behavior, which matters for a "list all" tool with no parameters to bound the output.
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 short sentences: what you get first, what to do with it second. No filler, no repetition of the tool name, and the actionable guidance is 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?
With zero parameters and no output schema, the description carries the return-field documentation itself and does so adequately, plus names the consuming tools. Only the lack of any note on output size or ordering keeps it from being fully 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?
The tool takes no parameters, so the baseline is 4. There is nothing for the description to disambiguate, and it correctly does not invent parameter 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?
States a specific verb and resource ("List all templates") and enumerates the returned fields (ID, name, type, default flag), which clearly separates it from the singular get_template sibling. It falls short of a 5 because it never explicitly names get_template as the single-item alternative.
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?
Gives concrete downstream routing: use the returned IDs with create_campaign, send_transactional_email or update_template. That tells the agent where this tool fits in the workflow, but there is no explicit when-not guidance (e.g. use get_template when you already know the ID).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_subscribersARead-only
List subscribers, newest first, one page at a time. Returns the total subscriber count and each subscriber's name, email, status and list names. Use query to filter with a SQL expression; use get_subscriber_by_email when you already know the address.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, starting at 1 | |
| query | No | Optional SQL condition on the subscribers table, e.g. subscribers.name LIKE '%john%' or subscribers.status = 'blocklisted'. Omit to list everyone | |
| per_page | No | Subscribers per page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint already declaring safety, the description adds real value beyond annotations: results are ordered newest first, returned one page at a time, and include the total subscriber count plus specific fields per record. It omits default page size behavior and what an empty result looks like, but the core operational picture is there.
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?
Three tight sentences: what it returns, how results are ordered/paged, then how to filter and which sibling to prefer instead. Nothing is padded and the most important facts come first.
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?
No output schema exists, so describing the return payload (total count, name, email, status, list names) is exactly the right compensation, and pagination is covered. The remaining gap is the unresolved overlap with get_list_subscribers_tool, which an agent would still have to guess about.
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 descriptions already explain `page`, `per_page`, and give concrete SQL examples for `query`. The description's note about using `query` to filter largely restates the schema rather than adding syntax or constraints, 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?
States a specific verb and resource (list subscribers) plus ordering and pagination behavior, which an agent can act on. It does not, however, distinguish itself from the very similarly named sibling get_list_subscribers_tool, leaving one obvious ambiguity unresolved.
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?
Gives clear routing: use `query` for SQL filtering, and use get_subscriber_by_email when the address is already known. It stops short of mentioning get_subscriber_by_id or get_list_subscribers_tool, so the full alternative set is not covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
regex_replace_in_campaign_bodyADestructive
Replace all matches of a JavaScript regular expression in a campaign's body and save the campaign. Reports how many matches were replaced and changes nothing if there is no match. An invalid pattern returns an error. For plain text use replace_in_campaign_body.
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | JavaScript regular expression source without slashes, applied globally, e.g. https://old\.example\.com | |
| replace | Yes | Replacement text; may use capture groups such as $1 | |
| campaign_id | Yes | Campaign ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=false and readOnlyHint=false; the description adds real value on top by clarifying that the replacement is global, that the campaign is persisted, that a no-match case is a safe no-op, and that an invalid pattern errors out. It stops short of saying the saved mutation is irreversible / has no undo, which is the main remaining behavioral gap for a destructive write.
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?
Four short sentences, front-loaded with the action and the persistence side effect, followed by outcome reporting, error behavior, and the alternative routing. No filler.
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 3-parameter mutation tool with no output schema, the description covers the write side effect, the return signal (count of matches replaced), the zero-match no-op, and the invalid-pattern error path — everything an agent needs to call it and interpret the result.
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 pattern (JS source without slashes, global), replace ($1 capture groups) and campaign_id. The description adds only the implicit confirmation that matching is global, which the schema states anyway — 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?
States a specific verb (replace all matches of a JavaScript regex) applied to a specific resource (a campaign's body) and explicitly notes that the campaign is saved. It also names the sibling it is not (replace_in_campaign_body) for plain-text substitution, so an agent can distinguish it without opening the schema.
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?
Explicitly routes plain-text substitutions to replace_in_campaign_body, which is a clear when-to-use signal. It does not mention the other related sibling batch_replace_in_campaign_body, nor state any exclusion such as when a single-campaign regex edit is the wrong choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_subscriberADestructiveIdempotent
Permanently delete a subscriber and all their list subscriptions. This cannot be undone. To stop mailing someone but keep their record, use change_subscriber_status with 'blocklisted' instead.
| Name | Required | Description | Default |
|---|---|---|---|
| subscriber_id | Yes | Subscriber ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and idempotentHint=true, but the description adds the key detail annotations cannot convey: the delete cascades to all list subscriptions, not just the record. Irreversibility is stated outright, though permission requirements and any confirmation step are not mentioned.
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?
Three sentences, zero waste: the action and its irreversibility come first, then the cascade consequence, then the redirect to the safer sibling. Nothing is buried.
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 mutation with no output schema, the description covers what is destroyed, that it is irreversible, and what to do instead. Nothing an agent needs before calling is 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?
Single required parameter with 100% schema coverage, so the schema already documents subscriber_id fully. The description adds no format, range, or lookup hints beyond that, making the baseline 3 correct.
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?
Specific verb (permanently delete) plus resource (subscriber) and the cascade scope (all their list subscriptions). It also implicitly distinguishes itself from sibling delete_mailing_list/delete_media_file by naming the subscriber domain and from soft-suppression alternatives.
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?
Explicitly names an alternative tool (change_subscriber_status with 'blocklisted') and the exact condition that should route an agent there instead. This is textbook when-to-use/when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rename_mediaADestructiveIdempotent
Change a media file's display title in the media library. The filename and public URL stay the same, so existing links keep working.
| Name | Required | Description | Default |
|---|---|---|---|
| media_id | Yes | Media ID | |
| new_title | Yes | New media title |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare mutation, idempotency, and destructiveness, so the bar is lower, yet the description adds real value by stating that the filename and public URL are untouched and existing links keep working. It doesn't say that the previous title is overwritten or what permissions are required, so it falls short of a 5.
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 short sentences, front-loaded with the action, followed by the consequence that matters. Every sentence earns its place with zero filler.
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 two-parameter mutation with full schema coverage and annotations carrying safety semantics, this is nearly complete: the effect and the non-effects (filename/URL preserved) are covered. The only real gap is the absence of information about overwriting the old title or auth requirements.
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, giving a baseline of 3. The description adds only marginal semantic nuance by framing new_title as the display title rather than the filename.
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 ('Change') and a specific, narrow resource ('a media file's display title in the media library'), and goes on to delimit it from filename/URL changes. An agent can distinguish it cleanly from upload_media_file, delete_media_file, and get_media_list.
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: the note that the filename and public URL stay the same hints at 'rename without breaking links' as the reason to prefer this over re-uploading, but no explicit when-to-use/when-not guidance or named alternative is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
replace_in_campaign_bodyADestructive
Replace every occurrence of a literal text in a campaign's body (case-sensitive, not a regex) and save the campaign. Reports how many replacements were made and changes nothing if the text is not found. For patterns use regex_replace_in_campaign_body; for several replacements in one save use batch_replace_in_campaign_body.
| Name | Required | Description | Default |
|---|---|---|---|
| search | Yes | Exact text to find (case-sensitive, not a regex) | |
| replace | Yes | Text to put in place of every match; may be empty to delete | |
| campaign_id | Yes | Campaign ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the write/destructive/non-idempotent profile, but the description adds real value beyond them: case-sensitive literal matching, a no-op when the search text is absent ('changes nothing if the text is not found'), and that a replacement count is reported. The only gap is not saying whether it edits the HTML source or the plain-text body, which matters for a destructive edit.
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?
Three compact clauses: what it does, its no-match behavior and return signal, then sibling routing. No filler, and the core action is front-loaded ahead of the disambiguation.
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 3-parameter mutation tool with no output schema, the description covers the action, the match semantics, the no-op case, the reported count, and the alternatives. Only the scope of 'body' (HTML vs. text) is left implicit, which is a minor but non-trivial omission for a destructive edit.
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 each parameter is documented inline, so the schema does the heavy lifting. The description's 'literal text (case-sensitive, not a regex)' partially restates the search parameter's own description; it adds no new semantics about campaign_id or the empty-replace deletion case. 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 and resource ('Replace every occurrence of a literal text in a campaign's body ... and save the campaign') and immediately distinguishes itself from regex_replace_in_campaign_body and batch_replace_in_campaign_body. An agent can select it without opening any schema.
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?
Explicitly routes to alternatives by condition: patterns → regex_replace_in_campaign_body, multiple replacements in one save → batch_replace_in_campaign_body. The literal/case-sensitive constraint additionally implies when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
schedule_campaignADestructiveIdempotent
Schedule a campaign to start sending automatically at a future date and time. Nothing is sent now. Use send_campaign to send immediately instead.
| Name | Required | Description | Default |
|---|---|---|---|
| send_at | Yes | Future start time in ISO 8601 format with a timezone, e.g. 2026-12-25T10:00:00Z | |
| campaign_id | Yes | Campaign ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true and destructiveHint=true, so the mutation profile is structured. The description adds genuine value by clarifying the deferred, non-immediate effect, but it never addresses what makes this 'destructive' — e.g. whether an existing scheduled send is overwritten — nor any preconditions such as the campaign having to exist or be unsent. With annotations carrying the safety profile, a 3 is appropriate.
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?
Three short sentences, front-loaded with the action and scope, then the disambiguation. No filler and no restatement of the name.
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 2-parameter tool with full schema coverage, annotations, and no output schema, this covers the essentials: what happens, when to use it, and what not to confuse it with. The remaining gaps are preconditions and state effects (draft-only, overwriting an existing schedule, behavior for past timestamps), which an agent would still have to discover.
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%: send_at is documented with ISO 8601 + timezone and a concrete example, and campaign_id with its type. The description only adds the constraint that the time must be in the future, which is marginal but real value. Baseline 3 is correct 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?
States a specific verb and resource ('Schedule a campaign') plus the outcome semantics ('start sending automatically at a future date and time'), which an agent can map to a distinct operation. It explicitly contrasts with the sibling send_campaign, so the tool is separable from alternatives without opening any schema.
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?
Gives the selecting condition ('future date and time') and names the explicit alternative with its own condition ('Use send_campaign to send immediately instead'). The clarification 'Nothing is sent now' eliminates the main ambiguity an agent would have between the two tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_campaignADestructive
Start sending a campaign to its target lists right now by setting its status to running. This emails real subscribers and cannot be undone, so check get_campaign_preview first. It returns as soon as sending starts and delivery continues in the background; follow progress with get_campaign. To send later use schedule_campaign.
| Name | Required | Description | Default |
|---|---|---|---|
| campaign_id | Yes | Campaign ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as destructive and non-idempotent, and the description adds crucial context beyond them: it emails real subscribers, cannot be undone, returns as soon as sending starts, and continues delivery in the background. It even points to get_campaign for progress, which is exactly the operational detail an agent needs before invoking a destructive send.
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?
Three sentences, front-loaded with the action and its risk. Every sentence adds a distinct operational fact: what it does, that it is irreversible, how it returns, and when to use the alternative.
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 destructive send tool with no output schema, the description covers action, irreversible side effect, async return behavior, monitoring path, precondition, and alternative. Nothing needed to call it safely is 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 coverage is 100% for the single campaign_id parameter, so the schema already documents it. The description implies the campaign defines the target lists but adds no syntax or format detail beyond that. 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 and resource ('Start sending a campaign') and immediately clarifies the mechanism ('by setting its status to running'). It is unmistakable next to siblings such as schedule_campaign and get_campaign_preview.
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?
It explicitly routes the agent: check get_campaign_preview first, and use schedule_campaign to send later. Both the prerequisite and the alternative path are stated, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_transactional_emailADestructive
Send one transactional email right away, using a 'tx' template, to a subscriber that already exists in Listmonk. The email cannot be recalled. data fills the template variables. Create tx templates with create_template (type 'tx').
| Name | Required | Description | Default |
|---|---|---|---|
| data | No | Key/value data for the template, available there as {{ .Tx.Data.<key> }} | |
| template_id | Yes | ID of a template of type 'tx' (see get_templates) | |
| content_type | No | Body format: html, markdown or plain | html |
| subscriber_email | Yes | Email of an existing subscriber to send to |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false. The description adds useful context beyond that: the email is sent immediately and 'cannot be recalled', which clarifies the irreversibility of the side effect. It does not discuss permissions or rate limits, but annotations carry the primary safety signal.
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 three compact sentences, front-loaded with the action and critical constraints. Every sentence contributes useful information, including the template creation pointer, with no filler.
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 send tool with full schema coverage and annotations, the description covers timing, irreversibility, prerequisites, and where to create tx templates. Response and error behavior are not described, but that is minor because no output schema exists.
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 already documents all four parameters, including the nested data object and its template-variable usage. The description only restates that 'data' fills the template variables, adding little semantic detail beyond what the schema provides.
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 and resource: send one transactional email right away. It adds distinguishing constraints ('one', 'right away', 'tx template', 'subscriber that already exists') and explicitly points to create_template for template creation, so an agent can distinguish this from sibling operations.
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?
It gives clear prerequisites: the subscriber must already exist and the template must be of type 'tx'. It also directs users to create_template for creating tx templates. However, it does not explicitly mention send_campaign or schedule_campaign as alternatives for bulk/campaign email, so the exclusion is only implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_campaignADestructiveIdempotent
Update a campaign's name, subject, target lists, body or tags. Only the fields you provide are sent, and the target lists are kept if you omit lists. Use it before sending, because Listmonk may reject edits once a campaign is running. Does not send anything.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | New message content; replaces the whole current body | |
| name | No | Campaign name | |
| tags | No | Tags | |
| lists | No | Full new set of target list IDs; omit to keep the current lists | |
| subject | No | New email subject line | |
| campaign_id | Yes | Campaign ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare it a destructive, idempotent write, and the description adds real context on top: only supplied fields are sent (partial update), omitted `lists` are preserved, and 'Does not send anything' rules out the most dangerous misreading. It does not warn that supplying `body` wholesale overwrites existing content, which matters given destructiveHint=true.
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?
Three short sentences, all load-bearing: capabilities first, update semantics second, timing constraint and non-send guarantee last. Zero filler.
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 6-parameter mutation with full schema coverage and no output schema, the description covers purpose, partial-update behavior, list preservation, timing, and the non-send guarantee. Minor gaps remain (whether tags are replaced or appended), but nothing needed to call it safely is 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 coverage is 100%, so the baseline is 3. The description restates the partial-update rule and the `lists` omission behavior, which largely duplicates what the schema already says ('omit to keep the current lists'), rather than adding new syntax or format detail.
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 and resource ('Update a campaign') and enumerates the mutable fields, so the agent knows exactly what the tool touches. It is clearly distinct from update_subscriber/update_template by resource, but it does not distinguish itself from body-only siblings like replace_in_campaign_body or regex_replace_in_campaign_body.
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?
'Use it before sending, because Listmonk may reject edits once a campaign is running' gives an explicit timing condition that no structured field conveys. It stops short of naming alternatives (replace_in_campaign_body) for the body-only case, so the routing is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_mailing_listADestructiveIdempotent
Update a mailing list's name, type, opt-in mode, tags or description. Only the fields you provide are sent. Existing subscribers are not removed.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | List name | |
| tags | No | List tags | |
| type | No | public or private | |
| optin | No | single or double | |
| list_id | Yes | List ID | |
| description | No | List description |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true and destructiveHint=true. The description adds two genuinely new facts beyond that — partial-update semantics and that subscribers are preserved — which is real value. However, it does not address the tension with destructiveHint=true (what actually gets overwritten, or whether a type change from public to private affects subscribers), leaving the destructive flag unexplained.
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 short sentences with no filler: the first defines scope, the second and third each carry a distinct behavioral guarantee. The most decision-relevant facts are 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 6-parameter mutation tool with full schema coverage, no nested objects and no output schema, the description covers mutation scope, partial-update behavior and subscriber safety. Minor gaps remain: what the response looks like and whether changing type/opt-in affects existing subscribers' status.
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%, so baseline is 3. The description goes slightly beyond by naming the mutable fields in prose and, more importantly, stating that omitted fields are not sent — semantic partial-update behavior the schema alone (which only marks list_id required) does not spell out.
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 (Update) and resource (mailing list) and enumerates the mutable fields (name, type, opt-in mode, tags, description). Sibling differentiation is implicit — the 'existing subscribers are not removed' clause separates it from delete_mailing_list, but no sibling is named explicitly.
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 sentence 'Only the fields you provide are sent' tells the agent how to call it (partial update), which is useful implied guidance, but there is no statement of when to prefer this over update_subscriber or create_mailing_list, and no prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_subscriberADestructiveIdempotent
Update an existing subscriber's email, name, status, list memberships or attributes. Only the fields you provide are sent to Listmonk. When lists or attributes is provided it is sent as the full new value, not merged with the old one. To only change status use change_subscriber_status.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | New name | |
| No | New email | ||
| lists | No | Full new set of mailing list IDs; replaces the current memberships | |
| status | No | New status: enabled, disabled or blocklisted | |
| attributes | No | Full new attributes object; replaces the current attributes | |
| subscriber_id | Yes | Subscriber ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description adds important behavioral context: partial updates only send provided fields, while lists and attributes are replaced rather than merged. It does not discuss return values or error behavior, so it is strong but not exhaustive.
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 front-loaded with the core action and fields, then immediately covers partial-update behavior and the status-only alternative. Every sentence adds useful information with no filler.
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 mutation tool with rich annotations and full schema coverage, the description covers the essential update semantics and sibling routing. It does not describe response shape or failure behavior, which is a minor gap given the absence of an output schema.
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 is 3. The description still adds meaningful semantics beyond the schema by stating that omitted fields are not sent and that lists/attributes are full replacements rather than merges.
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 clearly states the specific action (update) and resource (existing subscriber), and enumerates the updatable fields. It also distinguishes the tool from change_subscriber_status, so an agent can select it without opening the schema.
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?
It explains that only provided fields are sent, clarifies replacement behavior for lists and attributes, and explicitly routes status-only changes to change_subscriber_status. This gives clear when-to-use and when-to-use-an-alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_templateADestructiveIdempotent
Update a template's name, body, default flag or subject. Only the fields you provide are sent, and a provided body replaces the old one completely. For large HTML bodies prefer update_template_from_file.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | New full template HTML; replaces the whole current body | |
| name | No | Template name | |
| subject | No | Subject line (required for 'tx' transactional templates) | |
| is_default | No | Default template flag | |
| template_id | Yes | Template ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, destructiveHint=true, idempotentHint=true), it discloses patch semantics ('only the fields you provide are sent') and that a supplied body fully replaces the old one — the key destructive detail. It doesn't say whether overwritten content is recoverable or what the response 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?
Three short sentences with zero waste; the field list and the replacement caveat are front-loaded, and the sibling pointer comes last where it belongs.
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 five-parameter mutation tool with fully documented schema and no output schema, the description covers scope, patch semantics, and the large-body alternative. Only minor gaps remain, such as the subject requirement being deferred entirely to the schema 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 coverage is 100%, so the baseline is 3, but the description adds non-schema meaning: partial-update behavior (unspecified fields are left untouched) and the all-or-nothing nature of body. The body-replacement phrasing partially duplicates the schema, hence not a 5.
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 (update) and resource (template) plus the exact updatable fields (name, body, default flag, subject). It also names the sibling update_template_from_file, so the agent can distinguish it from the closest alternative without opening a schema.
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?
Explicitly routes the agent to update_template_from_file when the body is large HTML, which is real when-to-use guidance. It doesn't cover when to prefer update_template over delete_template/create_template or mention prerequisites, so it stops short of full routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_template_from_fileADestructiveIdempotent
Update an existing template, replacing its HTML body with the contents of a UTF-8 file inside LISTMONK_MCP_FILES_DIR. Otherwise identical to update_template. Fails if LISTMONK_MCP_FILES_DIR is not set or the path is outside it.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Template name | |
| subject | No | Subject line (required for 'tx' transactional templates) | |
| file_path | Yes | Path to the template HTML file inside LISTMONK_MCP_FILES_DIR (absolute or relative to it) | |
| is_default | No | Default template flag | |
| template_id | Yes | Template ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the description's job is to add context — and it does: the body is replaced wholesale, input must be UTF-8, and the call fails if LISTMONK_MCP_FILES_DIR is unset or the path escapes it. That sandbox/precondition detail is real value beyond the annotations. It does not discuss what happens to unspecified fields or the response, but the delegation to update_template covers that reasonably.
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?
Three short sentences, leading with what it does, then the sibling equivalence, then the failure conditions. Nothing repeats the schema and no sentence is filler.
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 with full schema coverage and annotations carrying the safety profile, the description supplies the preconditions and input-format constraints an agent needs to call it successfully. The only gap is how non-body fields are handled when omitted, which is pushed onto update_template rather than stated here.
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%, so every parameter including file_path's 'inside LISTMONK_MCP_FILES_DIR (absolute or relative)' wording is already documented. The description only adds the UTF-8 encoding constraint and the directory restriction, which is marginal on top of the schema. 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?
Names a specific verb and resource (update a template) plus the exact mechanism that separates it from the sibling create/update tools: the HTML body comes from a UTF-8 file in LISTMONK_MCP_FILES_DIR. The phrase 'Otherwise identical to update_template' explicitly positions it relative to the closest sibling, so an agent can distinguish them without opening either schema.
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 file-based mechanism implicitly tells the agent when to pick this over update_template, and the sibling is named for comparison. It also states the failure preconditions (env var unset, path outside the directory). It stops short of an explicit 'use update_template instead when you have inline HTML', so it is clear but not fully prescriptive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upload_media_fileA
Upload a file from LISTMONK_MCP_FILES_DIR to the Listmonk media library and return its ID and public URL for use in campaign bodies. Fails if LISTMONK_MCP_FILES_DIR is not set or the path is outside it. Image types (jpg, png, gif, webp, svg) get the right MIME type; other types upload as generic binary and Listmonk may reject them.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | Display title in the media library; defaults to the filename | |
| file_path | Yes | Path to the media file inside LISTMONK_MCP_FILES_DIR (absolute or relative to it) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (mutation, non-idempotent, non-destructive), it discloses real behavioral traits: a filesystem sandbox constraint, the failure mode when the path escapes it, and MIME-type handling with the caveat that non-image types are sent as generic binary and may be rejected by Listmonk. It does not address what happens on repeat uploads of the same path (duplicate vs. overwrite), which is the main remaining gap.
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?
Three dense sentences with zero filler: purpose and returns first, constraints second, type-handling caveat last. Every clause carries actionable 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 2-parameter tool with full schema coverage and no output schema, the description covers purpose, return values (ID and public URL), the directory precondition, and the file-type limitation an agent needs to avoid a failed upload. Nothing material is 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%, so both parameters are already documented, giving a baseline of 3. The description reinforces the sandbox constraint on file_path but never mentions the title parameter or its filename default, adding only marginal meaning 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?
States a specific verb and resource ("Upload a file ... to the Listmonk media library") and names the concrete outputs (ID and public URL) plus the downstream use (campaign bodies). It is clearly distinguishable from siblings like get_media_list, rename_media, and delete_media_file.
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?
Establishes the operating context: the file must live under LISTMONK_MCP_FILES_DIR, and it fails if that variable is unset or the path escapes the directory. It does not name an alternative sibling or state when not to use this versus another upload path, so it stops short of explicit routing.
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.
17 tool updates
v0.1.1- Changed
add_subscriber4 fields changed- changed
Input schema / properties / attributes / descriptionPrevious value: -"Custom subscriber attributes"New value: +"Free-form JSON object stored with the subscriber, e.g. {\"city\": \"Berlin\"}" - changed
Input schema / properties / lists / descriptionPrevious value: -"Mailing list IDs"New value: +"IDs of the mailing lists to subscribe them to (see get_mailing_lists); empty means no lists" - changed
Input schema / properties / preconfirm / descriptionPrevious value: -"Whether to preconfirm subscriptions"New value: +"If true, subscriptions to double opt-in lists are marked confirmed and no confirmation email is sent" - changed
Input schema / properties / status / descriptionPrevious value: -"Subscriber status (enabled, disabled, blocklisted)"New value: +"enabled (can receive mail), disabled, or blocklisted (never mailed)"
- Changed
batch_replace_in_campaign_body2 fields changed- changed
Input schema / properties / replacements / descriptionPrevious value: -"Replacement operations"New value: +"Search/replace pairs applied in order; each search is a literal, case-sensitive text" - changed
Input schema / properties / replacements / items / properties / search / descriptionPrevious value: -"Search text"New value: +"Exact text to find"
- Changed
create_campaign6 fields changed- changed
Input schema / properties / body / descriptionPrevious value: -"Campaign body"New value: +"Message content in the chosen content_type; can also be added later with update_campaign" - added
Input schema / properties / content_type / descriptionAdded value: +"Format of body: richtext, html, markdown or plain" - changed
Input schema / properties / lists / descriptionPrevious value: -"List IDs"New value: +"IDs of the mailing lists to send to, at least one (see get_mailing_lists)" - changed
Input schema / properties / tags / descriptionPrevious value: -"Campaign tags"New value: +"Labels for organising campaigns" - changed
Input schema / properties / template_id / descriptionPrevious value: -"Template ID"New value: +"Layout template that wraps the body (see get_templates); omit to use the default campaign template" - added
Input schema / properties / type / descriptionAdded value: +"regular (normal campaign) or optin (asks subscribers to confirm a double opt-in subscription)"
- Changed
create_mailing_list4 fields changed- added
Input schema / properties / description / descriptionAdded value: +"Short description of the list" - added
Input schema / properties / optin / descriptionAdded value: +"single (subscribed at once) or double (subscriber must confirm by email)" - added
Input schema / properties / tags / descriptionAdded value: +"Labels for organising lists" - added
Input schema / properties / type / descriptionAdded value: +"public (can appear on subscription forms) or private (internal only)"
- Changed
create_template1 field changed- changed
Input schema / properties / body / descriptionPrevious value: -"Template HTML body"New value: +"Full template HTML. A 'campaign' template must contain {{ template \"content\" . }} where the campaign body goes"
- Changed
get_campaigns3 fields changed- changed
Input schema / properties / page / descriptionPrevious value: -"Page number"New value: +"Page number, starting at 1" - changed
Input schema / properties / per_page / descriptionPrevious value: -"Items per page"New value: +"Campaigns per page" - changed
Input schema / properties / status / descriptionPrevious value: -"Filter by status"New value: +"Only campaigns with this status: draft, scheduled, running, paused, cancelled or finished. Omit for all"
- Changed
get_list_subscribers_tool2 fields changed- added
Input schema / properties / page / descriptionAdded value: +"Page number, starting at 1" - added
Input schema / properties / per_page / descriptionAdded value: +"Subscribers per page"
- Changed
list_subscribers3 fields changed- changed
Input schema / properties / page / descriptionPrevious value: -"Page number"New value: +"Page number, starting at 1" - changed
Input schema / properties / per_page / descriptionPrevious value: -"Items per page"New value: +"Subscribers per page" - changed
Input schema / properties / query / descriptionPrevious value: -"Optional query string"New value: +"Optional SQL condition on the subscribers table, e.g. subscribers.name LIKE '%john%' or subscribers.status = 'blocklisted'. Omit to list everyone"
- Changed
regex_replace_in_campaign_body2 fields changed- changed
Input schema / properties / pattern / descriptionPrevious value: -"Regex pattern"New value: +"JavaScript regular expression source without slashes, applied globally, e.g. https://old\\.example\\.com" - changed
Input schema / properties / replace / descriptionPrevious value: -"Replacement pattern"New value: +"Replacement text; may use capture groups such as $1"
- Changed
replace_in_campaign_body2 fields changed- changed
Input schema / properties / replace / descriptionPrevious value: -"Replacement text"New value: +"Text to put in place of every match; may be empty to delete" - changed
Input schema / properties / search / descriptionPrevious value: -"Search text"New value: +"Exact text to find (case-sensitive, not a regex)"
- Changed
schedule_campaign1 field changed- changed
Input schema / properties / send_at / descriptionPrevious value: -"ISO datetime string (for example: 2024-12-25T10:00:00Z)"New value: +"Future start time in ISO 8601 format with a timezone, e.g. 2026-12-25T10:00:00Z"
- Changed
send_transactional_email4 fields changed- changed
Input schema / properties / content_type / descriptionPrevious value: -"Content type"New value: +"Body format: html, markdown or plain" - changed
Input schema / properties / data / descriptionPrevious value: -"Template data"New value: +"Key/value data for the template, available there as {{ .Tx.Data.<key> }}" - changed
Input schema / properties / subscriber_email / descriptionPrevious value: -"Recipient email"New value: +"Email of an existing subscriber to send to" - changed
Input schema / properties / template_id / descriptionPrevious value: -"Template ID"New value: +"ID of a template of type 'tx' (see get_templates)"
- Changed
update_campaign3 fields changed- changed
Input schema / properties / body / descriptionPrevious value: -"Body"New value: +"New message content; replaces the whole current body" - changed
Input schema / properties / lists / descriptionPrevious value: -"List IDs"New value: +"Full new set of target list IDs; omit to keep the current lists" - changed
Input schema / properties / subject / descriptionPrevious value: -"Subject"New value: +"New email subject line"
- Changed
update_mailing_list2 fields changed- changed
Input schema / properties / optin / descriptionPrevious value: -"Opt-in type"New value: +"single or double" - changed
Input schema / properties / type / descriptionPrevious value: -"List type"New value: +"public or private"
- Changed
update_subscriber3 fields changed- changed
Input schema / properties / attributes / descriptionPrevious value: -"New subscriber attributes"New value: +"Full new attributes object; replaces the current attributes" - changed
Input schema / properties / lists / descriptionPrevious value: -"New list IDs"New value: +"Full new set of mailing list IDs; replaces the current memberships" - changed
Input schema / properties / status / descriptionPrevious value: -"New status"New value: +"New status: enabled, disabled or blocklisted"
- Changed
update_template1 field changed- changed
Input schema / properties / body / descriptionPrevious value: -"Template body"New value: +"New full template HTML; replaces the whole current body"
- Changed
upload_media_file1 field changed- changed
Input schema / properties / title / descriptionPrevious value: -"Title"New value: +"Display title in the media library; defaults to the filename"
36 tool updates
- First observed
add_subscriber - First observed
batch_replace_in_campaign_body - First observed
change_subscriber_status - First observed
check_listmonk_health - First observed
create_campaign - First observed
create_mailing_list - First observed
create_template - First observed
create_template_from_file - First observed
delete_mailing_list - First observed
delete_media_file - First observed
delete_template - First observed
get_campaign - First observed
get_campaign_preview - First observed
get_campaigns - First observed
get_list_by_id - First observed
get_list_subscribers_tool - First observed
get_mailing_lists - First observed
get_media_list - First observed
get_subscriber_by_email - First observed
get_subscriber_by_id - First observed
get_template - First observed
get_templates - First observed
list_subscribers - First observed
regex_replace_in_campaign_body - First observed
remove_subscriber - First observed
rename_media - First observed
replace_in_campaign_body - First observed
schedule_campaign - First observed
send_campaign - First observed
send_transactional_email - First observed
update_campaign - First observed
update_mailing_list - First observed
update_subscriber - First observed
update_template - First observed
update_template_from_file - First observed
upload_media_file
TDQS
Scored across 36 tools
Most tools target clearly distinct resources and actions, with helpful cross-references in descriptions (e.g. get_subscriber_by_id vs get_subscriber_by_email, send_campaign vs schedule_campaign). The main overlaps are the three campaign-body replacement variants and the file-based template creation/update variants, but each is explicitly differentiated.
The set predominantly follows a verb_noun convention (add_subscriber, update_campaign, delete_template), with mostly snake_case names. Minor deviations exist: listing uses both 'get' (get_mailing_lists, get_media_list) and 'list' (list_subscribers), and get_list_subscribers_tool has an inconsistent '_tool' suffix.
At 36 tools, the surface is quite large for one MCP server and exceeds the typical well-scoped range. While the domain is broad (subscribers, lists, campaigns, templates, media), several tools are close variants, making the set heavier than necessary.
Core newsletter workflows are well covered: subscriber and list CRUD, campaign creation/preview/send/schedule, template CRUD with file-based variants, transactional email, and media management. A few lifecycle gaps remain, such as campaign deletion or duplication and broader subscriber import/bulk operations, but agents can work around these.
Maintenance
Related MCP Connectors
Official remote MCP server of MailSenpai, the EU-hosted email marketing platform. Connect Claude, ChatGPT, Cursor or another MCP client with OAuth 2.1 and PKCE. 74 tools manage lists, subscribers, segments, templates, draft campaigns and stats, and check email DNS, blacklists and spam. Sends and deletions require explicit confirmation; every call is logged. The same team also offers SMTP Senpai, an SMTP relay and email API for transactional sending: https://en.mailsenpai.com/smtp-senpai/.
MCP server for Lemon Squeezy — stores, products, orders, subscriptions, license keys.
Email API + newsletters. 17 MCP tools. OAuth 2.1 PKCE or API key. EU-hosted (Hetzner + SES).
MCP server for Nylas — read email, calendars, events and contacts, and send email or create events.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server implementation that enables AI assistants to interact with Listmonk instances, providing programmatic access to newsletter and mailing list management functionality including subscriber, list, and campaign operations.43MIT
- AlicenseAqualityDmaintenanceMCP server for Sendook - an AI email communication platform. Enables AI agents to send and receive emails, manage inboxes, threads, and webhooks programmatically.16MIT
- FlicenseDqualityAmaintenanceEnables AI agents to manage Listmonk email campaigns, subscribers, lists, and analytics through typed MCP tools with production safety features.37254 PyPI2-
- AlicenseNot gradedqualityBmaintenanceMCP server for the big-mailer self-hosted email platform, exposing 93 tools to manage subscribers, consent, sequences, broadcasts, segments, and Stripe reconciliation via natural language.10MIT