MCP tools for condition discovery and validation
Discover condition sources and exact fields, paginate the catalog, and validate audience rules without changing your project.
Use these MCP tools to find condition fields and validate rules for segment signals, flow branches, question options, and widget visibility. They do not evaluate a real visitor or save a rule.
MCP condition access and validation results
Both tools accept an optional string project_id and follow the shared MCP authorization and project-selection rules. There is no extra condition-specific plan gate. A catalog entry does not grant access to the provider or product feature that uses it.
Project context comes from draft configuration when available, otherwise published configuration. The tools return JSON payloads inside MCP responses. Project-selection and authorization failures are MCP errors. An invalid condition normally returns a successful tool result with valid: false, not an MCP transport error.
All examples are illustrative and were not executed. WorkForge IDs and example.com values are fictional.
list-condition-sources
Returns static condition definitions plus project-specific segment, input-answer, and provider sources.
| Argument | Required | Type, default, and limits |
|---|---|---|
project_id | No | String. Shared project selection. |
source | No | String. Exact source name, case-sensitive. |
search | No | String. Case-insensitive match against source names, source labels, type names, question IDs and labels, and segment names. Leading and trailing spaces are trimmed. |
compact | No | Boolean, default false. Removes examples and defaults to 20 entries. |
limit | No | Integer from 1 through 100. Default 20 in compact mode, otherwise all matching entries. |
offset | No | Integer at least 0, default 0. Counts matching type or question entries, not source objects. |
Without filters or pagination arguments, the result contains sources, logic_definition_schema, and signal_schema. Each ordinary source has name, label, optional description, and types. Each type has value, label, operators, and fields. Dynamic segment types also have available_segments: [{id, name}].
Field definitions have name and, where applicable, type, description, required, required_when, and enum values. A missing required flag is not a guarantee that the runtime can use an omitted field; descriptions contain additional conditional requirements.
The answers source differs. It has source-level fields and a questions array. Each question entry contains questionId, label, inputType, and its valid operators.
logic_definition_schema contains a description and, outside compact mode, example_simple and example_complex. signal_schema contains a description, weight_values: ["weak", "moderate", "strong"], and, outside compact mode, an example.
Any filter, compact mode, explicit limit, or positive offset adds total and next. total counts matching type/question entries before pagination. next is the next offset or null. A source can span several pages. Sources without entries on the current page are omitted. An unknown source or unmatched search returns an empty sources array rather than an error. Following next requires the same filters.
This read does not save configuration or contact a visitor. Shared access errors apply.
Illustrative request:
Illustrative result:
Descriptive strings in this illustrative result are explanatory, not values to compare in client code.
Logic structure
A simple definition is {"and":[condition]}. Alternatives use {"or":[{"and":[condition]}, {"and":[anotherCondition]}]}. Groups can nest and use {"not":group}. The validator accepts empty and and or arrays, but they aren't interchangeable. For widget visibility, empty AND matches all and empty OR matches none.
Most leaves contain $source, $type, and source-specific arguments. answers leaves contain $source: "answers", questionId, operator, and optional value, with no $type.
A signal wraps a definition in {indicates, weight, definition}. indicates is a segment ID. Signal creation belongs to segment tools. The validator accepts the definition, not that outer signal object. Campaign changes.segment_ids is a separate campaign input format, not a LogicDefinition argument.
Operator sets
The following names are exact strings:
- String comparisons:
equals,does not equal,contains,does not contain,starts with,ends with,glob,is set,is not set. - Inclusion comparisons:
include any,do not include any,is set,is not set. - Mathematical comparisons:
equals,does not equal,gt,lt,gte,lte. - Count comparisons in
occurrenceOperator:equals,gte,lte,gt,lt.
An empty operators list denotes a source that does not use a comparison operator, or one that uses a differently named comparison field.
Static sources and fields
| Source and type | Operators and leaf fields |
|---|---|
pageviews / landingpage | String comparisons. String value, a pathname beginning with /, without domain, query, or hash. |
pageviews / path | String comparisons plus matches pattern. String pathname value; occurrence: last, penultimate, any, or not_any; timeframe: ever, within, or outside. For any, add numeric occurrenceCount and occurrenceOperator. For within or outside, add numeric duration and unit: week, day, or hour. matches pattern requires occurrence: "last". |
pageviews / domain | String comparisons plus matches pattern. String value. Pattern matching ignores www., otherwise matches the domain exactly. Blank or * means any domain. |
pageviews / newvisitor | No other fields. |
pageviews / returningvisitor | timeframe: ever, within, or outside; numeric duration and unit for a bounded window. |
pageviews / pageCount | scope: any by default, or filtered. Filtered scope adds string operator and path value. Numeric occurrenceCount; occurrenceOperator defaults to gte. Optional timeframe, duration, and unit as above. |
pageviews / sessionCount | Numeric occurrenceCount, and occurrenceOperator defaulting to gte. This source defines a session as pageviews separated by no gap longer than one hour. |
pageviews / visitorAge | occurrenceOperator, numeric duration, and unit: week, day, or hour. |
utm / utm_source, utm_medium, utm_campaign, utm_term, utm_content | String comparisons, string value, and occurrence: last touch, last, first touch, first, or any. Presence operators need no value. |
query / custom | Same string operators and occurrence choices as UTM, plus required string query, the parameter name. |
referrer / direct, referral | No additional fields. |
referrer / domain | Required string domain without scheme. No comparison operator. |
referrer / custom | String comparisons and string URL value. |
location / country | Inclusion comparisons and string-array value of country codes. |
location / city | String comparisons and string value. |
device / os | Inclusion comparisons and string-array value. Catalog names are iOS, Android, Windows, MacOS, and Linux. |
device / browser | Inclusion comparisons and string-array value. Catalog names are Chrome, Firefox, Safari, Edge, and Opera. |
date / date | between, equals, before, or after; string date value in YYYY-MM-DD. between also needs string dateEnd. |
date / weekday, month | Inclusion comparisons and string-array value, using English day or month names. |
jsdata / windowVariable, cookie, localStorage | String comparisons, required string variable, and string value. variable is the window path, cookie name, or storage key. |
scores / score | Mathematical comparisons, required string score, and numeric value. |
scores / variable | Mathematical comparisons, required string variable, and string value in the catalog. |
scores / inputQuestion | Mathematical comparisons, required string inputQuestion, and string value in the catalog. |
rightmessage / widget | Inclusion comparisons and string-array value of widget IDs. |
rightmessage / question | Inclusion comparisons and string-array questionId of raq_ or dim_ IDs. Optional scope: "pageview". |
wordpress / current-pageId, current-postId, current-taxonomy-post_tag, current-taxonomy-category, favorite-taxonomy-post_tag, favorite-taxonomy-category | Inclusion comparisons and string-array value of the corresponding WordPress IDs. |
For current-page matches pattern, one leading or trailing slash is ignored and * is a wildcard. / means the homepage, /blog means that exact path, and /blog/* means paths beneath it. UTM and query values use readable strings; callers do not need to pre-encode spaces.
Project-specific sources
For segments, $type is an existing dimension ID. segmentId is an array of segment IDs. Inclusion operators apply. The catalog supplies the real IDs and names through available_segments.
The provider source uses the active provider's name, not a generic esp string. Available types depend on provider capabilities:
| Provider type | Fields and operators |
|---|---|
isAnonymous, isSubscriber | No fields or operators. |
tags | Inclusion operators and tagIds string array. |
customField | Required customFieldId string, string operators, optional value for presence checks and a string value for comparisons. |
lists | Inclusion operators and listIds string array. Only exposed if the provider can query lists. |
eventHistory | Required string eventName; has_fired, has_not_fired, gte, lt, or equals. Numeric count for count comparisons. |
purchaseHistory | Inclusion operators. String-array productIds for include and exclude comparisons. |
totalRevenue | Mathematical operators and required numeric value. Exposed only when supported. |
Without a connected integration, espplaceholder exposes only isAnonymous and isSubscriber. It does not supply provider fields or tags. Connected profile conditions depend on visitor identification; catalog discovery does not identify anyone.
Previous input answers
The answers source lists only existing input questions. Every input type accepts has answered and has not answered. Additional operators depend on the question's inputType:
| Input type | Additional operators |
|---|---|
number, rating, nps | equals, does not equal, greater than, greater than or equal to, less than, less than or equal to, between |
date | before, after, on, between, in the past, in the future, within the next days, within the last days |
country | is, is not, is any of |
phone | country is, country is not, country is any of |
email | domain is, domain is not, domain is any of, domain ends with, is a business email, is a personal email |
address | country is, country is not, country is any of, region equals, city equals, postal code starts with |
name | first name equals, first name contains, has last name, has no last name |
url | equals, contains, starts with, is empty, is not empty, domain is, domain ends with |
text, textarea | equals, contains, starts with, is empty, is not empty |
Presence, empty-value, business/personal-email, last-name-presence, and past/future operators reject a supplied value. Numeric comparisons require finite JSON numbers. Country comparisons require uppercase two-letter codes. Dates require real YYYY-MM-DD calendar dates. Domain targets must be hostnames of at most 253 characters, not URLs or email addresses. Name and address text targets cannot be blank.
Any-of operators need a nonempty array. between needs exactly two values in ascending order and is inclusive. Relative-day comparisons need a nonnegative integer no greater than 9007199254740991. They include today and the endpoint in the visitor's local calendar. in the past and in the future exclude today.
Missing answers or missing answer parts fail ordinary comparisons. Only has not answered matches a missing answer. is empty can match an explicitly stored empty string.
validate-condition
Checks one LogicDefinition against the current project's known sources, dimensions, and input questions.
| Argument | Required | Type and default |
|---|---|---|
project_id | No | String. Shared project selection. |
condition | Yes | Nonempty object containing and, or, or not logic. |
allow_legacy_pageview_values | No | Boolean, default false. Only literal true relaxes pathname checks for existing stored rules. |
Returns exactly {"valid":true} when no issues are found, or {"valid":false,"errors":["..."]}. Errors identify paths such as and[0] or or[1].and[0].
Checks include group structure, missing $source, unknown source/type, unknown segment dimension, invalid supplied operators, and selected required fields. It checks query names, browser-data variable names, referrer domains, score identifiers, provider custom-field identifiers, tag/list arrays, event names, revenue values, and dateEnd for a date range. Input-answer rules receive the stricter type-specific checks above, including rejection of extra keys.
New pageviews/path and pageviews/landingpage values must begin with / and contain no query or hash. The legacy flag skips that pathname restriction for an existing stored rule. It does not make matches pattern valid for historical occurrences; that operator still requires occurrence: "last".
This is a rule-shape check, not a full runtime simulation. In particular, it does not validate every catalog requirement, resolve every segment ID or provider value, fetch a contact, or guarantee that a provider implements a type merely because validation passed. A bare leaf is not the accepted top-level validation format, even though widget visibility can store one. Wrapping the leaf in and validates its fields without saving it.
An empty object returns valid: false with Condition must be a non-empty object with "and" or "or" keys. Shared authorization failures remain MCP errors. No rule is normalized or saved by this tool.
Illustrative request and result:
Illustrative invalid request and result: