Installs into .claude/skills of the current project.
Are you the author of Subtext Session?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/fullstorydev-subtext-session)
---
name: subtext-session
description: Session replay tools for analyzing Fullstory session recordings. Sparse API catalog — tools are self-describing.
---
# Session Replay
> **PREREQUISITE:** Read `subtext-shared` for MCP conventions.
API catalog for the session replay tools (all prefixed `review-`). One gesture — **zoom** — over two data sets: the **signal stream** (temporal) and the **snapshot** (spatial). Opening a session hands back a **map**: an always-on orientation header, never a zoom level.
## MCP Tools
| Tool | Description |
|------|-------------|
| `review-search` | Find sessions across the org by *what happened in them* — a predicate tree over navigate/network/custom signals within a time window. See `subtext-search` for the query language. |
| `review-list-sessions` | Find reviewable sessions — numbered URLs + timestamps. With no arguments, the org's most recent captures. With `email_address`/`user_uid`, one user's sessions, paged with `before`. |
| `review-open` | Open a session for analysis. Returns a handle (`client_id`) plus the **map** and a digest rollup. |
| `review-summary` | Static "what happened" — the default zoom (all kinds @ `standard`), frozen. No map, no handle. Stateless, cheapest call. Use for a quick read before deciding whether to `open`. |
| `review-zoom` | The live lens. Pass a `resolution` map and/or a `t0_ms`/`t1_ms` time window — returns the matching signal slice. |
| `review-snapshot` | The screen at a moment — screenshot + component tree + boxes, rooted at an optional `component_id`. |
| `review-close` | Close the session and free resources; records a short usage summary. |
## Discovering Parameters
Parameter schemas are visible in the tool definition at call time.
## Session Input
`review-open` accepts six mutually-exclusive identifiers. Pick the one that matches what you have on hand — they're all first-class:
- `session_url` — a full Fullstory session URL. The most common form — a customer-shared link, a Slack paste, or a session from the app UI.
- `trace_id` — the 12-char base62 id from a prior `review-open` response.
- `trace_url` — a full trace URL copied from the browser or returned by a live tool.
- `device_id` + `session_id` — both required together. Use when you have the raw ids but no URL.
- `email_address` / `user_uid` — looks up the user's most recent session.
All six paths return the same handle. Capture the `client_id` from the response so follow-on `review-zoom`/`review-snapshot`/`review-close` calls don't need to re-resolve the session.
`review-open`'s `email_address`/`user_uid` jumps straight to that user's *most recent* session. To see more than one, or to search back through their history, use `review-list-sessions` instead.
## Finding a user's sessions
`review-list-sessions` with no arguments lists the org's most recently captured sessions — no filtering, no paging.
Pass `email_address` or `user_uid` to scope it to one user instead. That response reports `newest`/`oldest` — the creation-time range it covered — and, when more history exists, a note to pass `oldest` back as `before` to page further back. `before` is only valid alongside `email_address`/`user_uid`; the org-wide list isn't time-scoped.
Ticket-triage recipe: given a report against a known user, `review-list-sessions` by their `email_address`/`user_uid` to get candidates, `review-summary` each to find the one matching the report, then `review-open` it to investigate.
When the report names a *behavior* rather than a user — "the payment call is failing" — reach for `review-search` instead; it filters on signals, which `review-list-sessions` does not do. See `subtext-search`.
## The map
`review-open`'s response includes a map — a cheap counting fold over the signal layer, never a body dump:
```
## Map · 114 signals · 0.0s–353s · 2 pages
flow: /ui ▸ /settings/overview ▸ /subtext/sessions ▸ /subtext/session/asr
kinds: navigation 18 · interaction 36 · network 58 (2 err) · console 2 (2 err)
tags: error:4
```
The map is **whole** — rendered once, over the entire session. Zooming into `{navigation: "standard"}` later doesn't touch it: `error:4` stays in the map's counts regardless of what you go on to zoom into. Read the map first; it tells you what exists before you pay for a zoom.
## The resolution contract
`review-zoom` takes:
```
resolution?: { [scope | kind | tag]: "digest" | "standard" | "machine" | "detail" }
t0_ms?: number // narrow the zoom to a time window
t1_ms?: number
```
Grain ladder, coarse → fine:
| grain | what you see |
|-------|--------------|
| `digest` | one rollup line per (section × kind) — `network ×19 (1 err)` |
| `standard` *(default)* | the readable transcript — bursty/repeated signals merged into one line |
| `machine` | every signal, nothing merged |
| `detail` | every signal plus its payload — headers, bodies, stack traces |
- **Omit `resolution`** → everything at `standard`.
- **Provide it** → an explicit allow-list. Unlisted kinds are excluded from the slice (never from the map).
- **Overlap → finest-wins.** A signal matching more than one key takes the finest grain among them — order-independent, and it can only ever show *more*, never hide something.
Keys are scopes (`navigation`, `interaction`, `network`, `console`, …), kinds (`click`, `network`, `exception`, `classified`, …), or tags — they resolve the same way. `error`/`warn`/`exception` are intrinsic (derived from a signal's own fields); a project's `.sightmap/` can author more: a component's `tags:` rides onto any signal that targets it (e.g. `defect` on a checkout-error element), and a `signals:` rule can generate a brand-new `classified` signal when a match fires against another signal's fields — surfacing a classification buried in a payload (a 200 response whose body says a payment declined) as its own selectable line, without touching the signal it fired on.
### Zoom recipes
```
// what went wrong, anywhere
review-zoom resolution={ error: "standard" }
// what happened in this session
review-zoom resolution={ navigation: "standard", interaction: "standard" }
// devtool-level detail
review-zoom resolution={ network: "machine", console: "machine" }
// network readable, but every error deep — finest-wins, no override needed
review-zoom resolution={ network: "standard", error: "detail" }
// a project-authored classification (a .sightmap/ tag or signals: rule), deep
review-zoom resolution={ defect: "detail" }
```
## Snapshot
`review-snapshot` takes `client_id` + `timestamp`, plus:
- `component_id` — optional; roots **both** the image clip and the tree subtree, so "focus here" means one thing.
- `lens` — `visible` (default), `interactive`, or `full`. Governs which elements populate the tree/boxes, not the pixels.
- `include` — any of `image`, `tree`, `boxes`.
- `expand_pct` — grows the `component_id` clip outward by this percent (0–100) for surrounding context.
- `upload` — store the screenshot and return a shareable signed URL.
- `full_page` — capture the whole scrollable page instead of the viewport. Requires `include` to contain `image`; can't be combined with `component_id`. These images are big — pair with `upload`. Ignored for mobile session pages.
No network/console excerpts are stapled onto a snapshot — signals only come from `review-zoom`. Want the requests or logs around a moment? Zoom that window.
## Tips
- Read the map before you zoom. It's free and tells you whether there's anything worth looking at.
- Start every zoom at `standard` (or omit `resolution` entirely) unless you already have a hypothesis about which kind matters.
- `error` as a resolution key is a floor, not a special case — it only ever raises detail wherever it applies.
- Use `review-snapshot` for "what did the screen look like," not for signals — it's a different data set.
- Always close sessions when done to free server resources.
## See Also
- `subtext-shared` — MCP conventions
- `subtext-search` — finding sessions by what happened in them (`review-search`)