Skip to main content
LaunchDarkly tells you that a flag variation moved a metric: a guarded rollout is regressing, an experiment’s treatment lost, an error rate climbed right after a flag change. It can’t show you what a user who got that variation actually saw. Subtext can. Attach the Subtext session URL to your LaunchDarkly context and every flag signal becomes a jumping-off point — your agent reads the subtext_url, opens that person’s real session, and walks the decisive moments with screenshots, the component tree, network, and console. LaunchDarkly detects; Subtext diagnoses.
This guide assumes the Subtext capture snippet is installed and capturing sessions, and the LaunchDarkly JS client SDK (@launchdarkly/js-client-sdk in v4.x; published as launchdarkly-js-client-sdk in earlier versions) is initialized.

Attach the session URL

Store the current Subtext session URL on your LaunchDarkly context so it travels with the flag evaluation and every experiment result. There are two places to attach it, depending on how precise the link needs to be.

On the LaunchDarkly context

Attach the URL as a custom attribute on the context with ldClient.identify. Call it wherever your app already identifies the user — on auth resolution, not at module top level. The attribute is stored on the context and visible in the LaunchDarkly Contexts dashboard.
On the legacy user schema (pre-v3 contexts), nest the value under custom: ldClient.identify({ key: user.id, custom: { subtext_url: subtextUrl } }). Don’t mark subtext_url as a private attribute (privateAttributes in your SDK config): private attributes are still used for targeting but are redacted from events, so LaunchDarkly won’t store the value and it won’t be readable from the Contexts page, the REST API, or the MCP tools.

On a specific event

When the exact moment matters, attach the URL to a custom metric event. url.now carries a timestamp, so the link opens the replay at that instant — ideal for high-signal events like errors and conversion failures.
Don’t read FS('getSession') at module top level — it returns null until the session has started. Pass the full context to ldClient.identify: it replaces the context rather than merging, so dropping existing attributes clears them. Don’t use the session URL as the context key — keep the key stable and put the URL in its own attribute. The URL also changes on a new session and when FS('setIdentity') is called with a different uid, so re-call ldClient.identify on re-identify — the context attribute is frozen until the next identify.

From signal to session

However you first hear that a rollout is going sideways in LaunchDarkly, the path is the same: get to the subtext_url, then hand it to your agent for a Detect-vs-Diagnose read. The metric says the new variation is worse; the session shows whether the flagged feature rendered correctly, errored, or just changed behavior people didn’t like.
LaunchDarkly posts a guarded-rollout / release-monitoring alert to Slack: “Metric error_rate regressed for flag new-checkout — rollback recommended.”From the alert, open the flag and identify contexts that received the regressing variation. Then go to LaunchDarkly → Contexts, open one, and copy subtext_url from the Attributes tab. Grab several, then hand them to your agent:
LaunchDarkly emails you that an experiment reached significance — and the treatment lost on a primary metric.Open the experiment, pull contexts in the losing variation, and copy subtext_url for a few from Contexts.
Errors spike right after a flag change; you suspect the flag and want proof before reverting.Cross-reference the erroring users to LaunchDarkly contexts, then copy subtext_url from ContextsAttributes.
Paste the agent’s verdict into the flag’s comments or the incident channel so the rollout decision is documented with evidence. For a rollback, ask the agent to capture a quick proof document (doc-create) with before/after screenshots of the variation, so the “why we rolled back” is permanent. A “metric regressed but the feature works” verdict means iterate; a “feature is broken” verdict means revert now — the session review is what tells the two apart while the rollout clock is ticking.

For agents

An autonomous agent can run the whole loop against LaunchDarkly directly: discover the regressed variation, extract the subtext_url, and hand each session to the Subtext MCP. LaunchDarkly is the cleanest experimentation integration for this — the replay link is read back natively as a stored context attribute. LaunchDarkly ships an official MCP server, hosted at https://mcp.launchdarkly.com/mcp/launchdarkly (remote, HTTP), with a local stdio server at github.com/launchdarkly/mcp-server for federal or EU environments. The hosted server authenticates with OAuth via its install page; the local stdio server authenticates with an API access token created on the Authorization page. See LaunchDarkly’s MCP docs. It exposes around 100 tools — the relevant ones here are get-experiment-results, get-experiment-metric-results, list-experiments, and get-experiment for experiments, and query-flag-evaluations to map affected sessions to the variation they received. To read subtext_url back, use search-contexts or get-context-instances, which return stored context attributes.
1

Discover the regressed variation

Read experiment results with get-experiment-results / get-experiment-metric-results (mirrored by the GET /api/v2/.../experiments... REST endpoint) to find the variation that regressed, and use query-flag-evaluations to map affected sessions and contexts to the variation they received.
2

Extract the session URL

Read subtext_url from the stored context attributes with the MCP tools: search-contexts to find the context by kind, key, or attribute value, then get-context-instances for its full attribute set. On the local stdio server, which lacks context tools, fall back to REST: discover instances first via POST Search context instances or the context-instances list (filter e.g. applicationId, sort=ts / -ts, pagination), then GET the instance:
3

Hand off to Subtext

For each URL, call review-open(session_url=<subtext_url>) on the Subtext MCP, then step through the key moment in the variation for a Detect-vs-Diagnose read: metric regressed vs. did the variation actually break.
subtext_url only round-trips if it was set as a context attribute at capture time (see Attach the session URL), and the value is frozen at set-time. The documented context model nests custom attributes — including subtext_url — inside context, but the docs’ example response shows "context": null, so confirm the exact populated nesting against a live call. Use the local stdio server for EU or federal environments where the hosted endpoint isn’t permitted — note that it exposes only a small flag and AI Config toolset (feature flags, AI Configs, audit log, code references, environments), not the experiment or flag-evaluation tools above, so in those environments run the whole discovery and extraction loop over the REST API instead.