Skip to main content
Glama

Cluby MCP

Create smart link

create_smart_link

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.

Input Schema

NameRequiredDescriptionDefault
bodyYes
orgIdNoOrganization public id, the `id` field from list_orgs. Omit it when the API key reaches exactly one organization.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / body / oneOf
      Previous 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"
      +  }
      +]
  2. Added

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources