Subtext
Fullstory v1.0.0
Publisher description
From the marketplace listing
**Subtext is session replay built for agents instead of humans.** Connect Subtext, and your Codex agents can open real production sessions and investigate them directly—no scrubbing a timeline, no video to watch. Hand your agent a Subtext link from wherever it already connects—a Sentry issue, a Linear ticket, a support thread, a PR—and it uses Agentic Session Review to jump to the right moment, inspect screenshots and accessibility trees, diff DOM state, and read console and network activity to find the root cause. Then it files the fix or hands you the finding. You review the answer, not the replay. What your agent gets: * **Session tools it calls directly**: open a session, jump to a moment, inspect and compare state—purpose-built so agents traverse dense session data efficiently, with fewer tokens than pointing a general agent at raw replay. * **Best-in-class capture from Fullstory**: Fullcapture behavior, pixel-perfect screenshots on demand, DOM diffs, and windowed console and network context. * **Privacy built for production**: precision tools for agents to mask or exclude sensitive fields, plus agent-friendly DLP scanning tools over MCP. * **Cost-effective**: Capture every session without sampling and never miss a critical user experience or bug report. Agents review the ones that matter most. Works with Codex or any MCP-compatible agent. Code-first install, self-serve signup, generous free tier, usage-based pricing. Bring your own agent harness—Subtext is the session context it was missing.
Language: English · Automatically detected from descriptions.
Files & skills
File archives
Skill instructions
subtext-privacy7.98 KB
---
name: subtext-privacy
description: Privacy rule management — detect PII in sessions and manage element-block, URL, and network privacy rules. Use when you need to propose, create, list, delete, or promote privacy rules for a Fullstory org.
---
# Privacy
> **PREREQUISITE:** Read `subtext-shared` for MCP conventions.
Privacy tools manage three kinds of rules that control what Fullstory session recordings capture:
- **Element rules** — CSS-selector-based rules that mask or exclude specific page elements.
- **URL rules** — scrub sensitive parts of captured URLs (host/path/query).
- **Network rules** — control whether request/response bodies are captured, redacted, or partially allowlisted.
## MCP Tools
| Tool | Description |
|------|-------------|
| `privacy-propose` | Scan a session for PII and return suggested selectors (dry-run — persists nothing). Element rules only. |
| `privacy-create` | Create element-block rules from selectors in preview scope. |
| `privacy-list` | List existing element-block rules, with optional scope/type filters. |
| `privacy-delete` | Delete preview-scoped rules by ID. |
| `privacy-promote` | Promote preview-scoped rules to apply to all sessions. |
| `privacy-url-list` | List URL privacy rules. |
| `privacy-url-create` | Create a URL privacy rule that scrubs host/path/query, or update one in place by passing `guid`. Live immediately. |
| `privacy-network-list` | List network (request/response body) privacy rules. |
| `privacy-network-create` | Create a network privacy rule (elide or allowlist body fields), or update the existing rule for a `url_regex` by passing `overwrite=true`. Live immediately. |
Listing and creation are supported for all three rule kinds. There's no separate update tool for URL/network rules — `privacy-url-create`/`privacy-network-create` double as update when you pass `guid`/`overwrite`. Deletion is only supported for element rules today.
## Rule lifecycle (element rules)
Rules always start in **preview scope** (`PREVIEW_SESSIONS_ONLY`) and must be explicitly promoted to apply broadly:
```
propose (dry-run)
│
▼
create → PREVIEW_SESSIONS_ONLY
│
▼
list / verify
│
▼
promote → ALL_SESSIONS
│ ─ or ─
▼
delete (preview only)
```
## URL and network rules: no preview step
Unlike element rules, **URL and network rules have no scope and no preview/promote lifecycle.** `privacy-url-create` and `privacy-network-create` take effect for **all sessions immediately** — there is nothing to promote, and (for now) nothing to delete via MCP. Double-check a rule before creating it; use `privacy-url-list` / `privacy-network-list` afterward to confirm what's live.
### URL rules
`privacy-url-create` takes a `name` plus either simplified fields or a raw `advanced` override:
```
privacy-url-create name="scrub-ssn-param" match_host="example\.com" exclude_query_params=["ssn"]
```
This redacts the `ssn` query parameter's value (not its key) on URLs whose host matches `example\.com`. Leave `match_host`/`match_path` both empty for an unconditional rule (applies to every URL). Use `exclude_path` / `exclude_query` for a raw regex against the path or full query string instead of a named param. Use `advanced` (structured `if`/`exclude` pattern sets over hash/host/path/query_param/query) only when the simplified fields can't express the rule.
**Updating a URL rule:** pass the rule's `guid` (from `privacy-url-list`) to replace it in place instead of creating a new one:
```
privacy-url-create guid="<guid>" name="scrub-ssn-param" match_host="example\.com" exclude_query_params=["ssn", "token"]
```
Update is a **full replace**, not a merge — pass the complete desired state (name, condition, exclusions), not just the field you're changing. Built-in rules (part of the default rule set created at privacy settings setup) cannot be updated this way.
### Network rules
`privacy-network-create` takes a `url_regex` plus request/response body handling:
```
privacy-network-create url_regex="/api/checkout/.*" request_body="whitelist" request_allowlist_fields=["order_id", "status"]
```
Only `elide` (default, redact the whole body) and `whitelist` (keep only named fields) are supported for automated creation/update — `record` (capture the full body) increases data capture and must be set up manually. Rules are keyed by `url_regex`; without `overwrite`, creating a rule for a regex that already has one is a no-op.
**Updating a network rule:** pass `overwrite=true` to replace the existing rule for that `url_regex` instead of skipping it:
```
privacy-network-create url_regex="/api/checkout/.*" request_body="whitelist" request_allowlist_fields=["order_id", "status", "total"] overwrite=true
```
## Rules and constraints
- `privacy-propose` is always a **dry-run**. It returns suggested selectors but persists nothing. Use it to preview before committing.
- `privacy-create` only supports `mask` and `exclude` block types. Unmask rules cannot be created via this tool.
- `privacy-delete` only accepts preview-scoped rules. Promoted rules cannot be deleted here.
- `privacy-promote` also rejects unmask rules — only mask and exclude rules can be promoted.
- System-managed rules (not user-created) are hidden by default. Pass `include_system=true` to `privacy-list` to see them. These rules cannot be deleted or promoted.
- `privacy-url-create` and `privacy-network-create` rules go live for all sessions immediately — there's no preview scope to validate in first.
- `privacy-network-create` rejects `record` for request/response body mode; only `elide` and `whitelist` are allowed.
- Neither URL nor network rules currently support deletion via MCP — use the Fullstory settings UI if a rule needs to be removed.
## Typical flow
### 1. Propose — find PII in a session
```
privacy-propose session_url=<url>
```
Returns a list of CSS selectors the auto-configure pipeline identified as likely PII, with suggested rule names. Inspect the list — reject any false positives before proceeding.
### 2. Create — persist the rules you want
```
privacy-create selectors=[{"selector": ".email-field"}, {"selector": "#ssn"}]
```
Rules land in `PREVIEW_SESSIONS_ONLY` scope. They only apply to preview sessions until promoted.
### 3. Verify — list and review
```
privacy-list
privacy-list scope_filter=preview
```
Review what was created. Note the `rule_id` values — you'll need them for delete or promote.
### 4. Promote or delete
Promote to activate for all sessions:
```
privacy-promote rule_ids=["<id1>", "<id2>"]
```
Delete if the rule was wrong:
```
privacy-delete rule_ids=["<id1>"]
```
## Gotchas
- Running `propose` without reviewing the output — it's a starting point, not ground truth. Inspect selectors for false positives before creating rules.
- Creating rules and immediately promoting — always verify with a preview session first. The preview scope exists for exactly this purpose.
- Trying to delete a promoted rule — `delete` only works on preview-scoped rules.
- Using `unmask` as `block_type` in `create` — this is rejected. Unmask rules are system-managed.
- Assuming `privacy-url-create` / `privacy-network-create` land in a preview scope like element rules — they don't. They apply to all sessions the moment they're created, so double-check the pattern/regex before calling.
- Using `request_body="record"` (or `response_body="record"`) in `privacy-network-create` — this is rejected; only `elide` and `whitelist` are supported for automated creation.
- Passing `guid` to `privacy-url-create` with only the field you want to change — update is a full replace, so omitted fields (name, condition, exclusions) are lost, not preserved. Fetch the current rule from `privacy-url-list` first and resend its full state.
- Forgetting `overwrite=true` on `privacy-network-create` when you meant to change an existing rule — without it, a matching `url_regex` is silently skipped, not updated.
## See Also
- `subtext-shared` — MCP conventions
- `subtext-session` — session replay tools (for obtaining a session URL to pass to `propose`)
subtext-review4.51 KB
---
name: subtext-review
description: Review a completed Subtext session and produce a structured summary. Use when you have a session URL and want to understand what happened — verify a flow, walk through a dev / staging / preview session, or summarize a captured session. Optionally emits reproduction steps on request.
---
# Review
> **PREREQUISITE:** Read `subtext-shared` and `subtext-session` for tool conventions.
**Type:** Workflow — goal-oriented with decision logic.
Review a completed session and produce a structured summary of what happened. Optionally emit reproduction steps when the user asks. Review is read-only analysis.
## When to use
**Use when:**
- The user provides a session URL and wants to know what happened.
- The user asks for a walkthrough, summary, or diagnosis of a session.
- Session source is any of: local dev, staging, preview, production.
**Skip when:**
- The user wants the repro *executed*, not just described — that needs a live browser (the separate Subtext Verify plugin).
## The loop
### Step 1: Open the session
Call `review-open` with whichever identifier you have — see `subtext-session` for the six accepted forms. Capture the `client_id` from the response, and read the **map** it returns — signal counts by kind/tag and page flow. Don't call `review-zoom` yet.
### Step 2: Form hypotheses from the map
The map is the orientation layer. Before zooming, ask: does anything in `kinds`/`tags` stand out (an `error:` count, an unusually dense phase)? Form one or two hypotheses about what happened — that's what you zoom to confirm.
### Step 3: Zoom to confirm — as recipes, coarse to fine
Use `review-zoom` with a `resolution` map. Treat resolutions as recipes, not parameters to memorize:
- Errors anywhere → `resolution={ error: "standard" }`
- What happened overall → `resolution={ navigation: "standard", interaction: "standard" }`
- Devtool-level detail on a suspect window → `resolution={ network: "machine", console: "machine" }`, narrowed with `t0_ms`/`t1_ms`
Start coarse (`standard`, the default) and only reach for `machine`/`detail` on the specific kind or tag your hypothesis needs — each step down costs more tokens for more fidelity. Judge coverage against the map from `review-open` (its `kinds`/`tags` counts); `review-zoom` returns the signal slice.
When you need to see the screen itself — confirm a layout, grab a component tree — use `review-snapshot` at the timestamp in question. It's a separate data set from signals; don't expect it to carry network/console detail.
Don't sweep the entire session frame-by-frame — that's expensive and usually unnecessary. Lead with the map and the errors it surfaces.
### Step 4: Assess
Form a judgment on:
- **What the session was trying to accomplish** — inferable from behavior.
- **Did it succeed** — any errors? Did the final state match the apparent intent?
- **Notable moments** — anything surprising, confusing, or worth flagging to the user.
### Step 5: Produce the structured summary
Output in this shape — stable sections make the result easy to consume, especially for a downstream agent:
```markdown
## Session Summary
**Session:** <URL>
**Type:** <dev | staging | preview | production>
**Duration:** <if available>
### What happened
<One-paragraph narrative of what the user/agent tried to do.>
### Errors
<Timestamped list with context, or: "None observed.">
### Key moments
- `<timestamp>` — <inflection point>
### Assessment
<One paragraph. Did the session achieve its apparent goal? Anything the next reader should know?>
```
### Step 6: Reproduction steps — only if asked
If the user explicitly asks to reproduce, append a structured step list. **Do not execute** — this plugin is read-only. Executing a repro requires driving a live browser, which lives in the separate Subtext Verify plugin.
```markdown
### Reproduction steps
1. Navigate to <URL>
2. <action> — e.g., "Click the 'Sign in' button"
3. <observation to confirm> — e.g., "Verify modal appears within 2s"
```
Write the steps as deterministic actions: concrete selectors, URLs, and assertions. Avoid subjective instructions ("look around").
## Decision logic
### Errors present
Always lead with errors. A downstream reader — human or agent — will look for this section first.
### Repro steps requested
- "reproduce", "repro", "walk me through step by step", "how do I hit this" → produce the step list in Step 6.
- "review", "summarize", "what happened" → stop at Step 5. Don't volunteer repro steps; they add length without being asked for.
subtext-session5.62 KB
---
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-list-sessions` | Find reviewable sessions — numbered URLs + timestamps. |
| `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.
## 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`, …), or tags (`error`, `exception` — the only tags today) — they resolve the same way.
### 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" }
```
## 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.
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-shared1.67 KB
--- name: subtext-shared description: Foundation skill for the Subtext plugin. MCP tool conventions and security rules. Read this when any skill lists it in PREREQUISITE. --- # Shared Foundation for all Subtext skills. Read this when a skill lists it in PREREQUISITE. ## MCP Servers All tools are served from the **subtext** MCP server. A **subtext-eu1** variant exists for EU1 data center sessions (`app.eu1.fullstory.com`). The agent framework resolves tool prefixes automatically based on the configured MCP servers — you do not need to hardcode prefixes. ## Tool Name Prefixes | Prefix | Tools | |--------|-------| | `review-` | Session replay: `review-list-sessions`, `review-open`, `review-summary`, `review-zoom`, `review-snapshot`, `review-close` | | `privacy-` | Privacy rules: `privacy-propose`, `privacy-create`, `privacy-list`, `privacy-delete`, `privacy-promote`, `privacy-url-list`, `privacy-url-create`, `privacy-network-list`, `privacy-network-create` | | `telemetry-` | Workflow telemetry: `telemetry-event` | ## Discovering MCP Tool Parameters Each MCP tool is self-describing. If you're unsure about parameters, the tool's schema is available at call time. Don't memorize parameter lists — consult the atomic skill (`subtext-session` or `subtext-privacy`) for which tools exist, then let the schema guide parameter usage. ## Security Rules - Never expose API tokens, session tokens, or credentials in output. - Confirm with the user before any write operation that modifies org configuration (e.g. `privacy-promote`, `privacy-create`, `privacy-url-create`, `privacy-network-create`). - Session URLs may contain sensitive user data — don't log or repeat them unnecessarily.
subtext-telemetry4.34 KB
---
name: subtext-telemetry
description: Workflow telemetry logging — record AI-reported workflow milestones (currently the onboarding flow) for funnel analysis. Use when executing an instrumented Subtext workflow and you need to log step-by-step progress events.
---
# Telemetry
> **PREREQUISITE:** Read `subtext-shared` for MCP conventions.
The telemetry tool records workflow milestones to Fullstory's analytics backend (BigQuery) for funnel analysis and success-rate dashboards. It writes analytics events only — it never modifies application data or org configuration.
## MCP Tools
| Tool | Description |
|------|-------------|
| `telemetry-event` | Log one workflow milestone: a `workflow` + `step`, an optional `outcome`, and optional step-specific `metadata`. |
## Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `workflow` | yes | Workflow name. Currently only `onboard` (the Subtext capture-snippet install flow) is supported. |
| `step` | yes | Milestone within the workflow. For `onboard`, in order: `start`, `precheck`, `explore`, `plan`, `install`, `identify`, `link_analytics`, `mask_pii`, `complete`. |
| `outcome` | no | `success`, `partial`, `fail`, or `skipped`. Omit for in-progress milestones. |
| `metadata` | no | A JSON **object** (not an array or scalar) of step-specific fields — see below. |
## Metadata fields by step
Every step's metadata may include `duration_ms` (int) and `tokens` (int). Additional fields vary by step:
| Step | Extra fields |
|------|--------------|
| `start` | `harness` (string), `model` (string) |
| `precheck` | `already_installed` (bool) |
| `explore` | `framework` (string), `csp_present` (bool) |
| `plan` | `approved` (bool) |
| `install` | `framework` (string), `csp_modified` (bool) |
| `identify` | `identity_added` (bool) |
| `link_analytics` | `analytics_providers` (string[]) — names of every analytics / session-replay / error-monitoring / feature-flag SDK found installed, e.g. `["posthog", "segment", "sentry"]` |
| `mask_pii` | `masked_count` (int), `privacy_check` (bool) |
| `complete` | `total_duration_ms` (int), `total_tokens` (int) |
Unknown metadata fields are tolerated (ignored, not errors), but stick to the documented fields — only they land in typed columns for analysis.
## Typical flow
Log an event at each milestone as you execute the workflow, not retroactively at the end:
```
telemetry-event workflow="onboard" step="start" metadata={"harness": "claude-code", "model": "claude-fable-5"}
...
telemetry-event workflow="onboard" step="install" outcome="success" metadata={"framework": "nextjs", "csp_modified": false, "duration_ms": 42000}
...
telemetry-event workflow="onboard" step="complete" outcome="success" metadata={"total_duration_ms": 310000, "total_tokens": 85000}
```
The response is `{"logged": true}` on success or `{"logged": false, "reason": "..."}` on a soft failure.
## Rules and constraints
- **Fire-and-forget.** A `{"logged": false, ...}` response is a soft failure — note it and move on. Never retry in a loop, and never block or abort the user's workflow because telemetry failed.
- Org and user identity are attached server-side from the authenticated MCP session — don't put emails, org IDs, or other identifying data in `metadata`.
- Don't put secrets, tokens, file contents, or free-form user data in `metadata` — only the documented derived fields.
- `outcome` is a classification of the step, not a log level: use `skipped` when a step didn't apply, `partial` when it half-worked, and omit it entirely for a step that's still in progress.
- Only log events for workflows you are actually executing. The tool exists to measure real funnels — don't emit synthetic or exploratory events against a production org.
## Gotchas
- Passing `metadata` as anything other than a JSON object — arrays, strings, and scalars are rejected with `{"logged": false}`.
- Inventing workflow or step names — only `onboard` and its nine documented steps are recognized. New workflows require backend support first.
- Logging every step at the end of the workflow with made-up durations — log each milestone as it happens so `duration_ms` and failure points are real.
- Treating a soft failure as an error worth surfacing to the user — telemetry is invisible plumbing; a failed event is at most a one-line note.
## See Also
- `subtext-shared` — MCP conventions
subtext-using-subtext1.19 KB
--- name: subtext-using-subtext description: Overview of the Subtext plugin — when to reach for session review vs privacy tools. Read to orient before reviewing a Fullstory session or managing privacy rules. --- # Using Subtext This plugin gives you read-only access to Fullstory session recordings, plus privacy-rule management. ## When to reach for what | Signal | Skill | |--------|-------| | You have a session URL / want to know what happened | `subtext-review` | | You need the session-replay tool catalog (`review-*`) | `subtext-session` | | Detect PII or manage element-block, URL, or network privacy rules | `subtext-privacy` | | Log workflow milestones (e.g. onboarding progress) for analytics | `subtext-telemetry` | ## Notes - Everything here is read-only analysis **except** `privacy-create` / `privacy-promote` / `privacy-delete` / `privacy-url-create` / `privacy-network-create`, which modify org privacy rules — confirm with the user first. (`telemetry-event` writes analytics events only, never org configuration — no confirmation needed.) - This plugin does **not** drive a live browser or capture before/after proof of code changes. That lives in the separate **Subtext Verify** plugin.
Package details
Publisher declarations from the archived package. These are separate from our research and the live service's terms.
- Package author
- Fullstory
Package observed Sep 30, 2026.
Technical details
- First seen
- Sep 30, 2026 · 22:02 UTC
- Last seen
- Oct 1, 2026 · 18:00 UTC
- Collection status
- Collected
plugin_asdk_app_6a5e636eabcc8191b055490191e2a3ee
Download plugin data (JSON)