Update to Fullstory
Snapshot Oct 31, 2026 · 00:22 UTC · version 3.1.0
Collection source: downloaded plugin package. These snapshots do not have a confirmed matching collection source. Differences in file lists alone do not establish changes to the package.
Instructions updated for general-analysis
Full description — Now says: workflow — the default way to answer any question about user behavior. Use whenever someone asks how many, what percentage, which pages, whether something is...
Observed in instructions or declared skills. Runtime behavior has not been tested.
Up to 3 plugins free · no card required.
All fields and original values.
Full description
Sep 30, 2026 · 23:07 UTC
workflow. Use when answering a question that requires measuring user behavior — counts, rates, trends, breakdowns, or cohort comparisons. Builds segments and metrics, computes results, then investigates sessions to explain what the numbe...
Oct 31, 2026 · 00:22 UTC
workflow — the default way to answer any question about user behavior. Use whenever someone asks how many, what percentage, which pages, whether something is trending, where users drop off, what users did before or after an action, or ho...
Skill instructions
Sep 30, 2026 · 23:07 UTC
workflow. Use when answering a question that requires measuring user behavior — counts, rates, trends, breakdowns, or cohort comparisons. Builds segments and metrics, computes results, then investigates sessions to explain what the numbe...
Oct 31, 2026 · 00:22 UTC
workflow — the default way to answer any question about user behavior. Use whenever someone asks how many, what percentage, which pages, whether something is trending, where users drop off, what users did before or after an action, or ho...
Supporting files
Sep 30, 2026 · 23:07 UTC
[{"relative_path":"references/session-context.md","size_in_bytes":963},{"relative_path":"references/sessions.md","size_in_bytes":2457},{"relative_path":"references/validation.md","size_in_bytes":2828}]
Oct 31, 2026 · 00:22 UTC
[{"relative_path":"references/funnels.md","size_in_bytes":5135},{"relative_path":"references/journeys.md","size_in_bytes":5560},{"relative_path":"references/metrics.md","size_in_bytes":5852},{"relative_path":"references/session-context.m...
Compare saved observations
Download comparison JSONSKILL.md text changes
− removed · + added
--- before +++ after @@ -1,93 +1,140 @@ --- name: general-analysis -description: Fullstory analytics workflow. Use when answering a question that requires measuring user behavior — counts, rates, trends, breakdowns, or cohort comparisons. Builds segments and metrics, computes results, then investigates sessions to explain what the numbers mean. +description: Fullstory analytics workflow — the default way to answer any question about user behavior. Use whenever someone asks how many, what percentage, which pages, whether something is trending, where users drop off, what users did before or after an action, or how two cohorts compare — and also when they describe a business question that needs numbers behind it without ever saying "metric", "funnel", or "segment". Covers building and computing metrics, segments, funnels, and journeys, verifying that what got built is what was actually asked for, and pulling sessions to explain why the numbers look the way they do. Not for reviewing one specific session, or for setting up capture and instrumentation. --- # Fullstory Analytics -## Mental Model +## When to use -Internalize these three concepts before choosing tools: +Use this skill whenever answering the question takes a number out of Fullstory — a count, rate, percentage, breakdown, trend, drop-off, what users did before or after an action, or one cohort against another. That includes business questions that never name a primitive ("is checkout getting worse?", "which accounts are struggling?"). Pulling sessions is in scope when they're evidence for a number you computed. -- **Segment** = a cohort of users (the "who"). A segment is a filter, not a measurement. It narrows which users' data a metric runs against. -- **Metric** = the measurement (the "what" and "how much"). Every quantitative answer is a metric. Even "how many users visited /checkout" is a metric (count of page views), optionally filtered by a segment. -- **Session** = evidence (the "why"). Sessions are qualitative. Use them to understand *why* a number looks the way it does — not to answer the quantitative question itself. +## Skip when -## Step 0: Classify Intent +- **One specific session.** A session URL, a named user, "what happened to this person" — that's the `session-review` skill. +- **Instrumentation and capture.** Defining events, custom properties, privacy rules, or installing the snippet. This skill reads data that already exists; it can't make Fullstory record something new. +- **Account and product configuration.** Users, permissions, integrations, data export setup. +- **No Fullstory data in the loop.** A number the user already has, or one that lives in another system. -Before calling any tool, determine what the user is asking for: +Handing off isn't an exit. If a session review turns into "how often does this happen?", that part is this skill. -- "how many", "what's the count", "what percentage", "what's the rate" → quantitative answer → `single_number` metric -- "which pages", "top N", "by browser", "breakdown by" → breakdown → `top_n` metric -- "over time", "by day", "is it getting worse", "trend" → trend → `trend` metric -- "mobile vs desktop", "compare", "A vs B" → comparison → invoke the `comparisons` skill -- "show me sessions", "let me watch", "examples of" → session exploration → `fullstory:get_sessions` with `metric_id` -- "sessions from power users", "show me what enterprise users do" → cohort browsing → `fullstory:build_segment` then `fullstory:get_sessions` with `segment_id` +## The five primitives -If the intent is ambiguous, ask the user before proceeding. Getting the intent wrong wastes a build+compute cycle. +Pick the primitive first; the tools follow from it. -## Step 1: Resolve or Build +- **Segment** — a cohort of users (the "who"). A filter, not a measurement. It narrows whose data everything else runs against. +- **Metric** — a measurement (the "what" and "how much"). Every count, rate, breakdown, and trend is a metric. +- **Funnel** — a strictly ordered sequence (the "where do they drop off"). Step counts, step-to-step conversion, and median time between steps. +- **Journey** — what happens around a single anchor event (the "what else do they do"). Unordered fan-out before or after one pivot, not a fixed sequence. +- **Session** — evidence (the "why"). Qualitative. Use sessions to explain a number, never to produce one. -### Always search before building +Funnel vs. journey is the distinction people get wrong most often. A funnel asks "of the users who did A, how many went on to do B then C?" — you already know the steps. A journey asks "users did A; what did they do next?" — you don't know the steps and want the data to tell you. -Users often don't know what metrics or segments already exist in their Fullstory account. Always search first, even when the question sounds ad-hoc. Use `fullstory:get_metric(regex="...")` or `fullstory:get_segment(regex="...")`, starting broad and narrowing if needed (e.g., "how many rage clicks on checkout?" → start with `checkout`, then try `checkout.*rage` if the first search returns too many results). +## Build → Confirm → Compute -Results include a short description of the segment's filters and events, so use that — not just the name — to judge relevance. If no results match, tell the user nothing was found and confirm before building. If results come back but their filters/events don't match the question, tell the user what you found and that none seem to match, then confirm they'd like you to build a new one. +Every `build_*` and `update_*` tool is a language model translating a sentence into a structured definition. That translation is non-deterministic and it is the single largest source of wrong answers in this workflow — not because it fails loudly, but because it succeeds *plausibly*. A metric that filtered on the wrong URL still returns a clean, believable number. Nothing in the result signals the mistake. -If 2 or more plausible candidates come back, immediately call `fullstory:get_view_counts` on their IDs (up to 10) to rank by popularity. If search returns more than 10 candidates, pass the 10 most name-similar IDs. Then: +So treat the returned definition as the contract, and read it before you trust anything computed from it: -- If one candidate has clearly more views (roughly 5x or more than the next), treat it as the canonical object — proceed with it and tell the user you're using "the most-used version." -- If the top 2–3 are comparable in view count, present them sorted by popularity. Use the filters, events, and description fields from the search results to explain what each one measures or captures differently, then ask the user which to use. -- If all candidates have zero or near-zero views, flag them as likely stale and offer to build fresh. +1. **Build.** Call the builder. Capture both the ID and the returned definition/description. +2. **Confirm.** Read what actually got built and compare it against what was asked. See "Confirming the build" below — this beat is what makes the answer trustworthy. +3. **Compute.** Run the compute tool, then present the number with its URL. -### Building new +Two rules that hold across every tool here: -**Metrics:** Before building, make sure the unit of measurement is correct — getting this wrong is the most common source of misleading results. If the question is about "customers", "accounts", or "organizations", clarify whether the user wants to count individual users or group users by a customer/account/organization property. If it's the latter, look for user properties that match and build the metric to count by that property. Similarly, watch for ambiguity between pages and URLs — "which pages" usually means page titles or paths, not full URLs with query parameters. +- **IDs come from tool responses, never from memory or construction.** A `metric_id`, `segment_id`, `funnel_id`, `journey_id`, `device_id`, or `session_id` should always trace back to a response you actually received. Fabricated IDs look real and fail in confusing ways. +- **`fullstory:update_metric`, `fullstory:update_funnel`, `fullstory:update_journey`, and `fullstory:update_segment` return a NEW id and leave the source object untouched.** Carry the new id forward. Computing the old id after an update is a silent no-op that looks like the refinement did nothing. -Call `fullstory:build_metric` with a descriptive query and the correct `output_type` derived from intent classification: +## Step 0: Classify intent, and confirm scope if it's missing -- Quantitative answer → `single_number` -- Breakdown → `top_n` -- Trend → `trend` +| What they're asking | Route to | +|---|---| +| "how many", "what's the count/rate/percentage" | `single_number` metric | +| "which pages", "top N", "by browser", "breakdown by" | `top_n` metric | +| "over time", "by day", "is it getting worse" | `trend` metric | +| "mobile vs desktop", "A vs B", "compare" | the `comparisons` skill | +| "where do users drop off", "conversion through X → Y → Z", "how long does it take to complete" | funnel → `references/funnels.md` | +| "what do users do after X", "what led to Y", "where do they go next" | journey → `references/journeys.md` | +| "show me sessions", "let me watch some examples" | `fullstory:get_sessions` with `metric_id` or `segment_id` | +| "why is this happening" | compute first, then `references/sessions.md` | -For `top_n`, make sure the grouping dimension is expressed in the query (e.g., "top pages by rage click count"). The metric builder will not invent a dimension on its own. +**Scope is part of the question.** A request like "how's checkout doing?" or "where are users struggling?" has no defined boundary, and every boundary you pick silently produces a different answer. When the scope genuinely isn't recoverable from the conversation, ask once, concretely — which pages or flows matter, which users count, what time window — and offer a reasonable default so the user can just say "yes". Don't interrogate: if the request names its own scope, or the default is obvious, build and move on. -**Segments:** Call `fullstory:build_segment`. Always reference by `segment_id` in subsequent steps. If the same cohort is needed for multiple questions in the conversation, reuse the existing `segment_id` — do not rebuild. +## Step 1: Search before building -### Refining existing +Users often don't know what already exists in their Fullstory account. Search first even when the question sounds ad-hoc — an object the customer's team built and uses encodes how *they* define conversion or struggle, which is usually better than a fresh guess. -If the user wants to modify a metric or segment already established in this conversation — adding or removing a filter, changing aggregation, adjusting the time range, or changing output shape — use `fullstory:update_metric` or `fullstory:update_segment`. Pass the existing `metric_id` or `segment_definition` and a natural language `refinement`. +- Metrics and segments: `fullstory:get_metric(regex=...)`, `fullstory:get_segment(regex=...)` +- Funnels and journeys: `fullstory:get_funnel(regex=...)`, `fullstory:get_journey(regex=...)` -- `fullstory:update_metric`: accepts `metric_id` and supports two mutually exclusive modes: LLM refinement (filter changes, aggregation changes, output type overrides via `output_type`) and segment attachment (attach a `segment_id` to the metric). Does not support ratio metrics — rebuild those with `fullstory:build_metric`. -- `fullstory:update_segment`: supports filter additions/removals and time range changes. +Start broad, then narrow (for "rage clicks on checkout", try `checkout` before `checkout.*rage`). Results carry a rendered description of the filters, steps, or pivot — judge relevance from that, not from the name, which is often auto-generated and misleading. -## Step 2: Compute +If nothing matches, say so and confirm before building. If things come back but none fit the question, say what you found and why it doesn't fit, then confirm. -Call `fullstory:compute_metric` with: -- `metric_id` — the ID returned by `fullstory:build_metric`, `fullstory:get_metric`, or `fullstory:update_metric` -- `time_range` — default is `last_30_days`; ask the user if they want a different window +**Ranking duplicates:** when 2+ plausible metric or segment candidates come back, call `fullstory:get_view_counts` on their IDs (up to 10, most name-similar first) to rank by popularity. If one has roughly 5x the views of the next, treat it as canonical and say you're using the most-used version. If the top few are comparable, present them with what each one measures and ask. If all are near zero, flag them as likely stale and offer to build fresh. `fullstory:get_view_counts` only accepts `object_type` of `segment` or `metric` — for funnels and journeys, rank by `last_updated_at` and `created_by` from the search result instead. -If the question is scoped to a cohort, segments must be pre-attached before computing. Call `fullstory:update_metric(metric_id, segment_id)` first, then call `fullstory:compute_metric(metric_id)`. Do not pass `segment_id` directly to `fullstory:compute_metric`. +## Step 2: Build -Present results in plain language with context: +Metrics are the common case and are covered here; funnels and journeys have their own reference files. + +Call `fullstory:build_metric` with a descriptive `query` and the `output_type` from Step 0. + +- **Pass the user's phrasing through.** Rates ("bounce rate", "conversion rate", "error rate") must stay as rate phrasing — simplifying "error rate" to "error count" drops the denominator and produces a different, wrong number. Same for comparison phrasing ("vs last week", "week over week"): pass it verbatim and you get one metric covering both windows, rather than two metrics you have to reconcile by hand. +- **Get the unit of measurement right** before building — it's the most common source of misleading results. If the question is about "customers", "accounts", or "organizations", clarify whether that means individual users or users grouped by an account property, and build accordingly. +- **Exclusions need a segment.** `fullstory:build_metric` cannot express "excluding users who…" or "users who did NOT do X" — the filter tree has no negation. Call `fullstory:build_segment` with the negation phrasing verbatim, then pass the returned `segment_id` to `fullstory:build_metric(segment_id=...)`. Putting the exclusion in the query text gets it silently dropped or misread as a positive filter. +- **Simple user-property filters don't need a segment.** "unique users on app.example.com where email does not contain @example.com" goes straight into the query. Reach for a segment when you need segment semantics: a behavioral cohort ("users who did X"), a saved/named cohort, or several cohorts to compare. +- **Scoping to a cohort at build time:** `fullstory:build_metric` accepts `segment_id` directly. For a metric that already exists, attach with `fullstory:update_metric(metric_id, segment_id)` first and compute the returned id. `fullstory:compute_metric` does **not** take a `segment_id`. + +Segments: call `fullstory:build_segment` and reference by `segment_id` afterward. Reuse a `segment_id` across questions in the same conversation rather than rebuilding it. + +More on metric behavior — dimensions, revenue, time ranges, and the six `fullstory:update_metric` modes — is in `references/metrics.md`. + +## Step 3: Confirming the build + +Before computing, check that what was built is what was asked. The failure mode to catch is a definition that is *reasonable but not what the user meant* — it will produce a number that looks fine and is wrong. + +Read the returned definition (or the `metric_description` / `funnel_description` / `journey_description`) and check the handful of things the translator has to guess at: + +- **Page vs. URL.** "which pages" defaults to raw URL paths, not named pages. A filter on a named page and a filter on a URL substring are different populations. +- **Event set.** Did it filter on the event type you meant — clicks vs. rage clicks vs. page views vs. a defined event with a similar name? +- **Value casing and exact strings.** Custom property values, element names, and event names are matched as given. +- **Aggregation.** Event count vs. unique sessions vs. unique users. These are three different numbers for the same filter. +- **Time range.** Defaults to `last_30_days` for metrics, segments, and funnels; `last_7_days` for journeys. +- **Output shape and grouping.** `top_n` without a grouping dimension isn't a breakdown. +- **Scope.** If you attached a segment, confirm it's on the object you're about to compute — not on the pre-update id. + +When something is off, refine with the `update_*` tool rather than rebuilding from scratch: a refinement is a targeted edit, a rebuild re-rolls every decision the translator already got right. Then re-read the result. + +Don't narrate this check. It's a read, not a report — mention it only when it caught something. + +## Step 4: Compute and present + +`fullstory:compute_metric(metric_id)`. `time_range` / `start_date` + `end_date` override the saved window for that call only, without modifying the metric. + +Present in plain language with context: - Numbers: "12,340 dead clicks over the last 30 days" -- Tables: highlight the top entries; include percentages if a total is available -- Trends: call out direction, magnitude, and any inflection points +- Tables: highlight the top rows; include percentages when a total is available +- Trends: call out direction, magnitude, and inflection points + +Always surface the object URL (`metric_url`, `funnel_url`, `journey_url`, `segment_url`) so the user can verify in the Fullstory UI. Surface it as soon as a build or update returns it — don't wait for the compute. -Always surface `metric_url` so the user can verify in the Fullstory UI. +Metrics and funnels you build are unsaved drafts (their URLs contain `/create/`), and the MCP has no tool to save them. Call them unsaved when you link them, never "saved", so the user knows to save them in Fullstory if they want to keep them. Segments you build are saved under the name you give them. ## References Load these when the situation calls for it: -- `references/validation.md` — when results are zero, anomalous, or the user expresses skepticism -- `references/sessions.md` — when investigating sessions to understand why a metric looks the way it does +- `references/metrics.md` — metric behavior in depth: `fullstory:update_metric` modes, dimension gotchas, revenue, time ranges +- `references/funnels.md` — ordered conversion flows, drop-off, and time-to-complete +- `references/journeys.md` — what users do before or after one anchor event +- `references/validation.md` — when a result is zero, anomalous, implausible, or the user is skeptical +- `references/sessions.md` — investigating sessions to explain a number ## Guidelines -- Default `time_range` is `last_30_days`. Ask before using a different window unless the user specified one. -- When building a segment for use in a later step, always reference by `segment_id`. -- Reuse `segment_id` and `metric_id` within a conversation. Do not rebuild objects the user has already established. -- If the user asks for a different shape of an existing metric (e.g., they have a count but now want a trend), call `fullstory:update_metric` with the existing `metric_id` and the desired `output_type`. Only fall back to `fullstory:build_metric` for fundamentally different queries or ratio metrics. -- When presenting table results, include both the dimension value and the count. If a total is available, show percentages. -- Always surface `metric_url` in your response so the user can verify in the Fullstory UI. `fullstory:build_metric` and `fullstory:update_metric` both return `metric_url` — surface it as soon as it's available, don't wait until after computing. +- Default `time_range` is `last_30_days` (`last_7_days` for journeys). Ask before using a different window unless the user specified one. +- An invalid `time_range` is a hard error, not a silent fallback. Use the enum values, or pass `start_date` + `end_date` together as ISO 8601 (dates or full timestamps) for anything else — "this week", "yesterday", and "since the release" need concrete dates. +- Reuse `segment_id`, `metric_id`, `funnel_id`, and `journey_id` within a conversation. Don't rebuild what the user has already established. +- To reshape an existing metric (a count they now want as a trend), use `fullstory:update_metric` with the existing `metric_id` and the new `output_type`. Fall back to `fullstory:build_metric` only for a fundamentally different question or a ratio metric. +- If `fullstory:build_multi_metric` is available in this session, prefer it over `fullstory:build_metric` — it handles several measures and formulas in one object, and can build anything `fullstory:build_metric` can. +- Every number you report should come from a compute or read tool. Don't derive a figure by arithmetic on results that measure different populations, and don't estimate one.
Full technical diff · 3 changed fields
changed /description
"Fullstory analytics workflow. Use when answering a question that requires measuring user behavior — counts, rates, trends, breakdowns, or cohort comparisons. Builds segments and metrics, computes results, then investigates sessions to explain what the numbers mean."
"Fullstory analytics workflow — the default way to answer any question about user behavior. Use whenever someone asks how many, what percentage, which pages, whether something is trending, where users drop off, what users did before or after an action, or how two cohorts compare — and also when they describe a business question that needs numbers behind it without ever saying \"metric\", \"funnel\", or \"segment\". Covers building and computing metrics, segments, funnels, and journeys, verifying that what got built is what was actually asked for, and pulling sessions to explain why the numbers look the way they do. Not for reviewing one specific session, or for setting up capture and instrumentation."
changed /included_files
[
{
"relative_path": "references/session-context.md",
"size_in_bytes": 963
},
{
"relative_path": "references/sessions.md",
"size_in_bytes": 2457
},
{
"relative_path": "references/validation.md",
"size_in_bytes": 2828
}
][
{
"relative_path": "references/funnels.md",
"size_in_bytes": 5135
},
{
"relative_path": "references/journeys.md",
"size_in_bytes": 5560
},
{
"relative_path": "references/metrics.md",
"size_in_bytes": 5852
},
{
"relative_path": "references/session-context.md",
"size_in_bytes": 963
},
{
"relative_path": "references/sessions.md",
"size_in_bytes": 3651
},
{
"relative_path": "references/validation.md",
"size_in_bytes": 4751
}
]changed /skill_md_contents
"---\nname: general-analysis\ndescription: Fullstory analytics workflow. Use when answering a question that requires measuring user behavior — counts, rates, trends, breakdowns, or cohort comparisons. Builds segments and metrics, computes results, then investigates sessions to explain what the numbers mean.\n---\n\n# Fullstory Analytics\n\n## Mental Model\n\nInternalize these three concepts before choosing tools:\n\n- **Segment** = a cohort of users (the \"who\"). A segment is a filter, not a measurement. It narrows which users' data a metric runs against.\n- **Metric** = the measurement (the \"what\" and \"how much\"). Every quantitative answer is a metric. Even \"how many users visited /checkout\" is a metric (count of page views), optionally filtered by a segment.\n- **Session** = evidence (the \"why\"). Sessions are qualitative. Use them to understand *why* a number looks the way it does — not to answer the quantitative question itself.\n\n## Step 0: Classify Intent\n\nBefore calling any tool, determine what the user is asking for:\n\n- \"how many\", \"what's the count\", \"what percentage\", \"what's the rate\" → quantitative answer → `single_number` metric\n- \"which pages\", \"top N\", \"by browser\", \"breakdown by\" → breakdown → `top_n` metric\n- \"over time\", \"by day\", \"is it getting worse\", \"trend\" → trend → `trend` metric\n- \"mobile vs desktop\", \"compare\", \"A vs B\" → comparison → invoke the `comparisons` skill\n- \"show me sessions\", \"let me watch\", \"examples of\" → session exploration → `fullstory:get_sessions` with `metric_id`\n- \"sessions from power users\", \"show me what enterprise users do\" → cohort browsing → `fullstory:build_segment` then `fullstory:get_sessions` with `segment_id`\n\nIf the intent is ambiguous, ask the user before proceeding. Getting the intent wrong wastes a build+compute cycle.\n\n## Step 1: Resolve or Build\n\n### Always search before building\n\nUsers often don't know what metrics or segments already exist in their Fullstory account. Always search first, even when the question sounds ad-hoc. Use `fullstory:get_metric(regex=\"...\")` or `fullstory:get_segment(regex=\"...\")`, starting broad and narrowing if needed (e.g., \"how many rage clicks on checkout?\" → start with `checkout`, then try `checkout.*rage` if the first search returns too many results).\n\nResults include a short description of the segment's filters and events, so use that — not just the name — to judge relevance. If no results match, tell the user nothing was found and confirm before building. If results come back but their filters/events don't match the question, tell the user what you found and that none seem to match, then confirm they'd like you to build a new one.\n\nIf 2 or more plausible candidates come back, immediately call `fullstory:get_view_counts` on their IDs (up to 10) to rank by popularity. If search returns more than 10 candidates, pass the 10 most name-similar IDs. Then:\n\n- If one candidate has clearly more views (roughly 5x or more than the next), treat it as the canonical object — proceed with it and tell the user you're using \"the most-used version.\"\n- If the top 2–3 are comparable in view count, present them sorted by popularity. Use the filters, events, and description fields from the search results to explain what each one measures or captures differently, then ask the user which to use.\n- If all candidates have zero or near-zero views, flag them as likely stale and offer to build fresh.\n\n### Building new\n\n**Metrics:** Before building, make sure the unit of measurement is correct — getting this wrong is the most common source of misleading results. If the question is about \"customers\", \"accounts\", or \"organizations\", clarify whether the user wants to count individual users or group users by a customer/account/organization property. If it's the latter, look for user properties that match and build the metric to count by that property. Similarly, watch for ambiguity between pages and URLs — \"which pages\" usually means page titles or paths, not full URLs with query parameters.\n\nCall `fullstory:build_metric` with a descriptive query and the correct `output_type` derived from intent classification:\n\n- Quantitative answer → `single_number`\n- Breakdown → `top_n`\n- Trend → `trend`\n\nFor `top_n`, make sure the grouping dimension is expressed in the query (e.g., \"top pages by rage click count\"). The metric builder will not invent a dimension on its own.\n\n**Segments:** Call `fullstory:build_segment`. Always reference by `segment_id` in subsequent steps. If the same cohort is needed for multiple questions in the conversation, reuse the existing `segment_id` — do not rebuild.\n\n### Refining existing\n\nIf the user wants to modify a metric or segment already established in this conversation — adding or removing a filter, changing aggregation, adjusting the time range, or changing output shape — use `fullstory:update_metric` or `fullstory:update_segment`. Pass the existing `metric_id` or `segment_definition` and a natural language `refinement`.\n\n- `fullstory:update_metric`: accepts `metric_id` and supports two mutually exclusive modes: LLM refinement (filter changes, aggregation changes, output type overrides via `output_type`) and segment attachment (attach a `segment_id` to the metric). Does not support ratio metrics — rebuild those with `fullstory:build_metric`.\n- `fullstory:update_segment`: supports filter additions/removals and time range changes.\n\n## Step 2: Compute\n\nCall `fullstory:compute_metric` with:\n- `metric_id` — the ID returned by `fullstory:build_metric`, `fullstory:get_metric`, or `fullstory:update_metric`\n- `time_range` — default is `last_30_days`; ask the user if they want a different window\n\nIf the question is scoped to a cohort, segments must be pre-attached before computing. Call `fullstory:update_metric(metric_id, segment_id)` first, then call `fullstory:compute_metric(metric_id)`. Do not pass `segment_id` directly to `fullstory:compute_metric`.\n\nPresent results in plain language with context:\n- Numbers: \"12,340 dead clicks over the last 30 days\"\n- Tables: highlight the top entries; include percentages if a total is available\n- Trends: call out direction, magnitude, and any inflection points\n\nAlways surface `metric_url` so the user can verify in the Fullstory UI.\n\n## References\n\nLoad these when the situation calls for it:\n\n- `references/validation.md` — when results are zero, anomalous, or the user expresses skepticism\n- `references/sessions.md` — when investigating sessions to understand why a metric looks the way it does\n\n## Guidelines\n\n- Default `time_range` is `last_30_days`. Ask before using a different window unless the user specified one.\n- When building a segment for use in a later step, always reference by `segment_id`.\n- Reuse `segment_id` and `metric_id` within a conversation. Do not rebuild objects the user has already established.\n- If the user asks for a different shape of an existing metric (e.g., they have a count but now want a trend), call `fullstory:update_metric` with the existing `metric_id` and the desired `output_type`. Only fall back to `fullstory:build_metric` for fundamentally different queries or ratio metrics.\n- When presenting table results, include both the dimension value and the count. If a total is available, show percentages.\n- Always surface `metric_url` in your response so the user can verify in the Fullstory UI. `fullstory:build_metric` and `fullstory:update_metric` both return `metric_url` — surface it as soon as it's available, don't wait until after computing.\n"
"---\nname: general-analysis\ndescription: Fullstory analytics workflow — the default way to answer any question about user behavior. Use whenever someone asks how many, what percentage, which pages, whether something is trending, where users drop off, what users did before or after an action, or how two cohorts compare — and also when they describe a business question that needs numbers behind it without ever saying \"metric\", \"funnel\", or \"segment\". Covers building and computing metrics, segments, funnels, and journeys, verifying that what got built is what was actually asked for, and pulling sessions to explain why the numbers look the way they do. Not for reviewing one specific session, or for setting up capture and instrumentation.\n---\n\n# Fullstory Analytics\n\n## When to use\n\nUse this skill whenever answering the question takes a number out of Fullstory — a count, rate, percentage, breakdown, trend, drop-off, what users did before or after an action, or one cohort against another. That includes business questions that never name a primitive (\"is checkout getting worse?\", \"which accounts are struggling?\"). Pulling sessions is in scope when they're evidence for a number you computed.\n\n## Skip when\n\n- **One specific session.** A session URL, a named user, \"what happened to this person\" — that's the `session-review` skill.\n- **Instrumentation and capture.** Defining events, custom properties, privacy rules, or installing the snippet. This skill reads data that already exists; it can't make Fullstory record something new.\n- **Account and product configuration.** Users, permissions, integrations, data export setup.\n- **No Fullstory data in the loop.** A number the user already has, or one that lives in another system.\n\nHanding off isn't an exit. If a session review turns into \"how often does this happen?\", that part is this skill.\n\n## The five primitives\n\nPick the primitive first; the tools follow from it.\n\n- **Segment** — a cohort of users (the \"who\"). A filter, not a measurement. It narrows whose data everything else runs against.\n- **Metric** — a measurement (the \"what\" and \"how much\"). Every count, rate, breakdown, and trend is a metric.\n- **Funnel** — a strictly ordered sequence (the \"where do they drop off\"). Step counts, step-to-step conversion, and median time between steps.\n- **Journey** — what happens around a single anchor event (the \"what else do they do\"). Unordered fan-out before or after one pivot, not a fixed sequence.\n- **Session** — evidence (the \"why\"). Qualitative. Use sessions to explain a number, never to produce one.\n\nFunnel vs. journey is the distinction people get wrong most often. A funnel asks \"of the users who did A, how many went on to do B then C?\" — you already know the steps. A journey asks \"users did A; what did they do next?\" — you don't know the steps and want the data to tell you.\n\n## Build → Confirm → Compute\n\nEvery `build_*` and `update_*` tool is a language model translating a sentence into a structured definition. That translation is non-deterministic and it is the single largest source of wrong answers in this workflow — not because it fails loudly, but because it succeeds *plausibly*. A metric that filtered on the wrong URL still returns a clean, believable number. Nothing in the result signals the mistake.\n\nSo treat the returned definition as the contract, and read it before you trust anything computed from it:\n\n1. **Build.** Call the builder. Capture both the ID and the returned definition/description.\n2. **Confirm.** Read what actually got built and compare it against what was asked. See \"Confirming the build\" below — this beat is what makes the answer trustworthy.\n3. **Compute.** Run the compute tool, then present the number with its URL.\n\nTwo rules that hold across every tool here:\n\n- **IDs come from tool responses, never from memory or construction.** A `metric_id`, `segment_id`, `funnel_id`, `journey_id`, `device_id`, or `session_id` should always trace back to a response you actually received. Fabricated IDs look real and fail in confusing ways.\n- **`fullstory:update_metric`, `fullstory:update_funnel`, `fullstory:update_journey`, and `fullstory:update_segment` return a NEW id and leave the source object untouched.** Carry the new id forward. Computing the old id after an update is a silent no-op that looks like the refinement did nothing.\n\n## Step 0: Classify intent, and confirm scope if it's missing\n\n| What they're asking | Route to |\n|---|---|\n| \"how many\", \"what's the count/rate/percentage\" | `single_number` metric |\n| \"which pages\", \"top N\", \"by browser\", \"breakdown by\" | `top_n` metric |\n| \"over time\", \"by day\", \"is it getting worse\" | `trend` metric |\n| \"mobile vs desktop\", \"A vs B\", \"compare\" | the `comparisons` skill |\n| \"where do users drop off\", \"conversion through X → Y → Z\", \"how long does it take to complete\" | funnel → `references/funnels.md` |\n| \"what do users do after X\", \"what led to Y\", \"where do they go next\" | journey → `references/journeys.md` |\n| \"show me sessions\", \"let me watch some examples\" | `fullstory:get_sessions` with `metric_id` or `segment_id` |\n| \"why is this happening\" | compute first, then `references/sessions.md` |\n\n**Scope is part of the question.** A request like \"how's checkout doing?\" or \"where are users struggling?\" has no defined boundary, and every boundary you pick silently produces a different answer. When the scope genuinely isn't recoverable from the conversation, ask once, concretely — which pages or flows matter, which users count, what time window — and offer a reasonable default so the user can just say \"yes\". Don't interrogate: if the request names its own scope, or the default is obvious, build and move on.\n\n## Step 1: Search before building\n\nUsers often don't know what already exists in their Fullstory account. Search first even when the question sounds ad-hoc — an object the customer's team built and uses encodes how *they* define conversion or struggle, which is usually better than a fresh guess.\n\n- Metrics and segments: `fullstory:get_metric(regex=...)`, `fullstory:get_segment(regex=...)`\n- Funnels and journeys: `fullstory:get_funnel(regex=...)`, `fullstory:get_journey(regex=...)`\n\nStart broad, then narrow (for \"rage clicks on checkout\", try `checkout` before `checkout.*rage`). Results carry a rendered description of the filters, steps, or pivot — judge relevance from that, not from the name, which is often auto-generated and misleading.\n\nIf nothing matches, say so and confirm before building. If things come back but none fit the question, say what you found and why it doesn't fit, then confirm.\n\n**Ranking duplicates:** when 2+ plausible metric or segment candidates come back, call `fullstory:get_view_counts` on their IDs (up to 10, most name-similar first) to rank by popularity. If one has roughly 5x the views of the next, treat it as canonical and say you're using the most-used version. If the top few are comparable, present them with what each one measures and ask. If all are near zero, flag them as likely stale and offer to build fresh. `fullstory:get_view_counts` only accepts `object_type` of `segment` or `metric` — for funnels and journeys, rank by `last_updated_at` and `created_by` from the search result instead.\n\n## Step 2: Build\n\nMetrics are the common case and are covered here; funnels and journeys have their own reference files.\n\nCall `fullstory:build_metric` with a descriptive `query` and the `output_type` from Step 0.\n\n- **Pass the user's phrasing through.** Rates (\"bounce rate\", \"conversion rate\", \"error rate\") must stay as rate phrasing — simplifying \"error rate\" to \"error count\" drops the denominator and produces a different, wrong number. Same for comparison phrasing (\"vs last week\", \"week over week\"): pass it verbatim and you get one metric covering both windows, rather than two metrics you have to reconcile by hand.\n- **Get the unit of measurement right** before building — it's the most common source of misleading results. If the question is about \"customers\", \"accounts\", or \"organizations\", clarify whether that means individual users or users grouped by an account property, and build accordingly.\n- **Exclusions need a segment.** `fullstory:build_metric` cannot express \"excluding users who…\" or \"users who did NOT do X\" — the filter tree has no negation. Call `fullstory:build_segment` with the negation phrasing verbatim, then pass the returned `segment_id` to `fullstory:build_metric(segment_id=...)`. Putting the exclusion in the query text gets it silently dropped or misread as a positive filter.\n- **Simple user-property filters don't need a segment.** \"unique users on app.example.com where email does not contain @example.com\" goes straight into the query. Reach for a segment when you need segment semantics: a behavioral cohort (\"users who did X\"), a saved/named cohort, or several cohorts to compare.\n- **Scoping to a cohort at build time:** `fullstory:build_metric` accepts `segment_id` directly. For a metric that already exists, attach with `fullstory:update_metric(metric_id, segment_id)` first and compute the returned id. `fullstory:compute_metric` does **not** take a `segment_id`.\n\nSegments: call `fullstory:build_segment` and reference by `segment_id` afterward. Reuse a `segment_id` across questions in the same conversation rather than rebuilding it.\n\nMore on metric behavior — dimensions, revenue, time ranges, and the six `fullstory:update_metric` modes — is in `references/metrics.md`.\n\n## Step 3: Confirming the build\n\nBefore computing, check that what was built is what was asked. The failure mode to catch is a definition that is *reasonable but not what the user meant* — it will produce a number that looks fine and is wrong.\n\nRead the returned definition (or the `metric_description` / `funnel_description` / `journey_description`) and check the handful of things the translator has to guess at:\n\n- **Page vs. URL.** \"which pages\" defaults to raw URL paths, not named pages. A filter on a named page and a filter on a URL substring are different populations.\n- **Event set.** Did it filter on the event type you meant — clicks vs. rage clicks vs. page views vs. a defined event with a similar name?\n- **Value casing and exact strings.** Custom property values, element names, and event names are matched as given.\n- **Aggregation.** Event count vs. unique sessions vs. unique users. These are three different numbers for the same filter.\n- **Time range.** Defaults to `last_30_days` for metrics, segments, and funnels; `last_7_days` for journeys.\n- **Output shape and grouping.** `top_n` without a grouping dimension isn't a breakdown.\n- **Scope.** If you attached a segment, confirm it's on the object you're about to compute — not on the pre-update id.\n\nWhen something is off, refine with the `update_*` tool rather than rebuilding from scratch: a refinement is a targeted edit, a rebuild re-rolls every decision the translator already got right. Then re-read the result.\n\nDon't narrate this check. It's a read, not a report — mention it only when it caught something.\n\n## Step 4: Compute and present\n\n`fullstory:compute_metric(metric_id)`. `time_range` / `start_date` + `end_date` override the saved window for that call only, without modifying the metric.\n\nPresent in plain language with context:\n- Numbers: \"12,340 dead clicks over the last 30 days\"\n- Tables: highlight the top rows; include percentages when a total is available\n- Trends: call out direction, magnitude, and inflection points\n\nAlways surface the object URL (`metric_url`, `funnel_url`, `journey_url`, `segment_url`) so the user can verify in the Fullstory UI. Surface it as soon as a build or update returns it — don't wait for the compute.\n\nMetrics and funnels you build are unsaved drafts (their URLs contain `/create/`), and the MCP has no tool to save them. Call them unsaved when you link them, never \"saved\", so the user knows to save them in Fullstory if they want to keep them. Segments you build are saved under the name you give them.\n\n## References\n\nLoad these when the situation calls for it:\n\n- `references/metrics.md` — metric behavior in depth: `fullstory:update_metric` modes, dimension gotchas, revenue, time ranges\n- `references/funnels.md` — ordered conversion flows, drop-off, and time-to-complete\n- `references/journeys.md` — what users do before or after one anchor event\n- `references/validation.md` — when a result is zero, anomalous, implausible, or the user is skeptical\n- `references/sessions.md` — investigating sessions to explain a number\n\n## Guidelines\n\n- Default `time_range` is `last_30_days` (`last_7_days` for journeys). Ask before using a different window unless the user specified one.\n- An invalid `time_range` is a hard error, not a silent fallback. Use the enum values, or pass `start_date` + `end_date` together as ISO 8601 (dates or full timestamps) for anything else — \"this week\", \"yesterday\", and \"since the release\" need concrete dates.\n- Reuse `segment_id`, `metric_id`, `funnel_id`, and `journey_id` within a conversation. Don't rebuild what the user has already established.\n- To reshape an existing metric (a count they now want as a trend), use `fullstory:update_metric` with the existing `metric_id` and the new `output_type`. Fall back to `fullstory:build_metric` only for a fundamentally different question or a ratio metric.\n- If `fullstory:build_multi_metric` is available in this session, prefer it over `fullstory:build_metric` — it handles several measures and formulas in one object, and can build anything `fullstory:build_metric` can.\n- Every number you report should come from a compute or read tool. Don't derive a figure by arithmetic on results that measure different populations, and don't estimate one.\n"
Full snapshot data
{
"description": "Fullstory analytics workflow — the default way to answer any question about user behavior. Use whenever someone asks how many, what percentage, which pages, whether something is trending, where users drop off, what users did before or after an action, or how two cohorts compare — and also when they describe a business question that needs numbers behind it without ever saying \"metric\", \"funnel\", or \"segment\". Covers building and computing metrics, segments, funnels, and journeys, verifying that what got built is what was actually asked for, and pulling sessions to explain why the numbers look the way they do. Not for reviewing one specific session, or for setting up capture and instrumentation.",
"included_files": [
{
"relative_path": "references/funnels.md",
"size_in_bytes": 5135
},
{
"relative_path": "references/journeys.md",
"size_in_bytes": 5560
},
{
"relative_path": "references/metrics.md",
"size_in_bytes": 5852
},
{
"relative_path": "references/session-context.md",
"size_in_bytes": 963
},
{
"relative_path": "references/sessions.md",
"size_in_bytes": 3651
},
{
"relative_path": "references/validation.md",
"size_in_bytes": 4751
}
],
"name": "general-analysis",
"skill_md_contents": "---\nname: general-analysis\ndescription: Fullstory analytics workflow — the default way to answer any question about user behavior. Use whenever someone asks how many, what percentage, which pages, whether something is trending, where users drop off, what users did before or after an action, or how two cohorts compare — and also when they describe a business question that needs numbers behind it without ever saying \"metric\", \"funnel\", or \"segment\". Covers building and computing metrics, segments, funnels, and journeys, verifying that what got built is what was actually asked for, and pulling sessions to explain why the numbers look the way they do. Not for reviewing one specific session, or for setting up capture and instrumentation.\n---\n\n# Fullstory Analytics\n\n## When to use\n\nUse this skill whenever answering the question takes a number out of Fullstory — a count, rate, percentage, breakdown, trend, drop-off, what users did before or after an action, or one cohort against another. That includes business questions that never name a primitive (\"is checkout getting worse?\", \"which accounts are struggling?\"). Pulling sessions is in scope when they're evidence for a number you computed.\n\n## Skip when\n\n- **One specific session.** A session URL, a named user, \"what happened to this person\" — that's the `session-review` skill.\n- **Instrumentation and capture.** Defining events, custom properties, privacy rules, or installing the snippet. This skill reads data that already exists; it can't make Fullstory record something new.\n- **Account and product configuration.** Users, permissions, integrations, data export setup.\n- **No Fullstory data in the loop.** A number the user already has, or one that lives in another system.\n\nHanding off isn't an exit. If a session review turns into \"how often does this happen?\", that part is this skill.\n\n## The five primitives\n\nPick the primitive first; the tools follow from it.\n\n- **Segment** — a cohort of users (the \"who\"). A filter, not a measurement. It narrows whose data everything else runs against.\n- **Metric** — a measurement (the \"what\" and \"how much\"). Every count, rate, breakdown, and trend is a metric.\n- **Funnel** — a strictly ordered sequence (the \"where do they drop off\"). Step counts, step-to-step conversion, and median time between steps.\n- **Journey** — what happens around a single anchor event (the \"what else do they do\"). Unordered fan-out before or after one pivot, not a fixed sequence.\n- **Session** — evidence (the \"why\"). Qualitative. Use sessions to explain a number, never to produce one.\n\nFunnel vs. journey is the distinction people get wrong most often. A funnel asks \"of the users who did A, how many went on to do B then C?\" — you already know the steps. A journey asks \"users did A; what did they do next?\" — you don't know the steps and want the data to tell you.\n\n## Build → Confirm → Compute\n\nEvery `build_*` and `update_*` tool is a language model translating a sentence into a structured definition. That translation is non-deterministic and it is the single largest source of wrong answers in this workflow — not because it fails loudly, but because it succeeds *plausibly*. A metric that filtered on the wrong URL still returns a clean, believable number. Nothing in the result signals the mistake.\n\nSo treat the returned definition as the contract, and read it before you trust anything computed from it:\n\n1. **Build.** Call the builder. Capture both the ID and the returned definition/description.\n2. **Confirm.** Read what actually got built and compare it against what was asked. See \"Confirming the build\" below — this beat is what makes the answer trustworthy.\n3. **Compute.** Run the compute tool, then present the number with its URL.\n\nTwo rules that hold across every tool here:\n\n- **IDs come from tool responses, never from memory or construction.** A `metric_id`, `segment_id`, `funnel_id`, `journey_id`, `device_id`, or `session_id` should always trace back to a response you actually received. Fabricated IDs look real and fail in confusing ways.\n- **`fullstory:update_metric`, `fullstory:update_funnel`, `fullstory:update_journey`, and `fullstory:update_segment` return a NEW id and leave the source object untouched.** Carry the new id forward. Computing the old id after an update is a silent no-op that looks like the refinement did nothing.\n\n## Step 0: Classify intent, and confirm scope if it's missing\n\n| What they're asking | Route to |\n|---|---|\n| \"how many\", \"what's the count/rate/percentage\" | `single_number` metric |\n| \"which pages\", \"top N\", \"by browser\", \"breakdown by\" | `top_n` metric |\n| \"over time\", \"by day\", \"is it getting worse\" | `trend` metric |\n| \"mobile vs desktop\", \"A vs B\", \"compare\" | the `comparisons` skill |\n| \"where do users drop off\", \"conversion through X → Y → Z\", \"how long does it take to complete\" | funnel → `references/funnels.md` |\n| \"what do users do after X\", \"what led to Y\", \"where do they go next\" | journey → `references/journeys.md` |\n| \"show me sessions\", \"let me watch some examples\" | `fullstory:get_sessions` with `metric_id` or `segment_id` |\n| \"why is this happening\" | compute first, then `references/sessions.md` |\n\n**Scope is part of the question.** A request like \"how's checkout doing?\" or \"where are users struggling?\" has no defined boundary, and every boundary you pick silently produces a different answer. When the scope genuinely isn't recoverable from the conversation, ask once, concretely — which pages or flows matter, which users count, what time window — and offer a reasonable default so the user can just say \"yes\". Don't interrogate: if the request names its own scope, or the default is obvious, build and move on.\n\n## Step 1: Search before building\n\nUsers often don't know what already exists in their Fullstory account. Search first even when the question sounds ad-hoc — an object the customer's team built and uses encodes how *they* define conversion or struggle, which is usually better than a fresh guess.\n\n- Metrics and segments: `fullstory:get_metric(regex=...)`, `fullstory:get_segment(regex=...)`\n- Funnels and journeys: `fullstory:get_funnel(regex=...)`, `fullstory:get_journey(regex=...)`\n\nStart broad, then narrow (for \"rage clicks on checkout\", try `checkout` before `checkout.*rage`). Results carry a rendered description of the filters, steps, or pivot — judge relevance from that, not from the name, which is often auto-generated and misleading.\n\nIf nothing matches, say so and confirm before building. If things come back but none fit the question, say what you found and why it doesn't fit, then confirm.\n\n**Ranking duplicates:** when 2+ plausible metric or segment candidates come back, call `fullstory:get_view_counts` on their IDs (up to 10, most name-similar first) to rank by popularity. If one has roughly 5x the views of the next, treat it as canonical and say you're using the most-used version. If the top few are comparable, present them with what each one measures and ask. If all are near zero, flag them as likely stale and offer to build fresh. `fullstory:get_view_counts` only accepts `object_type` of `segment` or `metric` — for funnels and journeys, rank by `last_updated_at` and `created_by` from the search result instead.\n\n## Step 2: Build\n\nMetrics are the common case and are covered here; funnels and journeys have their own reference files.\n\nCall `fullstory:build_metric` with a descriptive `query` and the `output_type` from Step 0.\n\n- **Pass the user's phrasing through.** Rates (\"bounce rate\", \"conversion rate\", \"error rate\") must stay as rate phrasing — simplifying \"error rate\" to \"error count\" drops the denominator and produces a different, wrong number. Same for comparison phrasing (\"vs last week\", \"week over week\"): pass it verbatim and you get one metric covering both windows, rather than two metrics you have to reconcile by hand.\n- **Get the unit of measurement right** before building — it's the most common source of misleading results. If the question is about \"customers\", \"accounts\", or \"organizations\", clarify whether that means individual users or users grouped by an account property, and build accordingly.\n- **Exclusions need a segment.** `fullstory:build_metric` cannot express \"excluding users who…\" or \"users who did NOT do X\" — the filter tree has no negation. Call `fullstory:build_segment` with the negation phrasing verbatim, then pass the returned `segment_id` to `fullstory:build_metric(segment_id=...)`. Putting the exclusion in the query text gets it silently dropped or misread as a positive filter.\n- **Simple user-property filters don't need a segment.** \"unique users on app.example.com where email does not contain @example.com\" goes straight into the query. Reach for a segment when you need segment semantics: a behavioral cohort (\"users who did X\"), a saved/named cohort, or several cohorts to compare.\n- **Scoping to a cohort at build time:** `fullstory:build_metric` accepts `segment_id` directly. For a metric that already exists, attach with `fullstory:update_metric(metric_id, segment_id)` first and compute the returned id. `fullstory:compute_metric` does **not** take a `segment_id`.\n\nSegments: call `fullstory:build_segment` and reference by `segment_id` afterward. Reuse a `segment_id` across questions in the same conversation rather than rebuilding it.\n\nMore on metric behavior — dimensions, revenue, time ranges, and the six `fullstory:update_metric` modes — is in `references/metrics.md`.\n\n## Step 3: Confirming the build\n\nBefore computing, check that what was built is what was asked. The failure mode to catch is a definition that is *reasonable but not what the user meant* — it will produce a number that looks fine and is wrong.\n\nRead the returned definition (or the `metric_description` / `funnel_description` / `journey_description`) and check the handful of things the translator has to guess at:\n\n- **Page vs. URL.** \"which pages\" defaults to raw URL paths, not named pages. A filter on a named page and a filter on a URL substring are different populations.\n- **Event set.** Did it filter on the event type you meant — clicks vs. rage clicks vs. page views vs. a defined event with a similar name?\n- **Value casing and exact strings.** Custom property values, element names, and event names are matched as given.\n- **Aggregation.** Event count vs. unique sessions vs. unique users. These are three different numbers for the same filter.\n- **Time range.** Defaults to `last_30_days` for metrics, segments, and funnels; `last_7_days` for journeys.\n- **Output shape and grouping.** `top_n` without a grouping dimension isn't a breakdown.\n- **Scope.** If you attached a segment, confirm it's on the object you're about to compute — not on the pre-update id.\n\nWhen something is off, refine with the `update_*` tool rather than rebuilding from scratch: a refinement is a targeted edit, a rebuild re-rolls every decision the translator already got right. Then re-read the result.\n\nDon't narrate this check. It's a read, not a report — mention it only when it caught something.\n\n## Step 4: Compute and present\n\n`fullstory:compute_metric(metric_id)`. `time_range` / `start_date` + `end_date` override the saved window for that call only, without modifying the metric.\n\nPresent in plain language with context:\n- Numbers: \"12,340 dead clicks over the last 30 days\"\n- Tables: highlight the top rows; include percentages when a total is available\n- Trends: call out direction, magnitude, and inflection points\n\nAlways surface the object URL (`metric_url`, `funnel_url`, `journey_url`, `segment_url`) so the user can verify in the Fullstory UI. Surface it as soon as a build or update returns it — don't wait for the compute.\n\nMetrics and funnels you build are unsaved drafts (their URLs contain `/create/`), and the MCP has no tool to save them. Call them unsaved when you link them, never \"saved\", so the user knows to save them in Fullstory if they want to keep them. Segments you build are saved under the name you give them.\n\n## References\n\nLoad these when the situation calls for it:\n\n- `references/metrics.md` — metric behavior in depth: `fullstory:update_metric` modes, dimension gotchas, revenue, time ranges\n- `references/funnels.md` — ordered conversion flows, drop-off, and time-to-complete\n- `references/journeys.md` — what users do before or after one anchor event\n- `references/validation.md` — when a result is zero, anomalous, implausible, or the user is skeptical\n- `references/sessions.md` — investigating sessions to explain a number\n\n## Guidelines\n\n- Default `time_range` is `last_30_days` (`last_7_days` for journeys). Ask before using a different window unless the user specified one.\n- An invalid `time_range` is a hard error, not a silent fallback. Use the enum values, or pass `start_date` + `end_date` together as ISO 8601 (dates or full timestamps) for anything else — \"this week\", \"yesterday\", and \"since the release\" need concrete dates.\n- Reuse `segment_id`, `metric_id`, `funnel_id`, and `journey_id` within a conversation. Don't rebuild what the user has already established.\n- To reshape an existing metric (a count they now want as a trend), use `fullstory:update_metric` with the existing `metric_id` and the new `output_type`. Fall back to `fullstory:build_metric` only for a fundamentally different question or a ratio metric.\n- If `fullstory:build_multi_metric` is available in this session, prefer it over `fullstory:build_metric` — it handles several measures and formulas in one object, and can build anything `fullstory:build_metric` can.\n- Every number you report should come from a compute or read tool. Don't derive a figure by arithmetic on results that measure different populations, and don't estimate one.\n"
}SHA-256 of public snapshot: a83277cb6e9bbc7f2739a7aa4b6f7de76af7403619738429fa2152c3abec91e3