Skill instructions
comparisons4.95 KB
View saved version →
---
name: comparisons
description: How to structure A vs B comparisons in Fullstory — when to use dimensionality (event/session properties) vs separate segments (user-level properties), and why the distinction matters for correctness.
user-invocable: false
---
# Comparisons
When the user asks to compare A vs B, the right mechanism depends on what the comparison axis is. Use the decision table below to classify it — the user doesn't need to know this distinction exists.
## Event/session properties → dimensionality
If the comparison axis describes the context of an individual event at the moment it fired — not the user who triggered it — use dimensionality. Common examples: device type, browser, OS, page URL, element. But the rule is the principle, not the list: if the property travels with the event, not the user, it belongs here. Express it as a single `top_n` metric with the comparison axis as the grouping dimension.
Example: "rage clicks on mobile vs desktop" → `fullstory:build_metric(query="rage clicks by device type", output_type="top_n")`. The result table shows mobile and desktop as separate rows.
To refine an established comparison metric (e.g., "add a Chrome-only filter"), pass its `metric_id` to `fullstory:update_metric` with a refinement instruction rather than rebuilding.
**Do not use segments for event properties.** Building a "mobile users" segment and a "desktop users" segment would assign all of a user's rage clicks to whichever device they ever used — even clicks that happened on the other device.
## User-level properties → separate segments
Properties that describe a user rather than an event should use segments. The key mechanism: Fullstory resolves user properties to the user's **last known value** for that key. This canonical value is what segment queries match against — so you're asking "what bucket is this user in now?", not "what was their value at the moment of each event?".
Built-in user properties that work this way: `signed_up` (signed-up status), `first_seen` / `last_seen` (dates), `total_sessions` (engagement depth), and any custom user properties (`user_var_string`, `user_var_int`, etc.) set via `setUserProperties` — e.g. plan type or account ID. Build one metric and one segment per cohort, then compute each cohort in sequence: attach the segment via `fullstory:update_metric(metric_id, segment_id)`, call `fullstory:compute_metric(metric_id)`, store the result, then repeat with the next segment. Present the results side by side. The cohort segments are saved; the metrics are unsaved drafts, so say so when you link them. Do not pass `segment_id` directly to `fullstory:compute_metric`.
Example: "do enterprise users experience more errors than free users?" → build two segments (enterprise, free), build one metric (errors), compute twice.
To refine a cohort after it's been built (e.g., "also exclude trial users from the free segment"), use `fullstory:update_segment` with the existing `segment_definition` rather than rebuilding with `fullstory:build_segment`.
Using `top_n` dimensionality for user properties is valid if you specifically want point-in-time values — each event is attributed to the user property value at the moment it fired. If a user changed plan tier mid-period, their events will be split across both values. For most comparisons you want the canonical (current) value, which is why segments are the default choice.
## Decision table
| Comparison axis | Type | Mechanism |
|----------------|------|-----------|
| Device type, browser, OS | Event property | Dimensionality |
| Page URL, element | Event property | Dimensionality |
| `signed_up`, `first_seen`, `last_seen` | User property | Segments |
| `total_sessions` | User property | Segments |
| `user_var_*` (custom user properties) | User property | Segments |
If you can't tell whether a property is event-level or user-level, default to dimensionality — it's more precise and uses fewer API calls.
## Why the wrong choice produ
Preview of the first 4,000 characters. Read full instructions →
friction-analysis13.5 KB
View saved version →
---
name: friction-analysis
description: Finds where users struggle on a page or flow and whether a suspected problem is real. Ranks Fullstory's frustration and error signals, separates real problems from buttons people are meant to click many times, measures how many users each problem affects, and uses session replays to show what happened. Use when someone asks where users are struggling, what is broken on a page or flow, for top pain points or a friction audit, why users give up at a step, whether a rage click is real, whether pages feel slow, whether people keep retrying, re-typing or going back and forth, whether a mobile app keeps crashing, or whether a problem from support tickets is widespread or affects only a few people.
---
# Friction Analysis
## Goal
Find where users struggle and report problems the team can act on. Every finding needs:
- **A confirmation.** Frustration signals find leads; a Step 3 check confirms one before it becomes a finding.
- **An explanation** of what happened, from replay.
- **A size:** how many users were affected, out of how many.
## Related Skills
- `general-analysis`: metrics, segments, and count or trend questions with nothing suspected broken.
- `comparisons`: structuring an A vs B comparison; decides which signals are worth comparing.
- `session-review`: full diagnosis of a single session.
- `idea-generation`: what to build next, not what is broken.
- For a Fullstory Opportunities list, call `fullstory:get_opportunities` and stop.
## Step 1: Match the Depth to the Question
| If the question is like | Do this |
|---|---|
| "Is this rage click real?" | Run the Step 3 checks on that one element, then give a short, direct answer. |
| "Where do users struggle in checkout?" | Sweep every signal on that page or flow and rank them. |
| "Which pages have the most frustration?" | Sweep, then run Step 3 on the top two or three pages before reporting their order: confirm each page's leading element is a real control, not a container, and read one replay per page. |
If someone reports a page stuck loading, always run Step 3c, even when no frustration signal fires on that page. For anything else, stop once a Step 3 check and a replay support the answer.
## Step 2: Find the Signals
**Run the sweep.** Call `fullstory:discover_groups` scoped to the area.
**Set the time range once, and reuse it on every later call.** `fullstory:discover_groups` defaults to the last 24 hours, not whatever you used last. Use 30 days. If a 30-day call times out, switch to 7 days and call those results provisional.
**Use `fullstory:discover_groups`, not `fullstory:build_metric`, for click friction on a page.** A URL-path filter can silently return a fraction of the real count, because it misses pages whose URLs don't contain the path you guessed, and it raises no error. Funnels, custom-event counts, and signals with no built-in equivalent still need `fullstory:build_metric` or `fullstory:build_funnel`; a noise-only sweep is the cue to build one.
### Add one or two signals the sweep misses
Do this before stats or replays. The sweep returns rage, dead and error clicks by element, page refresh, abandoned form and app crash by page, network error by path, and uncaught exception and console error by text. That set misses struggle that looks different in a form, a search tool or a mobile app. Pick the rows below that fit the area, build each with `fullstory:build_metric`, `fullstory:build_segment` or `fullstory:build_funnel`, with exact numbers: "at least 2 times within 60 seconds," not "a few times quickly."
| If the area is | Check |
|---|---|
| A form, sign-up or checkout | the same field changed at least 3 times within 60 seconds; submit clicked twice within two minutes with a network error; slow load |
| Search or a list | the search box changed several times (group by search text for what people look for); back and forth between results and a detail page |
| A slow or content-heavy page | page-speed signal
Preview of the first 4,000 characters. Read full instructions →
general-analysis13.5 KB
View saved version →
---
name: general-analysis
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
## When to use
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.
## Skip when
- **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.
Handing off isn't an exit. If a session review turns into "how often does this happen?", that part is this skill.
## The five primitives
Pick the primitive first; the tools follow from it.
- **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.
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.
## Build → Confirm → Compute
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.
So treat the returned definition as the contract, and read it before you trust anything computed from it:
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.
Two rules that hold across every tool here:
- **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 actuallyPreview of the first 4,000 characters. Read full instructions →
Referenced files: 6 — file references are metadata, not package contents.
idea-generation24.1 KB
View saved version →
---
name: idea-generation
description: Finds product improvement ideas a team has not already considered. Searches the metrics, segments and funnels the team already built, builds the ones that are missing, measures how many users each idea affects against a baseline, and pulls session replays as evidence. Returns 3 to 5 ranked proposals, each with what is new about it, a user count with its baseline, and replay links. Use when someone asks what to build next, how to improve a product area or flow, what the team is missing, for data-backed product ideas or proposals, or what changed after a release. If the user only wants the list of Fullstory Opportunities, call the Opportunities tools directly instead. For counts, rates and trends use general-analysis, for A vs B mechanics use comparisons, and for one session use session-review.
---
# Idea Generation
## Goal
Produce 3 to 5 product proposals that the team has not already considered. Every proposal must pass three tests:
- **New.** It is not already on a dashboard, in the backlog, shipped, in progress, or returned by `fullstory:get_opportunities`. The obvious findings, such as the biggest funnel drop-off or the most rage-clicked element, are usually already known. Proposing them again does not help the team.
- **Fixable by the audience.** The team receiving the proposal can fix it with a product change: UI, copy, flow, defaults, or a feature. A problem that only a backend team, an infrastructure team, or a third party can fix does not qualify. Step 1e explains how to decide who the audience is.
- **Measurable.** You can state how many users it affects, as a count and as a share of a named total, next to the same number for a baseline group.
A finding that fails any test is an observation, not a proposal. Put observations in Emerging Signals (Step 5) or drop them.
## Related Skills
- `general-analysis`: how to build and compute metrics and segments.
- `comparisons`: how to structure an A vs B comparison. This skill decides what is worth comparing.
- `session-review`: deep diagnosis of a single session.
- If the user only wants to see their Fullstory Opportunities, call `fullstory:get_opportunities` directly and stop. This skill treats that list as things the team already knows, not as the answer.
## Workflow
1. Frame the question and fix the definitions.
2. Find leads. Start with existing metrics, segments and funnels, because reading them is cheap. Most of the run happens here.
3. Measure each lead against a baseline.
4. Pull session replays, only for the leads you plan to present.
5. Filter, rank and write the proposals.
## Step 1: Frame the Question
### 1a. State the question in one sentence
Many requests contain more than one question. "Improve retention" can mean "do these users convert at a lower rate?" or "what makes users come back?" Each needs different analysis. Pick the reading that best matches the user's words, state it in one sentence, and name the reading you did not pick.
Also name the **area** you are studying: the pages, screens or feature the question is about, such as "the checkout flow" or "the search results page". The rest of this skill calls it the area.
### 1b. Retention questions need a return-visit lead
Fixing problems in a flow helps subsequent users complete the flow the first time. It does not give them a reason to come back to the product. If the question is about repeat use or retention, at least one lead must be about what brings users back:
1. List what the product does to prompt users to come back, instead of relying on them to remember. This depends on the product. A store might have saved searches, price-drop or back-in-stock alerts, wishlists and reminder emails. A software tool might have scheduled reports, alerts and shared links. A content site might have follows and subscriptions.
2. Measure what share of users used at least one of them.
3. Compare users who returned with users who did not. Check whether the users who re
Preview of the first 4,000 characters. Read full instructions →
session-review4.21 KB
View saved version →
---
name: session-review
description: Use when diagnosing user-reported issues, investigating bugs, analyzing user behavior, or validating UI correctness using Fullstory session recordings.
---
# Session Review
Review Fullstory sessions to understand what happened — whether diagnosing a customer-reported bug or validating UI changes during development.
## When to Use
- User reports a bug and provides a session URL
- Investigating an error or unexpected behavior
- Understanding user flow through the application
- Debugging issues that are hard to reproduce
- Validating UI changes locally after testing
## MCP Tools
| Goal | Tool |
|------|------|
| Open a session | `fullstory:review-open` |
| See what happened in a time window | `fullstory:review-zoom` |
| See the screen at a moment | `fullstory:review-snapshot` |
| See what changed on screen | `fullstory:review-snapshot` at two timestamps, compare the trees |
| Close | `fullstory:review-close` |
## Workflow
### 1. Open the Session
```
fullstory:review-open(session_url="https://app.fullstory.com/ui/<org-id>/session/<device-id>:<session-id>")
```
Returns: a map of the session, an event slice, and a `client_id`.
Pass the whole URL as `session_url`. Here `session_id` means only the session part and must come with `device_id`. Other ways to open: `trace_id`, `trace_url`, `email_address`, `user_uid`.
### 2. Identify Key Moments
Scan the returned events for:
- **Page navigations** — entry points into different views
- **Click events** — user interactions with buttons, links, forms
- **Error events** — console errors, network failures, renderer errors
- **Rage clicks / mouse thrash** — signs of UX friction
- **Custom events** — application-specific telemetry
To read more of one stretch, narrow by time:
```
fullstory:review-zoom(client_id="<id>", t0_ms=<start_ms>, t1_ms=<end_ms>)
```
### 3. Visual Inspection
At each key moment, use `fullstory:review-snapshot` to see what the user saw. It finds the page from the timestamp, so you never pass a page id:
```
fullstory:review-snapshot(client_id="<id>", timestamp=<ms>)
```
It returns a screenshot and the component tree. Use the tree when you need element structure (roles, labels, hierarchy).
Check for:
- Layout correctness (elements positioned properly)
- Content rendering (text, images, icons present)
- Responsive behavior (no overflow, proper sizing)
- Empty/loading states handled
### 4. Compare States
For before/after analysis, take a snapshot at each timestamp and compare the two trees:
```
fullstory:review-snapshot(client_id="<id>", timestamp=<before_ms>)
fullstory:review-snapshot(client_id="<id>", timestamp=<after_ms>)
```
Whole trees are large. To keep the comparison cheap, focus on one element with `component_id` from an earlier snapshot, or ask for the interactive elements only with `lens="interactive"`.
### 5. Report Findings
Summarize what was observed:
- What the user saw at each key moment
- Any errors, visual regressions, or unexpected behavior
- Root cause analysis if diagnosing a bug
- Confirmation of correctness if validating changes
### 6. Cleanup
Always close the session:
```
fullstory:review-close(client_id="<id>")
```
## Example
When a user reports "the checkout button didn't work" and provides a session URL:
1. Call `fullstory:review-open` with `session_url`
2. Find the checkout-related events (note the timestamps)
3. Use `fullstory:review-snapshot` to see the UI state just before the button click
4. Take a second snapshot just after the click and compare the trees to see what changed (or didn't)
5. Report findings: what the user saw, any errors, why the action may have failed
6. Call `fullstory:review-close` to clean up
## Common Mistakes
| Mistake | Fix |
|---------|-----|
| Forgetting to close session | Always call `fullstory:review-close` — even on errors |
| Random timestamp access | Use sequential increasing timestamps for faster access |
| Passing the session URL as `session_id` to `fullstory:
Preview of the first 4,000 characters. Read full instructions →