Ray notifications
Server Details
Send email, push, Slack, Discord, Telegram and webhook notifications and manage templates with Ray.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- gege-mn/ray-mcp
- GitHub Stars
- 0
- Server Listing
- Ray: Your Notification Infra
TDQS
Scored across 21 tools
Each tool maps to a distinct resource+action (template, webhook, send, feed, usage, identity), and paired tools like archive/unarchive_template and send_notification/test_send_template are clearly separated. There is no pair an agent would plausibly confuse.
All tools follow a consistent snake_case verb_noun pattern such as create_webhook, list_templates, and update_template_draft. The only minor deviation is whoami, which is command-style rather than verb_noun, but it is still recognizable and predictable.
21 tools is above the typical 3-15 sweet spot, so the surface is slightly heavy, but the count is justified by covering templates, webhooks, sending/status, feeds, billing, docs, and identity. No tool is redundant, making this reasonable rather than excessive.
The set covers the full notification lifecycle: template create/read/update/publish/archive/unarchive/test, send and async status, webhook CRUD, feed reads, click stats, usage, and auth checking. Channel provisioning is intentionally dashboard-only and documented, so there are no obvious dead ends for the API's scope.
Available Tools
21 toolsarchive_templateArchive templateADestructiveIdempotentInspect
Archive a template (POST /templates/{id}/archive; write scope). Sends that reference it fail until it is restored with unarchive_template; its name stays reserved meanwhile. Confirm with the user first if it may be in production use.
| Name | Required | Description | Default |
|---|---|---|---|
| templateId | Yes | The template id (UUID). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing the concrete behavioral side effects: referencing sends fail until restored with unarchive_template, and the template name stays reserved meanwhile. This gives the agent real operational understanding of the action.
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?
Each sentence is compact and informative, covering the action, effects, and user-facing guidance. No filler words, and the most important details are placed early.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter destructive tool, the description addresses the action, consequences, restoration path, and a caution for production usage. No output schema is needed, and the required context is covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides a full description for templateId and the schema description coverage is 100%. The assistant description does not add additional parameter semantics, so it stays at the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific verb and resource—'Archive a template'—and further pins it down with the raw endpoint and write scope. The reference to unarchive_template clearly separates it from the restoring sibling.
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 context for when this should be used carefully ('Confirm with the user first if it may be in production use') and explains the main consequence: sends that reference the template will fail until restored. It could more explicitly contrast when to choose archive versus unarchive, but the context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_templateCreate templateAInspect
Create a template (POST /templates; write scope). channelKind is permanent and must match the channels you'll send through (list_channels templateKind). It is saved as an unpublished draft unless publish: true; sending by templateId needs a published version (publish_template). Names are unique per workspace including archived templates: a collision returns 409, so unarchive_template the old one instead. Returns { id, requiredParams }. Designed (drag-and-drop) email templates can only be made in the dashboard.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Template name, unique per workspace (archived templates included). | |
| folder | No | Optional folder path for organisation, e.g. "billing". | |
| content | Yes | Channel-shaped template body; the shape is fixed by `channelKind`: email_html → `{ subject, bodyHtml, bodyText }`; fcm_basic → `{ title, body, imageUrl?, data?: { [key]: string } }`; slack_text → `{ text }`; discord_text → `{ content }` (max 2000 chars); telegram_text → `{ text, disableLinkPreview? }`; webhook_json → `{ title, body, data?: { [key]: string } }`. Use `{{name}}` placeholders and `{{#items}}…{{/items}}` sections; the required params are derived from them automatically. | |
| publish | No | true = publish this version immediately so sends by templateId use it. Default false (saved as draft). | |
| logTitle | Yes | Short title shown in the in-app feed and delivery logs, e.g. "Invoice {{number}} is due". Placeholders allowed. | |
| channelKind | Yes | Which channel family the template renders for. Must match the `templateKind` of the channels you will send through (list_channels). Can't be changed after creation. | |
| logDescription | Yes | One-line description for the in-app feed and delivery logs. Placeholders allowed. | |
| paramOverrides | No | Per-param metadata keyed by param name: `{ optional?: boolean, description?: string }`. Mark a placeholder optional so sends may omit it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark the operation as non-read-only, non-idempotent, and non-destructive. The description adds rich behavioral context: channelKind is permanent, templates default to unpublished drafts, names collide with archived templates returning 409, and the response shape is { id, requiredParams }.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences deliver the endpoint, core constraints, collision behavior, return value, and a dashboard-only limitation without redundant schema repetition. The most important facts are front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 8-parameter tool with no output schema, the description covers the operational details an agent needs: default draft behavior, publish flow, uniqueness/409 handling, channelKind permanence, and the dashboard exception. The schema covers the parameter shapes.
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 already covers all 8 parameters at 100%, so the baseline is 3. The description adds valuable semantics: channelKind must match list_channels templateKind, publish controls draft vs published state, and requiredParams are derived automatically from content placeholders.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Create a template'), the HTTP endpoint, and the write scope, with enough detail to distinguish it from publish_template and update_template_draft. The operation is unambiguous and correctly named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear routing guidance: use publish_template to make a draft sendable, unarchive_template on 409 collisions, and the dashboard for drag-and-drop email templates. It does not explicitly exclude update_template_draft, but the create-vs-update context is inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_webhookCreate webhookAInspect
Create an outbound webhook that Ray POSTs signed event payloads to (POST /tenant-webhooks; write scope; Pro plan or higher, otherwise 403). The URL must be public HTTPS. The response contains the signing secret exactly once: show it to the user to store (e.g. as an env var), since it can't be read again, only rotated with update_webhook. Read the webhooks docs page for the signature scheme.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Public HTTPS endpoint that will receive the events. | |
| name | Yes | Label for the webhook, e.g. "Production delivery events". | |
| events | Yes | Events to receive: "notification.delivered", "notification.failed_terminal" (one per recipient), and "send.completed" (once per send, with status totals). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only indicate that the operation is not read-only, not idempotent, and not destructive. The description adds substantial behavioral context: auth/plan failure (403), HTTPS requirement, and the critical one-time secret retrieval behavior with rotation via update_webhook. This goes well beyond what the structured fields provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences, each earning its place: endpoint/scope/plan, HTTPS constraint, one-time secret warning, rotation path, and docs pointer. The most important operational risk (secret can't be read again) is explicitly called out without fluff.
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?
Given no output schema, the description still tells the agent what matters in the response (the secret, exactly once), the prerequisites for a successful call, and where to learn the signature scheme. This is sufficient for an agent to invoke the tool and handle the most consequential behavior 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 description coverage is 100%, so the schema already documents url, name, and events in detail. The description adds the public-HTTPS requirement and secret response behavior, but it does not materially extend the meaning of the parameters themselves beyond what the schema already states.
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 uses a specific verb and resource ('Create an outbound webhook') and adds the endpoint (POST /tenant-webhooks), the payload direction (Ray POSTs signed event payloads), and the scope/plan requirement. This clearly distinguishes it from siblings like update_webhook, delete_webhook, and get_webhook.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states clear conditions for use: write scope, Pro plan or higher, public HTTPS URL. It also tells the agent that the secret is only shown once and that update_webhook is the rotation path, which is a concrete alternative. It doesn't exhaustively list when not to use it, but the constraints are enough for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_webhookDelete webhookADestructiveIdempotentInspect
Delete (archive) a webhook so it receives no more events (DELETE /tenant-webhooks/{id}; write scope). It cannot be restored through the API; confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| webhookId | Yes | The webhook id (UUID). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry destructive and idempotent flags, but the description adds vital context: it archives the webhook, that events stop, and that the deletion cannot be undone through the API. It also notes the required 'write scope', providing security-relevant information that is not present in the structured 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?
Everything is captured in two concise sentences with no filler. The core outcome ('receives no more events') is front-loaded, followed by the irreversible caution and user confirmation, making every word earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive action with no output schema, the description covers all essential context: the action, the result, the irreversibility, the permission, and the safety step required before invocation. Nothing an agent needs to decide whether to call it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% coverage with a description for the only parameter (webhookId), including UUID format and pattern. The tool description adds only a passing mention of {id} in the path, which is useful but does not materially enrich the meaning beyond the schema's own definition.
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 uses a specific action verb ('Delete (archive)') on a concrete resource ('webhook') and states the immediate effect: it no longer receives events. It also includes the HTTP method and scope, making the tool's function unambiguous and clearly distinct from siblings like update_webhook, enable_webhook, or get_webhook.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly warns that the action is irreversible and instructs to confirm with the user first, which is a strong usage guideline. However, it does not explicitly mention when to use this tool instead of a soft-disable via update_webhook, so it misses the remainder of the 'vs alternatives' guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_click_statsGet click statsARead-onlyIdempotentInspect
Email link click counts grouped by destination URL (GET /clicks) for a sendId, a campaignId, or both (at least one is required). Only links from email sends made with trackClicks: true are counted.
| Name | Required | Description | Default |
|---|---|---|---|
| sendId | No | A sendId from send_notification. | |
| campaignId | No | The `campaignId` passed to send_notification, to total clicks across many sends. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so safety is covered. The description adds meaningful behavior beyond those annotations: results are grouped by destination URL and only links from trackClicks-enabled sends are counted. It does not discuss response shape or pagination, but the core filtering behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The first sentence front-loads the resource, grouping behavior, and accepted identifiers; the second adds the key tracking precondition. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only two-parameter tool with fully described schema properties and no output schema, the description provides the required parameter relationship, the grouping concept, and the filtering caveat. It does not spell out the exact response fields, but 'click counts grouped by destination URL' gives enough shape for an agent to invoke and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics: at least one of sendId/campaignId is required, campaignId totals across many sends, and only tracked-link emails contribute. These details are not encoded in the schema's property constraints and meaningfully shape invocation.
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 uses a specific verb and resource: it returns email link click counts grouped by destination URL, and it identifies the query scope (sendId, campaignId, or both). This clearly separates it from sibling read tools like get_send_status and get_usage.
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 states what identifiers the tool operates on and that at least one is required, and it gives an important precondition (trackClicks: true). However, it never explicitly contrasts this with alternatives such as get_send_status or get_usage, so an agent must infer when this tool is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_send_statusGet send statusARead-onlyIdempotentInspect
Delivery status of a send (GET /sends/{id}): aggregate counts per status over the whole send (pending, claimed, delivered, failed_retryable, failed_terminal, suppressed) plus one page of per-recipient delivery rows including provider errors. Right after sending, rows are usually pending; check again after a few seconds. Feed-only sends have no rows. For more rows, pass the returned nextCursor as cursor.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Rows per page (default 50, max 200). | |
| cursor | No | `nextCursor` from the previous page. | |
| sendId | Yes | The `sendId` returned by send_notification or test_send_template. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the idempotent/read-only annotations by revealing the dynamic behavior of the response (pending -> eventual statuses), the caveat about feed-only sends having no rows, and the pagination mechanism (nextCursor). This adds helpful context for an agent, though the annotations already cover idempotency and read-only safety, so the description adds value but doesn't disclose every possible 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?
The description is concise but packs a lot of essential info in two sentences. It starts with the core purpose, then explains the response contents, adds a timing tip, a special case, and pagination guidance. It is efficient without being sparse, though it could be slightly more structured (e.g., bullet points) but that's not required. It's a good length.
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 status tool with only 3 parameters (well-documented in schema) and no output schema, the description covers the response structure, timing considerations, special cases, and pagination. This makes it complete enough for an agent to call correctly. The only minor gap is lack of explicit mention of what 'provider errors' look like, but that's not essential for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already has 100% coverage with descriptions for each parameter: `sendId` is explained (returned by send_notification), `limit` has defaults and max, and `cursor` is tied to `nextCursor`. The description reinforces pagination via the `nextCursor` but does not add much extra meaning beyond the schema. Baseline is 3 due to high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose with a specific verb ('get') and resource ('send status'), and provides detailed details on the response: aggregate counts per status, per-recipient rows with provider errors. It distinguishes itself from other tools by focusing on delivery status, and the HTTP method and endpoint are stated explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear guidance on when to use the tool: to check delivery status after sending a notification. It notes that rows may be 'pending' initially and suggests checking again after a few seconds, offering practical usage tips. It also mentions that feed-only sends have no rows retreating directly from the tool's behavior, but does not explicitly state when not to use it or mention alternatives, so it's not a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_templateGet templateARead-onlyIdempotentInspect
Get one template with its published version and its current draft (GET /templates/{id}): content, logTitle/logDescription, requiredParams a send must supply, and paramOverrides. Read this before update_template_draft, which needs the full body.
| Name | Required | Description | Default |
|---|---|---|---|
| templateId | Yes | The template id (UUID). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds useful behavioral context: the tool returns both the published version and current draft, includes requiredParams and paramOverrides, and is the required precursor to update_template_draft. It doesn't cover error cases or auth, but the annotations plus this context are sufficient for a read-only fetch.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no redundancy. The first sentence front-loads the endpoint and payload fields; the second provides critical usage guidance. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with one fully documented parameter and annotations covering safety, the description provides enough return-value detail despite no output schema: it names the key fields and the relationship to update_template_draft. An agent can confidently select and invoke 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 description coverage is 100%, with the only parameter templateId fully documented as 'The template id (UUID).' The description confirms the parameter appears in the URL path but adds no new semantic detail beyond the schema, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Get one template with its published version and its current draft', and lists the exact fields returned (content, logTitle/logDescription, requiredParams, paramOverrides). It also gives the endpoint '(GET /templates/{id})', making it easy to distinguish from siblings like list_templates or update_template_draft.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent when to use this tool: 'Read this before update_template_draft, which needs the full body.' This names the sibling alternative and gives a clear sequencing rule, so an agent knows this is the prerequisite read for a specific downstream action.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_usageGet plan and usageARead-onlyIdempotentInspect
The workspace's plan, subscription status and this calendar month's usage against the monthly quota (GET /billing/subscription). used/remaining are null on unmetered plans. On a hard-capped plan, sends beyond the quota fail with HTTP 402 quota_exceeded.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive behaviorhol, so the description adds value by specifying that `used`/`remaining` are null on unmetered plans and that hard-capped plans return HTTP 402 quota_exceeded on sends. This is useful behavioral context beyond the annotations, though it doesn't detail the full response structure beyond those fields.
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 two sentences and front-loads the core purpose before adding edge-case details about unmetered plans and quota failures. Every sentence adds value, though the technical HTTP 402 detail could be slightly trimmed without losing essential meaning.
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?
Given the tool's simplicity (no params, no output schema), the description covers the key behavioral nuances: null values on unmetered plans and quota enforcement. It's complete enough for an agent to know when to call it and what to expect, though it could mention that this is account-scoped rather than template/webhook-scoped.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters)Skip the schema covers 100% of parameter docs by having none, so the description carries no parameter burden. The tool's no-argument nature is implicit but the description adds clarity by explaining the output fields' semantics (used/remaining null on unmetered plans). This is enough given no params exist.
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 returns the workspace's plan, subscription status, and month-to-date usage against quota, and it also names the underlying endpoint (GET /billing/subscription). It distinguishes itself from the 20 sibling tools by focusing on billing/usage rather than templates, webhooks, or sends. This is a specific verb+resource definition.
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 this tool is for checking billing/usage context, but it does not explicitly state when to use it vs. alternatives like whoami or list_* tools. It also doesn't mention that it's a zero-parameter call that gives account-level info. The context of when to check usage vs. other endpoints is left to the agent's inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_webhookGet webhookARead-onlyIdempotentInspect
Get one outbound webhook (GET /tenant-webhooks/{id}) including its delivery health (consecutiveFailures, lastDeliveryAt, lastFailureAt, lastError).
| Name | Required | Description | Default |
|---|---|---|---|
| webhookId | Yes | The webhook id (UUID). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, which clearly indicate this is a safe, non-mutating read operation. The description adds context about the specific fields returned (consecutiveFailures, lastDeliveryAt, lastFailureAt, lastError), which is useful for the agent. However, it doesn't disclose behaviors like caching, rate limiting, or error responses. Given the annotations cover the safety profile, the description adds some value but not extensive behavioral detail. It does not contradict 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 a single, concise sentence with no filler. It front-loads the essential action and resource (Get one outbound webhook), then adds a brief mention of the endpoint and the health fields. Every word is purposeful and contributes to the agent's understanding. It is appropriately sized and well-structured for quick consumption.
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?
Given the tool's simplicity (one parameter, read-only, safe), the description is quite complete. It tells the agent what it does, what it returns (health fields), and the endpoint. Since the schema fully documents the parameter and there is no output schema, the description suffices to guide correct invocation. The only minor gap is not explicitly stating the tool is used to fetch a single webhook versus listing all, but that is arguably covered by the purpose clarity. Overall, it's complete for its complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage of the single parameter 'webhookId', including its type, format (UUID), pattern, and a description. This is comprehensive. The description does not add anything about the parameter itself; it only refers to 'one outbound webhook', which implicitly ties the parameter to a webhook resource. Since the schema fully documents the parameter, the description is not required to add more, but it also doesn't enhance the meaning beyond what's already there. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get') and resource ('one outbound webhook'), and clearly identifies the tool's function: retrieving a single webhook by its ID. It also mentions the inclusion of delivery health fields, which distinguishes it from sibling tools like list_webhooks and update_webhook. The inclusion of the HTTP method (GET) and endpoint path provides additional clarity. An agent can immediately understand what this tool does and how it differs from other webhook-related tools.
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 when to use this tool: when you need details about a specific webhook, including its delivery health. However, it does not explicitly state when not to use it or mention alternatives like list_webhooks for retrieving all webhooks. It also lacks guidance on prerequisites, such as the need to have a valid webhook ID. The description provides basic usage context but does not explicitly guide the agent on choosing between this and other webhook tools. Effective but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_channelsList channelsARead-onlyIdempotentInspect
List the delivery channels configured in this workspace (GET /channels). Call this FIRST before sending: each entry's id is the channelConfigId for send_notification and test_send_template, kind is the channel type (ses_email, smtp_email, fcm_push, slack_webhook, discord_webhook, telegram_bot, generic_webhook), templateKind is the template channelKind it accepts, and recipientSchema is the exact JSON Schema of the recipient it expects. Channels and their provider credentials are set up in the Ray dashboard, not through this API; if the list is empty, ask the user to add one there.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety is covered. The description adds behavioral context by detailing the response fields and the external configuration dependency, which goes beyond the annotations without contradicting them.
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 well-structured and front-loaded: the first sentence states the purpose, the second gives the critical usage instruction, the third details the response fields, and the fourth addresses setup. Each sentence contributes essential information without fluff.
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?
Despite having no parameters or output schema, the description thoroughly explains the output structure and the workflow (call first, then use fields for subsequent sends). It also covers the external setup and the empty-list case, making it fully self-sufficient for an agent.
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 covers everything. The description adds no parameter-specific info (none needed), so the baseline of 4 applies; it does not hurt but also does not need to compensate.
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 ('List') and resource ('delivery channels'), and specifies the endpoint (GET /channels). It is clearly distinguishable from sibling list tools like list_templates and list_webhooks, as it targets channels specifically.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to call this FIRST before sending, and explains how to use the returned fields (id maps to channelConfigId, kind, templateKind, recipientSchema). It also directs the user to the Ray dashboard for setup and what to do if the list is empty, leaving no ambiguity about when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_feed_notificationsList feed notificationsARead-onlyIdempotentInspect
Read one end user's in-app notification feed (GET /notifications): the entries created by sends with feed or showInFeed. This is what an in-app inbox would show, not delivery status (use get_send_status for that). Paginate by passing nextCursor back as cursor.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Only entries created after this ISO 8601 UTC datetime (e.g. "2026-09-01T00:00:00Z"). | |
| limit | No | Entries per page (default 50, max 200). | |
| before | No | Only entries created before this ISO 8601 UTC datetime. | |
| cursor | No | `nextCursor` from the previous page. | |
| templateId | No | Only entries from this template. | |
| externalUserId | Yes | The end user whose feed to read (the `externalUserId` used when sending). | |
| channelConfigId | No | Only entries whose first delivery used this channel. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior. The description adds meaningful context beyond annotations: the feed is specifically populated by sends with 'feed' or 'showInFeed', and pagination requires passing nextCursor back as cursor. 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 sentences, each earning its place: what the tool reads, what it excludes, and how pagination works. The most important scope information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only feed tool with 7 parameters, high schema coverage, and annotations covering safety, the description is mostly complete. It identifies the resource type, the relevant send modes, and pagination flow. It does not describe output ordering, but no output schema is declared and this is a minor gap for a list-type operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds useful parameter-related context by explaining the pagination contract ('Passing nextCursor back as cursor') and clarifying the feed's relationship to sends, which goes slightly beyond the schema's individual field descriptions.
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 the specific resource ('one end user's in-app notification feed'), the exact verb ('Read'), and the endpoint (GET /notifications). It also clearly differentiates this from delivery status, which is handled by get_send_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states exactly when to use this tool: to read in-app feed entries from sends with 'feed' or 'showInFeed'. It explicitly points to get_send_status as the alternative for delivery status, giving the agent clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_templatesList templatesARead-onlyIdempotentInspect
List message templates (GET /templates): id, name, folder, channelKind, and publishedVersionId (null = never published, so it cannot be sent by templateId yet). Archived templates are hidden unless includeArchived is true. Use get_template for content and required params.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | Only templates in this folder. | |
| includeArchived | No | Include archived templates. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the bar is lower. The description adds useful behavior beyond annotations: archived templates are excluded by default, and publishedVersionId null means the template has never been published and cannot yet be sent by templateId. There is no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler: endpoint, return fields, caveats, and sibling pointer are each given exactly one clause. The most decision-relevant information (what is listed and when archived templates appear) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple filtered list tool with readOnly/idempotent annotations, the description covers purpose, return fields, the one non-default flag, and the alternative for deeper content. No output schema exists, so the field enumeration and null semantics carry the necessary return-value explanation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 and the description does not need to compensate. It restates includeArchived's effect but adds no new meaning to either parameter beyond what the input schema already documents.
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 opens with a specific verb and resource ('List message templates') and names the exact endpoint plus the returned fields. It also distinguishes itself from get_template by delegating content and required params to that sibling, so an agent can tell the tools apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states that archived templates are hidden unless includeArchived is true, which tells the agent when to set that flag. It also gives an explicit alternative: 'Use get_template for content and required params,' covering the main when-not condition for this listing tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_webhooksList webhooksARead-onlyIdempotentInspect
List the workspace's outbound event webhooks (GET /tenant-webhooks): url, subscribed events, enabled flag and delivery health (consecutiveFailures, lastError). Signing secrets are never returned.
| Name | Required | Description | Default |
|---|---|---|---|
| includeArchived | No | Include deleted (archived) webhooks. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only, idempotent, and non-destructive nature of the operation. The description adds meaningful context by specifying the returned fields and explicitly stating that signing secrets are never returned, which is a useful safety-related disclosure 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 a single compact sentence that front-loads the verb, resource, and endpoint, then packs in the key return fields and the signing-secret caveat. There is no redundant or filler content.
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 list operation with rich annotations and only one optional parameter, the description is complete. It explains what the tool returns, includes the relevant endpoint, and adds a security note; the one parameter is already fully explained in the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the includeArchived parameter is fully documented in the schema. The description does not add any additional parameter semantics, but it does not need to; the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and resource ('the workspace's outbound event webhooks'), and enumerates what is included in the result. It is immediately distinguishable from sibling tools like get_webhook, delete_webhook, and update_webhook because it clearly frames this as a read-only listing operation.
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 makes the tool's purpose clear enough that an agent can infer when to call it, but it never explicitly contrasts it with alternatives. It does not mention get_webhook for single-webhook retrieval or state when to prefer list_webhooks over the other webhook-related siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_templatePublish templateAInspect
Publish a template's current draft as its new live version (POST /templates/{id}/publish; write scope). Sends by templateId use it immediately. Fails if there is no draft or the template is archived.
| Name | Required | Description | Default |
|---|---|---|---|
| templateId | Yes | The template id (UUID). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses key behavioral traits: it requires write scope, it fails if there is no draft or the template is archived, and it publishes immediately. The annotations already indicate it's not read-only, not idempotent, and not destructive, but the description adds context about the draft/live version mechanism and failure conditions.
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 concise and front-loaded with the core action, followed by the endpoint, scope requirement, and failure conditions. Every sentence earns its place with no waste.
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 tool with a clear schema and annotations, the description is quite complete. It covers the action, the endpoint, the scope requirement, and failure conditions. It doesn't describe the return value, but there's no output schema and the tool is simple enough that this is a 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 already provides 100% coverage for the single parameter (templateId) with a clear description. The description doesn't add much beyond the schema, but the baseline of 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (publish a template's current draft as its new live version), the resource (template), and the endpoint (POST /templates/{id}/publish). It distinguishes itself from sibling tools like update_template_draft and archive_template by focusing on the publish 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?
The description provides clear context for when to use the tool: when you want to publish a template's draft as the live version. It also mentions failure conditions (no draft or archived template), which helps the agent decide when not to use it. However, it doesn't explicitly name alternative tools for those cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_docsRead Ray docsARead-onlyIdempotentInspect
Read Ray's documentation as markdown. With no slug it returns the index (llms.txt) listing every page; then pass a page slug, i.e. the path after /docs/ without .md, such as sending, templates, idempotency, errors, rate-limits, webhooks, status-and-feeds or channels/telegram. Use it for anything the tool descriptions don't cover.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | No | Page slug like "sending" or "channels/push-fcm". Omit for the index of all pages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds behavioral context beyond annotations by explaining the two modes (index vs. page) and the slug format requirement (path after /docs/ without .md). It doesn't mention rate limits or response size, but for a read-only docs tool the added context is sufficient.
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 explains the two modes, gives examples, and ends with usage guidance. Every sentence earns its place with no redundancy or 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 simple read-only tool with one optional parameter and no output schema, the description is complete. It explains the two invocation modes, the slug format, provides examples, and states when to use the tool. The annotations cover the safety profile, and the schema covers the parameter. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the slug parameter. The description adds value by explaining the slug format precisely (path after /docs/ without .md) and providing concrete examples, plus clarifying that omitting it returns the index. This goes beyond the schema's generic 'Page slug like...' description.
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 reads Ray's documentation as markdown, with a specific verb and resource. It distinguishes itself from siblings by being the documentation lookup tool, and explicitly says to use it for anything the tool descriptions don't cover, which differentiates it from the other API tools.
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 provides explicit usage guidance: with no slug it returns the index, and with a slug it returns a specific page. It also gives concrete examples of valid slugs and states when to use it ('for anything the tool descriptions don't cover'), which is clear context for when to invoke this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_notificationSend notificationAInspect
Send a notification (POST /send; needs a write-scoped key). Returns { sendId } with HTTP 202: delivery is asynchronous, so check the outcome with get_send_status. Use exactly one mode:
Single:
channelConfigId+recipient.Fan-out:
channelConfigId+targets(1-1000{ recipient, externalUserId? }), one channel, one sendId.Multi-channel:
deliveries(1-10, each with its ownchannelConfigId,recipientandtemplateIdorcontent) for ONE person over several channels; addfeed+externalUserIdfor a single in-app feed entry.Feed-only:
feed(withtitle) +externalUserIdand no channel: an in-app notification only. In modes 1-2 give exactly one oftemplateId(a published template, plusparams) or inlinecontent; in mode 3 that choice is made per delivery. Get channel ids and each recipient shape from list_channels first. PassidempotencyKeywhenever a retry must not deliver twice.
| Name | Required | Description | Default |
|---|---|---|---|
| feed | No | Create exactly ONE in-app feed entry for `externalUserId` (read back with list_feed_notifications). `title`/`description` default to the rendered template text; `title` is required for a feed-only send (mode 4). | |
| params | No | Values for the template's `{{placeholders}}`. Any JSON: strings, numbers, booleans, arrays and nested objects (arrays/objects drive `{{#section}}…{{/section}}` blocks). Missing required params are rejected with a 400 naming them. | |
| content | No | Inline message content, used INSTEAD of `templateId` (give exactly one of the two). Shape by channel kind: ses_email / smtp_email → `{ subject, bodyHtml, bodyText }`; fcm_push → `{ title, body, imageUrl?, data?: { [key]: string } }`; slack_webhook → `{ text }` (Slack mrkdwn); discord_webhook → `{ content }` (max 2000 chars); telegram_bot → `{ text, disableLinkPreview? }` (Telegram HTML subset); generic_webhook → `{ title, body, data?: { [key]: string } }`. `{{name}}` placeholders are filled from `params` and escaped for the channel. | |
| targets | No | Mode 2: fan-out to 1-1000 recipients over ONE channel, sharing one sendId. Mutually exclusive with `recipient`. | |
| logTitle | No | Feed/log title for inline `content` sends only (template sends take it from the template). Placeholders allowed. | |
| priority | No | "high" (default) for transactional messages; "low" for marketing/bulk so it never delays transactional sends. | |
| notBefore | No | Schedule delivery for later: ISO 8601 datetime with offset, e.g. "2026-09-15T09:00:00+08:00". Omit to send now. | |
| recipient | No | Mode 1: the single recipient. Mutually exclusive with `targets`. Channel-specific delivery target. Its shape depends on the kind of the chosen channel (list_channels returns each channel's exact `recipientSchema`): ses_email / smtp_email → `{ email, name?, cc?: [{ email, name? }], bcc?: [...], attachments?: [{ filename, content (base64), contentType?, disposition?: "attachment"|"inline", contentId? }] }`; fcm_push → `{ deviceToken }` OR `{ topic }` (exactly one; Ray keeps no device registry); telegram_bot → `{ chatId }` (numeric id as a string, or "@channelname"); slack_webhook, discord_webhook, generic_webhook → `{}` (the destination is part of the channel config). | |
| campaignId | No | Free-form campaign id used to group click stats across sends. | |
| deliveries | No | Mode 3: the same notification to ONE person over several channels (e.g. push + email), max 10. Each entry has its own channel, recipient and content source. Do not combine with top-level channelConfigId/recipient/targets/templateId/content. | |
| showInFeed | No | Legacy modes 1-2 flag: also add a feed entry for each target that has an externalUserId. Prefer `feed`. Not valid with `deliveries`. | |
| templateId | No | Modes 1-2: a PUBLISHED template to render (see list_templates / publish_template). Exactly one of `templateId` or `content`. Its channelKind must match the channel's `templateKind`. | |
| trackClicks | No | Email channels only: rewrite links in bodyHtml so clicks are counted (read with get_click_stats). Default false. | |
| externalUserId | No | Your own id for the end user. Required with `feed`; keys their in-app feed. | |
| idempotencyKey | No | Sent as the Idempotency-Key header. Retrying with the same key and same arguments returns the original sendId without sending again (24h window); the same key with different arguments fails with 409. Use a fresh unique value (e.g. a UUID) per logical notification. | |
| logDescription | No | Feed/log description for inline `content` sends only. Placeholders allowed. | |
| channelConfigId | No | Modes 1-2: the channel to send through — an `id` from list_channels. Not allowed together with `deliveries`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses the HTTP 202 async delivery semantics, the required write-scoped key, the returned sendId, side effects like in-app feed entries, and idempotency behavior via idempotencyKey. These are exactly the behavioral facts an agent needs and they are not recoverable from the annotations alone.
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 long, but the tool is genuinely complex. It is front-loaded with the endpoint, auth, response, and async behavior, then compactly enumerates the four modes. Each sentence carries decision-relevant information; there is no filler or repetition of generic tool boilerplate.
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?
Despite having no output schema, the description covers the return contract ('Returns { sendId } with HTTP 202') and directs the agent to get_send_status for the outcome. It also covers prerequisites, per-channel recipient shapes, template vs inline content, mode-specific exclusions, and idempotency guidance. Nothing critical is missing for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description earns extra by organizing the 17 parameters into a mode-based decision tree, clarifying mutual exclusions such as 'exactly one of templateId or content', and explaining per-delivery vs top-level parameter usage in mode 3. The schema also documents these, but the description adds orchestration-level meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: 'Send a notification (POST /send; needs a write-scoped key).' It also distinguishes the tool from related siblings by naming get_send_status for checking the async result and list_channels for resolving channel ids, and it defines four mutually exclusive send modes so an agent can tell what this tool is for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use each mode ('Use exactly one mode: 1. Single… 2. Fan-out… 3. Multi-channel… 4. Feed-only'), gives the condition for template vs inline content, and names the prerequisite tool list_channels and the follow-up tool get_send_status. This is explicit, actionable guidance rather than implied usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
test_send_templateTest-send templateAInspect
Send a real test of a template's PUBLISHED version to one recipient (POST /templates/{id}/test-send; write scope). It goes through the provider for real, so use a recipient the user controls. Test sends don't count toward the monthly quota (a small daily allowance applies instead) and never appear in feeds. Returns { sendId } for get_send_status.
| Name | Required | Description | Default |
|---|---|---|---|
| params | No | Values for the template's `{{placeholders}}`. Any JSON: strings, numbers, booleans, arrays and nested objects (arrays/objects drive `{{#section}}…{{/section}}` blocks). Missing required params are rejected with a 400 naming them. | |
| recipient | Yes | Channel-specific delivery target. Its shape depends on the kind of the chosen channel (list_channels returns each channel's exact `recipientSchema`): ses_email / smtp_email → `{ email, name?, cc?: [{ email, name? }], bcc?: [...], attachments?: [{ filename, content (base64), contentType?, disposition?: "attachment"|"inline", contentId? }] }`; fcm_push → `{ deviceToken }` OR `{ topic }` (exactly one; Ray keeps no device registry); telegram_bot → `{ chatId }` (numeric id as a string, or "@channelname"); slack_webhook, discord_webhook, generic_webhook → `{}` (the destination is part of the channel config). | |
| templateId | Yes | The template id (UUID). | |
| channelConfigId | Yes | Channel to test through (from list_channels); its templateKind must match the template's channelKind. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false, destructiveHint=false, and openWorldHint=true. The description adds valuable behavioral context: the send goes through the provider for real, test sends don't count toward monthly quota but a daily allowance applies, and they never appear in feeds. It also discloses the return shape ({ sendId }). This goes beyond the annotations without contradicting them.
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 core action and endpoint appear in the first sentence, followed by the most important caveat (real send, use controlled recipient), then quota/feed behavior, then return value. Every sentence earns its place; no filler or repetition of schema details.
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 tool with no output schema, the description covers the return value ({ sendId }), the real-world side effect, quota implications, feed visibility, and recipient guidance. The schema covers parameter shapes thoroughly. The only minor gap is that it doesn't explicitly state what happens on failure, but the schema's 400 note and the reference to get_send_status provide enough context. Overall, an agent has everything needed to invoke this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful context beyond the schema: it explains that params drive section blocks, that missing required params are rejected with a 400 naming them, and it details the recipient shape per channel type (including that Ray keeps no device registry and webhooks use {}). This is genuinely helpful semantic enrichment.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Send a real test'), a specific resource ('a template's PUBLISHED version'), and the exact endpoint (POST /templates/{id}/test-send). It clearly distinguishes this from send_notification and other template tools by emphasizing it tests the published version to one recipient. The write scope is also disclosed.
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 explicitly says when to use this tool: to send a real test of a template's published version to one recipient. It warns to use a recipient the user controls, and notes the daily allowance vs monthly quota distinction. It also references get_send_status for follow-up, and the schema notes channelConfigId must match the template's channelKind, which guides correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unarchive_templateUnarchive templateAIdempotentInspect
Restore an archived template (POST /templates/{id}/unarchive; write scope). This is how to reclaim a name held by an archived template instead of creating a new one.
| Name | Required | Description | Default |
|---|---|---|---|
| templateId | Yes | The template id (UUID). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false, so the core safety profile is covered. The description adds the behavioral context of restoring an archived template and reclaiming a name, which is useful beyond the annotations. It does not add further details like response behavior or side effects, but the annotations lower the burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The purpose is front-loaded, the endpoint provides precise grounding, and the alternative use case is stated in the second sentence. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, no-output-schema tool, the description plus annotations and schema fully cover what an agent needs: what the tool does, when to use it, the parameter format, and the safe/idempotent behavior. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter templateId already has a clear description ('The template id (UUID).'). The tool description adds no additional parameter-level meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: "Restore an archived template". It then names the HTTP endpoint, which unambiguously identifies the operation, and contrasts it with creating a new template. This clearly differentiates the tool from siblings like archive_template and create_template.
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 explicitly states when to use this tool: "This is how to reclaim a name held by an archived template". It also names the alternative behavior it replaces ("instead of creating a new one"). This gives an agent a concrete decision rule for selection among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_template_draftUpdate template draftAInspect
Replace a template's draft (PATCH /templates/{id}; write scope). This is a full replacement, not a partial patch: pass content, logTitle, logDescription and paramOverrides as they should end up (get_template first). name, folder and channelKind are required for validation but not changed (channelKind must equal the original). Live sends keep using the published version until you publish, either with publish: true here or publish_template. Fails on archived templates.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Template name, unique per workspace (archived templates included). | |
| folder | No | Optional folder path for organisation, e.g. "billing". | |
| content | Yes | Channel-shaped template body; the shape is fixed by `channelKind`: email_html → `{ subject, bodyHtml, bodyText }`; fcm_basic → `{ title, body, imageUrl?, data?: { [key]: string } }`; slack_text → `{ text }`; discord_text → `{ content }` (max 2000 chars); telegram_text → `{ text, disableLinkPreview? }`; webhook_json → `{ title, body, data?: { [key]: string } }`. Use `{{name}}` placeholders and `{{#items}}…{{/items}}` sections; the required params are derived from them automatically. | |
| publish | No | true = publish this version immediately so sends by templateId use it. Default false (saved as draft). | |
| logTitle | Yes | Short title shown in the in-app feed and delivery logs, e.g. "Invoice {{number}} is due". Placeholders allowed. | |
| templateId | Yes | The template id (UUID). | |
| channelKind | Yes | Which channel family the template renders for. Must match the `templateKind` of the channels you will send through (list_channels). Can't be changed after creation. | |
| logDescription | Yes | One-line description for the in-app feed and delivery logs. Placeholders allowed. | |
| paramOverrides | No | Per-param metadata keyed by param name: `{ optional?: boolean, description?: string }`. Mark a placeholder optional so sends may omit it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=false, destructiveHint=false), the description discloses the write scope, the full-replacement semantics, and the crucial fact that live sends keep using the published version until publishing. It also reveals validation-only parameters (`name`, `folder`, `channelKind`) that are required but not changed, and the archived-template failure case—all valuable behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence carries essential information: the operation and method, the full-replacement rule, the publication behavior, and the archived failure condition. It is front-loaded with the primary purpose and avoids repeating schema details.
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?
Given the tool's complexity—9 parameters, nested content shapes, validation-only fields, and publish behavior—the description covers all critical invocation aspects: how to prepare parameters, whether to use publish, the live-send behavior, and an error condition. No output schema exists, but the description provides enough 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 100%, so the baseline is 3, but the description adds meaningful semantics beyond the schema: it identifies which parameters are changed vs. validation-only, stresses that `channelKind` must equal the original, and explains the delivery of `content`, `logTitle`, `logDescription` and `paramOverrides`. This helps the agent understand the overall replacement contract rather than just per-field constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Replace'), a precise resource ('a template's draft'), and the exact API operation ('PATCH /templates/{id}'). It also clarifies that this is a full replacement, not a partial patch, and explicitly contrasts with the sibling publish_template, so an agent can distinguish it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: call get_template first, pass the full intended state, and rely on `publish: true` here or publish_template to affect live sends. It also states an important exclusion—'Fails on archived templates'—which prevents the agent from attempting invalid updates.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_webhookUpdate webhookAInspect
Change a webhook (PATCH /tenant-webhooks/{id}; write scope). Only the fields you pass change; pass at least one. rotateSecret: true issues a new signing secret, returned once in the response, and the old secret stops verifying immediately, so the receiving service must be updated at the same time.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | New public HTTPS endpoint. | |
| name | No | New label. | |
| events | No | Replaces the subscribed events. Events to receive: "notification.delivered", "notification.failed_terminal" (one per recipient), and "send.completed" (once per send, with status totals). | |
| enabled | No | false pauses deliveries without deleting the webhook. | |
| webhookId | Yes | The webhook id (UUID). | |
| rotateSecret | No | true rotates the signing secret (new secret returned once; old one invalid immediately). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide readOnly=false, so the description carries the burden of exposing mutation behavior. It discloses write scope, one-time secret return, immediate invalidation of the old secret, and the coordination requirement for rotateSecret, going well beyond 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 sentences carry the essential information with no redundancy. The endpoint and primary purpose are front-loaded, and the rotateSecret warning is placed where it matters most.
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?
Given no output schema, the description still covers the output-critical behavior: a new signing secret is returned once. Combined with the rich schema, an agent has enough to call this tool correctly, including the operational risk of rotating the secret.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, and the description adds additional meaningful semantics: partial update, requiring at least one field, and the special side-effect of rotateSecret. It focuses on the riskiest parameter rather than duplicating the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Change'), a specific resource ('a webhook'), and the endpoint/method (PATCH /tenant-webhooks/{id}). This clearly separates it from sibling tools like create_webhook, delete_webhook, get_webhook, and list_webhooks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It makes the intended usage clear with partial-update semantics ('Only the fields you pass change; pass at least one') and gives a strong caution for rotateSecret. It does not explicitly enumerate when to prefer this tool over sibling alternatives, but the context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoamiWho am IARead-onlyIdempotentInspect
Identify the API key this connection uses (GET /me): tenantId (the workspace), apiKeyId and scopes. Write tools need the write scope; call this to check before attempting them.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only, idempotent, and non-destructive. The description adds important behavioral context beyond that by specifying what the endpoint returns (tenantId, apiKeyId, scopes) and why the scope info matters. Since there is no output schema, this return-value disclosure is especially valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the first states the purpose and result fields, the second gives the operational trigger. Every phrase earns its place, and the most actionable guidance comes immediately after the core purpose.
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 identity-check tool, the description is complete: it explains what the tool does, what it returns, and when to call it. Annotations cover the safety profile, and no output schema is needed because the description names the key return fields.
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 baseline is 4. The description appropriately focuses on the output rather than inputs; no additional parameter documentation is needed.
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 uses a specific verb ('Identify') and resource ('the API key this connection uses'), and names the returned fields (tenantId, apiKeyId, scopes). It is immediately distinct from all sibling tools, which focus on templates, webhooks, notifications, and stats.
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 explicitly states when to call the tool: before attempting write tools, because they need the `write` scope. This gives an agent a clear decision rule despite the tool having no obvious siblings performing a similar function.
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.
21 tool updates
- First observed
archive_template - First observed
create_template - First observed
create_webhook - First observed
delete_webhook - First observed
get_click_stats - First observed
get_send_status - First observed
get_template - First observed
get_usage - First observed
get_webhook - First observed
list_channels - First observed
list_feed_notifications - First observed
list_templates - First observed
list_webhooks - First observed
publish_template - First observed
read_docs - First observed
send_notification - First observed
test_send_template - First observed
unarchive_template - First observed
update_template_draft - First observed
update_webhook - First observed
whoami
Related MCP Connectors
Send notifications, manage templates, and configure integrations with Courier.
Let your AI agent notify you by email, Slack, Discord, or webhook. One tool: send_notification.
Send, search, and manage notifications, accounts, and push preferences
Build and send email, SMS, and push straight from your AI agent.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables sending rich notifications to Discord and/or Slack webhooks with automatic service detection, retry logic, and support for embeds, blocks, and attachments. Provides secure webhook management with comprehensive input validation and rate limiting.3TypeScriptMIT
- AlicenseNot gradedqualityCmaintenanceUnified notification MCP server with 36 tools to send messages across 23 channels — Email, SMS, Slack, Telegram, Discord, Teams, WhatsApp, Firebase Push, and more.5MIT
- FlicenseAqualityCmaintenanceEnables agents and applications to send notifications through configurable channels such as Telegram or a JSONL file, with queued delivery, status tracking, idempotency, and event-based routing.2-
- FlicenseNot gradedqualityBmaintenanceEnables agents to send structured notifications to recipients via configurable channels (initial SMTP provider) without exposing delivery addresses or credentials, with tools for listing recipients, listing channels, and sending notifications.-
Glama MCP Gateway
Add one secure layer between your agents and this server.