apply_labels
ChatGPTApply or remove existing labels on flows, charts and dashboards, many targets in one call. The whole batch is atomic: every item lands or none does, so there is no per-item outcome to reconcile. Label ids come from list_labels; this tool never creates a label, so an id it does not recognise rejects the call with label_not_found and writes nothing at all — create it with create_or_update_label first, then call again. A target that cannot be found rejects the call the same way (target_not_found, naming the item). If a label or target is hard-deleted while the call is running, an add against it rolls the whole batch back (write_failed, nothing applied), while a remove against it is a silent no-op — consistent with removes being idempotent. Labels are not part of a flow's draft/publish cycle, so a change here is live immediately. Each result row splits the ids you passed into what actually changed (added_label_ids, removed_label_ids) and what was already in the requested state (unchanged_label_ids), so describe the outcome from those rather than from what you sent — a call whose rows are all unchanged_label_ids changed nothing. Both directions are idempotent, so re-sending a rejected call is safe — but drop any label id that no longer exists first, or the retry returns label_not_found and writes nothing. Two caps, and they interact: max 50 items per call, and max 50 label ids in total across ALL items, counting both directions — so a full 50-item batch is only possible at one label id per item (25 items × 2 ids, or 50 × 1). Split larger work across calls.
check_user_activity
ChatGPTRecent activity for a user or company, found by id or free-text search — the path for "any <event> from Acme?", "did X do Y recently?", "what has X been up to?". Pass company_identifier or user_identifier plus an optional event_name or flow_name, and set flow_name whenever the ask names a flow or checklist. It scans a capped window of recent events, which makes it the wrong basis for two other questions: the complete event log is get_user_events (resolve the UUID first), and counts are query_usage_metrics, since a capped scan can undercount.
create_flow
ChatGPTCreate an unpublished flow of any supported type: flow — guides/tours with tooltips, modals, speech bubbles or on-element beacons, and NPS/surveys (a flow whose draft.steps carry question widgets: nps, scale, stars, multiple_choice, text, multiline_text) — plus announcement, banner, checklist, launcher, resource_center, assistant, tracker, embed, and site. Provide steps and target elements directly via a draft. Use this for any "add a tooltip / tour / banner / checklist / survey / NPS to my app" request. Elements that can only be captured by clicking in the browser return a Builder URL to finish targeting there.
create_or_update_chart
ChatGPTCreate a usage/funnel chart or update an existing one. Omit chart_id to create; pass chart_id to update. The ONLY top-level parameters are chart_id, name, type, usage, and funnel — every configuration field (metrics, visualization, group_by, condition_predicates, time_period, …) goes INSIDE the usage/funnel embed, and env_id is never passed. When the user names a chart style (bar chart, pie, stacked bars, …), set usage.visualization explicitly (e.g. bar_chart) — omitting it ships the line_chart default and silently drops their ask. See chart-dsl + predicate-dsl for full configuration.
create_or_update_dashboard
ChatGPTCreate a new dashboard or update an existing one. Panels reference saved charts; the tool auto-arranges them in a 12-column grid. Panels point at charts that already exist — call list_charts and pin the one that matches rather than creating a near-duplicate, which leaves the workspace with two charts answering the same question. A filter aimed at a named segment references it by id with a segment node; rebuilding its rule as attribute predicates makes a copy that stops matching the moment the segment changes. Dashboard filters take attribute, clause and segment nodes only. See dashboard-dsl + predicate-dsl for full input details.
create_or_update_label
ChatGPTCreates or updates a label (name and colour). Omit label_id to create, pass it to update. Labels are shared across flows, charts and dashboards, so a rename shows up everywhere the label is already attached. color is optional when creating — an unused colour from Userflow's palette is picked. Names are unique per workspace and compared ignoring case: when one already exists the reply carries its label_id, so rename that label rather than making a near-duplicate. Two things this tool does not do: deleting a label, which is dashboard-only, so say so rather than reaching for another write tool; and attaching or removing labels on flows, charts and dashboards, which is apply_labels's job.
create_or_update_segment
ChatGPTCreates or updates a condition segment (name, predicates, columns, archive state) — the kind whose membership is a rule. Manual segments (membership curated by hand) and integration-synced ones are read-only here: they appear in list_segments but can only be edited in the dashboard, so report that instead of attempting it. subject_type is fixed at creation: a user segment cannot become a company segment, and an update carrying a different one is rejected. Creating a second segment of the other type is a reasonable next step when that is clearly what was wanted — say that a new segment exists, not that the original changed type. Event predicates take a tracked event name; resolve it with list_event_definitions instead of asking which event was meant. Archiving is not deletion. Segments are audience definitions, not a way to message anyone — Userflow sends no email through MCP.
create_smart_flow
ChatGPTStart a SmartFlow Builder draft only when the step targets must be recorded by a human clicking through the app in the Userflow extension (returns a URL to open). If you can describe the target element yourself (e.g. a tooltip on a named button), use create_flow with a draft instead. This produces a recording session rather than a finished flow, so it is not a fallback for a create_flow draft that was rejected: fix the draft, or offer this route and let the user decide.
describe_session
ChatGPTReturns the current MCP session: company, your role, and the environments you can access.
duplicate_flow
ChatGPTCopy an existing flow's draft into a new unpublished flow named name. Duplicating leaves the original untouched, so it is not a route to taking a flow offline, archiving, or deleting it. The returned edited_at is the concurrency token update_flow requires as expected_edited_at.
get_adoption_agent_analytics
ChatGPTAnalytics for an Adoption Agent flow.
get_adoption_agent_top_topics
ChatGPTRanked Adoption Agent conversation topics (requires topic modeling).
get_dashboard_data
ChatGPTGet a dashboard's layout and panel metadata.
get_flow_analytics
ChatGPTFull analytics for a single flow: session stats (views, completions, time series) plus a per-step breakdown with conversion rates for guides, a task breakdown for checklists, or views, reactions and comments for announcements. Per-task or per-step detail comes from here — get_flow_summary is the compact snapshot and carries no task breakdown. Across several flows, query_flow_metrics with include_steps compares step funnels in one call; for the worst drop-off alone, get_flow_summary is enough.
get_flow_details
ChatGPTDetailed info for one flow ID in a single environment (env_id): labels, alert policy, recent versions/publications, and publication status for that env only (flow_envs is filtered to the env you pass). For "live in all environments or only some?", call describe_session then call this tool once per env_id — a single production call cannot answer staging. Use list_flows to find the flow ID, and to answer catalog-wide questions (what is unpublished, draft, or labeled X) directly — those take one list call rather than a lookup per flow. The returned edited_at is the concurrency token update_flow requires as expected_edited_at — call this immediately before editing a flow.
get_flow_summary
ChatGPTPerformance snapshot for a single flow: session totals, completion rate, per-step funnel and worst drop-off, by flow_id or flow_name, with optional dates and user predicates. Comparing, ranking or totalling several flows is query_flow_metrics' job — it does the whole set in one call, where this tool would need one call per flow. A checklist's per-task breakdown lives in get_flow_analytics; catalog-wide questions (which flows are published, draft, labeled) in list_flows. Announcements report views, reactions and comments rather than completion metrics.
get_nps_breakdown
ChatGPTAggregated Net Promoter Score over a date range: rolled-up totals plus daily buckets. The bucket size is fixed here, so week-by-week or month-by-month trends belong to get_survey_analytics, which takes interval: week or month.
get_survey_analytics
ChatGPTAnalytics for one survey question within a flow, bucketed by interval — the path for week-by-week or month-by-month trends (set interval: week or month). A single rolled-up NPS score over a date range is get_nps_breakdown, whose interval is fixed at day.
get_user_events
ChatGPTThe raw event log for a user, company, or flow session, newest first. For "every recorded event" or individual event records, resolve the subject's UUID and come here; check_user_activity scans only a capped recent window, so it cannot stand in for the full log.
get_user_segments
ChatGPTReverse lookup: which segments include a given user or company — pass company_id for "which segments is Acme in?". Membership for one subject, where list_segments catalogues the segment definitions themselves.
list_adoption_agent_conversations
ChatGPTList conversations for an Adoption Agent flow.
list_attribute_definitions
ChatGPTUser, company, event, and company-membership attribute definitions. Attribute questions are workspace-specific, so read them from here rather than from memory. Pick the scope to match: "group_membership" for attributes of the user↔company relationship, "group" for company attributes, "event" for properties recorded on events (list_event_definitions returns event names instead). FQNs and scopes come back exactly as stored, company attributes under the group/ prefix.
list_charts
ChatGPTLists existing usage and funnel charts (optional types filter). Only usage charts can be executed, via query_chart_data. If the chart the user named is a funnel, the honest answer is that funnel charts aren't queryable over MCP yet — there is no substitute path, so reaching for query_chart_data, query_flow_metrics, get_flow_summary, or a flow that happens to share the chart's name would report something other than what was asked.
list_companies
ChatGPTCompanies in the current environment. When the ask names a plan or attribute, filter server-side with predicates — company FQNs carry the group/ prefix, so "companies on the enterprise plan" is group/plan eq enterprise — and with segment_id where relevant; filtering an unfiltered dump in prose gives the same answer only until the list outgrows one page. "The first N companies by name" is order_by on the name FQN (typically group/name) together with limit: N in the same call, for the same reason. "Companies that did event X" works either as an event predicate here or as query_usage_metrics with measurement: unique_companies.
list_dashboards
ChatGPTList analytics dashboards in the workspace.
list_event_definitions
ChatGPTAll tracked event definitions — the event names and their metadata. The properties recorded on events are a separate catalogue: list_attribute_definitions with scope: "event", which can be populated even when no event definitions exist yet.
list_flow_sessions
ChatGPTList individual flow sessions with pagination.
list_flow_subjects
ChatGPTList who has interacted with / been tracked on a flow. Auto-routes by flow type: session-based flows (flow, checklist, launcher, …) return sessions; trackers return tracker users; announcements return announcement users. Supports pagination and date filtering — not the flow's targeting/audience configuration.
list_flow_survey_questions
ChatGPTList survey questions from a flow's published version.
list_flows
ChatGPTLists flows with optional filters and metadata. Every call carries a types scope: types when the user named a kind, otherwise list_all_flow_types: true — choose it from the ask rather than checking back, and prefer the catalog-wide flag over a guessed subset, which would quietly hide flows. Filters compose, so keep label, state, edited_after and order_by alongside the types scope.
list_inactive_users
ChatGPTUsers with no recent activity, over a configurable inactivity threshold. A read-only lookup: Userflow exposes no email or messaging tool over MCP, so an ask like "email the inactive users" ends with the list plus a note that sending isn't available. Creating a segment wouldn't send anything either, so it isn't a substitute — offer it only if the user wants the audience saved.
list_labels
ChatGPTList labels (id, name, color) — shared across flows, charts and dashboards, and the same labels used by the label filter in list_flows.
list_segments
ChatGPTCatalogue of audience segment definitions for the account (name, subject_type, archive state). Membership questions — "which segments is this user or company in?" — are answered by get_user_segments with their UUID.
list_survey_responses
ChatGPTRaw survey answer rows for a flow, newest answer first — so "the last N answers" is this tool with limit: N. Date-bounded asks ("answers in the last N days", "this past week") should carry start_date in ISO 8601: a high limit with no window is a broad export and stops at the confirm_large_export gate, where a modest limit plus the window goes straight through. Summaries and trends are get_survey_analytics and get_nps_breakdown.
list_themes
ChatGPTList visual themes available in the workspace.
list_users
ChatGPTEnd users of the product in the current environment — the people using the app, not teammates or company members (Userflow exposes no teammate directory or teammate emails over MCP). "Which users…" asks belong here: filter with predicates, combined with AND — enterprise-plan users who signed in this week is a plan attribute plus a signed_in event or last_seen_at within_days. query_usage_metrics answers how many, not who, so it can't produce the list. Free-text and exact-id search are also available.
query_chart_data
ChatGPTExecute a chart's configured metrics against the environment. Usage charts only — funnel charts are not yet queryable via MCP: if list_charts shows type funnel, refuse and stop (do not run query_flow_metrics with the chart name).
query_flow_metrics
ChatGPTCompares, ranks, and totals session metrics across flows in a single call: pass one or more flow names or UUIDs in flows and get views, completions and rates back, ranked by sort_by/sort_dir — "which flow performs worst", "rank these" and "the best of these" are all that pair, and the key defaults to views, so omitting it quietly answers a different question. This is the right tool whenever more than one flow is involved — repeated get_flow_summary calls answer the same question far more slowly. For "across all our flows", resolve the catalog with list_flows first and pass every name or id. A single flow is better served elsewhere: get_flow_summary for its snapshot or step funnel, get_flow_analytics for its week-by-week trend (or set include_time_series: true alongside interval here, since interval on its own returns totals). Requires a time window: last_n_days, start_date/end_date, or all_time: true. The audience filter is predicates — subject_predicates belongs to query_usage_metrics and would be dropped here, leaving the results unfiltered. Announcements report views, reactions and comments rather than completion metrics. Charts are not flows: a chart named by the user goes through query_chart_data (usage charts only).
query_usage_metrics
ChatGPTEvent-log analytics for any tracked event (names from list_event_definitions; no attribute definitions needed). measurement is required — see that field for which one a question implies. For "break down signed_in by plan" pass group_by: ["plan"] (or ["group/plan"]) with a time window — group_by does the splitting, where a subject_predicate on plan would filter to a single one. A "which companies" question asks for identities, and measurement only ever returns a count: unique_companies tells you how many, group_by ["group/name"] names them, and list_companies with an event predicate lists them as rows. The audience filter here is subject_predicates; predicates is query_flow_metrics' name for it and would be dropped, leaving the results unfiltered. Match the FQN scope to the question: "enterprise-plan users" is the user's own attribute, subject_type user with fqn "plan" and value "enterprise" (not "enterprise-plan"), while "users whose company is on the enterprise plan" is fqn "group/plan" — both are valid here, they just answer different questions. Not for listing which users match filters (use list_users with predicates) or a named company's recent event rows (use check_user_activity with company_identifier + event_name). Not for flow performance — views/completions/funnels live in get_flow_summary, get_flow_analytics, and query_flow_metrics.
read_knowledge_base
ChatGPTReturn the full content of a Userflow knowledge base article by the id returned by search_knowledge_base. Use this instead of fetching the article url.
read_resource
ChatGPTReturn the full content of a static MCP resource by URI or keyword (e.g. "predicate-dsl" for the predicate DSL reference).
search_knowledge_base
ChatGPTThe source for "how do I…?", install, snippet and product-help questions about using Userflow: search with the user's question as q and answer from the results, since setup steps change with the product and recollection goes stale. When the user asks for the top N articles, set limit to exactly that N ("top 3" → limit: 3). Searches Userflow's public help docs at help.userflow.com rather than this workspace's data, so no env_id. Each hit carries an id for read_knowledge_base, which returns the full article — more reliable than fetching the url.
set_flow_publication
ChatGPTPublishes or unpublishes a flow in the authenticated environment. Consent-gated: call it without confirm first and the confirmation_required response returns the impact summary to show the user, then pass confirm: true once they approve. Unpublishing is not deletion, and archiving and deleting a flow aren't supported at all — those asks are better answered as unsupported, with unpublish offered in your reply for the user to choose, than started as a consent flow they didn't request.
update_flow
ChatGPTUpdate metadata and unpublished draft settings/content for a flow, optionally including a Builder-like draft object, and return a Userflow Builder URL. Requires expected_edited_at (the draft's edited_at from get_flow_details) and rejects writes based on a stale draft with a stale_flow error. Every draft-content write also snapshots the previous draft as a new frozen version, recoverable from the Builder's version history.