SMS and WhatsApp Messaging
Server Details
Send WhatsApp, SMS, email or voice to a business with the compliance gate enforced.
- Status
- Healthy
- Uptime
- 99.7% over 41 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- basilalshukaili/agentbroker
- GitHub Stars
- 0
- Server Listing
- Agent Broker
TDQS
Scored across 10 tools
Most tools have clearly distinct actions/resources: send vs transactional, get_status vs get_outcome, check_compliance vs preview_cost. The main overlaps are send_message vs send_transactional_confirmation and find_business vs verify_business, but descriptions distinguish them by intent and data source.
All names use snake_case and nearly all follow verb_noun (send_message, get_status, verify_business). self_test is the only non-verb_noun outlier, but the set remains predictable.
10 tools is well within the 3-15 range and each tool has a clear role in messaging, async tracking, compliance, cost preview, or business lookup. No obvious bloat or missing count issue.
Core send/transactional/conversation/async/compliance flows are covered. However SMS and voice are advertised but marked unavailable on this deployment, and there is no scheduling or bulk/template management, leaving notable gaps for a messaging server.
Available Tools
10 toolscheck_complianceARead-onlyIdempotentInspect
Free, instant pre-flight for the compliance gate: runs the SAME TCPA/GDPR/CASL/CAN-SPAM/10DLC checks as send_message and call_business, in preview mode -- nothing is sent, nothing changes. Tells you whether a send would be permitted before you pay, and if not, names the exact rule and how to fix it. De-risks a paid send the way check_booking_link de-risks a paid booking. [free, no key]
| Name | Required | Description | Default |
|---|---|---|---|
| channel | No | Delivery channel. Omit to auto-infer sms/email from recipient_id; set 'voice'… | |
| content | Yes | The actual message body you intend to send. The gate classifies the real text,… | |
| state_code | No | US state code (e.g. 'CA') for state-specific rules. | |
| country_code | No | ISO 3166-1 alpha-2 (e.g. 'US', 'DE', 'CA'). Auto-inferred from phone if… | |
| message_type | No | One of transactional, marketing, reminder, follow_up, notification (any case).… | transactional |
| recipient_id | Yes | Phone in E.164 (e.g. '+14045550100') or email address the message would go to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/idempotent/non-destructive, but the description adds substantive behavior: nothing is sent or changed, it is free with no key required, it runs the same rules as the live tools, and on failure it returns the exact rule plus remediation. That is genuine value beyond the structured 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?
Front-loaded with the key claim (free, instant pre-flight) and tight overall, though the check_booking_link analogy and the bracketed '[free, no key]' tag partially repeat points already made. Efficient but not maximally lean.
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 carries the return contract and does so well: it states the outcome (permitted or not), names the failing rule, and points to the fix. Combined with the no-side-effect guarantee, an agent has everything needed to call and interpret this 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?
Schema description coverage is 100%, so the schema already documents all six parameters including the channel enum and auto-inference rules. The description adds no parameter-level detail (e.g. what content is scanned for), 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 precise verb+resource ('runs the SAME TCPA/GDPR/CASL/CAN-SPAM/10DLC checks ... in preview mode') and explicitly distinguishes itself from the real send tools send_message and call_business. An agent immediately knows this is a dry-run gate check, not an action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when-to-use condition ('pre-flight ... before you pay') and frames the alternative it de-risks (the paid send). The preview/no-side-effect framing tells the agent this is the correct pre-step rather than guessing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_businessARead-onlyIdempotentInspect
Find real businesses near a place, sorted by distance (nearest of those examined; see result.search). Data: OpenStreetMap (ODbL, (c) OSM contributors); phone, website, hours only when mapped. Coverage varies; community-mapped, NOT verified by us; source=openstreetmap rows cannot be booked. Answers within about 5 s: status partial (search_in_progress) means repeat the call. If OSM is down: retriable 'temporarily unavailable', never invented rows. [free, no key] [beta]
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | Instead of location: a city, e.g. 'Muscat, Oman'. | |
| region | No | With city: a state or region. | |
| location | Yes | City/town or ZIP, optionally with country ('Nizwa, Oman'). Geocoded by OSM. | |
| vertical | No | ||
| capability | No | Kind of business: 'dentist', 'cafe', 'plumber'. Use it or vertical. | |
| price_band | No | Supply-network rows only (OpenStreetMap has no prices). | |
| max_results | No | ||
| availability_window | No | Accepted but NOT APPLIED: it does not narrow results (no live calendars). The… |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses ~5s latency, that partial/search_in_progress means the call must be repeated, that an OSM outage yields a retriable 'temporarily unavailable' rather than fabricated rows, and that results are community-mapped and NOT verified by the provider. These are exactly the operational traits an agent needs and none 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core verb+resource, then grouped caveats (data provenance, latency/status, failure mode, tags). Dense but nearly every clause carries information; the trailing '[free, no key] [beta]' tags are slightly cluttered but useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 8 params, nested objects, and no output schema, the definition adequately covers provenance, retry semantics, latency, and the booking limitation, and points at result.search for ordering. It stops short of describing result fields or pagination, leaving a small gap for a discovery 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?
Schema description coverage is 75%, so the schema already carries most parameter meaning (radius_miles default/max, price_band scope, availability_window not applied). The description adds little parameter-specific detail of its own beyond the booking constraint tied to source rows, 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?
Specific verb+resource: 'Find real businesses near a place, sorted by distance', with the result ordering and the fact that sorting covers only examined rows made explicit. This cleanly separates it from siblings like verify_business, call_business, and capture_lead, which act on a business rather than discovering one.
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?
Implied context is present: it is the discovery step ('find real businesses'), and the caveat that source=openstreetmap rows cannot be booked hints at a downstream booking/verification flow. However it never explicitly states when to prefer this over siblings such as verify_business, nor does it name any alternative or exclusion condition, so usage must be inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_conversationARead-onlyInspect
Read a two-way conversation thread you started: its state, every message exchanged, and how many replies the business has sent. [free, requires key]
| Name | Required | Description | Default |
|---|---|---|---|
| reference | No | The 4-digit request reference, e.g. '4821'. Requires business_number. | |
| business_number | No | Scopes a `reference` to one business (references are reused across businesses). | |
| conversation_id | No | From the send_message receipt (preferred). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that it requires a key and is free, but annotations already provide readOnlyHint=true, which covers the safety profile. It does not add substantial behavioral context beyond that (e.g., rate limits, pagination), so the score is at the annotation-covered baseline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the core purpose, defines the scope, and adds a concise, relevant usage note. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with a fully documented schema and no output schema, the description adequately covers what the agent needs to know to invoke it. It could mention the need for either reference+business_number or conversation_id, but this is implied by the schema, so minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema coverage is 100%, so the schema fully documents all three parameters. The description adds minimal value beyond hinting that conversation_id is preferred, but it does not degrade since the schema is sufficient. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as reading a two-way conversation thread and specifies its contents (state, messages, reply count). The verb 'Read' is explicit and the resource ('conversation thread') is unambiguous, and it differentiates from siblings like send_message and get_status by its scope.
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 for reading a conversation, and the parameter hints (preferred conversation_id, reference requiring business_number) provide clear context for when to use it versus alternatives. However, it does not explicitly state when not to use it or name sibling alternatives, so it's not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_outcomeARead-onlyIdempotentInspect
Retrieve the final OutcomeReceipt for a completed operation. [free, no key]
| Name | Required | Description | Default |
|---|---|---|---|
| operation_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds useful context beyond annotations: the operation must be completed, and the call is free with no key required.
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 tight sentence plus a bracket note. Every element earns its place, and the core purpose is front-loaded before the access note.
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 retrieval tool with strong annotations, the description is mostly complete: it identifies what to pass, when it is valid, and the access requirements. It does not describe the return shape, but no output schema exists and the resource name 'OutcomeReceipt' is reasonably self-descriptive.
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 0% and the schema only says operation_id is a required string. The description adds context by tying operation_id to the completed operation whose OutcomeReceipt is requested, but it does not specify where the ID comes from or its format.
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 ('Retrieve') and a specific resource ('final OutcomeReceipt') for a 'completed operation'. This clearly distinguishes it from siblings like get_status, which would naturally map to intermediate status rather than the final receipt.
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 gives clear context: this is for retrieving the outcome only after an operation has completed. It does not explicitly name alternatives or exclusions, but the completed-operation condition is a meaningful usage signal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_statusARead-onlyIdempotentInspect
Query the current state of any in-flight async operation by operation_id. [free, no key]
| Name | Required | Description | Default |
|---|---|---|---|
| operation_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the description only needs to add context. It adds that the operation is free, requires no API key, and applies to in-flight async operations, which provides useful behavioral context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded. The primary purpose is stated in one clear sentence, and the cost/auth note is appended succinctly. 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?
For a simple, one-parameter, read-only status tool, the description provides enough to call it correctly: the target resource, the identifier, and the cost/auth constraints. It does not detail the output shape or possible statuses, and it does not explain what happens if the operation is not in-flight, but these are not critical for a basic status query given the annotations.
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 only specifies 'operation_id' as a string with no description, so the description carries the semantic burden. It clarifies that operation_id references an in-flight async operation and that the tool queries its state, which gives the parameter meaningful context. It could be stronger by explaining how to obtain the operation_id, but it is adequate.
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 specifies a verb ('Query'), a resource ('the current state of any in-flight async operation'), and the key identifier ('operation_id'). It also implicitly differentiates from the sibling 'get_outcome' by focusing on in-flight operations rather than completed outcomes.
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 gives clear context: use this when you need the current state of an in-flight operation identified by operation_id. It also notes the operation is free and requires no key. It does not explicitly mention exclusions or alternatives, but the usage context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preview_costARead-onlyIdempotentInspect
Return an expected cost estimate, latency estimate, and success-probability estimate for a proposed call before execution. Returns the exact price when it is fixed, and a min/max range when the cost depends on channel or outcome. It does not promise an accuracy percentage - check cost_range. [free, no key]
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes | The same request body you would pass to the operation | |
| operation | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent, and non-destructive behavior. The description adds valuable behavioral context beyond that: it returns exact prices when fixed, min/max ranges when variable, does not promise accuracy, and requires no API key ('[free, no key]'). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three focused sentences with no filler. The first sentence front-loads the core purpose, the second explains the exact-vs-range behavior, and the third adds a crucial caveat plus auth note. Every sentence 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?
The description covers what the tool returns, how pricing varies, and the free/no-key requirement. With no output schema, the return-value description is useful and mostly sufficient. Minor gaps remain around expected operation naming and the exact output shape, but the tool is simple enough that this is not a major deficiency.
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 schema documents params as 'the same request body you would pass to the operation,' and the description reinforces the 'proposed call' idea. However, the operation parameter is only a bare string with no allowed values or format, and the description does not elaborate on how operations are specified. Schema coverage is exactly 50%, so the description only partially compensates.
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 ('Return') and a precise resource: cost, latency, and success-probability estimates for a proposed call before execution. This clearly distinguishes it from siblings like get_outcome, get_status, or verify_company_record, which address different concerns.
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 clearly signals this tool is for pre-execution estimation ('before execution') and cautions that accuracy is not promised, directing the user to cost_range. It does not explicitly name alternatives or state when not to use it, but the context is clear enough given the sibling set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
self_testARead-onlyIdempotentInspect
Service health probe: runs 6 internal checks and reports how many passed. Confirms the server is up and responding - it does NOT probe each tool individually. Use to verify connectivity before production use. [free, no key]
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds value by disclosing the internal check count (6), the aggregate pass/fail nature, and the free/no-key requirement, which are not in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: it states the core function first, then the limitation, then the use case, then the free/no-key note. Every sentence earns its place with no redundancy.
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 the essential information: what it checks, what it reports, what it does not do, and when to use it. The only minor gap is not describing the exact output format, but that is not critical for a simple health probe.
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 has zero parameters, so the schema is trivially complete. The description adds no parameter details because none are needed; the baseline of 4 for zero-parameter tools applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: it runs 6 internal checks and reports how many passed, confirming the server is up. It explicitly distinguishes itself from per-tool probing, which differentiates it from sibling tools like get_status or verify_company_record.
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 says to use it to verify connectivity before production use, which gives a clear context. It does not explicitly name alternative tools or state when not to use it, but the 'does NOT probe each tool individually' exclusion provides useful guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageADestructiveInspect
Send a message on behalf of an agent's user or an SMB across WhatsApp (free during launch), SMS, email, or voice, sent immediately, no scheduling. Every send passes a non-bypassable gate: TCPA, GDPR, CASL where modeled, else the service's own opt-in default (the Gulf included). Marketing on SMS, voice, WhatsApp and non-US email without recorded opt-in is rejected (compliance_violation receipt). US marketing email follows CAN-SPAM opt-out rules. [from $0.02/call, variable, not charged while no payment rail is on] [async→get_outcome] [Not available on this deployment: SMS, Voice.]
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | ||
| recipient | Yes | ||
| business_id | No | Stable id for the recipient business; used for global demand shaping. | |
| message_type | Yes | 'marketing' needs recorded opt-in, except US email (CAN-SPAM opt-out rules).… | |
| on_behalf_of | No | Who this message is FOR (your end-user's name/label). On WhatsApp this opens a… | |
| idempotency_key | No | Retry key: a 24h replay returns the original receipt, not re-run or charged. | |
| preferred_channel | No | auto |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations: a non-bypassable compliance gate (TCPA/GDPR/CASL or the service default), a named rejection artifact (compliance_violation receipt), cost behavior ($0.02/call, not charged while no payment rail is on), async execution requiring get_outcome, and deployment-limited channels. These are exactly the side effects and failure modes an agent must know before invoking a destructive, open-world 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?
Front-loaded with the core action and scope in the first clause, so an agent gets the gist immediately. The trailing bracket block (pricing, async routing, deployment limits) is dense and slightly cluttered, but each item carries operational value rather than 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 7-parameter, nested-schema, highly regulated tool with no output schema, the description covers the decision-critical context: compliance gating, rejection behavior, cost, async outcome path, and channel availability. It does not describe the success receipt shape or authentication/permission requirements, which would fully round it out.
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 57% schema coverage, the description meaningfully compensates: it enumerates the usable channels in prose (WhatsApp/SMS/email/voice with availability caveats), ties message_type to consent rules, and explains the regulatory dimension behind country_code routing. It says nothing about business_id, on_behalf_of, idempotency_key, or template usage, so a few parameters remain schema-only.
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 scope: send a single message on behalf of a user/SMB across WhatsApp, SMS, email, or voice, immediately with no scheduling. The channel enumeration and compliance framing make the operation unambiguous. It does not name the sibling that overlaps most (send_transactional_confirmation), so the agent can't fully disambiguate from siblings on this description alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives real routing conditions: messages are immediate (no scheduling), marketing is rejected without recorded opt-in on most channels, US marketing email follows CAN-SPAM, and async results are routed to get_outcome. It also flags deployment limits (SMS and Voice unavailable here), which prevents an agent from selecting an unusable channel. No explicit 'use X instead of Y' comparison against send_transactional_confirmation or check_compliance is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_transactional_confirmationADestructiveInspect
Idempotent transactional messages: OTPs, booking confirmations, payment receipts, cancellation notices. Falls back across configured channels; an unconfigured channel fails honestly rather than reporting a delivery that did not happen. [$0.02/per_call, not charged while no payment rail is on] [async→get_outcome] [Not available on this deployment: SMS.]
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Type-specific payload; e.g., {otp_code} for otp, {appointment_time, smb_name}… | |
| recipient | Yes | ||
| idempotency_key | No | Retry key: a 24h replay returns the original receipt, not re-run or charged. | |
| confirmation_type | Yes | ||
| preferred_channel | No | sms |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: channel fallback semantics, an explicit honest-failure guarantee ('fails honestly rather than reporting a delivery that did not happen'), per-call cost and the condition under which it is not charged, and async retrievability. Minor tension: the description calls the messages 'Idempotent' while idempotentHint=false, though the schema's idempotency_key (24h replay) reconciles this as key-scoped idempotency rather than default behavior.
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?
Information-dense and front-loaded: the artifact types come first, then fallback semantics, then cost/async/deployment brackets. The bracketed shorthand is efficient but slightly telegraphic; every element still 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 usefully supplies the async retrieval path (get_outcome), the cost model, honest-failure semantics, and the SMS unavailability — enough for correct invocation. Residual gaps are the recipient/data payload expectations left to a schema that is only 40% documented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 40% across 5 params with a nested recipient/data object, so the description must carry more weight than it does. It does add meaning for channel behavior ('falls back across configured channels') and idempotency, and its type list overlaps the confirmation_type enum, but it never explains the data payload shape or recipient 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+resource ('transactional messages') and enumerates the concrete artifact types (OTPs, booking confirmations, payment receipts, cancellation notices), which maps directly onto the confirmation_type enum and separates it from the generic send_message sibling. An agent can identify the tool's domain 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?
Provides clear operating context: it routes the agent to get_outcome for async results ('async→get_outcome') and states an exclusion ('Not available on this deployment: SMS'). It does not, however, explicitly contrast this with the sibling send_message, so the when-to-use boundary between transactional and general messaging is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_businessARead-onlyIdempotentInspect
Look up what we know about a business in our supply network: contact channels, capabilities, last verification. A DIRECTORY LOOKUP - it does not contact the business. Supply-network ids only, not osm:... ids. [free, no key] [limited]
| Name | Required | Description | Default |
|---|---|---|---|
| smb_id | Yes | ||
| capability_to_verify | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, idempotent, non-destructive and closed-world behavior, so the bar is low. The description still adds genuinely new facts: that it performs no contact, the acceptable id namespace, and cost/access tags '[free, no key] [limited]' signaling no credentials but constrained availability. The '[limited]' tag is left undefined, which keeps it from 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?
Front-loads the lookup scope, then the disambiguating negative, then the id constraint and cost tags - a sensible ordering with no filler sentences. The bracketed tags are terse and functional, though '[limited]' is vague enough to cost a point.
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 naming the returned content (contact channels, capabilities, last verification), and annotations carry the safety profile. The remaining gap is the unexplained capability_to_verify parameter, which an agent may need to call the tool 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?
Schema coverage is 0%, so the description must carry both parameters. It does document the smb_id namespace constraint ('Supply-network ids only, not osm:... ids'), which is real added meaning. However, capability_to_verify is never explained - no hint of what capabilities exist or what verification means for them - leaving half the parameters undocumented.
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 what we know about a business in our supply network') and enumerates the fields returned (contact channels, capabilities, last verification). It also draws the key boundary against siblings by declaring 'A DIRECTORY LOOKUP - it does not contact the business', which separates it from call_business 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 clear context for when the tool applies: read-only directory inspection rather than outreach, and id-namespace restriction ('Supply-network ids only, not osm:... ids'). The alternative (call_business) is implied by the negation but never named explicitly, so an agent must infer the routing rather than being told it.
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.
2 tool updates
- Changed
check_compliance1 field changed- changed
Input schema / properties / message_type / descriptionPrevious value: -"Intent tag: transactional, marketing, reminder, follow_up, notification.…"New value: +"One of transactional, marketing, reminder, follow_up, notification (any case).…"
- Changed
send_message1 field changed- changed
Input schema / properties / message_type / descriptionPrevious value: -"Intent tag for the message. Five permitted types. 'marketing' is allowed only…"New value: +"'marketing' needs recorded opt-in, except US email (CAN-SPAM opt-out rules).…"
1 tool update
- Changed
find_business7 fields changed- changed
Input schema / properties / availability_window / descriptionPrevious value: -"Accepted but NOT APPLIED - it does not narrow results. We do not hold live…"New value: +"Accepted but NOT APPLIED: it does not narrow results (no live calendars). The…" - changed
Input schema / properties / capability / descriptionPrevious value: -"Kind of business, e.g. 'haircut', 'plumber', 'dentist'. Mapped to OSM tags."New value: +"Kind of business: 'dentist', 'cafe', 'plumber'. Use it or vertical." - changed
Input schema / properties / city / descriptionPrevious value: -"Alternative to location: a top-level city, normalised into…"New value: +"Instead of location: a city, e.g. 'Muscat, Oman'." - changed
Input schema / properties / location / properties / zip_or_city / descriptionPrevious value: -"City, town, address or postal code, optionally with the country, e.g. 'Nizwa, Oman'. A bare 5-digit ZIP is read as a US ZIP; give any non-US postal code with its country (e.g. '10115, Germany')."New value: +"Town, city, address or postal code, with the country if not US: 'Nizwa, Oman'. A bare 5-digit ZIP is a US ZIP; add the country for any other postal code." - changed
Input schema / properties / price_band / descriptionPrevious value: -"Supply-network rows only; OpenStreetMap has no prices."New value: +"Supply-network rows only (OpenStreetMap has no prices)." - changed
Input schema / properties / region / descriptionPrevious value: -"Alternative to location: a top-level state/region, normalised into…"New value: +"With city: a state or region." - changed
Input schema / requiredPrevious value: -[ - "vertical", - "location" -]New value: +[ + "location" +]
1 tool update
- Changed
find_business5 fields changed- changed
Input schema / properties / capability / descriptionPrevious value: -"Specific service capability required, e.g. 'haircut', 'plumbing',…"New value: +"Kind of business, e.g. 'haircut', 'plumber', 'dentist'. Mapped to OSM tags." - changed
Input schema / properties / location / descriptionPrevious value: -"Where to search. Matched against the business's city, state and ZIP as text -…"New value: +"City/town or ZIP, optionally with country ('Nizwa, Oman'). Geocoded by OSM." - changed
Input schema / properties / location / properties / radius_miles / descriptionPrevious value: -"Accepted but NOT applied - no coordinates exist, so results are not restricted to this radius. Disclosed back as radius_miles_applied: false."New value: +"Radius in miles (default 3.1, max 25); applies to OpenStreetMap results only." - added
Input schema / properties / location / properties / zip_or_city / descriptionAdded value: +"City, town, address or postal code, optionally with the country, e.g. 'Nizwa, Oman'. A bare 5-digit ZIP is read as a US ZIP; give any non-US postal code with its country (e.g. '10115, Germany')." - added
Input schema / properties / price_band / descriptionAdded value: +"Supply-network rows only; OpenStreetMap has no prices."
1 tool update
- Changed
find_business2 fields changed- added
Input schema / properties / cityAdded value: +{ + "description": "Alternative to location: a top-level city, normalised into…", + "type": "string" +} - added
Input schema / properties / regionAdded value: +{ + "description": "Alternative to location: a top-level state/region, normalised into…", + "type": "string" +}
1 tool update
- Changed
find_business2 fields changed- removed
Input schema / properties / cityRemoved value: -{ - "description": "Alternative to location: a top-level city, normalised into…", - "type": "string" -} - removed
Input schema / properties / regionRemoved value: -{ - "description": "Alternative to location: a top-level state/region, normalised into…", - "type": "string" -}
1 tool update
- Changed
find_business1 field changed- changed
Input schema / properties / location / properties / radius_miles / descriptionPrevious value: -"Accepted but NOT applied. The supply directory holds no coordinates, so no distance filter can be honoured; results are not restricted to this radius. Sending it is recorded and disclosed back as radius_miles_applied: false."New value: +"Accepted but NOT applied - no coordinates exist, so results are not restricted to this radius. Disclosed back as radius_miles_applied: false."
1 tool update
- Changed
find_business1 field changed- added
Input schema / properties / location / properties / radius_miles / descriptionAdded value: +"Accepted but NOT applied. The supply directory holds no coordinates, so no distance filter can be honoured; results are not restricted to this radius. Sending it is recorded and disclosed back as radius_miles_applied: false."
1 tool update
- Changed
find_business6 fields changed- added
Input schema / properties / cityAdded value: +{ + "description": "Alternative to location: a top-level city, normalised into…", + "type": "string" +} - added
Input schema / properties / location / descriptionAdded value: +"Where to search. Matched against the business's city, state and ZIP as text -…" - removed
Input schema / properties / location / properties / radius_miles / defaultRemoved value: -10 - added
Input schema / properties / location / properties / radius_miles / minimumAdded value: +0 - added
Input schema / properties / max_results / minimumAdded value: +1 - added
Input schema / properties / regionAdded value: +{ + "description": "Alternative to location: a top-level state/region, normalised into…", + "type": "string" +}
3 tool updates
- Changed
find_business1 field changed- removed
Input schema / properties / vertical / descriptionRemoved value: -"Service vertical to search within"
- Changed
send_message3 fields changed- changed
Input schema / properties / business_id / descriptionPrevious value: -"Optional stable id for the recipient business. Enables global demand shaping…"New value: +"Stable id for the recipient business; used for global demand shaping." - changed
Input schema / properties / idempotency_key / descriptionPrevious value: -"Optional client-supplied key for safe retries. Replaying the same key within 24h returns the original receipt - the operation is NOT re-executed and NOT re-charged."New value: +"Retry key: a 24h replay returns the original receipt, not re-run or charged." - removed
Input schema / properties / send_at_isoRemoved value: -{ - "description": "NOT SUPPORTED YET. We do not schedule messages. Supplying a time more than 2…", - "format": "date-time", - "type": "string" -}
- Changed
send_transactional_confirmation1 field changed- changed
Input schema / properties / idempotency_key / descriptionPrevious value: -"Optional client-supplied key for safe retries. Replaying the same key within 24h returns the original receipt - the operation is NOT re-executed and NOT re-charged."New value: +"Retry key: a 24h replay returns the original receipt, not re-run or charged."
4 tool updates
- Changed
check_compliance4 fields changed- changed
Input schema / properties / channel / descriptionPrevious value: -"Delivery channel. Omit to auto-infer sms/email from recipient_id; set 'voice' explicitly."New value: +"Delivery channel. Omit to auto-infer sms/email from recipient_id; set 'voice'…" - changed
Input schema / properties / content / descriptionPrevious value: -"The actual message body you intend to send. The gate classifies the real text, so a meaningful preview needs the real content."New value: +"The actual message body you intend to send. The gate classifies the real text,…" - changed
Input schema / properties / country_code / descriptionPrevious value: -"ISO 3166-1 alpha-2 (e.g. 'US', 'DE', 'CA'). Auto-inferred from phone if omitted; drives which jurisdiction rules apply."New value: +"ISO 3166-1 alpha-2 (e.g. 'US', 'DE', 'CA'). Auto-inferred from phone if…" - changed
Input schema / properties / message_type / descriptionPrevious value: -"Intent tag: transactional, marketing, reminder, follow_up, notification. 'marketing' triggers the consent checks. Defaults to transactional."New value: +"Intent tag: transactional, marketing, reminder, follow_up, notification.…"
- Changed
find_business2 fields changed- changed
Input schema / properties / availability_window / descriptionPrevious value: -"Accepted but NOT APPLIED - it does not narrow results. We do not hold live calendars for the supply network. The response carries availability_window_applied: false when you send one. To book a specific slot use schedule_appointment with requested_time, which checks real availability."New value: +"Accepted but NOT APPLIED - it does not narrow results. We do not hold live…" - changed
Input schema / properties / capability / descriptionPrevious value: -"Specific service capability required, e.g. 'haircut', 'plumbing', 'tax_consultation'"New value: +"Specific service capability required, e.g. 'haircut', 'plumbing',…"
- Changed
send_message4 fields changed- changed
Input schema / properties / business_id / descriptionPrevious value: -"Optional stable id for the recipient business. Enables global demand shaping (we rate-limit total inbound across ALL agents so businesses stay responsive instead of blocking us)."New value: +"Optional stable id for the recipient business. Enables global demand shaping…" - changed
Input schema / properties / message_type / descriptionPrevious value: -"Intent tag for the message. Five permitted types. 'marketing' is allowed only when paired with a valid consent_record_id; the compliance gate verifies the consent at send time and rejects (compliance_violation receipt) if it's missing, expired, or revoked."New value: +"Intent tag for the message. Five permitted types. 'marketing' is allowed only…" - changed
Input schema / properties / on_behalf_of / descriptionPrevious value: -"Who this message is FOR (your end-user's name/label). On WhatsApp this opens a tracked conversation and travels in-message as '#4821 for Sara (via HatchLoop)', so the business knows who it is talking to and their reply is matched back to this exact request instead of guessed. Strongly recommended for two-way channels."New value: +"Who this message is FOR (your end-user's name/label). On WhatsApp this opens a…" - changed
Input schema / properties / send_at_iso / descriptionPrevious value: -"NOT SUPPORTED YET. We do not schedule messages. Supplying a time more than 2 minutes in the future is REFUSED (reason_code scheduling_not_supported) rather than sent immediately, which is what used to happen. Call send_message at the moment you want delivery, or omit this field."New value: +"NOT SUPPORTED YET. We do not schedule messages. Supplying a time more than 2…"
- Changed
send_transactional_confirmation1 field changed- changed
Input schema / properties / data / descriptionPrevious value: -"Type-specific payload; e.g., {otp_code} for otp, {appointment_time, smb_name} for booking_confirmation"New value: +"Type-specific payload; e.g., {otp_code} for otp, {appointment_time, smb_name}…"
Related MCP Connectors
Send and receive across email, SMS, WhatsApp, and voice. One API, one contract.
AI phone calls, SMS and CRM records in one Lead Friendly account, compliance-checked on every send
Send, automate, and orchestrate SMS, WhatsApp, Viber, IVR, and USSD messaging in 150+ countries.
Run WhatsApp Business campaigns from any AI assistant: contacts, segments, and broadcasts.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to interact with WhatsApp by sending messages, triaging urgent conversations, scheduling messages, and managing automated replies with safety controls and human approval.19 npmMIT

SendAPI MCP Serverofficial
AlicenseAqualityDmaintenanceEnables any MCP-compatible AI agent to send WhatsApp messages, SMS, OTP codes, and email through a single REST API.18MIT- FlicenseNot gradedqualityDmaintenanceCompliance intelligence layer for AI agents sending WhatsApp Business messages. Prevents account suspensions by validating Meta's rules (care windows, opt-outs, rate limits) in real-time before every send.1-
- AlicenseAqualityDmaintenanceGoverns and automates WhatsApp messaging for AI agents with security controls like recipient allowlisting, secret scanning, rate limiting, and audit logging.5MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.