Skip to main content
Glama

PixelFlow

Create trigger

create_trigger
Idempotent

Create a trigger that sends an event to the site's ad platforms when a visitor submits a form, clicks an element, or loads a page, and return the saved trigger with its trigger_id. Build the selector, text_match, and data_extraction fields from one of these, never guess: the site's code open in this chat; a site builder's element data when that builder is connected in this chat; or the live page loaded in a browser tool the agent controls, where the agent runs the selector and confirms it matches only the elements the trigger should fire on. A page fetched as text, view-source, or a screenshot is not a source. Use what is rendered in the page: an element's id, a class, the control's visible label, or an input's name attribute. When none of these yields the selector, do not create a click or submit trigger: call get_connect_link with target visual_tagger and the page path, so the user picks the element and its fields. Call list_triggers first: a click or submit trigger on the same element may already exist, such as one the Visual Tagger saved. Nothing is added to the website code. Repeating an idempotency_key returns the same trigger. Refused until site setup has passed verify. Use it after the user approves a trigger, such as one proposed by suggest_triggers. Ask for approval in the user's words: the event, when it fires, and the fields it sends by their labels, if any.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "site_id": "<site_id>",
      "idempotency_key": "<idempotency_key>",
      "type": "<type>",
      "event": "<event>"
    },
    "name": "create_trigger"
  }
}

Input Schema

NameRequiredDescriptionDefault
urlNoPage on this site that fires the event when it loads. Required for url type. Refused for click and submit. Query values are ignored.
typeYesWhat the visitor does to trigger an event. submit: submits a `<form>` element that dispatches a native submit event. click: clicks a button, link, or other element, including one that submits a form with JavaScript without a native submit event, such as a form built without a `<form>` element, Ninja Forms, Elementor, or Gravity Forms with AJAX. url: loads a page (prefix match on host and path; the query is ignored), such as a product page for ViewContent.
eventYesEvent to send, such as Lead or Purchase. Names are in list_supported_values's `events`.
valueNoFixed value for every event. Omit when data_extraction reads the value from the page.
site_idYesSite to act on, as returned by list_sites.
currencyNoISO 4217 currency for value. Default the site's currency.
selectorNoRequired for click and submit type. For click: the element the visitor clicks, such as a button, a link, an image, or any other clickable element. For submit: the form's submit control, a `button` or an `input` of type submit, never the form or a wrapper around it; a submit selector that ends in `form`, `div`, `span`, `section`, or another container tag is refused. Prefer the element's `#id`, then a control tag (`button`, `input`, `a`) with text_match on its label, then a stable `[name=...]`, `[data-...=...]`, or `a[href=...]`, then a class chain read from the markup. The trigger fires on every element the selector matches, on every page, so a class has to be unique across the site, not only on this page. A bare tag without text_match is refused. At most 250 characters and 10 `>` segments.
text_matchNoThe control's own text, lowercased with whitespace collapsed: a button's label, or a submit input's `value`. Nothing else is compared, not aria-label, data-name, a form name, or an id. Required with a bare control tag such as `button` or `input`; optional with an id or attribute selector. equals: the whole label, such as "send message". contains: part of it. regex: a JavaScript regular expression, run on the lowercased text. Send one operator; when several are sent, equals is used, then contains.
allow_duplicateNoWhether to save even though the event already has another source. Without it, the call is refused and the refusal names that source. Default false.
data_extractionNoCustomer data, event value, and product data the script reads from the page when the trigger fires and sends with the event to the ad platforms. Recommended: it raises match quality and attribution, and lets the platform optimize on value. Each section is optional; unknown keys are refused.
idempotency_keyYesUnique string per intended change, such as a UUID. Repeating a key returns the first result instead of writing again.
url_params_mappingNoCustomer data and event value the script reads from the page URL's query when a url trigger fires and sends with the event to the ad platforms, such as a thank-you page opened as /thanks?email=...&amount=.... An object of query parameter name to field: `{ "email": "em", "amount": "value" }`. Fields: `em` (email), `ph` (phone), `fn` (first name), `ln` (last name), `full_name`, `ct` (city), `st` (state), `zp` (postal code), `country`, `value`, `currency`, `quantity`. url type only. Required when the page URL carries customer data in its query; without it, the call is refused and the refusal gives the mapping to send.

Output Schema

NameRequiredDescriptionDefault
triggerYesThe saved trigger, as a list_triggers row.
next_stepYesFor a saved trigger: what to do next. The previous configuration stays cached for about a minute; then the user tests once in a fresh private window and the event is confirmed with list_events. For click and submit: adding customer fields when missing, switching a silent submit trigger to click, and, when the test still sends no event, opening the Visual Tagger for that page.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / type / description
      Previous value: -"What the visitor does to trigger an event. submit: submits a `<form>` element. click: clicks a button, link, or other element, including the button of a form built without a `<form>` element. url: loads a page (prefix match on host and path; the query is ignored), such as a product page for ViewContent."New value: +"What the visitor does to trigger an event. submit: submits a `<form>` element that dispatches a native submit event. click: clicks a button, link, or other element, including one that submits a form with JavaScript without a native submit event, such as a form built without a `<form>` element, Ninja Forms, Elementor, or Gravity Forms with AJAX. url: loads a page (prefix match on host and path; the query is ignored), such as a product page for ViewContent."
    • changedOutput schema / properties / next_step / description
      Previous value: -"For a saved trigger: what to do next. The previous configuration stays cached for about a minute; then test once in a fresh private window and confirm with list_events. For click and submit: adding customer fields when missing, and, when the test sends no event, opening the Visual Tagger for that page."New value: +"For a saved trigger: what to do next. The previous configuration stays cached for about a minute; then the user tests once in a fresh private window and the event is confirmed with list_events. For click and submit: adding customer fields when missing, switching a silent submit trigger to click, and, when the test still sends no event, opening the Visual Tagger for that page."
  2. Changed12 schema fields changed
    • removedOutput schema / properties / trigger / properties / data_extraction / additionalProperties
      Removed value: -true
    • addedOutput schema / properties / trigger / properties / data_extraction / anyOf
      Added value: +[
      +  {
      +    "additionalProperties": true,
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / trigger / properties / data_extraction / type
      Removed value: -[
      -  "object",
      -  "null"
      -]
    • addedOutput schema / properties / trigger / properties / selector / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / trigger / properties / selector / type
      Removed value: -[
      -  "string",
      -  "null"
      -]
    • removedOutput schema / properties / trigger / properties / text_match / additionalProperties
      Removed value: -true
    • addedOutput schema / properties / trigger / properties / text_match / anyOf
      Added value: +[
      +  {
      +    "additionalProperties": true,
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / trigger / properties / text_match / type
      Removed value: -[
      -  "object",
      -  "null"
      -]
    • addedOutput schema / properties / trigger / properties / url / anyOf
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / trigger / properties / url / type
      Removed value: -[
      -  "string",
      -  "null"
      -]
    • addedOutput schema / properties / trigger / properties / value / anyOf
      Added value: +[
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • removedOutput schema / properties / trigger / properties / value / type
      Removed value: -[
      -  "number",
      -  "null"
      -]
  3. Changed25 schema fields changed
    • changedInput schema / properties / allow_duplicate / description
      Previous value: -"True only after the customer confirms a second source for an event that already has one"New value: +"Whether to save even though the event already has another source. Without it, the call is refused and the refusal names that source. Default false."
    • changedInput schema / properties / currency / description
      Previous value: -"3-letter currency code for the value, such as USD"New value: +"ISO 4217 currency for value. Default the site's currency."
    • addedInput schema / properties / currency / maxLength
      Added value: +3
    • changedInput schema / properties / data_extraction / additionalProperties
      Previous value: -trueNew value: +false
    • changedInput schema / properties / data_extraction / description
      Previous value: -"Copy this from suggest_triggers. The script reads customer.email, customer.firstName, customer.lastName, customer.fullName, and customer.phone, each { selector, extractFrom: \"value\" }. A single name is customer.fullName. An amount is form.valueSelector. Example: {\"customer\":{\"email\":{\"selector\":\"[name=\\\"email\\\"]\",\"extractFrom\":\"value\"},\"fullName\":{\"selector\":\"[name=\\\"name\\\"]\",\"extractFrom\":\"value\"}}}. Do not send customer_fields, a fields array, or em, fn, ph. Those codes belong in url_params_mapping."New value: +"Customer data, event value, and product data the script reads from the page when the trigger fires and sends with the event to the ad platforms. Recommended: it raises match quality and attribution, and lets the platform optimize on value. Each section is optional; unknown keys are refused."
    • addedInput schema / properties / data_extraction / examples
      Added value: +[
      +  {
      +    "customer": {
      +      "email": {
      +        "extractFrom": "value",
      +        "selector": "#Email"
      +      },
      +      "fullName": {
      +        "extractFrom": "value",
      +        "selector": "#Name"
      +      }
      +    }
      +  },
      +  {
      +    "customer": {
      +      "email": {
      +        "extractFrom": "value",
      +        "selector": "input[type=\"email\"]"
      +      },
      +      "phone": {
      +        "extractFrom": "value",
      +        "selector": "[name=\"phone\"]"
      +      }
      +    },
      +    "form": {
      +      "formContainerSelector": "#quote-form"
      +    }
      +  },
      +  {
      +    "commerce": {
      +      "fields": {
      +        "price": {
      +          "extractFrom": "text",
      +          "selector": ".product-price"
      +        },
      +        "productName": {
      +          "extractFrom": "text",
      +          "selector": ".product-title"
      +        }
      +      },
      +      "productContainerSelector": ".product-card"
      +    }
      +  }
      +]
    • addedInput schema / properties / data_extraction / properties
      Added value: +{
      +  "commerce": {
      +    "additionalProperties": false,
      +    "description": "Where the script reads product data on the page: one product on a product page, every product in a cart or checkout. `fields` is required.",
      +    "properties": {
      +      "fields": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "price": {
      +            "additionalProperties": false,
      +            "description": "Where the script reads the unit price, inside the product container.",
      +            "properties": {
      +              "attributeName": {
      +                "description": "Attribute to read when `extractFrom` is `attribute`.",
      +                "type": "string"
      +              },
      +              "extractFrom": {
      +                "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +                "enum": [
      +                  "value",
      +                  "text",
      +                  "attribute"
      +                ],
      +                "type": "string"
      +              },
      +              "fallbackSelector": {
      +                "description": "Tried when `selector` matches nothing.",
      +                "type": "string"
      +              },
      +              "selector": {
      +                "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +                "type": "string"
      +              },
      +              "textMatch": {
      +                "additionalProperties": false,
      +                "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +                "properties": {
      +                  "contains": {
      +                    "type": "string"
      +                  },
      +                  "equals": {
      +                    "type": "string"
      +                  },
      +                  "regex": {
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "selector"
      +            ],
      +            "type": "object"
      +          },
      +          "productId": {
      +            "additionalProperties": false,
      +            "description": "Where the script reads the product id, inside the product container.",
      +            "properties": {
      +              "attributeName": {
      +                "description": "Attribute to read when `extractFrom` is `attribute`.",
      +                "type": "string"
      +              },
      +              "extractFrom": {
      +                "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +                "enum": [
      +                  "value",
      +                  "text",
      +                  "attribute"
      +                ],
      +                "type": "string"
      +              },
      +              "fallbackSelector": {
      +                "description": "Tried when `selector` matches nothing.",
      +                "type": "string"
      +              },
      +              "selector": {
      +                "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +                "type": "string"
      +              },
      +              "textMatch": {
      +                "additionalProperties": false,
      +                "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +                "properties": {
      +                  "contains": {
      +                    "type": "string"
      +                  },
      +                  "equals": {
      +                    "type": "string"
      +                  },
      +                  "regex": {
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "selector"
      +            ],
      +            "type": "object"
      +          },
      +          "productName": {
      +            "additionalProperties": false,
      +            "description": "Where the script reads the product name, inside the product container.",
      +            "properties": {
      +              "attributeName": {
      +                "description": "Attribute to read when `extractFrom` is `attribute`.",
      +                "type": "string"
      +              },
      +              "extractFrom": {
      +                "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +                "enum": [
      +                  "value",
      +                  "text",
      +                  "attribute"
      +                ],
      +                "type": "string"
      +              },
      +              "fallbackSelector": {
      +                "description": "Tried when `selector` matches nothing.",
      +                "type": "string"
      +              },
      +              "selector": {
      +                "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +                "type": "string"
      +              },
      +              "textMatch": {
      +                "additionalProperties": false,
      +                "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +                "properties": {
      +                  "contains": {
      +                    "type": "string"
      +                  },
      +                  "equals": {
      +                    "type": "string"
      +                  },
      +                  "regex": {
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "selector"
      +            ],
      +            "type": "object"
      +          },
      +          "quantity": {
      +            "additionalProperties": false,
      +            "description": "Where the script reads the quantity, inside the product container.",
      +            "properties": {
      +              "attributeName": {
      +                "description": "Attribute to read when `extractFrom` is `attribute`.",
      +                "type": "string"
      +              },
      +              "extractFrom": {
      +                "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +                "enum": [
      +                  "value",
      +                  "text",
      +                  "attribute"
      +                ],
      +                "type": "string"
      +              },
      +              "fallbackSelector": {
      +                "description": "Tried when `selector` matches nothing.",
      +                "type": "string"
      +              },
      +              "selector": {
      +                "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +                "type": "string"
      +              },
      +              "textMatch": {
      +                "additionalProperties": false,
      +                "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +                "properties": {
      +                  "contains": {
      +                    "type": "string"
      +                  },
      +                  "equals": {
      +                    "type": "string"
      +                  },
      +                  "regex": {
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "selector"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "productContainerSelector": {
      +        "description": "The element that wraps one product, with its id, name, price, and quantity inside. On a product page it wraps the add-to-cart button; in a cart it repeats once per product.",
      +        "type": "string"
      +      },
      +      "productsListContainerSelector": {
      +        "description": "The element that wraps all product containers, such as a cart or an order summary; each product inside it is read.",
      +        "type": "string"
      +      },
      +      "totalPriceSelector": {
      +        "additionalProperties": false,
      +        "description": "Where the script reads the order total on the page.",
      +        "properties": {
      +          "attributeName": {
      +            "description": "Attribute to read when `extractFrom` is `attribute`.",
      +            "type": "string"
      +          },
      +          "extractFrom": {
      +            "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +            "enum": [
      +              "value",
      +              "text",
      +              "attribute"
      +            ],
      +            "type": "string"
      +          },
      +          "fallbackSelector": {
      +            "description": "Tried when `selector` matches nothing.",
      +            "type": "string"
      +          },
      +          "selector": {
      +            "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +            "type": "string"
      +          },
      +          "textMatch": {
      +            "additionalProperties": false,
      +            "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +            "properties": {
      +              "contains": {
      +                "type": "string"
      +              },
      +              "equals": {
      +                "type": "string"
      +              },
      +              "regex": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "selector"
      +        ],
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "fields"
      +    ],
      +    "type": "object"
      +  },
      +  "customer": {
      +    "additionalProperties": false,
      +    "description": "Where the script reads the visitor's data on the page: inside the submitted `<form>` first (or `form.formContainerSelector` for a click), then anywhere on the page.",
      +    "properties": {
      +      "email": {
      +        "additionalProperties": false,
      +        "description": "Where the script reads the visitor's email on the page.",
      +        "properties": {
      +          "attributeName": {
      +            "description": "Attribute to read when `extractFrom` is `attribute`.",
      +            "type": "string"
      +          },
      +          "extractFrom": {
      +            "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +            "enum": [
      +              "value",
      +              "text",
      +              "attribute"
      +            ],
      +            "type": "string"
      +          },
      +          "fallbackSelector": {
      +            "description": "Tried when `selector` matches nothing.",
      +            "type": "string"
      +          },
      +          "selector": {
      +            "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +            "type": "string"
      +          },
      +          "textMatch": {
      +            "additionalProperties": false,
      +            "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +            "properties": {
      +              "contains": {
      +                "type": "string"
      +              },
      +              "equals": {
      +                "type": "string"
      +              },
      +              "regex": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "selector"
      +        ],
      +        "type": "object"
      +      },
      +      "firstName": {
      +        "additionalProperties": false,
      +        "description": "Where the script reads the visitor's first name on the page.",
      +        "properties": {
      +          "attributeName": {
      +            "description": "Attribute to read when `extractFrom` is `attribute`.",
      +            "type": "string"
      +          },
      +          "extractFrom": {
      +            "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +            "enum": [
      +              "value",
      +              "text",
      +              "attribute"
      +            ],
      +            "type": "string"
      +          },
      +          "fallbackSelector": {
      +            "description": "Tried when `selector` matches nothing.",
      +            "type": "string"
      +          },
      +          "selector": {
      +            "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +            "type": "string"
      +          },
      +          "textMatch": {
      +            "additionalProperties": false,
      +            "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +            "properties": {
      +              "contains": {
      +                "type": "string"
      +              },
      +              "equals": {
      +                "type": "string"
      +              },
      +              "regex": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "selector"
      +        ],
      +        "type": "object"
      +      },
      +      "fullName": {
      +        "additionalProperties": false,
      +        "description": "Where the script reads the visitor's full name on the page, when the form has one name input. Split on whitespace into first and last name.",
      +        "properties": {
      +          "attributeName": {
      +            "description": "Attribute to read when `extractFrom` is `attribute`.",
      +            "type": "string"
      +          },
      +          "extractFrom": {
      +            "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +            "enum": [
      +              "value",
      +              "text",
      +              "attribute"
      +            ],
      +            "type": "string"
      +          },
      +          "fallbackSelector": {
      +            "description": "Tried when `selector` matches nothing.",
      +            "type": "string"
      +          },
      +          "selector": {
      +            "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +            "type": "string"
      +          },
      +          "textMatch": {
      +            "additionalProperties": false,
      +            "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +            "properties": {
      +              "contains": {
      +                "type": "string"
      +              },
      +              "equals": {
      +                "type": "string"
      +              },
      +              "regex": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "selector"
      +        ],
      +        "type": "object"
      +      },
      +      "lastName": {
      +        "additionalProperties": false,
      +        "description": "Where the script reads the visitor's last name on the page.",
      +        "properties": {
      +          "attributeName": {
      +            "description": "Attribute to read when `extractFrom` is `attribute`.",
      +            "type": "string"
      +          },
      +          "extractFrom": {
      +            "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +            "enum": [
      +              "value",
      +              "text",
      +              "attribute"
      +            ],
      +            "type": "string"
      +          },
      +          "fallbackSelector": {
      +            "description": "Tried when `selector` matches nothing.",
      +            "type": "string"
      +          },
      +          "selector": {
      +            "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +            "type": "string"
      +          },
      +          "textMatch": {
      +            "additionalProperties": false,
      +            "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +            "properties": {
      +              "contains": {
      +                "type": "string"
      +              },
      +              "equals": {
      +                "type": "string"
      +              },
      +              "regex": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "selector"
      +        ],
      +        "type": "object"
      +      },
      +      "phone": {
      +        "additionalProperties": false,
      +        "description": "Where the script reads the visitor's phone on the page.",
      +        "properties": {
      +          "attributeName": {
      +            "description": "Attribute to read when `extractFrom` is `attribute`.",
      +            "type": "string"
      +          },
      +          "extractFrom": {
      +            "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +            "enum": [
      +              "value",
      +              "text",
      +              "attribute"
      +            ],
      +            "type": "string"
      +          },
      +          "fallbackSelector": {
      +            "description": "Tried when `selector` matches nothing.",
      +            "type": "string"
      +          },
      +          "selector": {
      +            "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +            "type": "string"
      +          },
      +          "textMatch": {
      +            "additionalProperties": false,
      +            "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +            "properties": {
      +              "contains": {
      +                "type": "string"
      +              },
      +              "equals": {
      +                "type": "string"
      +              },
      +              "regex": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "selector"
      +        ],
      +        "type": "object"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "form": {
      +    "additionalProperties": false,
      +    "description": "Where the script reads the event value on the page, and the container of a form built without a `<form>` element.",
      +    "properties": {
      +      "formContainerSelector": {
      +        "description": "Applicable for click triggers only, recommended when customer fields or valueSelector are read: the element that wraps both the inputs and the clicked button. Customer fields and valueSelector are read inside it. When it does not wrap the clicked element, the first match on the page is used. Not needed for commerce fields.",
      +        "type": "string"
      +      },
      +      "valueSelector": {
      +        "additionalProperties": false,
      +        "description": "Where the script reads the event value on the page, such as a chosen plan's price. Omit when `value` is fixed.",
      +        "properties": {
      +          "attributeName": {
      +            "description": "Attribute to read when `extractFrom` is `attribute`.",
      +            "type": "string"
      +          },
      +          "extractFrom": {
      +            "description": "`value` for inputs, selects, and textareas (the default for them); `text` for visible text (the default otherwise); `attribute` with `attributeName`.",
      +            "enum": [
      +              "value",
      +              "text",
      +              "attribute"
      +            ],
      +            "type": "string"
      +          },
      +          "fallbackSelector": {
      +            "description": "Tried when `selector` matches nothing.",
      +            "type": "string"
      +          },
      +          "selector": {
      +            "description": "A valid, stable CSS selector for the element. Preferred order: `#id`; `[name=\"...\"]` exactly as rendered (letter case matters); a unique `[type=\"...\"]` such as `[type=\"email\"]`; a class. A label, placeholder, or display name is not a selector. A bare tag such as `input` is refused.",
      +            "type": "string"
      +          },
      +          "textMatch": {
      +            "additionalProperties": false,
      +            "description": "Narrows the matched elements by their text; same operators and rules as `text_match`.",
      +            "properties": {
      +              "contains": {
      +                "type": "string"
      +              },
      +              "equals": {
      +                "type": "string"
      +              },
      +              "regex": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "selector"
      +        ],
      +        "type": "object"
      +      }
      +    },
      +    "type": "object"
      +  }
      +}
    • addedInput schema / properties / event
      Added value: +{
      +  "description": "Event to send, such as Lead or Purchase. Names are in list_supported_values's `events`.",
      +  "type": "string"
      +}
    • removedInput schema / properties / event_type
      Removed value: -{
      -  "description": "Event type value, such as Lead or Purchase",
      -  "type": "string"
      -}
    • changedInput schema / properties / idempotency_key / description
      Previous value: -"Key for this approval line. The same key twice creates or changes one trigger"New value: +"Unique string per intended change, such as a UUID. Repeating a key returns the first result instead of writing again."
    • removedInput schema / properties / kind
      Removed value: -{
      -  "description": "page, click, or form",
      -  "type": "string"
      -}
    • changedInput schema / properties / selector / description
      Previous value: -"Selector you already have: an id, a name, a data attribute, an href, or a tag plus text_match"New value: +"Required for click and submit type. For click: the element the visitor clicks, such as a button, a link, an image, or any other clickable element. For submit: the form's submit control, a `button` or an `input` of type submit, never the form or a wrapper around it; a submit selector that ends in `form`, `div`, `span`, `section`, or another container tag is refused. Prefer the element's `#id`, then a control tag (`button`, `input`, `a`) with text_match on its label, then a stable `[name=...]`, `[data-...=...]`, or `a[href=...]`, then a class chain read from the markup. The trigger fires on every element the selector matches, on every page, so a class has to be unique across the site, not only on this page. A bare tag without text_match is refused. At most 250 characters and 10 `>` segments."
    • removedInput schema / properties / site
      Removed value: -{
      -  "description": "Domain, id, or external id from list_sites",
      -  "type": "string"
      -}
    • addedInput schema / properties / site_id
      Added value: +{
      +  "description": "Site to act on, as returned by list_sites.",
      +  "type": "integer"
      +}
    • removedInput schema / properties / suggestion_id
      Removed value: -{
      -  "description": "Proposal id when this line came from suggest_triggers. Omit otherwise",
      -  "type": "string"
      -}
    • changedInput schema / properties / text_match / additionalProperties
      Previous value: -trueNew value: +false
    • changedInput schema / properties / text_match / description
      Previous value: -"Optional text on the element. equals is the visible label lowercased with whitespace collapsed, such as send message. Use equals with a tag selector. Omit it when the selector is an id"New value: +"The control's own text, lowercased with whitespace collapsed: a button's label, or a submit input's `value`. Nothing else is compared, not aria-label, data-name, a form name, or an id. Required with a bare control tag such as `button` or `input`; optional with an id or attribute selector. equals: the whole label, such as \"send message\". contains: part of it. regex: a JavaScript regular expression, run on the lowercased text. Send one operator; when several are sent, equals is used, then contains."
    • addedInput schema / properties / text_match / properties
      Added value: +{
      +  "contains": {
      +    "type": "string"
      +  },
      +  "equals": {
      +    "type": "string"
      +  },
      +  "regex": {
      +    "type": "string"
      +  }
      +}
    • addedInput schema / properties / type
      Added value: +{
      +  "description": "What the visitor does to trigger an event. submit: submits a `<form>` element. click: clicks a button, link, or other element, including the button of a form built without a `<form>` element. url: loads a page (prefix match on host and path; the query is ignored), such as a product page for ViewContent.",
      +  "enum": [
      +    "url",
      +    "click",
      +    "submit"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / url / description
      Previous value: -"Page address on this Site. A page trigger needs only this. Query values are not returned"New value: +"Page on this site that fires the event when it loads. Required for url type. Refused for click and submit. Query values are ignored."
    • changedInput schema / properties / url_params_mapping / description
      Previous value: -"Query key to customer field, such as email to em. Omit and a page with those keys is not saved"New value: +"Customer data and event value the script reads from the page URL's query when a url trigger fires and sends with the event to the ad platforms, such as a thank-you page opened as /thanks?email=...&amount=.... An object of query parameter name to field: `{ \"email\": \"em\", \"amount\": \"value\" }`. Fields: `em` (email), `ph` (phone), `fn` (first name), `ln` (last name), `full_name`, `ct` (city), `st` (state), `zp` (postal code), `country`, `value`, `currency`, `quantity`. url type only. Required when the page URL carries customer data in its query; without it, the call is refused and the refusal gives the mapping to send."
    • changedInput schema / properties / value / description
      Previous value: -"Fixed amount for this event. Omit when the page or selector supplies it"New value: +"Fixed value for every event. Omit when data_extraction reads the value from the page."
    • addedInput schema / properties / value / minimum
      Added value: +0
    • changedInput schema / required
      Previous value: -[
      -  "site",
      -  "kind",
      -  "event_type",
      -  "idempotency_key"
      -]New value: +[
      +  "site_id",
      +  "idempotency_key",
      +  "type",
      +  "event"
      +]
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "next_step": {
      +      "description": "For a saved trigger: what to do next. The previous configuration stays cached for about a minute; then test once in a fresh private window and confirm with list_events. For click and submit: adding customer fields when missing, and, when the test sends no event, opening the Visual Tagger for that page.",
      +      "type": "string"
      +    },
      +    "trigger": {
      +      "additionalProperties": false,
      +      "description": "The saved trigger, as a list_triggers row.",
      +      "properties": {
      +        "created_at": {
      +          "description": "When the trigger was created.",
      +          "format": "date-time",
      +          "type": "string"
      +        },
      +        "data_extraction": {
      +          "additionalProperties": true,
      +          "description": "Where customer data, value, and product data are read on the page; same shape as the parameter.",
      +          "type": [
      +            "object",
      +            "null"
      +          ]
      +        },
      +        "event": {
      +          "description": "Event the trigger sends, such as Lead.",
      +          "type": "string"
      +        },
      +        "selector": {
      +          "description": "Element selector.",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "text_match": {
      +          "additionalProperties": true,
      +          "description": "Text filter on the element.",
      +          "type": [
      +            "object",
      +            "null"
      +          ]
      +        },
      +        "trigger_id": {
      +          "description": "Id of the trigger. update_trigger and delete_trigger take it.",
      +          "type": "integer"
      +        },
      +        "type": {
      +          "description": "Type of the saved trigger.",
      +          "enum": [
      +            "url",
      +            "click",
      +            "submit"
      +          ],
      +          "type": "string"
      +        },
      +        "url": {
      +          "description": "Page address, query removed.",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "value": {
      +          "description": "Fixed value.",
      +          "type": [
      +            "number",
      +            "null"
      +          ]
      +        }
      +      },
      +      "required": [
      +        "trigger_id",
      +        "type",
      +        "event",
      +        "url",
      +        "selector",
      +        "text_match",
      +        "value",
      +        "data_extraction",
      +        "created_at"
      +      ],
      +      "type": "object"
      +    }
      +  },
      +  "required": [
      +    "trigger",
      +    "next_step"
      +  ],
      +  "type": "object"
      +}
  4. First observed

TDQS

A4.4/5.0
Behavior4/5

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

Goes beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false) by disclosing side-effect scope (nothing is added to the website code), idempotency semantics (a repeated idempotency_key returns the same trigger), and a hard prerequisite (refused until site setup passes verify). It also describes refusal behavior for duplicate event sources and for container-tag submit selectors, though it does not discuss rate limits or authorization requirements.

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?

The first sentence front-loads purpose, side-effect, and return value, and the remaining paragraphs are ordered by decision sequence (sourcing the selector, fallback, duplicate check, then prerequisites). It is dense and occasionally repetitive with the schema's own selector guidance, which keeps it from a 5.

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

Completeness5/5

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

For a 12-parameter, deeply nested mutation tool with an output schema and full annotations, the description covers everything an agent needs before calling: allowed selector sources, refusals, idempotency, prerequisite gating, and the approval conversation in the user's own words. Return values need not be explained because an output schema exists.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents type, selector, text_match, data_extraction, and url_params_mapping in detail, establishing the baseline of 3. The description adds procedural meaning the schema cannot express, mainly how to derive selector/text_match/data_extraction from live page state and when to fall back to the visual tagger, but it does not add per-parameter syntax or constraints beyond that.

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

Purpose5/5

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

States a specific verb and resource (create a trigger that sends an event to ad platforms on form submit, element click, or page load) and states the return value (the saved trigger with its trigger_id). It is clearly distinguishable from siblings it names: suggest_triggers proposes, list_triggers detects duplicates, get_connect_link handles the fallback case.

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

Usage Guidelines5/5

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

Explicit about when to use (after the user approves a trigger, e.g. one proposed by suggest_triggers), what to do first (call list_triggers to check for an existing click/submit trigger on the same element), and when not to use it (no reliable selector source: call get_connect_link with target visual_tagger instead). It also names the only acceptable sources for selector fields and rules out page-as-text, view-source, and screenshots.

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.