Skip to main content
Glama
dragosh29

Engaging Networks MCP server

by dragosh29

Engaging Networks MCP server

An MCP server that lets Claude, ChatGPT and other MCP clients work with an Engaging Networks (ENS) account: campaign pages, supporters, their transaction history and recurring gifts, supporter fields and questions, and marketing automation statistics, and (when enabled) updating a supporter's opt-ins. It is built from Engaging Networks' public developer documentation: the OpenAPI 3.1 document "Engaging Networks Services REST API" v6.5.0 at developer.engagingnetworks.net/api/rest/engagingnetworks.app.json, and the knowledge-base pages on the REST services.

Once it's connected, someone at the organisation can ask things like:

  • "Which donation pages are live right now, and which petitions have we closed?"

  • "Is otto.nv@example.com still opted in to email? Is he a member?"

  • "What has supporter 212200 done with us: gifts, petitions, events? Does he have a monthly gift running?"

  • "Who signed up in the last week?" / "Find supporters called Bob in the UK or US."

  • "How is the welcome journey doing this year: open rate, donations, unsubscribes?"

  • With writes enabled: "Otto asked by phone to stop texts: opt him out of SMS."

Tools

Tool

What it does

API calls

list_pages

Campaign pages of one type (nd donation, pet petition, ev event, dcf data capture, survey, et email to target, mem membership and the other documented types), optionally with one status (new, live, close, tested, block, delete).

GET /page

get_page

One page: type, subtype, status, locale, base URL, template, tracking parameters, attributes.

GET /page/{id}

find_supporter

One supporter by email address or supporter ID: ID, suppression flag, name, and optionally question and opt-in answers and memberships. Every other field only on request (see Safety defaults). The supporter field list is fetched once per session to recognise name fields.

GET /supporter or GET /supporter/{supporterId}, GET /supporter/fields

query_supporters

The API's supporter queries: latestCreated, latestModified (with daysBack 1-32), suppressed, profile (with profileId) and search (with a filter such as firstName:Bob~country:GB||US). Returns supporter IDs with created and modified dates, paged 100 at a time.

GET /supporter/query

get_supporter_transactions

A supporter's history (donations, event tickets, petition signatures, emails to targets, data captures, email broadcasts, peer-to-peer) with page names, dates and statuses, plus their recurring schedules (amount, currency, frequency, status, next payment date). The history list has no amounts; only the recurring schedules do. max_results (default 100) caps each list, with counts and totals.

GET /supporter/{supporterId}/transactions, GET /supporter/{supporterId}/transactions/recurring

list_supporter_fields

The account's supporter fields: name, tag and standard property.

GET /supporter/fields

list_supporter_questions

Questions and opt-ins with their type (OPT, CONF for double opt-in, GEN). At most max_results (default 100), with the total.

GET /supporter/questions

get_supporter_question

How one question is presented per locale: label, field type, answer options or range. At most 50 locales and max_options (default 100) options per locale, with the totals.

GET /supporter/questions/{id}

list_marketing_automations

Marketing automations with status, filtered by dashboard folder (the API defaults to the Home folder) and part of the name. At most max_results (default 100), with the total.

GET /ma

get_marketing_automation

One automation and its statistics (journey starts, open and click rates, actions, donations, objective reached, unsubscribes, SMS delivery rate, jumps), optionally for a range of months.

GET /ma/{id}, GET /ma/{id}/stats

update_supporter_opt_ins

Sets named opt-ins to Y or N for one supporter and changes nothing else. The names are checked against the account's questions first: general questions are refused, and so is setting a double opt-in (CONF) question to Y. Writes only.

GET /supporter/questions, PUT /supporter/{supporterId}

Authentication uses POST /authenticate (see Setup).

Not covered on purpose: page processing (donations, actions and card payments through /page/{id}/process), survey responses (the response schema and the example for GET /page/{id}/survey disagree on its shape), single-transaction detail (GET /supporter/{supporterId}/transactions/{transactionId} takes the payment gateway's transaction ID, which the history list does not return, and answers with card digits and expiry), page components, import formats, creating, updating or deleting supporters beyond opt-ins, bulk suppression, origin sources, migrating or changing recurring gifts, export jobs and their downloads, adding supporters to automations in bulk, the audit log, and the token validation and retirement endpoints.

Related MCP server: NewZapp MCP server

Setup

Requires Node 18 or later.

npm install
npm run build

You need the token of an API User. An administrator of your Engaging Networks account creates the API user in the dashboard, gives it permissions (for example view permission on supporter data), and whitelists the IP address of the machine this server runs on. The server posts that token to /authenticate, receives a session token, and sends it in the ens-auth-token header of every other call. The session token is cached, renewed a minute before its documented expiry, and fetched again once if a call answers 401 "Invalid ens-auth-token".

Claude Desktop: add this to claude_desktop_config.json:

{
  "mcpServers": {
    "engagingnetworks": {
      "command": "node",
      "args": ["/absolute/path/to/engagingnetworks-mcp/dist/index.js"],
      "env": { "ENGAGINGNETWORKS_API_TOKEN": "your-api-user-token", "ENGAGINGNETWORKS_REGION": "ca" }
    }
  }
}

Claude Code:

claude mcp add engagingnetworks -e ENGAGINGNETWORKS_API_TOKEN=your-api-user-token -e ENGAGINGNETWORKS_REGION=ca -- node /absolute/path/to/engagingnetworks-mcp/dist/index.js

Variable

Required

Meaning

ENGAGINGNETWORKS_API_TOKEN

yes

The API User token.

ENGAGINGNETWORKS_REGION

no

The datacentre your account is on, from the spec's server list: ca (Canada / Europe, https://ca.engagingnetworks.app/ens/service, the default), us (https://us.engagingnetworks.app/ens/service) or us2 (https://us2.engagingnetworks.app/ens/service).

ENGAGINGNETWORKS_BASE_URL

no

Overrides the region's base URL. Used by the tests.

ENGAGINGNETWORKS_ALLOW_WRITES

no

true to register update_supporter_opt_ins. Off by default.

Safety defaults

  • Read-only unless ENGAGINGNETWORKS_ALLOW_WRITES=true. Read tools carry the MCP readOnlyHint annotation; update_supporter_opt_ins is marked as a write that is not destructive and is idempotent. There is no tool that sends email, processes a page or a payment, or deletes anything.

  • Supporter records come back with the account's own field names as keys. By default find_supporter returns the supporter ID, the suppression flag, the name fields (title, first, middle and last name, recognised through /supporter/fields by field name or tag), opt-in and question answers when asked for, and memberships when asked for. Every other field (email address, phone numbers, postal addresses, date of birth, appeal code and custom fields) is withheld and only its name is listed; include_contact_details returns them as stored.

  • Card and bank data are never returned, with or without include_contact_details: fields whose standard property is a card holder name, bank account number, routing number, bank account type or password are dropped and only counted, and so is any field whose name or tag, split into words (_, - and . as separators, camelCase split, so ccExpiry reads as "cc Expiry"), contains the word card or cards, credit card, cc followed by num, number, no, exp, expiry, expiration, cvv, cvc, holder or type, expiry or expiration, token, mandate, debit, CVV/CVC, bank, IBAN, BIC, SWIFT, sort code, routing, account number, no or type, PayPal, billing agreement, password, PAR, BIN, or last 4 / last four. This errs towards dropping: a custom "Membership Expiry" field is dropped too (the memberships list carries the term dates). A payment field named in some other way is not recognised by its name. A card number typed into any returned text (13 to 19 digits passing the Luhn check) is replaced by [card number redacted], also on request. Recurring schedules never include the payment gateway's transaction ID (which embeds the processor's customer reference), and the endpoint that answers with card digits and expiry (single-transaction detail) is never called.

  • In free text (question answers of every type, supporter, peer-to-peer and member names, email-to-target targets, recurring-gift change reasons, page names and titles, and Engaging Networks' own error messages) email addresses (also URL-encoded, name%40example.org) become [email redacted], phone-number-like sequences [phone redacted] and postcodes [postcode redacted] by default. Question answers are redacted whatever their type says; the opt-in values Y, N, P and D are unchanged by it. Page names and titles are always redacted (the page tools have no switch). query_supporters returns email addresses only on request, and get_supporter_transactions returns a peer-to-peer fundraiser's email only on request. The free-text redaction is pattern matching, not a guarantee:

    • phone numbers: international numbers written with + or 00; UK numbers with a bracketed area code and UK-style 0… numbers of 9 to 11 digits (other digit strings starting with 0 are redacted too); North American numbers as (613) 555-0142, 613-555-0142, 613.555.0142, 613 555 0142, optionally after 1 (1-800-555-0199). Ten digits written without separators are not recognised.

    • postcodes, in capitals: UK (EC1M 5PX), Canadian (K1A 0A2, K1A0A2), US ZIP+4 anywhere (20500-0003), and a five-digit ZIP only directly after a US state code (DC 20500, Washington, DC 20500; Idaho's ID is left out, since "ID 12345" is usually an identifier). A lone five-digit number is left alone.

    • street addresses and dates typed into free text (for example "24 Sussex Dr" or "born 04/12/1980") are not recognised.

  • The API user token and the session token are scrubbed from any text passed on: the spec's own 401 example for /authenticate echoes the token it was given ("Invalid api key [...]").

  • IDs are checked before any call is made: page, supporter, question, profile and automation IDs must be positive integers (the spec types them all as integers), months must be YYYYMM with the start not after the end, a profile query needs profile_id and a search query needs filter (as the spec says).

  • update_supporter_opt_ins fetches the account's questions first and refuses, without writing anything, a name that is not a question, a general question, a name given twice, or a double opt-in (CONF) question set to Y, which would skip the supporter's own confirmation step. The body is { "questions": { "<opt-in name>": "Y" | "N" } }, the shape of the spec's "Update the supporters contact preferences" example, and holds no other field.

  • Lists the API returns whole are capped: list_pages, list_supporter_questions, list_marketing_automations and both lists of get_supporter_transactions return at most max_results entries (default 100, at most 1000) and say how many there are in total; get_supporter_question returns at most 50 locales and max_options options per locale. query_supporters returns at most max_results supporters and says which start to continue from; if the API returns more rows than were asked for, the continuation starts at the first row that was cut.

  • Rate limits, as documented: 5,000 requests per hour per API User, and 200 page-processing requests per 5 minutes from one IP address (this server does no page processing); beyond these limits requests are blocked. The spec documents running out of the hourly allowance as a 401 with the message "... has exceeded its api limit.", not as a 429: that answer is reported as a used-up allowance, and no new session is requested for it. Requests are spaced 200 ms apart; the hourly allowance is not counted locally, because other integrations using the same API user share it. Each query_supporters page is one request of up to 100 rows.

  • The spec documents no 429. One is still retried at most twice for any method, including the PUT, on the assumption that a rate-limited request was not processed (see Status). The retry waits for Retry-After (whole or fractional seconds, or an HTTP-date; 2 s then 4 s when the header is absent). Each wait is capped at 10 seconds; if a longer wait is asked for the call gives up at once and says how long to wait.

  • 502, 503 and 504 are retried the same way for GET and for POST /authenticate only; when all three attempts fail the error says the service may be unavailable, without the gateway's HTML. The PUT /supporter/{supporterId} is never retried after a gateway error, because it may already have been applied; the error says to check with find_supporter first.

  • A 200 whose body is not JSON (a proxy or a login page in the way) is reported as an error naming the region and base URL settings, never as an empty list; the excerpt goes through the redaction first.

Tests

npm test

The test suite:

  1. Validates every fixture record against the response schemas in the ENS OpenAPI document (pages and page details, supporter fields, questions and question details, supporter records by email and by ID, supporter query rows, transactions, recurring schedules, automations and automation stats). The spec is downloaded from developer.engagingnetworks.net to spec.json on the first run. Three Ajv settings work around defects in the document: unicodeRegExp: false (the locale pattern ^[a-z]{2,3}\-[A-Z]{2}$ is invalid as a Unicode regular expression), validateSchema: false (some schemas give examples as an object) and strict: false (OpenAPI keywords). Two schema defects are handled explicitly and asserted: the supporter schemas' questions[].response pattern rejects Y, N and any punctuation, including the spec's own getSupporterByEmail example and the pattern's own example value, so fixtures are validated against a copy without that one pattern; and the page subType schema rejects the empty string the spec's page examples use, so the fixtures omit subType instead. The transaction list schema is an anyOf of objects with nothing required, so each transaction fixture is also checked for the keys of the spec's example of its type. Peer-to-peer payments (ppay, pacs, pacr) are mapped by the spec's discriminator to transactionP2Pdonation, but every transaction schema's own type enum leaves those values out, and that schema's campaignId and status are oneOfs that any ordinary value matches more than once; the ppay fixture is validated against its properties with those two read as anyOf, and each defect is asserted. Negative controls check that the schemas reject an undocumented page type and recurring frequency.

  2. Starts a local mock of the API under /ens/service that implements POST /authenticate (the API user token as the raw body or as a JSON-quoted string, since the spec can be read either way, answering 401 with the documented "Invalid api key [...]" body, messageId 10000000, for a wrong one), GET and DELETE /authenticate/{ens-auth-token}, the ens-auth-token check with the documented 401 "Invalid ens-auth-token", the documented type and status page filters, the five supporter query types with start/rows paging, daysBack, profileId and filter, the folderId and name automation filters, and the opt-in update. It answers the first GET /ma with a 429. Its authentication, list, record, update and error responses are validated against the documented schemas; the 404 body (the spec documents no 404) is checked against the documented { message } error shape.

  3. Starts the built server and drives it over stdio with the official MCP client: 31 checks covering tool annotations; the first call's POST /authenticate with the raw token body (asserted as the reading this client implements, not as conformance) and JSON content type, then reuse of the session token; list_pages passing type and status exactly, with name and title redaction (UK and North American phone numbers, Canadian postcodes, ZIP codes) and max_results; get_page; find_supporter by email and ID with names only by default, the renamed middle-name field recognised through /supporter/fields, the withheld field names, includeQuestions and includeMemberships sent only when asked, redaction of emails, UK phone numbers and postcodes in answers and names, and of North American phone numbers, Canadian postcodes and ZIP codes in a supporter's name and general answer; answers with an undocumented type (GEN, lower case, none) redacted too; every field returned with include_contact_details except the five card, bank, password and PayPal fields of the spec's example, five custom payment fields (a token, cc_num_last4, a card expiration date, ccExpiry, a direct debit mandate) and a Luhn-valid card number typed into a custom field; unknown emails (404, or 200 without a supporter) as "not found"; query_supporters paging at start 0, 100 and 200 up to the documented total of 253 and stopping, with requests at least 190 ms apart (the 200 ms spacing), continuing from start, a correct continuation when the API returns more rows than asked for, an echoed filter in an error message with its URL-encoded email and phone number redacted, and passing daysBack, profileId and filter through exactly, with the profile and search requirements refused locally; get_supporter_transactions with every documented transaction shape, seconds and milliseconds timestamps, recurring schedules without the gateway reference, the P2P email only on request, max_results capping the recurring schedules too, page names and a North American change reason redacted, and a ppay payment keeping its site ID; the question tools, and the caps on questions, question options and locales, and automations; the automation tools after a 429 retry that waits for Retry-After, with folderId, name, startMonth and endMonth passed through and bad month ranges refused locally; the opt-in update's body validated against the documented PUT /supporter/{supporterId} request schema and its local refusals; invalid IDs and out-of-range max_results / max_options refused before any request, and the 404 message; the session token scrubbed from an error the API echoes it in; four concurrent calls on an expired session sharing one POST /authenticate; a retired session replaced once and the call retried; a short-lived session renewed before it expires; the documented usage-limit 401 on a data call (no new session) and on /authenticate; a persistent 429 giving up after three attempts and a Retry-After above the cap giving up at once; HTTP-date and fractional Retry-After; a GET failing three times with 503, a 502 retried on a GET and on POST /authenticate and never on the PUT; a non-JSON 200 and a 200 from /authenticate without a token; the write gate with the variable unset and set to false; a wrong API token giving an actionable message with the echoed token scrubbed; and that every request used a documented method and path, with the raw token only on POST /authenticate and a mock-issued ens-auth-token on everything else.

The suite runs in about 35 seconds.

Status

This is a working prototype. It has not been run against the live API, because it was built without an Engaging Networks account (the company offers no trial or sandbox that we could find). Everything below is taken from the published spec and knowledge base and should be confirmed on a real account:

  • The body of POST /authenticate. The spec types it as a JSON string under application/json; the knowledge base says to put "the token in the body". This server sends the token as the raw body, without JSON quotes. If the API expects a JSON-encoded string ("..."), that is a one-line change. The mock accepts both forms, so the tests do not settle this.

  • The session lifetime: expires is documented in milliseconds (example 3,600,000, one hour), and an expired or retired session is assumed to answer 401 "Invalid ens-auth-token".

  • Which datacentre a UK account is on. The default region is ca (the first server in the spec, labelled "Canada / Europe").

  • What GET /supporter?email= answers for an address that is not on the account, and what any endpoint answers for an unknown ID: the spec documents only 200 and 401 (and a 204 for single-transaction detail). The server treats a 404, or a 200 without supporterId, as "not found".

  • Whether supporter record keys are the account's field names or its tags. The spec's examples use names such as "Email Address" and "First Name", which are both in its fields example; the server matches either.

  • The real values in questions[].response (the spec's example is Y, while its schema's pattern forbids it), and whether general answers are returned in full. Every answer goes through the redaction whatever its type, so this does not affect what is withheld.

  • Peer-to-peer payment transactions (ppay, pacs, pacr): the spec's discriminator maps them to a schema with siteId, but the type enums leave them out; the server reads site_id from any transaction that has one.

  • Whether a real page list carries subType: "" for pages without a subtype, as the spec's examples do; the server treats an empty subtype as none.

  • The start parameter of GET /supporter/query. The parameter's example is 0 and the server treats it as the 0-based index of the first row, but the response example shows "start": 1 for a one-row result. If it is 1-based, the paging offset is one row out. Also to confirm: what rows above 100 does, whether a page can hold more rows than asked for (handled, but not observed), which query types honour daysBack, and the sort order of each query type.

  • The filter syntax of search queries is passed on exactly as given; which field names it accepts (the example uses firstName and country) is not documented beyond that example.

  • GET /supporter/questions/{id}: whether {id} is the question's id or its questionId (the list returns both; the detail example uses id).

  • GET /ma without folderId: documented as defaulting to the Home folder, so automations in other folders need folder_id. Whether the name filter is case-sensitive is not documented; the mock matches case-insensitively.

  • createdDate in the transaction list: the spec's examples mix seconds (1519918699) and milliseconds (1424408400000); values below 10^11 are read as seconds. createdOn (for example "01/03/2018") is passed on as a string because the day/month order is not documented.

  • The transaction history list carries no amounts; single-gift amounts are only in the per-transaction detail, which needs the gateway's transaction ID that the list does not return. Confirm whether the list on a real account includes more than the spec shows.

  • PUT /supporter/{supporterId} with only a questions object: that it changes only those opt-ins, that questions are keyed by their dashboard name, and what it answers for an unknown name (the documented 400 "The following fields are not present in the account" belongs to POST /supporter).

  • A 429 on the PUT is retried on the assumption that a rate-limited request was not processed; the spec documents no 429 at all.

  • Which API user permissions each endpoint needs, and what a missing permission looks like (a 403 is assumed and reported as a permission problem; it is not documented).

  • The statistics' month range: whether startMonth and endMonth are inclusive and what the defaults are.

find_supporter cannot search by name; query_supporters with type search and a filter on name fields is the documented way.

Going to production

This version runs locally over stdio, with the API user's own token, and the machine it runs on must be whitelisted for that API user. For organisations to connect from claude.ai or ChatGPT without handling tokens, the next step is a remote server (Streamable HTTP) behind OAuth, hosted by Engaging Networks, and then a listing in the Claude and ChatGPT connector directories.

Licence

MIT. Built by Alexandru Dragoș (alexandru.dragos96@gmail.com) with an AI agent (Claude) working under his direction.

Available Tools

10 tools
find_supporterFind a supporterA
Read-only

Look up one supporter by email address or by supporter ID. Returns the supporter ID, whether they are suppressed (excluded from email), their name, and optionally their question and opt-in answers and memberships. The email, phone, postal address, date of birth and every other supporter field are only returned with include_contact_details; card and bank fields are never returned. Emails, phone numbers and postcodes typed into names and answers are redacted by pattern unless include_contact_details is set.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailNoThe supporter's email address
supporter_idNoSupporter ID (numeric)
include_questionsNoInclude question and opt-in answers (the API's includeQuestions)
include_membershipsNoInclude memberships (the API's includeMemberships)
include_contact_detailsNoInclude every supporter field (email, phone, address, date of birth, custom fields) and stop redacting contact details from names and free-text answers

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint and openWorldHint; the description goes substantially beyond them by disclosing exactly which fields are returned by default, that email/phone/address/DOB require include_contact_details, that card and bank fields are never returned, and that contact-pattern redaction is applied unless contact details are requested. This is exactly the kind of non-obvious behavioral context an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, none wasted: lookup key first, then default return set, then the gating flag, then the redaction caveat. Dense but front-loaded. Slightly long, and the return-value detail could be tightened, but every sentence carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 carries the burden of explaining return values and field gating, and it does so thoroughly. The remaining gap is the absence of any statement about required inputs (0 required params) or error behavior when neither email nor supporter_id is provided.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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, but the description adds real meaning the schema lacks: it explains the concrete effect of include_contact_details (unlocks email, phone, address, DOB, custom fields and disables redaction) rather than just restating the field list. include_questions and include_memberships are only echoed from the schema, keeping this short of a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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 supporter') and names both lookup keys (email address or supporter ID). The 'one supporter' framing clearly distinguishes it from the sibling query_supporters without the agent needing to open the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'one supporter by email address or by supporter ID', which makes the single-record intent clear relative to the plural query_supporters. However, it never explicitly names the alternative or states when-not to use it, and with zero required parameters the description gives no guidance on what happens if neither key is supplied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_marketing_automationMarketing automation and its statsA
Read-only

One marketing automation with its statistics: journey starts, average open and click rates, actions and donations completed from it, objective reached, unsubscribes, SMS delivery rate and jumps. Optionally limit the stats to a range of months.

ParametersJSON Schema
NameRequiredDescriptionDefault
end_monthNoLast month to include in the stats, YYYYMM
start_monthNoFirst month to include in the stats, YYYYMM
automation_idYesAutomation ID, from list_marketing_automations (numeric)
include_statsNo

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds genuine behavioral value by enumerating exactly which metrics are returned (journey starts, open/click rates, donations, objective reached, unsubscribes, SMS delivery, jumps) and by noting the month-range scoping option, none of which are in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two efficient sentences: the purpose and metric enumeration lead, the optional month scoping follows. The metric list is long but earns its place since there is no output schema to describe return values.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 shoulders the burden of describing what is returned via its metric enumeration. The only gap is the undocumented include_stats parameter, which is missing from both schema description and prose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75%, so most parameters (automation_id, start_month, end_month with YYYYMM pattern and format) are already documented in the schema. The description restates the month-range concept but adds no syntax or constraints beyond the schema, and it never explains the undocumented include_stats parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (retrieve one marketing automation) and enumerates the statistics it returns, so the purpose is clear. It implicitly distinguishes itself from the sibling list_marketing_automations by the singular 'One marketing automation', but never names 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.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description notes the optional month-range limiting, which is implied usage guidance. However, it offers no explicit when-to-use/when-not-to-use, does not say to call list_marketing_automations first to obtain the ID, and does not address the include_stats toggle.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pageGet page detailsB
Read-only

Details of one campaign page: type, subtype, status, locale, base URL, template, tracking parameters and attributes.

ParametersJSON Schema
NameRequiredDescriptionDefault
page_idYesPage ID, from list_pages (numeric)

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a read-only, open-world operation. The description adds value by listing what data is returned, but it does not cover behavioral details such as error handling, required permissions, or pagination, which are less critical for a simple get tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that efficiently lists the returned details without unnecessary wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, read-only get tool with one fully documented parameter and no output schema, the description adequately explains the returned content. It could be slightly more complete by explicitly routing from list_pages, but it is sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the single page_id parameter is fully documented in the schema as coming from list_pages. The description adds no parameter-specific detail, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns details for one campaign page and enumerates the fields included (type, subtype, status, locale, base URL, template, tracking parameters, attributes). It distinguishes the single-page scope from list_pages by implication, though it does not explicitly name the sibling alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit guidance on when to use get_page versus list_pages or other sibling tools. The description only states what details are returned, leaving the selection context to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_supporter_questionGet question detailsA
Read-only

How one question is presented, per locale: label, HTML field type, the answer options (value and label) or range settings. Returns at most 50 locales and max_options answer options per locale, with the totals.

ParametersJSON Schema
NameRequiredDescriptionDefault
max_optionsNoMaximum number of answer options to return per locale
question_idYesThe question's `id` from list_supporter_questions (numeric)

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds non-obvious behavioral details beyond the annotations: a hard cap of 50 locales returned and max_options options per locale, plus the presence of totals, which tells the agent results can be truncated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences that front-load the returned content and then the truncation limits; little waste. It leans toward describing outputs rather than action, but stays tightly scoped.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter getter with no output schema and annotations covering safety, the description does the important work of outlining the return shape (label, field type, options/ranges) and the 50-locale and per-locale option caps. Only error/invalid-id behavior is left unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both question_id and max_options fully documented in the schema, so the baseline is 3. The description restates that max_options applies per locale but adds no new syntax, format, or edge-case semantics beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description conveys a specific resource and scope: the presentation of one question, per locale, including label, HTML field type, and answer options/ranges. The verb is implicit ('How one question is presented') rather than an explicit 'Get/Retrieve', and it does not name or distinguish itself from the sibling list_supporter_questions, though the question_id pointer implies the relationship.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use guidance, no prerequisites, and no mention of alternatives such as list_supporter_questions. An agent must infer from the name and the question_id description that this fetches a single question previously obtained from a listing call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_supporter_transactionsSupporter transaction historyA
Read-only

A supporter's transaction history: donations, event tickets, petition signatures, emails to targets, data captures and peer-to-peer activity, with page names, dates and statuses, plus their recurring donation schedules (amount, currency, frequency, status, next payment date). The history list carries no amounts; recurring schedules do. max_results caps each of the two lists. Card details and payment-gateway references are never returned.

ParametersJSON Schema
NameRequiredDescriptionDefault
max_resultsNoMaximum number of history entries to return, and separately of recurring schedules (the API returns each list whole)
supporter_idYesSupporter ID, from find_supporter or query_supporters (numeric)
include_recurringNoAlso fetch the supporter's recurring schedules
include_contact_detailsNoInclude peer-to-peer fundraiser email addresses and stop redacting contact details from names, targets and change reasons

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint and openWorldHint already covering the safety profile, the description still adds meaningful behavior: the history list carries no amounts while recurring schedules do, max_results caps each list separately, and card details and payment-gateway references are never returned. That privacy/field-omission disclosure is real value beyond the annotations, though it omits anything about rate limits, pagination beyond the cap, or permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences, front-loaded with what the tool returns, then two short sentences on the most surprising semantics (where amounts live, what is never returned). Every clause carries information; nothing restates the title or name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must describe the return payload, and it does: both lists, their contents, the presence/absence of amounts, and the redaction guarantee. Combined with a fully documented 4-parameter schema, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 goes further by spelling out the shape of recurring schedule data (amount, currency, frequency, status, next payment date) and by clarifying that max_results applies to each of the two lists independently. It does not explain include_contact_details' redaction behavior, which the schema already handles.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource precisely (a supporter's transaction history) and enumerates exactly which activity types are included: donations, event tickets, petition signatures, emails to targets, data captures, peer-to-peer activity, plus recurring donation schedules. That level of enumerative specificity clearly separates it from siblings like find_supporter and query_supporters, which locate supporters rather than return their history.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the resource description — an agent can infer this is the tool to call once a supporter_id is known — but there is no explicit when-to-use, when-not-to-use, or named alternative. The schema hints supporter_id comes from find_supporter or query_supporters, which supplies some routing context, but the description itself offers no selection guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_marketing_automationsList marketing automationsA
Read-only

Marketing automations (email journeys) in the account with status (ACTIVE, INACTIVE, PAUSED), folder and dates. Filter by dashboard folder and/or part of the name. Without folder_id the API lists the Home folder (0) only.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoOnly automations whose reference name contains this text
folder_idNoDashboard folder to list; the API defaults to the Home folder, 0
max_resultsNoMaximum number of automations to return

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered; the description adds real behavioral context beyond that — the implicit Home-folder (0) scoping when folder_id is omitted, and the fact that status/folder/dates are returned. Missing pagination behavior, but the folder-scoping disclosure is the high-value detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with what the tool returns before the filtering and default behavior. Slightly list-like in the first sentence but every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with safety covered by annotations and all three params documented, the description supplies the key operational caveat (Home folder default) and the returned fields. An output schema is absent but the description implies the shape sufficiently; only pagination/response-envelope detail is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each of the three params documented, so the schema carries the semantics. The description largely restates the folder default already in the schema and adds no format or syntax detail beyond it; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the specific resource (marketing automations / email journeys) and the fields exposed (status, folder, dates), which is more than a tautology of the name. It doesn't explicitly contrast with the sibling get_marketing_automation, but the list-vs-get distinction is apparent from the names.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete filtering guidance ('filter by dashboard folder and/or part of the name') and, importantly, warns that without folder_id the API lists only the Home folder (0). It stops short of naming alternative tools or when not to use it, but the default-folder caveat is genuinely actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pagesList campaign pagesA
Read-only

List the account's campaign pages of one type (donation, petition, event, data capture and so on), optionally only those with one status, with name, title, subtype, status, locale and dates. Names and titles have contact details redacted.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesPage type: nd = donation, pet = petition, ev = event, dcf = data capture form, survey, et = email to target, mem = membership, ... (see the server instructions)
statusNoOnly pages with this status
max_resultsNoMaximum number of pages to return (the API returns the whole list in one response)

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only and open-world behavior, but the description adds a genuinely non-obvious trait: names and titles have contact details redacted, so an agent will not treat the output as raw PII. It also states the type/status scoping. It does not discuss pagination or ordering, but with annotations carrying safety this is solid added context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence, front-loaded with the verb and resource, with filters and return fields following in logical order. Every clause carries information; it is slightly long, but no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 enumerating the returned fields (name, title, subtype, status, locale, dates) and disclosing the redaction behavior. The required type and optional status, and the result cap, are covered via schema. Only ordering/pagination semantics beyond the single-response note are left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, including enum labels and the max_results cap, so the schema already does the heavy lifting. The description adds only human-readable glosses of the type values (donation, petition, event, data capture) and the optional-status behavior, which is baseline value when the schema is fully documented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: list the account's campaign pages, scoped to one type and optionally one status. It also enumerates the returned fields, so the agent knows exactly what this returns. It does not explicitly contrast itself with siblings like get_page or list_marketing_automations, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"optionally only those with one status" implies when the status filter is appropriate, and the type requirement signals the mandatory scoping. However there is no explicit when-to-use-this-vs-get_page guidance or note that this is the bulk-retrieval path for a single page lookup. Usage is implied rather than directed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_supporter_fieldsList supporter fieldsB
Read-only

The supporter fields defined in the account's data structure: each field's name (as used in supporter records), tag and standard property name.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds that the result reflects the account's configured data structure, which hints at account-scoped output, but says nothing about ordering, caching, or whether custom vs standard fields are included. Modest added value over annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact sentence that front-loads the resource and then lists the returned attributes. No filler or redundancy, though the missing verb makes the opening feel like a fragment rather than a directive.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description's enumeration of returned properties (name, tag, standard property name) usefully compensates for that gap. However, it omits usage context relative to its many sibling tools, leaving the agent to guess when this list is the right choice.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the rubric the baseline is 4. The description correctly implies a no-argument, whole-schema read with no filtering options to document.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (supporter fields in the account's data structure) and enumerates what each entry contains, which distinguishes it from sibling list_supporter_questions. However it is a noun phrase with no verb, so it reads as a description of a data entity rather than stating the tool's action (listing). Adequate but not fully self-evident as an operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this versus the many sibling listers (list_supporter_questions, query_supporters, etc.) or what prerequisites exist. The agent must infer from the name alone that this returns field metadata for the account's supporter schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_supporter_questionsList supporter questionsB
Read-only

The questions and opt-ins defined in the account: id, questionId, name and type (OPT = opt-in, CONF = opt-in needing confirmation, GEN = general question).

ParametersJSON Schema
NameRequiredDescriptionDefault
max_resultsNoMaximum number of questions to return

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds real value by decoding the returned type codes (OPT/CONF/GEN), which is behavioral information not present anywhere else. It omits pagination/truncation behavior and the default result cap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no waste; the field enumeration and enum legend are both useful. Slightly awkward as a fragment rather than a statement of action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 enumerates the returned fields and decodes the type values, which is exactly what an agent needs. Only pagination/limit semantics are left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — max_results is fully documented with default, minimum and maximum — so the schema does the heavy lifting. The description adds nothing about the parameter, which is acceptable at this coverage level.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource ('the questions and opt-ins defined in the account') but uses no verb, so the listing action is only inferred from the tool name. It also does not distinguish itself from the singular sibling get_supporter_question. The added field list and type-code legend give it more substance than a pure name restatement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no statement of scope relative to get_supporter_question, and no prerequisite or exclusion conditions. An agent must guess whether this or the singular getter is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

query_supportersQuery supportersA
Read-only

List supporters matching one of the API's queries: latestCreated or latestModified (optionally within days_back, 1-32), suppressed, profile (needs profile_id, a supporter profile built in the dashboard) or search (needs filter, e.g. 'firstName:Bobcountry:GB||US': ':' is equals, '||' is OR between values, '' adds another filter with AND). Returns supporter IDs with created and modified dates; email addresses only with include_contact_details. Pages through the results 100 at a time.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesThe query to run
startNoRow to start from (to continue a previous call)
filterNoFilter for type 'search', as fieldName:value with '||' for OR and '~' to add filters
days_backNoNumber of days of data to return (1-32)
profile_idNoSupporter profile ID (required for type 'profile') (numeric)
max_resultsNoMaximum number of supporters to return
include_contact_detailsNoInclude each supporter's email address

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint and openWorldHint, so the description adds real value: paging behavior (100 at a time), the returned fields (IDs plus created/modified dates), and the privacy-relevant gating of email behind include_contact_details. It stops short of stating auth requirements or rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single dense paragraph that front-loads the query modes and is free of filler, with every clause earning its place. It reads as a run-on sentence, which slightly hurts scannability, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter read-only tool with no output schema, the description covers the mode-specific requirements, the filter syntax, the return shape, and pagination. An agent has everything needed to invoke it correctly and interpret the results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100% (baseline 3), but the description goes beyond it by decoding the filter mini-language: ':' as equals, '||' as OR between values, '~' as AND, with a concrete example. It clarifies cross-parameter dependencies (filter is only for type 'search', profile_id only for type 'profile') that the flat schema cannot express.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (list) plus resource (supporters) and enumerates the five query modes (latestCreated, latestModified, suppressed, profile, search) that define what the tool can do. This is far more than a restatement of the name and lets an agent immediately distinguish this broad query tool from the sibling find_supporter.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear per-mode selection guidance and prerequisites ('profile' needs profile_id, 'search' needs filter, days_back 1-32). It does not explicitly name alternatives such as find_supporter or explain when NOT to use this tool, so it falls short of the 5 bar.

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.

  1. 10 tool updatesv0.1.0
    • First observedfind_supporter
    • First observedget_marketing_automation
    • First observedget_page
    • First observedget_supporter_question
    • First observedget_supporter_transactions
    • First observedlist_marketing_automations
    • First observedlist_pages
    • First observedlist_supporter_fields
    • First observedlist_supporter_questions
    • First observedquery_supporters

TDQS

A3.7/5.0

Scored across 10 tools

Disambiguation5/5

Each tool targets a distinct resource and action: list vs get for automations, pages and questions, separate supporter lookup vs query, and dedicated transaction/field/question list tools. The only potential overlap is find_supporter vs query_supporters, but the descriptions clearly delineate single-record lookup from filtered listing.

Naming Consistency5/5

All names use snake_case verb_noun constructions with predictable plural/singular forms (list_marketing_automations, get_marketing_automation; list_pages, get_page). Verbs vary (list, get, find, query) but remain semantically appropriate and consistent throughout.

Tool Count5/5

10 tools for a multi-entity CRM/advocacy platform is well-scoped; each tool covers a needed read operation without redundant or filler entries.

Completeness3/5

The surface is entirely read-only and omits create/update/delete for all entities, which is a notable gap for a platform management server. There are also dead ends for required IDs: no tool lists marketing automation folders or supporter profiles referenced by list_marketing_automations and query_supporters, and transaction-level detail retrieval is absent.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

  • An MCP for marketers that gives agents tools for SEO, AEO, socials and ads data. Generous free tier; works in Claude, ChatGPT, Cursor and other MCP clients.

  • The HubSpot MCP Server acts as a bridge that enables AI assistants and Large Language Models to securely interact with HubSpot CRM data through natural conversation, without requiring users to understand complex API structures. It provides read-only access to standard CRM objects (contacts, companies, deals, tickets, products, invoices, and more) and their associations, secured via OAuth 2.0, allowing AI agents to perform tasks like summarizing deals, fetching company updates, and looking up record changes.

  • Connect your ads, shop, analytics, social, CRM and finance platforms once, then let Claude, ChatGPT, Cursor or any MCP client read, join and explain your numbers. Public statistics from the World Bank, IMF, Eurostat, OECD, WHO and SEC filings come as context, searchable and chartable from the same tools. Read-only by design, every number carries its source.

  • Read and edit GA4, Search Console and Google Tag Manager from any MCP client. 29 tools.

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Lets Claude, ChatGPT and other MCP clients read a SmartSurvey account's surveys, survey designs, responses, exports and folders, and — when writes are enabled — open or close a survey or send an existing invitation to one named recipient. It runs read-only by default, redacting respondent contact details and phone-number-like text unless contact details are explicitly requested.
    7
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude, ChatGPT and other MCP clients to read NewZapp account details, campaign reports, open heatmaps, contact groups and contact counts, and to search contacts with personal data withheld by default; when writes are enabled, it can also create and update contacts.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude, ChatGPT and other MCP clients to search a membership database's people and organisations, read a contact's summary and membership history, list events with ticket types and attendance lists, read invoices, and find and count segments. When writes are enabled, it also lets clients record who attended an event.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables MCP clients such as Claude and ChatGPT to read a campsite's supplier account data from the Pitchup.com API — campsites, pitch types, pitches, charge types, prices and stay rules, allocation, extras and arrivals and bookings. When writes are explicitly enabled, it also sets allocation, prices and charge types, with writes off and the sandbox environment used by default.
    14
    MIT