Skip to help content
RightMessage
MCP referenceReference

MCP tools for widgets

Exact MCP widget arguments, targeting rules, design options, response fields, errors, and draft-only changes.

Available on the Grow, Scale, and Pro plans.

Updated

View as Markdown

Use these tools to connect a flow to a widget, set its audience and placement, and edit its design. A widget controls where and how a flow appears; it does not contain the flow's questions or branches. See flow tools for those resources.

MCP widget access and draft changes

Every tool accepts optional project_id (string). If omitted, the server uses the connection's active project or an accessible project it can resolve. Supply the ID explicitly when operating across projects.

The tools follow the shared MCP authorization and project-selection rules. There is no additional per-tool plan requirement. A missing project, inaccessible project, or missing entitlement returns an error rather than another project's data.

Configuration reads use the current draft when one exists, otherwise the published configuration. Create, update, duplicate, and delete save the draft and a configuration snapshot. They do not publish, display a widget, or execute its flow. Invalid configuration returns a validation error. Lookup and mutation errors are MCP errors, not successful resource objects. See publication tools before making the widget live.

Examples below are illustrative, not executed. Requests show MCP tool names and arguments; results show the JSON content, not the surrounding MCP transport envelope. Short result examples are explicitly labeled excerpts.

Widget arguments

create-widget and update-widget share these fields. Only creation requires name. Update requires widget_id and at least one changed field.

ArgumentType and behavior
nameString. Internal widget name.
typeString: modal, bar, toaster, inline, or takeover. Creation default: modal.
is_enabledBoolean. Creation default: true.
flow_idString identifying the flow. Creation default: no linked flow. On update, explicit null detaches it; omission preserves it.
frequencyString: startover, immediately, pageview, session, or none. Creation default: session. Returned as whenToAskNext.
visibilityObject described below.
optionsDesign object described below. Nested updates preserve omitted keys.

visibility

PropertyType and behavior
conditionsRecursive logic object or null. A leaf, {"and":[...]}, {"or":[...]}, or {"not":...}. null means all pages; {"or":[]} means none. Creation default: null. See condition tools for leaf arguments and validation.
placementsArray of ordered inline-placement objects. Each requires nonblank string path, nonblank string selector, and position: before, after, or inside. Optional domain is a bare hostname, at most 253 characters, with no scheme, port, path, or wildcard. Omit it to match any domain.
areasString identifying an inline embed area, such as workforge-survey.
triggerString. Creation default: exitIntent. The runtime values and default mismatch are described below.
dismissRuleObject with type: session, duration, or forever. Duration rules also use numeric duration and unit: minutes, hours, days, or weeks. Creation default: {"type":"session"}.
instantDismissBoolean.
formSubmitSelectorSelector used by the modal formsubmit trigger. The stored schema does not impose a dedicated type rule.

Placement paths can be exact (/welcome) or wildcard (/blog/*). Exact paths take precedence over wildcard paths, then list order resolves ties. inside appends to the target's children. Domains are saved lowercase.

Audience conditions and visual placement are separate. Preserve returned visibility.conditions unchanged if you are not changing targeting. On update, omitted visibility properties survive; a supplied property replaces that property. In particular, conditions, placements, and dismissRule are not recursively merged. Send placements: [] to clear placements. Inline widgets must retain an embed area or at least one complete placement. Non-inline widgets cannot have nonempty placements; clear them when changing type.

Legacy page-targeting properties (show_on_specific_pages, show_pages, hide_on_specific_pages, hide_pages, isWhitelistEnabled, whitelist, isBlacklistEnabled, blacklist) are rejected. Use conditions instead.

Trigger values and the creation default

The tool's description names exitIntent, scroll, and timed, but the visitor runtime does not recognize those as complete trigger values. New widgets nevertheless default to exitIntent. For a non-inline widget, set a supported trigger explicitly. Saving the default alone does not establish that it will appear.

Runtime valueBehavior
immediateShows when the widget is eligible.
exitExit intent on desktop; idle-based intent on mobile.
time_5sShows after five seconds. Replace 5 with an integer number of seconds.
scroll_50pcShows at 50% page scroll. Replace 50 with the intended integer percentage. A page too short to scroll shows immediately.
manualWaits for the widget's manual link or JavaScript trigger.
formsubmitModal only. Observes website form submission, optionally limited by formSubmitSelector.
barstaticBar only. Shows as a static bar.

Inline widgets show through their placement rather than waiting for visibility.trigger. A valid trigger still does not bypass audience, dismissal, frequency, or device settings.

options

All properties are optional. Returned options use camelCase. custom_css and display_targets are accepted aliases for customCss and displayTargets. Explicit null resets a nullable override; omission preserves it.

Some older design properties have no type restriction in the production schema. They are marked unconstrained below rather than given an invented enum. Copy their existing values when you are not changing them.

PropertySchema and purpose
themeUnconstrained; creation default plain.
paletteLight-palette object; fields below.
paletteDarkObject or null. Same palette fields. With darkMode: auto, overrides light colors for the visitor's dark color scheme.
darkModeoff or auto. off uses the light palette.
fontUnconstrained body-font setting.
headingFontString or null; null inherits the body font.
typeScales, m, l, or custom. Send actual fontSize values when changing scale.
fontSizeTypography object; fields below.
structureSizing and spacing object; fields below.
lookAppearance object; fields below.
overridesObject containing only phone and tablet. Device-specific fields are described below.
customCssUnconstrained advanced CSS setting; creation default empty string.
placementUnconstrained placement setting.
headerInfoObject with unconstrained isEnabled, style, imageUrl, title, and subtitle.
progressBarObject with unconstrained isEnabled and baseColor.
displayTargetsObject with phones, desktop, and tablets; all default to true on creation. These properties are unconstrained in the schema.
styleObject with unconstrained shadowSize.
backButtonLabel, backButtonEnabledUnconstrained settings.
nextButtonLabel, skipButtonLabelStrings; defaults Next and Skip.
buttonAnimationTriggerUnconstrained setting.

Palette fields

palette accepts these unconstrained base properties: borderColor, contrastColor, backgroundColor, textOnContrastColor, and textOnBackgroundColor. Creation defaults are #e2e8f0, #3b82f6, #ffffff, #ffffff, and #1e293b, respectively. In paletteDark, those five properties must be strings.

Both palettes also accept nullable strings: answerButtonColor, textOnAnswerButtonColor, formFieldColor, formFieldTextColor, formFieldBorderColor, placeholderColor, linkColor, backdropColor, backgroundGradientFrom, backgroundGradientTo, questionHeadingColor, questionTextColor, offerHeadingColor, offerTextColor, headerTitleColor, and headerSubtitleColor. backdropOpacity is a number from 0 to 1 or null.

contrastColor and textOnContrastColor style submit buttons. answerButtonColor and textOnAnswerButtonColor style answers. Null question, offer, and header text-color overrides inherit textOnBackgroundColor.

Typography fields

fontSize accepts unconstrained lineHeight, headlineFontSize, formFieldFontSize, descriptionFontSize, answerButtonFontSize, and submitButtonFontSize.

headingFontWeight, bodyFontWeight, and buttonFontWeight are numbers from 400 to 900 or null. submitButtonFontWeight also accepts theme. headerTitleFontSize and headerSubtitleFontSize are nonnegative pixel strings such as 24px or null; null retains the theme size.

Structure fields

These structure properties are unconstrained: formFieldSpacing, buttonBorderRadius, answerButtonSpacing, containerBorderWidth, containerBorderRadius, and widgetWidth.

These properties accept a nonnegative pixel string or null: submitButtonBorderRadius, fieldBorderRadius, imageHeight, backdropBlur, containerPaddingY, containerPaddingX, titleSpacing, contentSpacing, submitSpacing, and headerSpacing.

buttonLetterSpacing and submitButtonLetterSpacing accept an em string, including negative values, or null. Examples: 0.05em, -0.02em.

Custom padding and content spacing apply with look.density: custom, except on bars. Other density presets ignore them.

Appearance fields

look propertyAccepted values
densitycompact, comfortable, spacious, custom, or null
buttonStyle, submitButtonStylesolid, outline, ghost, gradient, or null
buttonSize, submitButtonSizes, m, l, or null
buttonFullWidthBoolean or null
submitButtonFullWidthBoolean, theme, or null
buttonUppercaseBoolean
submitButtonUppercaseBoolean or null
buttonHoverdarken, lighten, lift, none, or null
submitButtonHoverThe same values, plus theme
fieldStyleboxed, underlined, filled, or null
labelPositionabove, inside, hidden, or null
borderStylesolid, dashed, or dotted
backgroundTypecolor, gradient, or image
backgroundGradientAngleNumber from 0 to 360 or null
backgroundImageUrlString or null
imagePositiontop, left, background, or null
entrancenone, fade, slide, scale, or null
entranceSpeedslow, normal, or fast
stepTransitionslideLeft, slideUp, slideDown, crossfade, zoom, none, or null
stepTransitionFadeBoolean or null
closeButtonStyleicon, circle, text, or null
closeButtonPositionleft, right, or null
backButtonStylelink, button, icon, or null
skipButtonStylelink, button, or null

Answer-button settings and submit-button settings are independent. Nullable submit overrides inherit answer settings; theme selects the theme value where allowed.

Device overrides

overrides.phone and overrides.tablet each accept only fontSize, structure, and look; unknown properties are rejected. Base values apply on desktop.

  • Device fontSize accepts all typography fields above. Unlike the base object, lineHeight must be a number, and headlineFontSize, formFieldFontSize, descriptionFontSize, answerButtonFontSize, and submitButtonFontSize must be strings. Weight and header-size constraints are unchanged.
  • Device structure accepts all structure fields above. The otherwise unconstrained properties must be strings, except widgetWidth, which also accepts null. Pixel and em constraints are unchanged.
  • Device look accepts only density, buttonSize, buttonFullWidth, submitButtonSize, and submitButtonFullWidth, with the same constraints as the base object.

A generated-design preview does not rebuild for CSS-only changes. Changes to theme, placement, headerInfo, progressBar, displayTargets, backButtonEnabled, backButtonLabel, or look.labelPosition, look.imagePosition, and look.closeButtonStyle require a rebuilt preview rather than an in-place change to an open generated-design preview.

Returned widget object

Create, update, and duplicate return the saved object: id, name, type, isEnabled, contentId (flow ID or null), whenToAskNext, visibility, and options, with schema defaults and any existing configuration properties. IDs start with wdg_. Arguments use flow_id, but the saved object uses contentId.

Get adds presentation fields. List returns a compact summary instead. Do not copy a whole response into an update request; map the writable arguments above.

Configuration repair fills additional defaults beyond the widget constructor. Missing structure values become containerBorderRadius: "8px", containerBorderWidth: "0px", buttonBorderRadius: "0px", answerButtonSpacing: "8px", and formFieldSpacing: "8px". Missing headline size is 18px for bars/toasters and 24px otherwise; description size is 14px for toasters and 16px otherwise. Answer, form-field, and submit sizes default to 13px, with lineHeight: 1.5. Missing header/progress controls are disabled, header style is left, progress base color is #60a5fa, and shadow size is lg. A toaster with no placement receives right. Supplied options survive repair, so read the saved object rather than assuming it contains only the fields sent.

Newer repair also supplies darkMode: "off", paletteDark: null, headingFont: null, and typeScale: "custom" when missing. Optional palette colors, typography weight/header-size overrides, and advanced spacing overrides default to null. Missing look.density, look.buttonStyle, look.buttonSize, and look.fieldStyle are null rather than an explicit preset; borderStyle, backgroundType, and entranceSpeed default to solid, color, and normal.

list-widgets

List widgets without changing the configuration. The only argument is optional project_id.

Returns an array of {id, name, type, isEnabled, trigger, flowId, flowName, pageTargeting, visibility}. flowId and flowName can be null. pageTargeting is all, none, or conditions; the authoritative rule remains visibility.conditions.

Inline entries also include placements, the same array at visibility.placements, and embedCode when an embed area exists. embedCode is a string to place on your site, not an indication that the tool installed anything. Shared access errors apply; an empty project returns an empty array.

Illustrative request and result:

JSON
{"name":"list-widgets","arguments":{}}
JSON
[{"id":"wdg_workforge","name":"WorkForge welcome","type":"modal","isEnabled":true,"trigger":"exitIntent","flowId":"ofn_workforge","flowName":"WorkForge intake","pageTargeting":"all","visibility":{"conditions":null}}]

get-widget

Read the full widget. Requires widget_id (string); optional project_id uses the shared contract.

Returns the widget object plus flowName when a contentId exists, dismissRuleSummary, and resolved names alongside recognized resource IDs. Inline widgets can add embedCode, embedInstructions, and placements. Executable conditions and placement rules are returned unchanged; options is the saved design object, not a presentation summary.

Missing ID returns widget_id is required. An unknown ID returns Widget '…' not found. No draft or live changes occur.

Illustrative request and result excerpt:

JSON
{"name":"get-widget","arguments":{"widget_id":"wdg_workforge"}}
JSON
{"id":"wdg_workforge","name":"WorkForge welcome","type":"modal","isEnabled":true,"contentId":"ofn_workforge","flowName":"WorkForge intake","whenToAskNext":"session","visibility":{"conditions":null,"trigger":"exitIntent","dismissRule":{"type":"session"}}}

create-widget

Create a widget in the draft. Requires name (string). Accepts all shared widget arguments and optional project_id.

Returns the saved widget object. It does not create a flow. An inline widget without an embed area or complete placement fails validation. Invalid options or visibility return Validation error: …; missing name returns name is required. The shared configuration validation also applies.

Illustrative request and result excerpt:

JSON
{"name":"create-widget","arguments":{"name":"WorkForge welcome","type":"inline","flow_id":"ofn_workforge","visibility":{"conditions":null,"placements":[{"domain":"example.com","path":"/welcome","selector":"#intake","position":"inside"}]},"options":{"look":{"density":"comfortable"}}}}
JSON
{"id":"wdg_workforge","name":"WorkForge welcome","type":"inline","isEnabled":true,"contentId":"ofn_workforge","whenToAskNext":"session","visibility":{"conditions":null,"trigger":"exitIntent","dismissRule":{"type":"session"},"placements":[{"domain":"example.com","path":"/welcome","selector":"#intake","position":"inside"}]}}

update-widget

Change a widget in the draft. Requires widget_id (string) plus one or more shared widget arguments. Optional project_id uses the shared contract. All omitted values survive. Top-level null values are ignored except flow_id: null, which detaches the flow. Nested nullable option properties retain their reset behavior.

Returns the complete saved widget. A supplied nonempty flow_id must resolve to an existing flow. Unknown IDs return Widget '…' not found. or Flow '…' not found. Use list-flows to see available flows, or create one with create-flow. No changed fields returns No fields provided to update. Visibility and design validation errors use the shared rules.

Illustrative request and result excerpt:

JSON
{"name":"update-widget","arguments":{"widget_id":"wdg_workforge","options":{"palette":{"contrastColor":"#1d4ed8"},"look":{"submitButtonSize":"l"}}}}
JSON
{"id":"wdg_workforge","options":{"theme":"plain","palette":{"borderColor":"#e2e8f0","contrastColor":"#1d4ed8","backgroundColor":"#ffffff","textOnContrastColor":"#ffffff","textOnBackgroundColor":"#1e293b"},"look":{"density":"comfortable","submitButtonSize":"l"},"customCss":"","nextButtonLabel":"Next","skipButtonLabel":"Skip","displayTargets":{"phones":true,"tablets":true,"desktop":true}}}

duplicate-widget

Copy a widget into the draft. Requires widget_id (string). Optional new_name (string) defaults to the original name followed by (Copy); optional project_id uses the shared contract.

Returns the copied widget with a fresh wdg_ ID. The flow link, audience rules, placements, and design are copied, not duplicated into new resources. The copy keeps the original enablement setting but does not become live until published.

Missing ID or an unknown widget returns an error. Shared save validation applies.

Illustrative request and result excerpt:

JSON
{"name":"duplicate-widget","arguments":{"widget_id":"wdg_workforge","new_name":"WorkForge pricing intake"}}
JSON
{"id":"wdg_pricing1","name":"WorkForge pricing intake","type":"inline","isEnabled":true,"contentId":"ofn_workforge","whenToAskNext":"session"}

delete-widget

Remove a widget from the draft. Requires widget_id (string); optional project_id uses the shared contract.

Returns {deleted: true, widget_id}. It does not delete the linked flow, questions, or offers. The published widget remains live until the draft deletion is published. Missing ID returns widget_id is required.; an unknown ID returns Widget '…' not found.

Illustrative request and result:

JSON
{"name":"delete-widget","arguments":{"widget_id":"wdg_pricing1"}}
JSON
{"deleted":true,"widget_id":"wdg_pricing1"}

Still need a hand?

Tell us what you’re trying to do and where you’re getting stuck.

support@rightmessage.com