Skip to main content
The Subtext setup wizard (npx @subtextdev/subtext-wizard) handles the full install in one step for most projects. If you are working with a custom framework, a monorepo with a non-standard structure, or simply prefer to control each piece of the integration yourself, this guide walks you through every step manually. You will add the capture snippet to your HTML, install the Subtext plugin for your agent (or configure the MCP server by hand), and end with a verification check to confirm everything is connected.
1

Add the capture snippet to your HTML

Open the HTML file that is served for every page of your application. Depending on your framework, this is typically:
  • Create React Apppublic/index.html
  • Viteindex.html at the project root
  • Next.js App Routerapp/layout.tsx (use <Script strategy="afterInteractive"> from next/script)
  • Remixapp/root.tsx (use dangerouslySetInnerHTML on a <script> tag)
  • Custom or static HTML — whichever .html file wraps your application shell
Paste the snippet before the closing </head> tag (or equivalent). Replace YOUR_ORG_ID with the Org ID from Subtext → Settings → Capture.
The snippet loads fs.js from Fullstory’s edge asynchronously. It does not block rendering and adds no measurable overhead to page load time.
2

Install the Subtext plugin for your agent

The plugin is the fastest way to connect an agent: it configures the MCP server connection and installs the Subtext skills and commands in one step, and it updates automatically.Claude Code (full plugin — MCP server, skills, and commands):
Cursor — install Subtext from the Cursor marketplace directly inside Cursor.Codex — open /plugins and install subtext from the repo marketplace.Gemini CLI:
Windsurf and other editors — install the skills via OpenSkills, then add the MCP server manually in the next step:
claude.ai — Subtext is also available as a connector in the Claude directory.
If you installed the plugin for Claude Code, Cursor, Codex, or Gemini CLI, the MCP server is configured for you — skip the next step and go straight to verification.
3

Add the MCP server manually (if needed)

If your tool didn’t configure MCP servers automatically during installation, add the server by hand. Subtext’s MCP server is hosted — https://api.fullstory.com/mcp/subtext over HTTP, with no local process to run.
Any tool that accepts a remote MCP URL — Linear’s Custom URL… field, for example — takes the same endpoint directly.
Once saved, restart your agent or reload its MCP configuration.
4

Verify the full integration

With the snippet deployed and your agent connected, run through this checklist to confirm everything is working end to end:Capture is working:
  1. Open your application in a browser and navigate to a few pages.
  2. Go to Subtext → Sessions. A new session should appear within 60 seconds.
  3. Click into the session and confirm you can see a replay timeline with page events.
MCP server is reachable:
  1. Open your agent (Claude Code, Cursor, etc.) in the project where you installed the plugin or added the MCP config.
  2. Ask it: “List my recent Subtext sessions.”
  3. The agent should respond with a list of sessions from your account. If it returns an authentication error, redo the OAuth flow (or check the Bearer token value), and confirm the config file is in the correct location for your agent.
Skills are available:
  1. In your agent, type / and look for Subtext skills in the command list (e.g., /subtext:review, /subtext:session).
  2. If they do not appear, reinstall the plugin (or re-run npx openskills sync) and restart your agent.
If sessions appear in the Subtext dashboard but the MCP server cannot be reached, the most common cause is a misplaced or malformed MCP config file. Check that the JSON is valid (no trailing commas) and that the file path matches what your agent expects.
The capture snippet records full production sessions and masks all form inputs by default. Once your agent is connected, it can review sessions, flag additional PII, and propose masking rules for your approval — closing the privacy governance loop without manual scrubbing.