Cluby MCP
Server Details
Cluby MCP allows you to manage your restaurant, loyalty program and events from your favorite AI chat.
- Status
- Healthy
- Uptime
- 99.8% over 48 days
- OAuth
- Works in Glama
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 32 tools
Most tools target distinct resources and actions, with clear separation between benefits, birthday gifts, smart links, webhook endpoints, POS connections, and various read-only listings. The main possible confusion is between the two webhook test tools and among stats-oriented tools such as dashboard_summary, member_stats, and org_activity, but descriptions make their scopes reasonably clear.
The dominant pattern is consistent snake_case verb_noun naming across create, list, update, delete, get, set, test, replay, and import tools. A few tools use noun-only names such as dashboard_summary, member_stats, and org_activity, which is a minor deviation but still readable and predictable.
With 32 tools, the surface is heavy for the apparent scope, and several tools are narrow list/get variants rather than distinct workflows. The breadth of the domain partly justifies the size, but it exceeds the range where each tool clearly earns its place.
Core workflows for benefits, birthday gifts, smart links, webhook endpoints, and POS connections have create/list/update coverage, with full CRUD for webhook endpoints and POS connections. However, notable gaps remain: no delete operations for benefits, birthday gifts, or smart links, and many domain objects such as venues, events, status cards, and stamp cards are read-only.
Available Tools
32 toolscreate_benefitCreate benefitAInspect
Create a benefit (member perk), the same as saving the Partner Hub's benefit form. An independent copy is created in each venue of venueIds (public ids from list_venues) and the response lists every copy. Requires the admin role on those venues. For a new photo, call import_image first and pass its image as content.image. Text fields are localized strings: { default: "…" } plus optional per-locale translations such as fi or en. activation needs validFrom (ISO datetime; the current time for a benefit available right away), validUntil (null for no end date) and frequency (how often one member can activate it). visibleToStatusCards (ids from list_status_cards) limits it to holders of those membership cards; omit it for every member. For a benefit created from the partner product catalogue (productVariantId), materialsOrder gives the shipping contact's name, email and phone for the free marketing materials sent to the venue. The benefit is live for members at once unless status is hidden, so confirm the details with the user before calling this.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| status | No | Effective hidden state: the venue's own hide toggle OR the campaign layer (see hiddenByCampaignAt) OR the partner-catalogue layer (see hiddenByProductAt) | active |
| content | Yes | ||
| venueIds | Yes | Venue IDs where this benefit is available | |
| sortOrder | No | ||
| activation | Yes | ||
| campaignId | No | ||
| templateId | No | Template ID used to create this benefit | |
| materialsOrder | No | Marketing-materials order, sent when the benefit is created from the partner product catalogue. Reported, never stored. | |
| productVariantId | No | Partner product variant this benefit was created from | |
| visibleToStatusCards | No | Membership tier IDs. Undefined/empty = public benefit |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the lone destructiveHint=false annotation, the description discloses important behavior: an independent copy is created per venue, the response lists every copy, admin role is required, the benefit is live immediately unless status is hidden, and materialsOrder is reported but never stored. This adds substantial operational context an agent needs before mutating state.
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 front-loaded and dense with actionable facts. Every sentence addresses creation behavior, prerequisites, or tricky parameter semantics, though the length is near the limit for comfortable scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter nested creation tool with no output schema, the description explains the critical side effects, permissions, live-status warning, image workflow, localization shape, activation requirements, and visibility scoping. Some secondary parameters remain undocumented, but the gaps are minor relative to the complexity 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?
With 64% schema description coverage and many nested fields, the description adds meaningful semantics for the most complex parameters: localized text shape, activation validFrom/validUntil/frequency, visibleToStatusCards, productVariantId with materialsOrder, and content.image sourcing. It leaves sortOrder, campaignId, templateId, and orgId largely to the schema, but it covers the parameters most likely to be misunderstood.
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 a benefit (member perk)') and immediately distinguishes the operation from list_benefits and update_benefit by explaining that it saves the Partner Hub benefit form and creates an independent copy in each venue. An agent can identify the exact operation without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage context: requires admin role on the venues, call import_image first for a new photo, and confirm details with the user before calling because the benefit is live immediately unless hidden. It does not explicitly compare against update_benefit or list_benefits, but the creation context and prerequisites are clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_birthday_giftCreate birthday giftAInspect
Create a birthday gift, the same as saving the Partner Hub's birthday gift form. It applies to every venue of venueIds (public ids from list_venues). Requires the admin role on those venues. For a new photo, call import_image first and use its originalUrl as content.imageUrl (and the photo credit in image.attribution, if any, as content.imageAttribution). content.name and content.description are localized strings: { default: "…" } plus optional per-locale translations such as fi or en. options.expirationDays is how long a member has to use the gift and options.advanceSendDays how many days before the birthday it is delivered. Unless status is hidden, members receive the gift around their birthday, as options.advanceSendDays sets, so confirm the details with the user before calling this.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| status | No | active | |
| content | Yes | ||
| message | Yes | ||
| options | Yes | ||
| venueIds | Yes | Venue orgBasedPublicIds where this birthday gift applies | |
| templateId | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, so the description carries most of the burden and does well: it discloses the real side effect (members receive the gift around their birthday unless status is hidden), the per-venue fan-out, and the admin requirement. It stops short of describing what is returned or how partial failures across many venues behave.
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 purpose, then permissions, then per-parameter guidance, then the user-confirmation caution. Every sentence adds usable information for a tool this complex; nothing is filler or restatement of the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter nested-object mutation with no output schema and thin annotations, the description supplies the operational context an agent needs to call it safely. Missing pieces are minor: templateId's purpose and what happens to the member-facing send schedule on failure.
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 only 29% schema description coverage the description must compensate, and it does for the highest-risk fields: it explains the localized-string shape of content.name/description, the import_image originalUrl → content.imageUrl linkage, imageAttribution, options.expirationDays, options.advanceSendDays, and the status hidden meaning. It leaves templateId and message semantics entirely to the schema, which is the main gap.
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 (Create) and resource (a birthday gift) and anchors it to a known analog ('the same as saving the Partner Hub's birthday gift form'). It also states the object scope ('applies to every venue of venueIds'), which lets an agent separate it from update_birthday_gift and list_birthday_gifts without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives prerequisites ('Requires the admin role on those venues') and routes prerequisite sub-tasks explicitly (list_venues for ids, import_image first for a new photo). Adds a caution ('confirm the details with the user before calling this'), though it never states when to prefer update_birthday_gift over creating a new gift.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_smart_linkCreate smart linkAInspect
Create a smart link; the response carries its public url (cluby.app/). Requires the admin role. name is optional and defaults to a label built from the action and target. action is what the link does when scanned: join (member joins the venue; target venue::<venueId>), show (opens the venue or a benefit; target venue::<venueId> or org::<orgId>::venue::<venueId>::benefit::<benefitId>), stamp (gives a stamp; target org::<orgId>::venue::<venueId>::stampcard::<stampCardId>), redirect (target an https URL) or none (target null). Every scan of a link whose target names a venue emits a smart_link.scanned event to each of the organization's endpoints subscribed to it. webhook: { endpointId, ref } additionally ties the tag to one endpoint (its id from list_webhook_endpoints or get_pos_connection's endpoint.id; create_webhook_endpoint / set_pos_connection first): ref is that receiver's own reference for the tag, such as a cash register id, echoed to it as posRef. webhook: null drops the tie. smartCardPublicId (a card's publicId from list_nfc_cards) attaches that NFC card to the link so a tap opens it. A card already attached to another link is refused (409): first detach it with update_smart_link on that link, smartCardPublicId: null, which detaches every card from it.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | ||
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses behavior well beyond the single destructiveHint annotation: admin authorization, response shape (public url), scan-triggered smart_link.scanned events to subscribed endpoints, 409 refusal when an NFC card is already attached, and the webhook null tie-dropping semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose, response, and authorization, and every sentence adds needed detail. The single dense paragraph covering action variants, webhook semantics, and NFC card conflicts is readable but would benefit from list-style separation.
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 five-branch oneOf schema, no output schema, and cross-resource dependencies, the description covers action/target pairing, webhook endpoint sourcing, NFC card attachment and conflict resolution, and event emission. Nothing critical for correct invocation 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?
With only 50% schema description coverage, the description compensates substantially: it defines the action values and their exact target formats (venue::, org::venue::benefit::, stampcard::, https URL, null), explains name's default label behavior, webhook ref/endpointId sourcing, and smartCardPublicId provenance from list_nfc_cards.
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?
Opens with a specific verb and resource ('Create a smart link') and immediately states the response carries the public url. The action variants make the tool's scope unmistakable relative to list_smart_links and update_smart_link.
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 strong usage context: admin role required, endpoint prerequisites for webhook linking, and the explicit detach flow via update_smart_link when a card is already attached. It does not explicitly say when to prefer this over any sibling beyond the detach workflow, so 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.
create_webhook_endpointCreate webhook endpointAInspect
Add a webhook endpoint (requires the admin role). Omit secret to have one generated: it is returned once in secret and never again, so show it to the user. name defaults to the URL's host. Plain http URLs are accepted for localhost only. Events are POSTed as JSON with an HMAC signature in X-Cluby-Signature (t=<unix>,v1=<hex hmac-sha256(secret, "<t>.<body>")>). Event types: smart_link.scanned (A member scanned a smart link or NFC tag whose target names a venue (sent to every endpoint subscribed to it; posRef only to the endpoint the tag is tied to).). Includes (optional sections added to each event's data): profile (The member's display name, profile photo URL and the date they joined the event's venue.), membershipCards (Membership / VIP cards the member holds at the venue, valid now.), benefits (Benefits the member can activate at the venue right now — a spent one, one outside its schedule, or a members-only one the member does not hold is left out (name, price text, and for the POS channel an actionId and its single-use redeemUrl).), stampCards (The member's stamp cards in the organization, with stamps and the number to fill (and for the POS channel an actionId and awardStampUrl on the cards that run at the scanned venue).), items (Items the member holds that are usable at the scanned venue — rewards earned (a full stamp card, a birthday gift) and products bought — with units left (and for the POS channel an actionId and a useUrl, good for as many uses as there are units, at most 10).).
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | A public HTTPS URL. Private, link-local and loopback addresses are refused, and redirects are not followed. | |
| name | No | A label for lists and alerts. The URL's host by default. | |
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| events | No | The event types to receive. `smart_link.scanned` by default. | |
| secret | No | The key events are signed with. Omit it to have one generated (`whsec_…`), returned once and never again. Use the whole string, prefix included, as the HMAC key. A new one replaces the old at once. | |
| enabled | No | `false` stops deliveries without deleting the endpoint. | |
| includes | No | What each event carries beyond its own data: `profile`, `membershipCards`, `benefits`, `stampCards`, `items`. None by default; a POS connection's own endpoint gets all of them. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Rich beyond what `destructiveHint: false` provides: the secret is shown once and never again (so it must be surfaced to the user), signatures and their HMAC format are documented, event delivery semantics and per-endpoint `posRef` scoping are described. One internal inconsistency weakens it: the description says plain http is accepted for localhost, while the schema says loopback addresses are refused.
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 security and secret guidance is correctly front-loaded, but the bulk of the text is a sprawling enumeration of event payload fields that largely restates the schema's `includes` description, complete with doubled parentheses ('(A member scanned ... at most 10).).') that make it hard to parse. Much of it does not earn its place in a tool-selection description.
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 mutation tool with no output schema, the description covers the returned `secret`, defaults, and delivery behavior, so an agent has what it needs to call it correctly. It is undermined mainly by formatting and by the http/loopback inconsistency rather than by missing information.
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 already 100%, but the description adds semantics the schema cannot: the generated secret's one-time visibility and format, the `name` default, and that a POS connection's own endpoint silently receives all `includes`. That is real value over baseline 3.
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?
Opens with a specific verb + resource ('Add a webhook endpoint') and immediately constrains it with the admin-role requirement. An agent can tell this apart from update_webhook_endpoint or test_webhook_endpoint 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 useful preconditions (admin role required, omit `secret` to auto-generate) but never routes to alternatives such as `update_webhook_endpoint` for existing endpoints, `list_webhook_endpoints` to check for duplicates, or `test_webhook_endpoint` to verify delivery afterward. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dashboard_summaryDashboard summaryARead-onlyInspect
Headline numbers, the same figures as the Partner Hub dashboard: benefit activations, event entrances, push messages, returning members and page visitors, with 30-day trends. Covers every venue of the organization unless venue is given. Stamp figures are summed across all stamp cards in scope: rewardsEarned counts rewards minted from stamp cards and rewardsRedeemed those the member actually claimed, matching the per-card stats in list_stamp_cards.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| venue | No | Venue public id (from list_venues) to scope the response to a single venue. Omit for the whole organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already covers the safety profile, and the description adds genuine behavioral context beyond it: the default all-venue scope, the 30-day trend horizon, and the distinction between rewardsEarned (minted) and rewardsRedeemed (claimed). It doesn't mention rate limits or auth requirements, but for a read-only dashboard this is solid added value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with what is returned, followed by scope and then metric definitions. Every sentence carries information the agent needs, and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must carry the return-value burden, and it does: it lists the metric families and defines the two ambiguous stamp-derived figures. Combined with the fully documented two-parameter schema, an agent has everything needed to call it 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% and both parameters (orgId, venue) are fully documented there, so the baseline is 3. The description's 'unless `venue` is given' and the org-key behavior largely restate what the schema already says, adding no new parameter-level semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description enumerates the exact metrics returned (benefit activations, event entrances, push messages, returning members, page visitors) and the 30-day trend window, so the agent knows precisely what it gets. This clearly separates it from sibling aggregates like member_stats and org_activity.
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 the scoping rule ('covers every venue unless `venue` is given'), which implies default usage, but never says when to prefer this tool over member_stats or org_activity, nor any exclusions. Usage is inferable rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_pos_connectionDelete POS connectionADestructiveIdempotentInspect
Remove the organization's POS connection and the webhook endpoint it manages; register tags keep their refs. The connected app itself is revoked in the Partner Hub (Integrations → Connected apps). Requires the admin role. Confirm with the user before calling this.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the destructiveHint/idempotentHint annotations by disclosing the blast radius (webhook endpoint is deleted, register tags keep their refs) and by clarifying that the connected app lifecycle is outside this tool (revoked in Partner Hub). It also names the required privilege and a confirmation protocol, all things annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight clauses lead with the destructive action and its blast radius, then the out-of-band consequence, then the authorization/confirmation caveat. No filler sentences and nothing redundant with the annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive tool with no output schema, the description covers action, side effects, scope limits, required role, and user-confirmation protocol. Nothing an agent needs before calling is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so orgId (public id from list_orgs, omittable for single-org keys) is already fully documented in the schema. The description adds no syntax, format, or edge-case detail about orgId, 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 (Remove) + resource (organization's POS connection) with the scope boundary made explicit: it also removes the webhook endpoint the connection manages, but leaves register tag refs intact. This is enough to distinguish it from sibling set_pos_connection, get_pos_connection, and delete_webhook_endpoint.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives two concrete preconditions that gate invocation: the caller needs the admin role, and the agent must confirm with the user first. It does not name an alternative tool (e.g. set_pos_connection for reassignment) or state when not to delete, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_webhook_endpointDelete webhook endpointADestructiveIdempotentInspect
Remove a webhook endpoint; smart links pointing at it are detached (they keep their ref) and a POS connection using it as its channel is left without one. Requires the admin role. Confirm with the user before calling this.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| endpointId | Yes | Webhook endpoint `id` from list_webhook_endpoints |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint and idempotentHint, but the description adds what those hints cannot: smart links are detached yet retain their `ref`, and a POS connection using the endpoint is left without a channel. It also discloses the required admin role and the confirmation expectation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence packed with the operation, its cascade effects, the auth requirement, and the confirmation rule, with the destructive action front-loaded. No clause is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter mutation with no output schema, the description covers the action, side effects on dependent resources, permission requirements, and user-confirmation expectations. Nothing an agent needs to call it safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters (orgId, endpointId) are fully documented in the schema, including where to source each id. The description adds no parameter-level detail, 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?
The description opens with a specific verb+resource ("Remove a webhook endpoint") and immediately scopes the operation's blast radius. It is clearly distinguishable from siblings like update_webhook_endpoint and create_webhook_endpoint without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states a hard prerequisite ("Requires the admin role") and an interaction rule ("Confirm with the user before calling this"), which is concrete guidance beyond a bare purpose statement. It stops short of naming an alternative for non-destructive edits, so it lacks explicit when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pos_connectionGet POS connectionARead-onlyInspect
The organization's POS connection — the connected app that owns it, its event channel (a webhook endpoint subscribed to smart_link.scanned), the article search URL and capabilities.apply (which apply instructions the POS executes) — or null. Secrets are never returned.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes the safety profile, so the description's job is to add context — and it does: it discloses the null-return case and the explicit guarantee that secrets are never returned. It also explains the semantic role of the event channel (webhook subscribed to `smart_link.scanned`) and that `capabilities.apply` governs which apply instructions the POS executes. No pagination or rate-limit context is offered, which is the remaining gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence that front-loads the resource and then unpacks its fields, with no filler. The nested em-dash parentheticals are heavy but each clause carries information that has nowhere else to live, given there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully carries the return shape (owner app, event channel, article search URL, capabilities.apply, null case, secret redaction), which is exactly what an agent needs to interpret the response. It falls short only on routing — an agent learning nothing about when get_pos_connection is preferable to set_pos_connection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single optional param (orgId) with 100% schema description coverage, and the schema already explains it references `list_orgs` and is omittable for single-org API keys. The description adds nothing about the parameter, 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 precisely enumerates what the tool returns: the connected app that owns the POS connection, its event channel (a webhook endpoint subscribed to `smart_link.scanned`), the article search URL, and `capabilities.apply`. The `— or null` clause makes the retrieval action implicit but unmistakable. It does not, however, explicitly distinguish itself from set_pos_connection / delete_pos_connection beyond the read-only framing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not-to-use guidance, and no alternative is named despite set_pos_connection and list_pos_identifications being adjacent siblings. The only usage signal is implied by the readOnlyHint annotation and the resource-shaped phrasing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_imageImport imageAInspect
Import a photo from a public https URL into the organization's image storage, the same as picking an image in the Partner Hub. Returns originalUrl and image; pass image unchanged as a benefit's content.image in create_benefit or update_benefit, which wait for the processed versions before saving. Only images imported this way are accepted by the benefit write tools; a birthday gift takes the originalUrl as content.imageUrl.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Public https URL of the image | |
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| attribution | No | Photographer credit for an Unsplash photo. Kept on every processed version so the credit travels with the image. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give openWorldHint and destructiveHint=false, so the description must carry the behavioral burden. It does: return values (`originalUrl`, `image`), the fact that benefit writes wait for processed versions, and the acceptance constraint on which images benefit tools will take. Missing: what happens on invalid/unreachable URLs, size/format limits, or whether imports are idempotent.
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 purpose, then build in the downstream contract in order of use. Dense but every clause carries decision-relevant information; slightly packed in the final sentence where `originalUrl`/`imageUrl` pairing takes effort to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, so the description usefully names the returned fields and their downstream role. For a 3-param tool with fully documented nested schema, the remaining gap is failure behavior (bad URL, license/attribution rejection), a minor but real omission.
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 100% schema coverage the baseline is 3, but the description adds cross-tool semantics the schema cannot: pass `image` unchanged into a benefit's `content.image`, and use `originalUrl` as `imageUrl` for gifts. It does not restate `url`/`orgId`/`attribution` rules, which the schema already covers well.
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 (import a photo from a public https URL into the organization's image storage) and anchors it to a familiar operation (picking an image in the Partner Hub). No sibling tool does this; the identity is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says the tool is a prerequisite for the benefit write tools: only images imported this way are accepted by create_benefit/update_benefit, and birthday gifts take `originalUrl` as `content.imageUrl`. This is exactly the when-to-use vs alternatives guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_benefitsList benefitsBRead-onlyInspect
Benefits (member perks) of an organization. With includeStats, add activation counts for the statsFrom–statsTo date range.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| statsTo | No | Stats range end, YYYY-MM-DD. | |
| statsFrom | No | Stats range start, YYYY-MM-DD. Requires statsTo and includeStats. | |
| includeStats | No | Include usage statistics for each item. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes this as a safe read, so the description's burden is lighter, and it does add that stats are "activation counts" computed over the statsFrom–statsTo range. It says nothing about pagination, result size, or what happens when includeStats is set without the full parameter trio beyond what the schema implies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, resource statement front-loaded, no filler. The second sentence largely mirrors schema content, but it is brief enough that the overlap is not costly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the tool takes zero required parameters and the schema fully describes orgId scoping and the stats range, so an agent has enough to invoke it. It lacks pagination or result-shape notes, which is a minor gap for a list endpoint.
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 all four parameters are documented there, including the dependency chain (statsFrom requires statsTo and includeStats). The description adds no syntax, default, or format detail beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource and disambiguates the term with a parenthetical ("Benefits (member perks) of an organization"), which prevents confusion with insurance-style benefits. It is a noun fragment rather than a verb+resource statement, and it never explicitly differentiates itself from list_orgs, list_stamp_cards, or member_stats, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to reach for list_benefits versus sibling tools such as member_stats or list_status_cards. The only conditional given ("With includeStats, add activation counts...") restates the parameter contract rather than guiding tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_birthday_giftsList birthday giftsARead-onlyInspect
Birthday gifts of an organization: the gift each member receives around their birthday, with the venues it applies to, its message, validity and delivery timing. With includeStats, each gift gets rewardsGiven (gifts sent to members) and rewardsRedeemed (gifts members actually claimed), each in total and for the last 30 days. Use it to answer how many birthday gifts have been sent or redeemed.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| includeStats | No | Include usage statistics for each item. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description then adds genuine behavioral detail: what includeStats produces (rewardsGiven / rewardsRedeemed, each with total and last-30-days values). It omits pagination/result-size behavior, which is the main remaining gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the resource definition before the stats mechanic. Dense but nothing is padding; each clause adds information an agent would otherwise have to guess.
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 enumerates the returned gift attributes and stats shape, so an agent knows what comes back. Completeness is strong for a low-complexity two-parameter read tool; only pagination/limits are undocumented.
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 goes beyond it by expanding includeStats into the concrete fields it adds and their time windows. That is meaningfully more than the schema's terse "Include usage statistics for each item", though orgId handling is left entirely to 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 names a specific resource (birthday gifts of an organization) and enumerates its facets: applicable venues, message, validity, and delivery timing. It is clearly distinguishable from create_birthday_gift / update_birthday_gift by implication, though it never explicitly frames itself as the read/list counterpart to those write siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Use it to answer how many birthday gifts have been sent or redeemed" gives a concrete use case that ties the tool to a question type, which is real guidance. It stops short of naming alternatives (e.g. member_stats, dashboard_summary) or stating when this tool is the wrong choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_connected_appsList connected appsARead-onlyInspect
Apps connected to the organization with "Connect Cluby" (OAuth, pos scope): each is a service account with the admin role — id (what get_pos_connection reports as connectedAppId), name, client id, scopes, when it connected and last used its key. An organization admin revokes one in the Partner Hub (Integrations → Connected apps).
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true. The description adds real value beyond that: each entry is a service account with the admin role (a privilege/security fact the annotation cannot convey) and revocation is out-of-band in the Partner Hub (Integrations → Connected apps), telling the agent there is no API path to revoke. It omits pagination/result-count 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?
One dense sentence with the purpose front-loaded, followed by the return-field detail and the revocation note. The em-dash and parenthetical packing make it slightly heavy, but every clause earns its place and nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with no output schema, the description covers purpose, returned fields, cross-tool linkage, and the out-of-band revocation path. It lacks pagination and ordering details, so it is thorough but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single optional `orgId` parameter and schema description coverage is 100%, so the schema already carries the semantics, including the omit-when-single-org rule. The description adds no further parameter guidance, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — apps connected to the organization via "Connect Cluby" OAuth with the `pos` scope — and enumerates the returned fields (id, name, client id, scopes, connect/last-used timestamps). It is clearly distinguishable from siblings like list_orgs or get_pos_connection, which it explicitly cross-references.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the tool is the discovery path for connected apps and the `connectedAppId` link to get_pos_connection is noted. There is no explicit statement of when to call this versus alternatives, nor any prerequisite or exclusion, so the agent must infer the context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_eventsList eventsARead-onlyInspect
Events of an organization with ticket types. Filter by time (upcoming, past) and status; includeStats adds sales figures. publicUrl is the consumer web address for the current environment.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| timeFilter | No | ||
| includeStats | No | Include usage statistics for each item. | |
| statusFilter | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes this as a safe read. The description adds that includeStats pulls in sales figures and that publicUrl is environment-scoped, which is genuine context beyond the annotation, but it says nothing about result limits, pagination, or visibility rules for hidden events.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences, filter semantics front-loaded and readable. The trailing publicUrl sentence is oddly placed because that field has no counterpart in the input schema, adding mild noise.
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 a read-only listing tool, no output schema, and four optional params, the description covers the core filtering model adequately. It leaves the return shape (what an event record contains beyond ticket types) and paging behavior unspecified, which is a minor gap rather than a blocking one.
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 50%: orgId and includeStats are documented in the schema, while timeFilter and statusFilter have no schema description. The description partially compensates by naming time values (yet omits the 'all' enum member) and noting status filtering, but then mentions 'publicUrl', which is not even a parameter – so the added meaning is mixed.
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 resource clearly ('Events of an organization with ticket types') and enumerates the filter dimensions, so an agent can see it is an events listing distinct from list_benefits/list_venues. It omits an explicit verb and never contrasts itself with sibling list tools, but the resource plus ticket-type annotation is enough to place it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the description says events can be filtered by time and status, which hints at how to narrow results, but never states when to pick this tool over list_orgs, org_activity, or dashboard_summary. No prerequisites or exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_nfc_cardsList NFC cardsARead-onlyInspect
The organization's physical NFC cards: publicId (the 4-character id printed on the card — what create_smart_link / update_smart_link take as smartCardPublicId), nfcUid, secure (NTAG 424 with a key: taps are verified and the card can carry a stamp tag), tapCount, and the smart link it is attached to (smartLinkId, smartLinkSlug; null when loose). Cards are registered by Cluby; this lists and does not create them.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so safety is covered. The description adds value beyond that: it clarifies cards are registered by Cluby and cannot be created here, explains the `secure` flag (NTAG 424 with a key, verified taps, can carry a stamp tag), and notes smartLinkId/Slug are null when loose. Useful behavioral and field semantics, though no pagination/volume info.
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 resource, then enumerates the meaningful fields in a single organized sentence, closing with the list-vs-create boundary. Dense but every clause carries useful field context; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description appropriately explains the shape of returned cards (ids, secure flag, tapCount, attached smart link). Combined with the readOnly annotation, an agent has enough to call and interpret the result, though ordering/pagination details are absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single optional orgId is fully documented in the schema. The description references publicId but that is a returned field, not an input parameter, so it adds no meaning to the actual orgId argument. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resource (the organization's physical NFC cards) and states the action explicitly at the end ('this lists and does not create them'). It also distinguishes itself from creation siblings (create_smart_link / update_smart_link), so an agent can tell what this tool does. The heavy focus on return fields rather than the action keeps it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: by noting the 4-character publicId is what create_smart_link / update_smart_link take as smartCardPublicId, it hints this tool is the source for that value. There is no explicit statement of when to choose this tool vs alternatives or any prerequisites beyond that.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_orgsList organizationsARead-onlyInspect
Organizations (and their venues) this API key can access. Call this first: every other tool takes an organization's id as orgId.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| search | No | Case-insensitive search across organization and venue names | |
| perPage | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description doesn't need to restate safety. It adds meaningful behavioral context beyond the annotations: results are scoped to the API key's access, and the tool is a required first step for other operations. It does not cover pagination or default return order, but the added access and workflow details are 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 tightly constructed sentences with no filler. The resource scope is front-loaded, and the prerequisite instruction follows immediately, making the key routing information highly scannable.
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 discovery tool, the description provides enough context to use it correctly: what it returns, that it is scoped to the API key, and that it must be called first. Pagination behavior for page and perPage is left to the schema, and since no output schema exists, the description does not need to explain return values further.
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 33%, with page and perPage undocumented anywhere. The description adds no input parameter semantics at all; it mentions orgId only as an output identifier used by other tools, not as an argument to this tool. It therefore fails to compensate for the low 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?
The description identifies the exact resource (organizations and their venues) and the access scope (this API key), while the tool name and title supply the list verb. It also distinguishes this tool from all siblings by declaring that it must be called first, making its purpose unmistakable.
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 when to use this tool: 'Call this first.' It further explains why by noting that every other tool takes an organization's id as orgId, effectively defining this as the prerequisite discovery call. No alternative tool exists for this prerequisite, so the guidance is complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pos_identificationsList POS identificationsARead-onlyInspect
Who is at the till: the open identifications (scans still within their expiresAt) on the POS connection's channel, newest first, each the smart_link.scanned data as delivered (member, profile, cards, benefits, stamp cards, items, sequence, expiresAt; action links and profileUrl for admins only) plus eventId, the scan event's id, which a reported sale sends as identificationId. posRef narrows to one till.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| posRef | No | The till's reference (a tag's `webhook.ref`) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint, it discloses ordering, expiry filtering, admin-only fields, the eventId/identificationId mapping for reported sales, and posRef scoping. It still omits pagination or default limit behavior, so it is not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with 'Who is at the till' and packs useful return-field context into a short block. However, the main sentence is very dense with nested parentheticals, so structure could be cleaner.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries the return-value burden; it enumerates fields and explains the eventId/identificationId relationship. It is nearly complete for invocation, with only default limit or pagination behavior notably absent.
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 67%; orgId and posRef are already described in the schema, and the description repeats posRef's narrowing behavior but adds little for orgId or limit. With one of three parameters undocumented and no compensating detail for limit, this is adequate but not strong.
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 the exact resource (open POS identifications on the POS connection's channel), ordering (newest first), scope (only scans still within expiresAt), and payload. It is specific enough to distinguish this from sibling connection-management tools like get_pos_connection and set_pos_connection.
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 implies the use case with 'Who is at the till' and explains that posRef narrows to one till, plus that only unexpired scans are returned. However, it does not explicitly say when to choose this versus other listing/event tools or list exclusions, so guidance remains implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_smart_linksList smart linksBRead-onlyInspect
Smart links (QR / NFC tag targets) of an organization with their public url, action, target, NFC card count, visit count and webhook ({ endpointId, ref } when the tag is tied to an endpoint, null otherwise). action is what the link does when scanned: join (member joins the venue; target venue::<venueId>), show (opens the venue or a benefit; target venue::<venueId> or org::<orgId>::venue::<venueId>::benefit::<benefitId>), stamp (gives a stamp; target org::<orgId>::venue::<venueId>::stampcard::<stampCardId>), redirect (target an https URL) or none (target null). Every scan of a link whose target names a venue emits a smart_link.scanned event to each of the organization's endpoints subscribed to it. webhook: { endpointId, ref } additionally ties the tag to one endpoint (its id from list_webhook_endpoints or get_pos_connection's endpoint.id; create_webhook_endpoint / set_pos_connection first): ref is that receiver's own reference for the tag, such as a cash register id, echoed to it as posRef. webhook: null drops the tie. smartCardPublicId (a card's publicId from list_nfc_cards) attaches that NFC card to the link so a tap opens it. A card already attached to another link is refused (409): first detach it with update_smart_link on that link, smartCardPublicId: null, which detaches every card from it.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only readOnlyHint=true in the annotations, the description carries the return-shape burden (there is no output schema) and does so well, spelling out the webhook `{ endpointId, ref }` versus null distinction and the `smart_link.scanned` event emitted on venue-target scans. Much of the remaining prose (409 on double-attached cards, detaching via update_smart_link) describes sibling mutations rather than this read, which is genuinely useful domain context but slightly off-target.
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?
For a one-parameter read, the description is heavily bloated: most of it narrates action/target encodings, webhook tying, card attachment and a 409 detach workflow that belong to create_smart_link / update_smart_link. The purpose is front-loaded, but the excess text risks leading an agent to expect mutation behavior from a read-only tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by documenting every returned field, the action/target grammar, and webhook nullability, plus org scoping via orgId. An agent can interpret the response without further lookup; only the return-container/pagination shape is unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
A single parameter with 100% schema description coverage, so the schema already explains that orgId is the `id` from list_orgs and may be omitted for single-org keys. The description adds nothing param-specific, which is the expected baseline when the schema does the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause names the resource precisely — smart links (QR / NFC tag targets) of an organization — and enumerates the fields returned (url, action, target, card/visit counts, webhook), so an agent knows what it gets. It never states the verb 'list' outright and never contrasts itself with create_smart_link / update_smart_link, but the resource is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance: nothing says 'call this to enumerate an org's tag targets' or when to prefer it over list_nfc_cards / list_webhook_endpoints. Other tools are named only as dependency lookups (list_webhook_endpoints, get_pos_connection), not as alternatives this tool replaces or complements.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_stamp_cardsList stamp cardsBRead-onlyInspect
Stamp (loyalty punch) cards of an organization with per-card stats: members who started the card, stamps given, rewardsEarned (rewards minted) and rewardsRedeemed (rewards actually claimed).
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint already declares the safety profile, but the description goes beyond the annotation by disclosing what the response contains and disambiguating the easily-confused rewardsEarned (minted) versus rewardsRedeemed (claimed) metrics. That is genuine value-added context, though it says nothing about pagination, ordering, or result size.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence that front-loads the resource and then defines the returned metrics, with zero filler. Slightly awkward parenthetical phrasing but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description sensibly carries the burden of naming the key returned fields and their meanings. It stops short of describing list behavior (pagination, ordering, filtering) and offers no usage context, which leaves gaps for a list-style read 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?
With a single parameter and 100% schema description coverage, the schema already explains that orgId is the id from list_orgs and that it can be omitted for single-org keys. The description only echoes the 'of an organization' scope, so no syntax or meaning is added beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource precisely ('Stamp (loyalty punch) cards of an organization') and defines the per-card metrics returned, so an agent knows this retrieves loyalty card data rather than generic cards. However, it never states that it returns a list, and it does not differentiate itself from the closely-named sibling list_status_cards, so sibling disambiguation is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives such as member_stats or list_status_cards. The only usage hint ('of an organization') is implicit, and the actual rule for supplying or omitting orgId lives solely in the schema, not the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_status_cardsList status cardsBRead-onlyInspect
Membership (status) cards of an organization: tiers members can hold, with pricing and linked benefits.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| includeStats | No | Include usage statistics for each item. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered structurally. The description adds no behavioral detail beyond that — nothing about whether the full list is returned, ordering, pagination, or how includeStats changes the payload — so it does not meet the bar of adding context 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?
A single tight sentence with the resource front-loaded and no filler. It is efficient, though as a fragment it omits the operation verb rather than being maximally front-loaded for an action tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter, read-only list tool with no output schema and full schema coverage, the definition of what a status card is (tiers with pricing and linked benefits) is sufficient to call the tool correctly. Missing listing/pagination behavior is the only real gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (orgId with its list_orgs reference and single-org omission rule, and includeStats) are fully documented in the schema itself. The description mentions no parameters, which is acceptable at this coverage level but adds nothing.
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 resource — membership/status cards of an organization — and clarifies what the records contain (tiers, pricing, linked benefits), which distinguishes it from the similarly named sibling list_stamp_cards. However, it is a noun phrase that never states the verb 'list', so the agent infers the listing action from the tool name rather than the description.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no indication of when to use this tool versus siblings such as list_stamp_cards (stamps vs. membership tiers) or list_benefits, and no prerequisites or exclusions are stated. The agent gets resource semantics but no routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_venuesList venuesCRead-onlyInspect
Venues (locations) of an organization with their public ids.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already establishes this is a safe read, so the bar is lower, but the description adds almost no behavioral context beyond 'with their public ids'. It says nothing about pagination, result limits, or what happens when the org has no venues.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the resource and return payload front-loaded; nothing is wasted, though it is arguably under-specified rather than optimally concise.
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, optional-argument read tool with a fully documented schema and no output schema, the definition is minimally adequate. It lacks any mention of result shape or volume, which a listing tool would benefit from.
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 orgId parameter is documented with the cross-reference to list_orgs and the omit-when-single-org rule. The description adds no parameter detail, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (venues/locations) and scope (of an organization) plus what is returned (public ids). It is distinguishable from siblings like list_orgs and list_events, though it never uses an explicit verb and offers no contrast with alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no prerequisites, and no mention of alternatives among the eight sibling list_* tools. The agent must infer usage purely from the name and resource noun.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_webhook_endpointsList webhook endpointsARead-onlyInspect
The organization's webhook endpoints (name, URL, subscribed events, includes, enabled, and posConnectionId when one is a POS connection's channel). Secrets are never returned. Every event goes to every enabled endpoint subscribed to its type. Events are POSTed as JSON with an HMAC signature in X-Cluby-Signature (t=<unix>,v1=<hex hmac-sha256(secret, "<t>.<body>")>). Event types: smart_link.scanned (A member scanned a smart link or NFC tag whose target names a venue (sent to every endpoint subscribed to it; posRef only to the endpoint the tag is tied to).). Includes (optional sections added to each event's data): profile (The member's display name, profile photo URL and the date they joined the event's venue.), membershipCards (Membership / VIP cards the member holds at the venue, valid now.), benefits (Benefits the member can activate at the venue right now — a spent one, one outside its schedule, or a members-only one the member does not hold is left out (name, price text, and for the POS channel an actionId and its single-use redeemUrl).), stampCards (The member's stamp cards in the organization, with stamps and the number to fill (and for the POS channel an actionId and awardStampUrl on the cards that run at the scanned venue).), items (Items the member holds that are usable at the scanned venue — rewards earned (a full stamp card, a birthday gift) and products bought — with units left (and for the POS channel an actionId and a useUrl, good for as many uses as there are units, at most 10).).
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the 'readOnlyHint' annotation by detailing critical behavioral aspects: secrets are never returned, specific event routing logic is provided, and the exact HMAC signing structure for events is defined, offering deep insight into system 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 overwhelmingly long and highly dense, reading more like a technical API specification document than a concise tool description. Its excessive length significantly hinders quick comprehension by an AI agent.
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 complexity of the data handled (event types, various 'includes' sections, delivery methods), this description is extremely thorough. It provides all necessary context regarding payload structure and event distribution, making it maximally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Since schema description coverage is 100%, the description's role in explaining the parameter `orgId` is minimal. It provides context (API key scope) rather than technical guidance beyond what the 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 title and description clearly state the purpose is to list the organization's webhook endpoints. It distinguishes itself from sibling tools like update_webhook_endpoint by using the specific action 'list' and referencing the existing set of endpoints.
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?
While it does not explicitly state 'when' to use this tool versus others, its explicit function (listing existing endpoints) combined with the presence of creation and modification siblings provides sufficient usage context for an AI agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_webhook_eventsList webhook eventsARead-onlyInspect
The organization's webhook log, newest first: every event sent (or due) to its endpoints with the delivery attempts — status (pending | delivered | failed | expired | dropped), HTTP status, error and the head of the receiver's response. Use it to answer "did the POS get the scan at 12:03 and what did it say". Filter by endpointId, type, status, since (ISO); page with cursor = the previous page's nextCursor. Below the admin role, capability URLs and the receivers' answers come back null.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Only this event type. | |
| limit | No | Events per page, 1 to 200. 50 by default. | |
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| since | No | Only events made at or after this instant, such as `2026-10-21T12:00:00Z`. | |
| cursor | No | The previous page's `nextCursor`. | |
| status | No | Only events in this status. | |
| endpointId | No | Only this endpoint's events. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true is consistent with a log read. Beyond annotations, the description discloses result ordering, the full status lifecycle (pending | delivered | failed | expired | dropped), the per-event payload fields, the pagination contract via nextCursor, and an important permission caveat: below admin role, capability URLs and receiver responses come back null.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense paragraph that front-loads what the log is, then filters/pagination, then the permission caveat. Every sentence carries information; nothing is redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description takes on the burden of describing return values and does so concretely (delivery attempts, HTTP status, error, response head). Combined with the filters, paging contract, and role caveat, an agent has what it needs to call 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 coverage is 100%, so baseline is 3. The description's parameter mentions (since as ISO, cursor = previous page's nextCursor, the status set) largely restate what the schema already documents, adding no syntax or edge-case insight the schema lacks, and it omits orgId/limit entirely.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (the organization's webhook log of events sent to endpoints) plus its ordering (newest first) and per-event content (delivery attempts, status, HTTP status, error, response head). This is clearly distinguishable from endpoint-management siblings like list_webhook_endpoints and from the generic list_events.
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 use case ("did the POS get the scan at 12:03 and what did it say") and enumerates the available filters, which tells the agent when this is the right tool. It never names an alternative tool or a when-not-to-use condition, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
member_statsMember statisticsARead-onlyInspect
Members currently joined (users who joined and have not left), split by venue and by membership card, plus the cumulative members timeline trimmed to the last 90 days. Covers every venue of the organization unless venue is given. The timeline can dip when members leave, so a past point can exceed the current count.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| venue | No | Venue public id (from list_venues) to scope the response to a single venue. Omit for the whole organization. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, so safety is covered. The description adds non-obvious behavior beyond that: the 90-day trim, that the count excludes leavers, and the counterintuitive fact that historical points can exceed the current count. It doesn't cover return shape, but that is a read-only stats tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: definition, default scope, and the anomaly caveat. Front-loaded with the core metric and no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must convey what comes back, and it does: two breakdowns plus a 90-day timeline, and it flags the dip anomaly. The only gap is that no formal return shape is given, which is minor for a descriptive stats endpoint.
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 still adds meaning by stating the effect of omitted `venue` (org-wide) and the semantic distinction between 'currently joined' and 'have not left', which goes beyond the schema's id-reference 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?
States precisely what is counted ('members currently joined... who joined and have not left'), how it is split (by venue, by membership card), and what else is returned (cumulative 90-day timeline). No sibling tool offers member counts, so it is clearly distinguishable.
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?
Explains default scope ('covers every venue unless venue is given') and the quirky semantics exploration ('timeline can dip when members leave, so a past point can exceed the current count'). It does not route to an alternative tool, but for a standalone stats tool no obvious alternative exists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
org_activityRecent activityBRead-onlyInspect
Recent member activity in an organization: benefit activations, joins, purchases, stamps, event check-ins. Newest first, paginated.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | ||
| limit | No | ||
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| venues | No | Comma-separated venue public ids to include. Omit for all venues. | |
| excludeTypes | No | Comma-separated activity types to omit, e.g. JOIN,LEAVE |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint already declares a safe read, so the description's job is to add behavior. It adds newest-first ordering and pagination, which is genuinely useful and not in the annotations. It doesn't state filtering defaults, rate limits, or what an empty result means, so the disclosure is partial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the data domain and followed by ordering/pagination constraints. Zero filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, 5-param, no-output-schema list tool, the essentials (what's returned, ordering, pagination) are covered. But with no output schema, the response shape is left implicit, and page/limit semantics go unexplained, leaving gaps an agent must guess at.
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 60%: page and limit have no schema descriptions, and venues/excludeTypes are reasonably documented in the schema already. The description adds no mapping of activity types to excludeTypes values or format of venues, so it fails to compensate for the uncovered page/limit semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states what the tool returns: a list of member activity types (activations, joins, purchases, stamps, check-ins) scoped to an organization. It distinguishes from siblings by being the only activity/feed tool among list_* and stats tools. It does not explicitly name an alternative, but its domain is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no exclusions, and no mention of alternatives such as member_stats or dashboard_summary. The ordering and pagination hints are behavioral, not usage-routing guidance. An agent gets no help deciding this tool over a stats tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
replay_webhook_eventReplay webhook eventAInspect
Deliver a webhook event again (eventId from list_webhook_events): same id and body, so the receiver deduplicates; the attempt lands in the log as trigger: replay. Ignores the event's expiry, not a disabled endpoint. Each call sends again. Requires the admin role.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| eventId | Yes | Event `id` from list_webhook_events |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses the admin-role requirement, that the same id/body are reused so receivers deduplicate, that the attempt is recorded with `trigger: replay`, and that each call re-sends (consistent with idempotentHint=false). The phrase 'Ignores the event's expiry, not a disabled endpoint' is a valuable constraint but is worded cryptically and does not spell out the resulting error.
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?
Dense but front-loaded: the core action leads, followed by payload semantics, logging side effect, edge-case constraint, and auth requirement. Every clause contributes, though the 'not a disabled endpoint' fragment could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter mutation-style tool with no output schema, the description covers the essential operational context: auth requirement, repeat semantics, dedup behavior, and logging. Only the failure mode for disabled endpoints or unknown event ids remains unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented; the description only reiterates that `eventId` comes from list_webhook_events and adds no format or lookup detail beyond the schema. Baseline 3 is appropriate when the schema carries the parameter burden.
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 ('Deliver a webhook event again') and ties the resource to its identifying source (`eventId` from list_webhook_events). An agent can tell this apart from list_webhook_events and test_webhook_endpoint without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear preconditions: an existing event id, admin role, an enabled endpoint, and it notes expiry is ignored. It does not explicitly contrast itself with the sibling test_webhook_endpoint, which also pushes a webhook, so the alternative-selection guidance is incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_pos_connectionSet POS connectionADestructiveIdempotentInspect
Create or update the organization's POS connection (requires the admin role; one per organization). Called with a connected app's token the app becomes its owner. endpoint: { url, secret?, includes? } creates — or on a later call edits — the connection's event channel; webhookEndpointId adopts an existing endpoint instead. Generated secrets (secret for Cluby → POS calls, endpointSecret for a created endpoint) are returned once, so show them to the user. Only the fields sent change.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Your product's name, as the organization sees it. | |
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| secret | No | Reserved for calls from Cluby to your service, such as the article search. Generated when omitted and returned once. | |
| enabled | No | `false` pauses the connection and its channel. Your next PUT after reconnecting turns them back on. | |
| endpoint | No | The connection's event channel, the webhook endpoint that receives `smart_link.scanned`. Created with every include unless `includes` says otherwise; an endpoint created earlier keeps the includes it lists. `url` is required on the first call; later calls change only the fields sent. | |
| capabilities | No | What your POS can do with an action's answer. | |
| articleSearchUrl | No | Reserved: where Cluby will search your article catalogue once venues can map benefits to articles. Optional. | |
| webhookEndpointId | No | Instead of `endpoint`: use one of the organization's existing endpoints as the channel. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint and destructiveHint, so safety framing is covered. The description adds non-obvious behavior: admin role required, a connected app's token makes that app the owner, secrets are returned exactly once and must be surfaced to the user, and partial-update semantics ('only the fields sent change') — all beyond the structured 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?
Front-loaded with the core verb, prerequisite, and cardinality, then the endpoint/webhookEndpointId branch. Dense but every sentence carries a distinct fact; the packed single paragraph is the only minor readability cost.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter tool with nested endpoint and capabilities objects and no output schema, the description covers ownership, prerequisites, secret lifecycle, and partial-update behavior. What's missing is any signal about what the call returns besides the generated secrets, which matters given there is no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 8 parameters in depth; baseline is 3. The description adds the create-versus-adopt distinction between `endpoint` and `webhookEndpointId` and flags the one-time secret return, but leaves capabilities, articleSearchUrl, and enabled to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair (create or update) and resource (the organization's POS connection) and clarifies upsert semantics and one-per-org cardinality. An agent can separate it from get_pos_connection / delete_pos_connection and from create_webhook_endpoint, which the description implicitly routes to via `webhookEndpointId` adoption.
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 admin-role prerequisite and an explicit either/or rule: use `endpoint` to create or edit the event channel versus `webhookEndpointId` to adopt an existing endpoint. It does not explicitly say when to prefer get_pos_connection first or which sibling to use for endpoint management, so it falls short of full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
test_smart_link_webhookTest smart link webhookAInspect
Deliver one test smart_link.scanned event (test: true, sample member data) for a smart link to the endpoint it points at, synchronously, and return the event sent and the receiver's response (HTTP status, duration, error). Use it to check the URL, the signature and the tag routing before a real scan. Requires the admin role and a link with webhook set.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| smartLinkId | Yes | Smart link `id` from list_smart_links |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, so the description carries most of the burden and does well: it discloses synchronous delivery, that the payload is flagged `test: true` with sample member data, the returned fields (HTTP status, duration, error), the admin-role requirement, and the preconditions. It omits whether the test event is logged in webhook events or any rate limits, keeping 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?
Two tight sentences: behavior and return shape first, then usage and prerequisites. Every clause carries information an agent needs; nothing is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description itself enumerates the return content (event sent, HTTP status, duration, error), and covers auth, preconditions and side effects. An agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both parameters already documented (orgId from list_orgs, smartLinkId from list_smart_links). The description adds only the constraint that the link must have `webhook` set, so the schema does the heavy lifting and 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 and resource: deliver one test `smart_link.scanned` event for a specific smart link. The scope (single synthetic event, synchronous, to the link's own endpoint) clearly separates it from siblings like test_webhook_endpoint and replay_webhook_event.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use it: verifying URL, signature and tag routing before a real scan. It also names prerequisites (admin role, link with `webhook` set). It stops short of naming the alternative tools for endpoint-level testing, so 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.
test_webhook_endpointTest webhook endpointAInspect
Deliver one test smart_link.scanned event (test: true, sample tag and member) to a webhook endpoint, synchronously, and return the event sent and the receiver's response (HTTP status, duration, error). Checks the URL and the signature before any tag exists; test_smart_link_webhook also checks a tag's posRef routing. Requires the admin role.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| endpointId | Yes | Webhook endpoint `id` from list_webhook_endpoints |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, so the description carries the behavioral burden and does so richly: synchronous delivery, return payload (event sent, HTTP status, duration, error), what it validates for, the `test: true` synthetic payload, and the admin-role requirement. 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?
Two dense sentences with zero waste, front-loading the core action and following with the differentiating detail and prerequisite. Nothing is repeated from structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Although there is no output schema, the description explains the return contents (event sent plus HTTP status, duration, and error), the synchronous nature, the admin requirement, and the validation performed. An agent has everything needed to invoke it 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 both orgId and endpointId thoroughly. The description adds no syntax or format meaning beyond the schema, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: deliver one test `smart_link.scanned` event to a webhook endpoint. It also explicitly distinguishes itself from the sibling tool test_smart_link_webhook, so the agent can select correctly without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use context and names the alternative: this tool checks the URL and signature before any tag exists, whereas test_smart_link_webhook also checks a tag's `posRef` routing. That is exactly the routing an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_benefitUpdate benefitADestructiveIdempotentInspect
Edit a benefit (benefitId is the id from list_benefits). Only the fields sent change; content and activation are merged field by field, so send just the keys being edited. Requires the admin role on the benefit's venue. To change the photo, call import_image and pass its image as content.image; content.image: null removes it. Set status to hidden to hide it from members or active to show it again. visibleToStatusCards: [] makes it visible to every member; activation.schedules: null removes its schedules. Fields owned by a campaign or the partner product catalogue (see campaign and productVariantId) can be overwritten by them later.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| status | No | ||
| content | No | ||
| venueIds | No | Venue IDs where this benefit is available | |
| benefitId | Yes | Benefit `id` from list_benefits | |
| sortOrder | No | ||
| activation | No | ||
| campaignId | No | ||
| productVariantId | No | ||
| visibleToStatusCards | No | Status card IDs. Undefined = no change, empty array = public benefit |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond `idempotentHint`/`destructiveHint`: partial-update semantics, per-field merging of `content` and `activation`, the admin-role permission requirement, the destructive removals (`content.image: null`, `activation.schedules: null`), and the warning that campaign/catalogue-owned fields may be overwritten later.
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 merge semantics and ID provenance, then stacks the special cases as compact clauses. Dense but nearly every sentence carries operational information; only the campaign-ownership sentence could be trimmed.
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 10-parameter nested mutation with no output schema, it covers the highest-risk behaviors: partial update semantics, permission gate, image flow, removal sentinels, and external ownership. Missing coverage of `venueIds`/`sortOrder` semantics and return behavior keeps it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 40% against 10 parameters, so the description must compensate. It clarifies the tricky ones (image, status, visibleToStatusCards, schedules) but says nothing about `venueIds`, `sortOrder`, `campaignId`, or `productVariantId`, leaving roughly half the surface to the schema alone.
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 ('Edit a benefit') with an explicit provenance note that `benefitId` comes from `list_benefits`, which anchors it to the sibling listing tool. It immediately distinguishes itself from create_benefit by framing the whole operation as editing an existing 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?
Gives concrete routing: use `import_image` and pass its `image` for photos, set `status: hidden` to hide, `active` to show. It does not explicitly contrast with update_birthday_gift or say when not to use this tool, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_birthday_giftUpdate birthday giftADestructiveIdempotentInspect
Edit a birthday gift (giftId is the id from list_birthday_gifts). Only the fields sent change; content and options are merged field by field, so send just the keys being edited, and at least one field is required. Requires the admin role on every venue the gift currently applies to and on any venue in a new venueIds. Set status to hidden to stop it going out or active to resume it. Changing it affects members' upcoming gifts, so confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| giftId | Yes | Birthday gift `id` from list_birthday_gifts | |
| status | No | ||
| content | No | ||
| message | No | ||
| options | No | ||
| venueIds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only flag idempotentHint and destructiveHint; the description adds substantial context beyond that: patch/merge semantics for `content` and `options`, the admin-role requirement on affected venues, the effect of `status` (hidden stops, active resumes), and a confirmation warning because changes hit members' upcoming gifts. This is exactly the extra behavioral detail the annotations don't carry.
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, front-loaded with the core edit action, then merge rules, then permissions, then status/confirmation behavior. Every sentence carries information, though the status and confirmation points could be tightened.
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 mutation with nested objects and no output schema, the description covers mutation impact, auth, and update semantics, which is what an agent most needs. Return behavior is omitted but no output schema exists to require it, and a couple of unmentioned scalar fields are minor gaps.
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 only 29% schema description coverage, the description compensates well for the tricky parameters: it defines `giftId`'s source, explains the field-by-field merge of `content`/`options` (how to pass them), and clarifies `venueIds` role requirements. It says nothing about `message` or `orgId`, so it isn't fully compensating for the coverage gap.
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+resource ("Edit a birthday gift") and anchors `giftId` to list_birthday_gifts, so an agent can separate it from create_birthday_gift and list_birthday_gifts. It stops short of an explicit "not for creating" exclusion, which keeps it at 4 rather than 5.
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 the operative conditions: send only the keys being edited, at least one field is required, and use `status` to stop/resume sending. It also advises confirming with the user first, which is actionable usage guidance. No sibling alternative is named for edge cases, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_smart_linkUpdate smart linkADestructiveIdempotentInspect
Edit a smart link (smartLinkId is the id from list_smart_links). Only the fields sent change. Requires the admin role. action is what the link does when scanned: join (member joins the venue; target venue::<venueId>), show (opens the venue or a benefit; target venue::<venueId> or org::<orgId>::venue::<venueId>::benefit::<benefitId>), stamp (gives a stamp; target org::<orgId>::venue::<venueId>::stampcard::<stampCardId>), redirect (target an https URL) or none (target null). Every scan of a link whose target names a venue emits a smart_link.scanned event to each of the organization's endpoints subscribed to it. webhook: { endpointId, ref } additionally ties the tag to one endpoint (its id from list_webhook_endpoints or get_pos_connection's endpoint.id; create_webhook_endpoint / set_pos_connection first): ref is that receiver's own reference for the tag, such as a cash register id, echoed to it as posRef. webhook: null drops the tie. smartCardPublicId (a card's publicId from list_nfc_cards) attaches that NFC card to the link so a tap opens it. A card already attached to another link is refused (409): first detach it with update_smart_link on that link, smartCardPublicId: null, which detaches every card from it.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | ||
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| smartLinkId | Yes | Smart link `id` from list_smart_links |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotent and destructive behavior, and the description adds substantial beyond that: partial-update semantics, admin-role requirement, smart_link.scanned event emission, webhook tie behavior with posRef echo, 409 conflict handling for cards already attached, and detach remediation. Nothing here contradicts 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 core edit semantics and admin requirement are front-loaded before the detailed action and webhook rules. It is dense and long, but most of the length earns its place given the complexity of action targets, webhook ties, and NFC card conflicts.
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, destructive, idempotent update tool with nested parameters and no output schema, the description covers prerequisites, partial-update behavior, action semantics, webhook tie lifecycle, and conflict remediation. An agent has enough information to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes most properties, and the description adds valuable meaning for action/target pairings, webhook endpoint ties, ref echo behavior, and smartCardPublicId attach/detach. Some details, such as name/slug/expiresAt, are left mostly to the schema, and the target format for stamp/show is described slightly differently from the schema, so it is not fully exemplary.
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 ('Edit a smart link') and immediately clarifies partial-update semantics ('Only the fields sent change') plus the required admin role. It clearly distinguishes this from create_smart_link and other sibling mutations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear operational context: admin role required, smartLinkId comes from list_smart_links, webhook endpointId must be created or found first, and cards come from list_nfc_cards. It does not explicitly say when not to use it versus create_smart_link, but for an update tool that is largely implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_webhook_endpointUpdate webhook endpointADestructiveIdempotentInspect
Edit a webhook endpoint (requires the admin role). Only the fields sent change; a secret sent replaces the stored one. Events are POSTed as JSON with an HMAC signature in X-Cluby-Signature (t=<unix>,v1=<hex hmac-sha256(secret, "<t>.<body>")>). Event types: smart_link.scanned (A member scanned a smart link or NFC tag whose target names a venue (sent to every endpoint subscribed to it; posRef only to the endpoint the tag is tied to).). Includes (optional sections added to each event's data): profile (The member's display name, profile photo URL and the date they joined the event's venue.), membershipCards (Membership / VIP cards the member holds at the venue, valid now.), benefits (Benefits the member can activate at the venue right now — a spent one, one outside its schedule, or a members-only one the member does not hold is left out (name, price text, and for the POS channel an actionId and its single-use redeemUrl).), stampCards (The member's stamp cards in the organization, with stamps and the number to fill (and for the POS channel an actionId and awardStampUrl on the cards that run at the scanned venue).), items (Items the member holds that are usable at the scanned venue — rewards earned (a full stamp card, a birthday gift) and products bought — with units left (and for the POS channel an actionId and a useUrl, good for as many uses as there are units, at most 10).).
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | A public HTTPS URL. Private, link-local and loopback addresses are refused, and redirects are not followed. | |
| name | No | A label for lists and alerts. The URL's host by default. | |
| orgId | No | Organization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization. | |
| events | No | The event types to receive. `smart_link.scanned` by default. | |
| secret | No | The key events are signed with. Omit it to have one generated (`whsec_…`), returned once and never again. Use the whole string, prefix included, as the HMAC key. A new one replaces the old at once. | |
| enabled | No | `false` stops deliveries without deleting the endpoint. | |
| includes | No | What each event carries beyond its own data: `profile`, `membershipCards`, `benefits`, `stampCards`, `items`. None by default; a POS connection's own endpoint gets all of them. | |
| endpointId | Yes | Webhook endpoint `id` from list_webhook_endpoints |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=true; the description backs the destructive claim with "a `secret` sent replaces the stored one" and adds signing details (HMAC-SHA256 over `<t>.<body>` in `X-Cluby-Signature`) that no annotation covers. It does not say what happens to endpoints still holding the old secret after rotation, nor what the call returns, which is the remaining behavioral gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The operative content is two short clauses at the front; everything after that is a long payload/signature reference with deeply nested parentheses (e.g. the `smart_link.scanned` and `items` entries) that is tangential to editing an endpoint. Much of it restates what the event documentation and schema already cover, so the description is far larger than the call it describes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description says nothing about the return value of an update (the fact that a generated secret is returned once lives only in the schema). For a destructive, partial-update mutation with 8 parameters, it covers input semantics well but leaves the post-call contract implicit.
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 goes beyond it by explaining what each `includes` section actually puts into `data` (profile, membershipCards, benefits, stampCards, items) and what `smart_link.scanned` delivers, which the enum-only schema does not convey. Some of that detail, like `posRef` routing, is narrower than an update caller needs.
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 first clause states a specific verb and resource ("Edit a webhook endpoint") plus the admin-role prerequisite, which clearly separates it from create_webhook_endpoint, delete_webhook_endpoint and test_webhook_endpoint. It never names a sibling explicitly, so differentiation is implied by the verb rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives one genuinely useful usage rule — "Only the fields sent change" (PATCH semantics) — and the admin-role gate. It never says when to prefer this over deleting/recreating an endpoint, when to use test_webhook_endpoint to verify, or when to set enabled=false instead of deleting; those choices are left to inference.
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
create_benefit1 field changed- changed
Input schema / properties / activation / properties / resetTime / descriptionPrevious value: -"Time of day in UTC (HH:MM) when the per-member quota resets. Only the hour is kept."New value: +"Time of day on the venue's clock (HH:MM) when the per-member quota resets; 06:00 when omitted on create. Only the hour is kept."
- Changed
update_benefit1 field changed- changed
Input schema / properties / activation / properties / resetTime / descriptionPrevious value: -"Time of day in UTC (HH:MM) when the per-member quota resets. Only the hour is kept."New value: +"Time of day on the venue's clock (HH:MM) when the per-member quota resets; 06:00 when omitted on create. Only the hour is kept."
2 tool updates
- Changed
create_benefit5 fields changed- added
Input schema / properties / content / properties / imageAdded value: +{ + "anyOf": [ + { + "properties": { + "attribution": { + "anyOf": [ + { + "description": "Attribution metadata for images sourced from third-party providers (Unsplash, Pexels, Wikimedia Commons). Stored on each image variant so attribution travels with the image data wherever it's persisted. Wikimedia images under a CC BY or CC BY-SA license must be displayed with the photographer, license and source link.", + "properties": { + "license": { + "description": "Wikimedia only, e.g. \"CC BY-SA 4.0\"", + "type": "string" + }, + "licenseUrl": { + "format": "uri", + "type": "string" + }, + "photoId": { + "type": "string" + }, + "photographerName": { + "type": "string" + }, + "photographerProfileUrl": { + "format": "uri", + "type": "string" + }, + "source": { + "enum": [ + "unsplash", + "pexels", + "wikimedia" + ], + "type": "string" + }, + "sourceUrl": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "source", + "photoId", + "photographerName", + "sourceUrl" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "url": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The photo: `{ url }` with an image upload's `originalUrl`. Omit to keep the current one, null to remove it." +} - removed
Input schema / properties / content / properties / images / defaultRemoved value: -[] - added
Input schema / properties / content / properties / images / descriptionAdded value: +"Refused: send content.image" - removed
Input schema / properties / content / properties / images / itemsRemoved value: -{ - "description": "An image source with URL, format, type, and optional dimensions for building responsive srcset", - "properties": { - "attribution": { - "description": "Attribution metadata for images sourced from third-party providers (Unsplash, Pexels, Wikimedia Commons). Stored on each image variant so attribution travels with the image data wherever it's persisted. Wikimedia images under a CC BY or CC BY-SA license must be displayed with the photographer, license and source link.", - "properties": { - "license": { - "description": "Wikimedia only, e.g. \"CC BY-SA 4.0\"", - "type": "string" - }, - "licenseUrl": { - "format": "uri", - "type": "string" - }, - "photoId": { - "type": "string" - }, - "photographerName": { - "type": "string" - }, - "photographerProfileUrl": { - "format": "uri", - "type": "string" - }, - "source": { - "enum": [ - "unsplash", - "pexels", - "wikimedia" - ], - "type": "string" - }, - "sourceUrl": { - "format": "uri", - "type": "string" - } - }, - "required": [ - "source", - "photoId", - "photographerName", - "sourceUrl" - ], - "type": "object" - }, - "format": { - "enum": [ - "original", - "raw", - "jpg", - "webp", - "avif", - "heif" - ], - "type": "string" - }, - "height": { - "type": "number" - }, - "type": { - "type": "string" - }, - "url": { - "type": "string" - }, - "width": { - "type": "number" - } - }, - "required": [ - "url", - "format", - "type" - ], - "type": "object" -} - removed
Input schema / properties / content / properties / images / typeRemoved value: -"array"
- Changed
update_benefit4 fields changed- added
Input schema / properties / content / properties / imageAdded value: +{ + "anyOf": [ + { + "properties": { + "attribution": { + "anyOf": [ + { + "description": "Attribution metadata for images sourced from third-party providers (Unsplash, Pexels, Wikimedia Commons). Stored on each image variant so attribution travels with the image data wherever it's persisted. Wikimedia images under a CC BY or CC BY-SA license must be displayed with the photographer, license and source link.", + "properties": { + "license": { + "description": "Wikimedia only, e.g. \"CC BY-SA 4.0\"", + "type": "string" + }, + "licenseUrl": { + "format": "uri", + "type": "string" + }, + "photoId": { + "type": "string" + }, + "photographerName": { + "type": "string" + }, + "photographerProfileUrl": { + "format": "uri", + "type": "string" + }, + "source": { + "enum": [ + "unsplash", + "pexels", + "wikimedia" + ], + "type": "string" + }, + "sourceUrl": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "source", + "photoId", + "photographerName", + "sourceUrl" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "url": { + "format": "uri", + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The photo: `{ url }` with an image upload's `originalUrl`. Omit to keep the current one, null to remove it." +} - added
Input schema / properties / content / properties / images / descriptionAdded value: +"Refused: send content.image" - removed
Input schema / properties / content / properties / images / itemsRemoved value: -{ - "description": "An image source with URL, format, type, and optional dimensions for building responsive srcset", - "properties": { - "attribution": { - "description": "Attribution metadata for images sourced from third-party providers (Unsplash, Pexels, Wikimedia Commons). Stored on each image variant so attribution travels with the image data wherever it's persisted. Wikimedia images under a CC BY or CC BY-SA license must be displayed with the photographer, license and source link.", - "properties": { - "license": { - "description": "Wikimedia only, e.g. \"CC BY-SA 4.0\"", - "type": "string" - }, - "licenseUrl": { - "format": "uri", - "type": "string" - }, - "photoId": { - "type": "string" - }, - "photographerName": { - "type": "string" - }, - "photographerProfileUrl": { - "format": "uri", - "type": "string" - }, - "source": { - "enum": [ - "unsplash", - "pexels", - "wikimedia" - ], - "type": "string" - }, - "sourceUrl": { - "format": "uri", - "type": "string" - } - }, - "required": [ - "source", - "photoId", - "photographerName", - "sourceUrl" - ], - "type": "object" - }, - "format": { - "enum": [ - "original", - "raw", - "jpg", - "webp", - "avif", - "heif" - ], - "type": "string" - }, - "height": { - "type": "number" - }, - "type": { - "type": "string" - }, - "url": { - "type": "string" - }, - "width": { - "type": "number" - } - }, - "required": [ - "url", - "format", - "type" - ], - "type": "object" -} - removed
Input schema / properties / content / properties / images / typeRemoved value: -"array"
7 tool updates
- Changed
create_smart_link1 field changed- changed
Input schema / properties / body / oneOfPrevious value: -[ - { - "properties": { - "action": { - "const": "redirect", - "type": "string" - }, - "enabled": { - "default": true, - "type": "boolean" - }, - "expiresAt": { - "anyOf": [ - { - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO datetime after which the link stops working; null for never." - }, - "name": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ] - }, - "smartCardPublicId": { - "type": [ - "string", - "null" - ] - }, - "target": { - "format": "uri", - "type": "string" - }, - "webhook": { - "anyOf": [ - { - "properties": { - "endpointId": { - "maxLength": 16, - "minLength": 1, - "type": "string" - }, - "ref": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "required": [ - "endpointId" - ], - "type": "object" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "action", - "target" - ], - "type": "object" - }, - { - "properties": { - "action": { - "const": "join", - "type": "string" - }, - "enabled": { - "default": true, - "type": "boolean" - }, - "expiresAt": { - "anyOf": [ - { - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO datetime after which the link stops working; null for never." - }, - "name": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ] - }, - "smartCardPublicId": { - "type": [ - "string", - "null" - ] - }, - "target": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "webhook": { - "anyOf": [ - { - "properties": { - "endpointId": { - "maxLength": 16, - "minLength": 1, - "type": "string" - }, - "ref": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "required": [ - "endpointId" - ], - "type": "object" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "action", - "target" - ], - "type": "object" - }, - { - "properties": { - "action": { - "const": "stamp", - "type": "string" - }, - "enabled": { - "default": true, - "type": "boolean" - }, - "expiresAt": { - "anyOf": [ - { - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO datetime after which the link stops working; null for never." - }, - "name": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ] - }, - "smartCardPublicId": { - "type": [ - "string", - "null" - ] - }, - "target": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "webhook": { - "anyOf": [ - { - "properties": { - "endpointId": { - "maxLength": 16, - "minLength": 1, - "type": "string" - }, - "ref": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "required": [ - "endpointId" - ], - "type": "object" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "action", - "target" - ], - "type": "object" - }, - { - "properties": { - "action": { - "const": "show", - "type": "string" - }, - "enabled": { - "default": true, - "type": "boolean" - }, - "expiresAt": { - "anyOf": [ - { - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO datetime after which the link stops working; null for never." - }, - "name": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ] - }, - "smartCardPublicId": { - "type": [ - "string", - "null" - ] - }, - "target": { - "maxLength": 200, - "minLength": 1, - "type": "string" - }, - "webhook": { - "anyOf": [ - { - "properties": { - "endpointId": { - "maxLength": 16, - "minLength": 1, - "type": "string" - }, - "ref": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "required": [ - "endpointId" - ], - "type": "object" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "action", - "target" - ], - "type": "object" - }, - { - "properties": { - "action": { - "const": "none", - "type": "string" - }, - "enabled": { - "default": true, - "type": "boolean" - }, - "expiresAt": { - "anyOf": [ - { - "format": "date-time", - "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", - "type": "string" - }, - { - "type": "null" - } - ], - "description": "ISO datetime after which the link stops working; null for never." - }, - "name": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ] - }, - "smartCardPublicId": { - "type": [ - "string", - "null" - ] - }, - "target": { - "type": "null" - }, - "webhook": { - "anyOf": [ - { - "properties": { - "endpointId": { - "maxLength": 16, - "minLength": 1, - "type": "string" - }, - "ref": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "required": [ - "endpointId" - ], - "type": "object" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "action", - "target" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "action": { + "const": "redirect", + "description": "What a scan does: open a URL.", + "type": "string" + }, + "enabled": { + "default": true, + "description": "`false` turns the tag off.", + "type": "boolean" + }, + "expiresAt": { + "anyOf": [ + { + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO datetime after which the link stops working; null for never." + }, + "name": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "A label, such as `Till K-1`." + }, + "smartCardPublicId": { + "description": "The id printed on an NFC card from Cluby, such as `00AE`, to attach it to the tag.", + "type": [ + "string", + "null" + ] + }, + "target": { + "description": "The https URL to open.", + "format": "uri", + "type": "string" + }, + "webhook": { + "anyOf": [ + { + "properties": { + "endpointId": { + "description": "The webhook endpoint the tag is tied to: the POS connection's `endpoint.id`.", + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "ref": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Your till reference, sent back as `posRef` on every scan. Unique per endpoint: a duplicate answers 409." + } + }, + "required": [ + "endpointId" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Ties the tag to your endpoint, so its scans carry `posRef` and the action links. `null` removes the tie. The target must be a venue." + } + }, + "required": [ + "action", + "target" + ], + "type": "object" + }, + { + "properties": { + "action": { + "const": "join", + "description": "What a scan does: join the venue; a register tag's action.", + "type": "string" + }, + "enabled": { + "default": true, + "description": "`false` turns the tag off.", + "type": "boolean" + }, + "expiresAt": { + "anyOf": [ + { + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO datetime after which the link stops working; null for never." + }, + "name": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "A label, such as `Till K-1`." + }, + "smartCardPublicId": { + "description": "The id printed on an NFC card from Cluby, such as `00AE`, to attach it to the tag.", + "type": [ + "string", + "null" + ] + }, + "target": { + "description": "`venue::{venueId}` for `join` and `show`, `stampcard::{stampCardId}` for `stamp`. A register tag targets its venue.", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "webhook": { + "anyOf": [ + { + "properties": { + "endpointId": { + "description": "The webhook endpoint the tag is tied to: the POS connection's `endpoint.id`.", + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "ref": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Your till reference, sent back as `posRef` on every scan. Unique per endpoint: a duplicate answers 409." + } + }, + "required": [ + "endpointId" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Ties the tag to your endpoint, so its scans carry `posRef` and the action links. `null` removes the tie. The target must be a venue." + } + }, + "required": [ + "action", + "target" + ], + "type": "object" + }, + { + "properties": { + "action": { + "const": "stamp", + "description": "What a scan does: give a stamp on a stamp card.", + "type": "string" + }, + "enabled": { + "default": true, + "description": "`false` turns the tag off.", + "type": "boolean" + }, + "expiresAt": { + "anyOf": [ + { + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO datetime after which the link stops working; null for never." + }, + "name": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "A label, such as `Till K-1`." + }, + "smartCardPublicId": { + "description": "The id printed on an NFC card from Cluby, such as `00AE`, to attach it to the tag.", + "type": [ + "string", + "null" + ] + }, + "target": { + "description": "`venue::{venueId}` for `join` and `show`, `stampcard::{stampCardId}` for `stamp`. A register tag targets its venue.", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "webhook": { + "anyOf": [ + { + "properties": { + "endpointId": { + "description": "The webhook endpoint the tag is tied to: the POS connection's `endpoint.id`.", + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "ref": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Your till reference, sent back as `posRef` on every scan. Unique per endpoint: a duplicate answers 409." + } + }, + "required": [ + "endpointId" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Ties the tag to your endpoint, so its scans carry `posRef` and the action links. `null` removes the tie. The target must be a venue." + } + }, + "required": [ + "action", + "target" + ], + "type": "object" + }, + { + "properties": { + "action": { + "const": "show", + "description": "What a scan does: open the venue or a benefit.", + "type": "string" + }, + "enabled": { + "default": true, + "description": "`false` turns the tag off.", + "type": "boolean" + }, + "expiresAt": { + "anyOf": [ + { + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO datetime after which the link stops working; null for never." + }, + "name": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "A label, such as `Till K-1`." + }, + "smartCardPublicId": { + "description": "The id printed on an NFC card from Cluby, such as `00AE`, to attach it to the tag.", + "type": [ + "string", + "null" + ] + }, + "target": { + "description": "`venue::{venueId}` for `join` and `show`, `stampcard::{stampCardId}` for `stamp`. A register tag targets its venue.", + "maxLength": 200, + "minLength": 1, + "type": "string" + }, + "webhook": { + "anyOf": [ + { + "properties": { + "endpointId": { + "description": "The webhook endpoint the tag is tied to: the POS connection's `endpoint.id`.", + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "ref": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Your till reference, sent back as `posRef` on every scan. Unique per endpoint: a duplicate answers 409." + } + }, + "required": [ + "endpointId" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Ties the tag to your endpoint, so its scans carry `posRef` and the action links. `null` removes the tie. The target must be a venue." + } + }, + "required": [ + "action", + "target" + ], + "type": "object" + }, + { + "properties": { + "action": { + "const": "none", + "description": "What a scan does: nothing beyond the scan itself.", + "type": "string" + }, + "enabled": { + "default": true, + "description": "`false` turns the tag off.", + "type": "boolean" + }, + "expiresAt": { + "anyOf": [ + { + "format": "date-time", + "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$", + "type": "string" + }, + { + "type": "null" + } + ], + "description": "ISO datetime after which the link stops working; null for never." + }, + "name": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "description": "A label, such as `Till K-1`." + }, + "smartCardPublicId": { + "description": "The id printed on an NFC card from Cluby, such as `00AE`, to attach it to the tag.", + "type": [ + "string", + "null" + ] + }, + "target": { + "description": "No target.", + "type": "null" + }, + "webhook": { + "anyOf": [ + { + "properties": { + "endpointId": { + "description": "The webhook endpoint the tag is tied to: the POS connection's `endpoint.id`.", + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "ref": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Your till reference, sent back as `posRef` on every scan. Unique per endpoint: a duplicate answers 409." + } + }, + "required": [ + "endpointId" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "Ties the tag to your endpoint, so its scans carry `posRef` and the action links. `null` removes the tie. The target must be a venue." + } + }, + "required": [ + "action", + "target" + ], + "type": "object" + } +]
- Changed
create_webhook_endpoint7 fields changed- added
Input schema / properties / enabled / descriptionAdded value: +"`false` stops deliveries without deleting the endpoint." - added
Input schema / properties / events / descriptionAdded value: +"The event types to receive. `smart_link.scanned` by default." - added
Input schema / properties / includes / descriptionAdded value: +"What each event carries beyond its own data: `profile`, `membershipCards`, `benefits`, `stampCards`, `items`. None by default; a POS connection's own endpoint gets all of them." - changed
Input schema / properties / includes / items / enumPrevious value: -[ - "profile", - "membershipCards", - "benefits", - "stampCards" -]New value: +[ + "profile", + "membershipCards", + "benefits", + "stampCards", + "items" +] - added
Input schema / properties / name / descriptionAdded value: +"A label for lists and alerts. The URL's host by default." - added
Input schema / properties / secret / descriptionAdded value: +"The key events are signed with. Omit it to have one generated (`whsec_…`), returned once and never again. Use the whole string, prefix included, as the HMAC key. A new one replaces the old at once." - added
Input schema / properties / url / descriptionAdded value: +"A public HTTPS URL. Private, link-local and loopback addresses are refused, and redirects are not followed."
- Changed
list_webhook_events6 fields changed- added
Input schema / properties / cursor / descriptionAdded value: +"The previous page's `nextCursor`." - added
Input schema / properties / endpointId / descriptionAdded value: +"Only this endpoint's events." - added
Input schema / properties / limit / descriptionAdded value: +"Events per page, 1 to 200. 50 by default." - added
Input schema / properties / since / descriptionAdded value: +"Only events made at or after this instant, such as `2026-10-21T12:00:00Z`." - added
Input schema / properties / status / descriptionAdded value: +"Only events in this status." - added
Input schema / properties / type / descriptionAdded value: +"Only this event type."
- Changed
set_pos_connection17 fields changed- changed
Input schema / properties / articleSearchUrl / anyOfPrevious value: -[ - { - "format": "uri", - "maxLength": 2048, - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "description": "A public HTTPS URL. Private, link-local and loopback addresses are refused, and redirects are not followed.", + "format": "uri", + "maxLength": 2048, + "type": "string" + }, + { + "type": "null" + } +] - added
Input schema / properties / articleSearchUrl / descriptionAdded value: +"Reserved: where Cluby will search your article catalogue once venues can map benefits to articles. Optional." - added
Input schema / properties / capabilities / descriptionAdded value: +"What your POS can do with an action's answer." - changed
Input schema / properties / capabilities / properties / apply / defaultPrevious value: -[ - "price", - "percent_off", - "manual" -]New value: +[ + "percent_off", + "amount_off", + "price", + "free_item", + "manual" +] - added
Input schema / properties / capabilities / properties / apply / descriptionAdded value: +"The `apply` kinds your POS executes on the open sale. Every kind by default; list fewer if it cannot execute some. Preview." - changed
Input schema / properties / capabilities / properties / apply / items / enumPrevious value: -[ - "price", - "percent_off", - "manual" -]New value: +[ + "percent_off", + "amount_off", + "price", + "free_item", + "manual" +] - added
Input schema / properties / enabled / descriptionAdded value: +"`false` pauses the connection and its channel. Your next PUT after reconnecting turns them back on." - added
Input schema / properties / endpoint / descriptionAdded value: +"The connection's event channel, the webhook endpoint that receives `smart_link.scanned`. Created with every include unless `includes` says otherwise; an endpoint created earlier keeps the includes it lists. `url` is required on the first call; later calls change only the fields sent." - added
Input schema / properties / endpoint / properties / enabled / descriptionAdded value: +"`false` stops deliveries without deleting the endpoint." - added
Input schema / properties / endpoint / properties / includes / descriptionAdded value: +"What each event carries beyond its own data: `profile`, `membershipCards`, `benefits`, `stampCards`, `items`. None by default; a POS connection's own endpoint gets all of them." - changed
Input schema / properties / endpoint / properties / includes / items / enumPrevious value: -[ - "profile", - "membershipCards", - "benefits", - "stampCards" -]New value: +[ + "profile", + "membershipCards", + "benefits", + "stampCards", + "items" +] - added
Input schema / properties / endpoint / properties / name / descriptionAdded value: +"A label for lists and alerts. The URL's host by default." - added
Input schema / properties / endpoint / properties / secret / descriptionAdded value: +"The key events are signed with. Omit it to have one generated (`whsec_…`), returned once and never again. Use the whole string, prefix included, as the HMAC key. A new one replaces the old at once." - added
Input schema / properties / endpoint / properties / url / descriptionAdded value: +"A public HTTPS URL. Private, link-local and loopback addresses are refused, and redirects are not followed." - added
Input schema / properties / name / descriptionAdded value: +"Your product's name, as the organization sees it." - added
Input schema / properties / secret / descriptionAdded value: +"Reserved for calls from Cluby to your service, such as the article search. Generated when omitted and returned once." - added
Input schema / properties / webhookEndpointId / descriptionAdded value: +"Instead of `endpoint`: use one of the organization's existing endpoints as the channel."
- Changed
update_benefit1 field changed- added
Input schema / properties / activation / properties / duration / descriptionAdded value: +"How long activation remains visible on the screen when activated. Seconds."
- Changed
update_smart_link7 fields changed- added
Input schema / properties / body / properties / action / descriptionAdded value: +"What a scan does: `join` the venue, `show` it, `stamp` a stamp card, `redirect` to a URL, or `none`." - added
Input schema / properties / body / properties / enabled / descriptionAdded value: +"`false` turns the tag off." - added
Input schema / properties / body / properties / name / descriptionAdded value: +"A label, such as `Till K-1`." - added
Input schema / properties / body / properties / smartCardPublicId / descriptionAdded value: +"Attach the NFC card with this printed id, such as `00AE`; `null` detaches the tag's card. A card is on one tag at a time." - added
Input schema / properties / body / properties / target / descriptionAdded value: +"What the action acts on: `venue::{venueId}` for `join` and `show`, `stampcard::{stampCardId}` for `stamp`, an https URL for `redirect`, `null` for `none`. A register tag targets its venue." - changed
Input schema / properties / body / properties / webhook / anyOfPrevious value: -[ - { - "properties": { - "endpointId": { - "maxLength": 16, - "minLength": 1, - "type": "string" - }, - "ref": { - "anyOf": [ - { - "maxLength": 100, - "minLength": 1, - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "required": [ - "endpointId" - ], - "type": "object" - }, - { - "type": "null" - } -]New value: +[ + { + "properties": { + "endpointId": { + "description": "The webhook endpoint the tag is tied to: the POS connection's `endpoint.id`.", + "maxLength": 16, + "minLength": 1, + "type": "string" + }, + "ref": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Your till reference, sent back as `posRef` on every scan. Unique per endpoint: a duplicate answers 409." + } + }, + "required": [ + "endpointId" + ], + "type": "object" + }, + { + "type": "null" + } +] - added
Input schema / properties / body / properties / webhook / descriptionAdded value: +"Ties the tag to your endpoint, so its scans carry `posRef` and the action links. `null` removes the tie. The target must be a venue."
- Changed
update_webhook_endpoint7 fields changed- added
Input schema / properties / enabled / descriptionAdded value: +"`false` stops deliveries without deleting the endpoint." - added
Input schema / properties / events / descriptionAdded value: +"The event types to receive. `smart_link.scanned` by default." - added
Input schema / properties / includes / descriptionAdded value: +"What each event carries beyond its own data: `profile`, `membershipCards`, `benefits`, `stampCards`, `items`. None by default; a POS connection's own endpoint gets all of them." - changed
Input schema / properties / includes / items / enumPrevious value: -[ - "profile", - "membershipCards", - "benefits", - "stampCards" -]New value: +[ + "profile", + "membershipCards", + "benefits", + "stampCards", + "items" +] - added
Input schema / properties / name / descriptionAdded value: +"A label for lists and alerts. The URL's host by default." - added
Input schema / properties / secret / descriptionAdded value: +"The key events are signed with. Omit it to have one generated (`whsec_…`), returned once and never again. Use the whole string, prefix included, as the HMAC key. A new one replaces the old at once." - added
Input schema / properties / url / descriptionAdded value: +"A public HTTPS URL. Private, link-local and loopback addresses are refused, and redirects are not followed."
17 tool updates
- Added
create_smart_link - Added
create_webhook_endpoint - Added
delete_pos_connection - Added
delete_webhook_endpoint - Added
get_pos_connection - Added
list_connected_apps - Added
list_nfc_cards - Added
list_pos_identifications - Added
list_smart_links - Added
list_webhook_endpoints - Added
list_webhook_events - Added
replay_webhook_event - Added
set_pos_connection - Added
test_smart_link_webhook - Added
test_webhook_endpoint - Added
update_smart_link - Added
update_webhook_endpoint
2 tool updates
- Changed
create_benefit9 fields changed- added
Input schema / properties / content / properties / size / anyOfAdded value: +[ + { + "description": "Optional numeric size of the benefit (e.g. 0.33, 500). Stored as DECIMAL(10,3) — at most 3 decimal places.", + "exclusiveMinimum": 0, + "maximum": 9999999.999, + "type": "number" + }, + { + "type": "null" + } +] - changed
Input schema / properties / content / properties / size / descriptionPrevious value: -"Optional numeric size of the benefit (e.g. 0.33, 500). Stored as DECIMAL(10,3) — at most 3 decimal places."New value: +"null clears the size" - removed
Input schema / properties / content / properties / size / exclusiveMinimumRemoved value: -0 - removed
Input schema / properties / content / properties / size / maximumRemoved value: -9999999.999 - removed
Input schema / properties / content / properties / size / typeRemoved value: -"number" - added
Input schema / properties / content / properties / sizeUnits / anyOfAdded value: +[ + { + "description": "Optional unit of measurement for `size`", + "enum": [ + "MILLILITER", + "CENTILITER", + "LITER", + "PINT" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / content / properties / sizeUnits / descriptionPrevious value: -"Optional unit of measurement for `size`"New value: +"null clears the size unit" - removed
Input schema / properties / content / properties / sizeUnits / enumRemoved value: -[ - "MILLILITER", - "CENTILITER", - "LITER", - "PINT" -] - removed
Input schema / properties / content / properties / sizeUnits / typeRemoved value: -"string"
- Changed
update_benefit9 fields changed- added
Input schema / properties / content / properties / size / anyOfAdded value: +[ + { + "description": "Optional numeric size of the benefit (e.g. 0.33, 500). Stored as DECIMAL(10,3) — at most 3 decimal places.", + "exclusiveMinimum": 0, + "maximum": 9999999.999, + "type": "number" + }, + { + "type": "null" + } +] - changed
Input schema / properties / content / properties / size / descriptionPrevious value: -"Optional numeric size of the benefit (e.g. 0.33, 500). Stored as DECIMAL(10,3) — at most 3 decimal places."New value: +"null clears the size" - removed
Input schema / properties / content / properties / size / exclusiveMinimumRemoved value: -0 - removed
Input schema / properties / content / properties / size / maximumRemoved value: -9999999.999 - removed
Input schema / properties / content / properties / size / typeRemoved value: -"number" - added
Input schema / properties / content / properties / sizeUnits / anyOfAdded value: +[ + { + "description": "Optional unit of measurement for `size`", + "enum": [ + "MILLILITER", + "CENTILITER", + "LITER", + "PINT" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / content / properties / sizeUnits / descriptionPrevious value: -"Optional unit of measurement for `size`"New value: +"null clears the size unit" - removed
Input schema / properties / content / properties / sizeUnits / enumRemoved value: -[ - "MILLILITER", - "CENTILITER", - "LITER", - "PINT" -] - removed
Input schema / properties / content / properties / sizeUnits / typeRemoved value: -"string"
2 tool updates
- Changed
create_benefit1 field changed- changed
Input schema / properties / activation / properties / resetTime / descriptionPrevious value: -"Time when benefit resets in venue's local timezone (HH:MM format)"New value: +"Time of day in UTC (HH:MM) when the per-member quota resets. Only the hour is kept."
- Changed
update_benefit1 field changed- changed
Input schema / properties / activation / properties / resetTime / descriptionPrevious value: -"Time when benefit resets in venue's local timezone (HH:MM format)"New value: +"Time of day in UTC (HH:MM) when the per-member quota resets. Only the hour is kept."
1 tool update
- Changed
create_benefit3 fields changed- added
Input schema / properties / materialsOrder / properties / declined / constAdded value: +false - changed
Input schema / properties / materialsOrder / properties / declined / descriptionPrevious value: -"The merchant opted out of the free marketing materials"New value: +"Deprecated: the materials can no longer be declined" - changed
Input schema / properties / materialsOrder / requiredPrevious value: -[ - "declined" -]New value: +[ + "contactName", + "contactEmail", + "contactPhone" +]
2 tool updates
- Changed
create_benefit1 field changed- removed
Input schema / properties / content / properties / iconRemoved value: -{ - "default": { - "name": "star", - "variant": "solid" - }, - "properties": { - "name": { - "default": "star", - "type": "string" - }, - "variant": { - "default": "solid", - "enum": [ - "solid", - "regular", - "light" - ], - "type": "string" - } - }, - "type": "object" -}
- Changed
update_benefit1 field changed- removed
Input schema / properties / content / properties / iconRemoved value: -{ - "properties": { - "name": { - "default": "star", - "type": "string" - }, - "variant": { - "default": "solid", - "enum": [ - "solid", - "regular", - "light" - ], - "type": "string" - } - }, - "type": "object" -}
3 tool updates
- Added
create_birthday_gift - Added
list_birthday_gifts - Added
update_birthday_gift
3 tool updates
- Changed
create_benefit6 fields changed- changed
Input schema / properties / content / properties / images / items / properties / attribution / descriptionPrevious value: -"Attribution metadata for images sourced from third-party providers (e.g. Unsplash). Stored on each image variant so attribution travels with the image data wherever it's persisted."New value: +"Attribution metadata for images sourced from third-party providers (Unsplash, Pexels, Wikimedia Commons). Stored on each image variant so attribution travels with the image data wherever it's persisted. Wikimedia images under a CC BY or CC BY-SA license must be displayed with the photographer, license and source link." - added
Input schema / properties / content / properties / images / items / properties / attribution / properties / licenseAdded value: +{ + "description": "Wikimedia only, e.g. \"CC BY-SA 4.0\"", + "type": "string" +} - added
Input schema / properties / content / properties / images / items / properties / attribution / properties / licenseUrlAdded value: +{ + "format": "uri", + "type": "string" +} - removed
Input schema / properties / content / properties / images / items / properties / attribution / properties / source / constRemoved value: -"unsplash" - added
Input schema / properties / content / properties / images / items / properties / attribution / properties / source / enumAdded value: +[ + "unsplash", + "pexels", + "wikimedia" +] - changed
Input schema / properties / content / properties / images / items / properties / attribution / requiredPrevious value: -[ - "source", - "photoId", - "photographerName", - "photographerProfileUrl", - "sourceUrl" -]New value: +[ + "source", + "photoId", + "photographerName", + "sourceUrl" +]
- Changed
import_image5 fields changed- added
Input schema / properties / attribution / properties / licenseAdded value: +{ + "description": "Wikimedia only, e.g. \"CC BY-SA 4.0\"", + "type": "string" +} - added
Input schema / properties / attribution / properties / licenseUrlAdded value: +{ + "format": "uri", + "type": "string" +} - removed
Input schema / properties / attribution / properties / source / constRemoved value: -"unsplash" - added
Input schema / properties / attribution / properties / source / enumAdded value: +[ + "unsplash", + "pexels", + "wikimedia" +] - changed
Input schema / properties / attribution / requiredPrevious value: -[ - "source", - "photoId", - "photographerName", - "photographerProfileUrl", - "sourceUrl" -]New value: +[ + "source", + "photoId", + "photographerName", + "sourceUrl" +]
- Changed
update_benefit6 fields changed- changed
Input schema / properties / content / properties / images / items / properties / attribution / descriptionPrevious value: -"Attribution metadata for images sourced from third-party providers (e.g. Unsplash). Stored on each image variant so attribution travels with the image data wherever it's persisted."New value: +"Attribution metadata for images sourced from third-party providers (Unsplash, Pexels, Wikimedia Commons). Stored on each image variant so attribution travels with the image data wherever it's persisted. Wikimedia images under a CC BY or CC BY-SA license must be displayed with the photographer, license and source link." - added
Input schema / properties / content / properties / images / items / properties / attribution / properties / licenseAdded value: +{ + "description": "Wikimedia only, e.g. \"CC BY-SA 4.0\"", + "type": "string" +} - added
Input schema / properties / content / properties / images / items / properties / attribution / properties / licenseUrlAdded value: +{ + "format": "uri", + "type": "string" +} - removed
Input schema / properties / content / properties / images / items / properties / attribution / properties / source / constRemoved value: -"unsplash" - added
Input schema / properties / content / properties / images / items / properties / attribution / properties / source / enumAdded value: +[ + "unsplash", + "pexels", + "wikimedia" +] - changed
Input schema / properties / content / properties / images / items / properties / attribution / requiredPrevious value: -[ - "source", - "photoId", - "photographerName", - "photographerProfileUrl", - "sourceUrl" -]New value: +[ + "source", + "photoId", + "photographerName", + "sourceUrl" +]
2 tool updates
- Changed
create_benefit10 fields changed- added
Input schema / properties / content / properties / description / anyOfAdded value: +[ + { + "description": "A localized string with a required default value and optional locale-specific translations", + "properties": { + "cs": { + "type": "string" + }, + "da": { + "type": "string" + }, + "de": { + "type": "string" + }, + "default": { + "type": "string" + }, + "en": { + "type": "string" + }, + "es": { + "type": "string" + }, + "et": { + "type": "string" + }, + "fi": { + "type": "string" + }, + "fr": { + "type": "string" + }, + "it": { + "type": "string" + }, + "ka": { + "type": "string" + }, + "lt": { + "type": "string" + }, + "lv": { + "type": "string" + }, + "nb": { + "type": "string" + }, + "nl": { + "type": "string" + }, + "pl": { + "type": "string" + }, + "pt": { + "type": "string" + }, + "ru": { + "type": "string" + }, + "sk": { + "type": "string" + }, + "sv": { + "type": "string" + }, + "uk": { + "type": "string" + } + }, + "required": [ + "default" + ], + "type": "object" + }, + { + "type": "null" + } +] - changed
Input schema / properties / content / properties / description / descriptionPrevious value: -"A localized string with a required default value and optional locale-specific translations"New value: +"null clears the description" - removed
Input schema / properties / content / properties / description / propertiesRemoved value: -{ - "cs": { - "type": "string" - }, - "da": { - "type": "string" - }, - "de": { - "type": "string" - }, - "default": { - "type": "string" - }, - "en": { - "type": "string" - }, - "es": { - "type": "string" - }, - "et": { - "type": "string" - }, - "fi": { - "type": "string" - }, - "fr": { - "type": "string" - }, - "it": { - "type": "string" - }, - "ka": { - "type": "string" - }, - "lt": { - "type": "string" - }, - "lv": { - "type": "string" - }, - "nb": { - "type": "string" - }, - "nl": { - "type": "string" - }, - "pl": { - "type": "string" - }, - "pt": { - "type": "string" - }, - "ru": { - "type": "string" - }, - "sk": { - "type": "string" - }, - "sv": { - "type": "string" - }, - "uk": { - "type": "string" - } -} - removed
Input schema / properties / content / properties / description / requiredRemoved value: -[ - "default" -] - removed
Input schema / properties / content / properties / description / typeRemoved value: -"object" - added
Input schema / properties / content / properties / offerAdded value: +{ + "anyOf": [ + { + "properties": { + "type": { + "enum": [ + "price", + "percent_off" + ], + "type": "string" + }, + "value": { + "description": "For `price`: the amount in the minor unit of the organization's currency (500 = 5.00 EUR; 0 = free). For `percent_off`: basis points (2000 = 20 % off), at most 10000.", + "maximum": 2147483647, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The benefit's value: a price or a percentage off. null or absent for a benefit with no value shown." +} - changed
Input schema / properties / content / properties / valueDisplay / descriptionPrevious value: -"A localized string with a required default value and optional locale-specific translations"New value: +"Read-only and refused: send content.offer" - removed
Input schema / properties / content / properties / valueDisplay / propertiesRemoved value: -{ - "cs": { - "type": "string" - }, - "da": { - "type": "string" - }, - "de": { - "type": "string" - }, - "default": { - "type": "string" - }, - "en": { - "type": "string" - }, - "es": { - "type": "string" - }, - "et": { - "type": "string" - }, - "fi": { - "type": "string" - }, - "fr": { - "type": "string" - }, - "it": { - "type": "string" - }, - "ka": { - "type": "string" - }, - "lt": { - "type": "string" - }, - "lv": { - "type": "string" - }, - "nb": { - "type": "string" - }, - "nl": { - "type": "string" - }, - "pl": { - "type": "string" - }, - "pt": { - "type": "string" - }, - "ru": { - "type": "string" - }, - "sk": { - "type": "string" - }, - "sv": { - "type": "string" - }, - "uk": { - "type": "string" - } -} - removed
Input schema / properties / content / properties / valueDisplay / requiredRemoved value: -[ - "default" -] - removed
Input schema / properties / content / properties / valueDisplay / typeRemoved value: -"object"
- Changed
update_benefit10 fields changed- added
Input schema / properties / content / properties / description / anyOfAdded value: +[ + { + "description": "A localized string with a required default value and optional locale-specific translations", + "properties": { + "cs": { + "type": "string" + }, + "da": { + "type": "string" + }, + "de": { + "type": "string" + }, + "default": { + "type": "string" + }, + "en": { + "type": "string" + }, + "es": { + "type": "string" + }, + "et": { + "type": "string" + }, + "fi": { + "type": "string" + }, + "fr": { + "type": "string" + }, + "it": { + "type": "string" + }, + "ka": { + "type": "string" + }, + "lt": { + "type": "string" + }, + "lv": { + "type": "string" + }, + "nb": { + "type": "string" + }, + "nl": { + "type": "string" + }, + "pl": { + "type": "string" + }, + "pt": { + "type": "string" + }, + "ru": { + "type": "string" + }, + "sk": { + "type": "string" + }, + "sv": { + "type": "string" + }, + "uk": { + "type": "string" + } + }, + "required": [ + "default" + ], + "type": "object" + }, + { + "type": "null" + } +] - changed
Input schema / properties / content / properties / description / descriptionPrevious value: -"A localized string with a required default value and optional locale-specific translations"New value: +"null clears the description" - removed
Input schema / properties / content / properties / description / propertiesRemoved value: -{ - "cs": { - "type": "string" - }, - "da": { - "type": "string" - }, - "de": { - "type": "string" - }, - "default": { - "type": "string" - }, - "en": { - "type": "string" - }, - "es": { - "type": "string" - }, - "et": { - "type": "string" - }, - "fi": { - "type": "string" - }, - "fr": { - "type": "string" - }, - "it": { - "type": "string" - }, - "ka": { - "type": "string" - }, - "lt": { - "type": "string" - }, - "lv": { - "type": "string" - }, - "nb": { - "type": "string" - }, - "nl": { - "type": "string" - }, - "pl": { - "type": "string" - }, - "pt": { - "type": "string" - }, - "ru": { - "type": "string" - }, - "sk": { - "type": "string" - }, - "sv": { - "type": "string" - }, - "uk": { - "type": "string" - } -} - removed
Input schema / properties / content / properties / description / requiredRemoved value: -[ - "default" -] - removed
Input schema / properties / content / properties / description / typeRemoved value: -"object" - added
Input schema / properties / content / properties / offerAdded value: +{ + "anyOf": [ + { + "properties": { + "type": { + "enum": [ + "price", + "percent_off" + ], + "type": "string" + }, + "value": { + "description": "For `price`: the amount in the minor unit of the organization's currency (500 = 5.00 EUR; 0 = free). For `percent_off`: basis points (2000 = 20 % off), at most 10000.", + "maximum": 2147483647, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "description": "The benefit's value: a price or a percentage off. null or absent for a benefit with no value shown." +} - changed
Input schema / properties / content / properties / valueDisplay / descriptionPrevious value: -"A localized string with a required default value and optional locale-specific translations"New value: +"Read-only and refused: send content.offer" - removed
Input schema / properties / content / properties / valueDisplay / propertiesRemoved value: -{ - "cs": { - "type": "string" - }, - "da": { - "type": "string" - }, - "de": { - "type": "string" - }, - "default": { - "type": "string" - }, - "en": { - "type": "string" - }, - "es": { - "type": "string" - }, - "et": { - "type": "string" - }, - "fi": { - "type": "string" - }, - "fr": { - "type": "string" - }, - "it": { - "type": "string" - }, - "ka": { - "type": "string" - }, - "lt": { - "type": "string" - }, - "lv": { - "type": "string" - }, - "nb": { - "type": "string" - }, - "nl": { - "type": "string" - }, - "pl": { - "type": "string" - }, - "pt": { - "type": "string" - }, - "ru": { - "type": "string" - }, - "sk": { - "type": "string" - }, - "sv": { - "type": "string" - }, - "uk": { - "type": "string" - } -} - removed
Input schema / properties / content / properties / valueDisplay / requiredRemoved value: -[ - "default" -] - removed
Input schema / properties / content / properties / valueDisplay / typeRemoved value: -"object"
3 tool updates
- Added
create_benefit - Added
import_image - Added
update_benefit
9 tool updates
- First observed
dashboard_summary - First observed
list_benefits - First observed
list_events - First observed
list_orgs - First observed
list_stamp_cards - First observed
list_status_cards - First observed
list_venues - First observed
member_stats - First observed
org_activity
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceRemote MCP server that lets AI assistants read tracked competitive intelligence — competitor news, reviews, website changes, social posts and ads — and act on it by managing projects, competitors, battle cards, reports and canvases. Every answer carries a source and a date, and write actions only publish when explicitly shared.MIT
- AlicenseCqualityBmaintenanceCompetitor Monitor AI - MCP server providing AI-powered tools and automation by MEOK AI Labs115 npm55 PyPIMIT
- AlicenseAqualityCmaintenanceEnables brand visibility monitoring across major AI platforms like ChatGPT, Claude, Gemini, and Perplexity. It allows users to track visibility scores, analyze competitor data, and receive actionable insights to improve AI-generated brand recommendations.1618 npm1MIT

industrylens-mcpofficial
AlicenseNot gradedqualityBmaintenanceBrowse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.