Docs

Crumbtrail documentation

Everything you need to capture complete sessions, detect the moment a user gives up, and hand the reproduction to your coding agent.

Introduction

Crumbtrail has two packages. crumbtrail-core is the browser SDK: it runs the collectors and the silent-signal detectors inside your app. crumbtrail-node is the local server: capture ingest, Express middleware, the CLI, and an MCP server that exposes finished sessions as tools your coding agent can call. Adopt only what you need.

Quickstart

On Crumbtrail Cloud? Create an account and the in-app setup wires your app in one guided pass. The steps below run the local capture server yourself — no account needed.

1. Install and start the server

terminal
pnpm add crumbtrail-core crumbtrail-node
# start the local capture + MCP server on :9898
# (sessions land under ~/.crumbtrail/sessions)
npx crumbtrail-server serve

On pnpm 10+? Its supply-chain check queries the registry for every dependency, and a version that was just published can fail a fresh lockfile with ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION until it ages in. If you hit that for crumbtrail-core, add it to minimumReleaseAgeExclude in pnpm-workspace.yaml (pnpm does not read this key from .npmrc).

2. Initialize in the browser

app/entry.ts
import { Crumbtrail } from "crumbtrail-core";

// "passive" — embedded end-user monitoring: collectors on,
// silent-signal detection enabled, no widget.
Crumbtrail.init("passive");

// …or configure explicitly:
Crumbtrail.init({
  httpEndpoint: "http://localhost:9898",
  autoFlagOnSignals: true,
});

3. Verify end to end

Use your app as normal, then let the doctor prove the pipeline — capture, correlation, and MCP-readability — before you trust it:

terminal
npx crumbtrail-server doctor

Collectors

A collector subscribes to one source of browser events. Each is a boolean in Crumbtrail.init(); the full, light and passive presets pick sensible sets so you rarely toggle them by hand.

Interactions

Clicks, inputs and route changes, keyed to a stable component signature — not a brittle CSS path.

Keystrokes

Key events with sensitive input types (password, email, tel and more) masked by default.

Console

console.log / warn / error, with level and serialized, redacted arguments.

Network

fetch and XHR — method, URL, status, timing and redacted bodies, with cross-origin correlation headers.

Errors

Uncaught exceptions and unhandled promise rejections, with stacks.

Scroll & visibility

Throttled scroll position plus tab visibility — the raw material of the give-up signal.

Cookies & storage

Cookie changes plus localStorage, sessionStorage, IndexedDB and Cache API writes, value-capped and maskable.

Clipboard

Copy and paste events, length-capped; raw contents off by default.

Performance

Timing marks, so a slow response is a recorded fact instead of a memory.

Environment & flags

Feature flags, config, build and runtime recorded with every session.

Detection

The SDK keeps a rolling buffer of the last five minutes of session events. Four behavioral detectors watch that stream for the signals of a user giving up — none of them requires an exception. When one fires, Crumbtrail flags the reproduction window around it as a bug, automatically.

Rage-click

Four or more clicks on the same target within 1.5 seconds. The button that does nothing.

Retry storm

Four or more requests to the same endpoint within 5 seconds, or repeated failed responses. The user hammering refresh.

Slow response

Three or more responses of 3 seconds or longer inside a 10-second window. The app that feels broken.

Abandoned flow

Two or more filled inputs, then the tab hides with no submit. The form the user walked away from.

Enabled by autoFlagOnSignals — on in the passive and fullpresets. Every threshold above is a config key; tune them to your app's rhythm.

Session format

Each session is a directory of plain files you fully own: events.ndjson (the raw, append-only log), a manifest, and a pre-computed evidence index including a normalized, redacted search.jsonl. Agents read the index; the raw log stays cold.

~/.crumbtrail/sessions/<session-id>/events.ndjson
{"t":1751818000123,"k":"clk","d":{…}}
{"t":1751818000304,"k":"net.req","d":{…}}
{"t":1751818000451,"k":"net.res","d":{…}}
{"t":1751818000460,"k":"err","d":{…}}

Every event shares t (Unix milliseconds), k (a kind code — clk, net.req, con, err, db.diff, …) and d, the collector-specific payload.

Integrations

Two ways to get your stack into a bundle — stream it in, or let Crumbtrail pull it at ticket time. Pick per source; most teams run both.

Stream it in — SDK & OTLP

Express / Node

createCrumbtrailExpressMiddleware correlates backend requests to the click that caused them, across origins.

OpenTelemetry / OTLP

Already on Sentry, Datadog, Grafana or Splunk? Point an exporter at the server — crumbtrail-server init --provider <name> prints the exact block.

Headless sessions

startHeadlessSession records backend job runs — imports, syncs, scheduled tasks — as sessions with no browser at all.

Or pull it at incident time — evidence adapters

When a ticket arrives, Crumbtrail queries the observability tools you already run inside the located incident window and folds the hits into the same ranked bundle — no re-instrumentation. Fetches are read-only and zero-copy: only the derived bundle is stored, never the raw provider data. A missing join key degrades to an honest gap, never an error.

Sentry

logscode

Errors and breadcrumbs from the incident window, correlated by trace id, release or URL.

CloudWatch

logs

Logs Insights queried by request id or trace id, scoped to the incident window.

Splunk

logs

Search results bounded to the window by trace id, request id or service.

Datadog

logsnetwork

Logs and network spans matched by trace id, service or URL.

PostHog

browserflow

The user's own events and session replay, by distinct id, session or URL.

Cloudflare

networklogs

Edge request logs and R2-archived Logpush by request id or URL.

See the full capture pipeline for spans, database diffs and MCP.

MCP for agents

The same binary serves MCP over stdio — so your coding agent pulls the evidence itself instead of guessing from a screenshot.

claude_desktop_config.json
{
  "mcpServers": {
    "crumbtrail": {
      "command": "npx",
      "args": ["crumbtrail-server", "serve", "--mcp"]
    }
  }
}

More than thirty tools in total. The ones you'll reach for most: getFixContext (the ranked causal window for one failure), getRegressionContext (what diverged between two releases), getEvidence, listBugs, listSessions and getEvents.

CLI reference

One binary, crumbtrail-server. Run any command with --help for flags.

serve

Run the local capture + MCP server (default if no command given).

init

Install the SDK into your project and generate wiring helpers.

doctor

Verify capture, correlation and MCP-readability end to end.

scan

Flag components and functions missing IDs or logging — coverage gaps.

fix-context

Emit the ranked, correlated, LLM-ready fix-context bundle for a session.

inspect

Summarize a finalized session's manifest and artifacts.

compare

Compare two recorded sessions or releases.

Self-hosting

The capture server is a single process with no database — it appends plain files to disk. Run it anywhere Node runs; set CRUMBTRAIL_AUTH_TOKEN to require a token on ingest.

terminal
CRUMBTRAIL_AUTH_TOKEN=<token> \
npx crumbtrail-server serve --port 9898 --output /var/crumbtrail/sessions

Sessions are plain files under the output directory — back them up, rotate them or delete them with ordinary tooling. Crumbtrail is deployment-flexible: run the server wherever your compliance posture wants it.

FAQ

Where do my sessions live?

Wherever you point the SDK. Crumbtrail is deployment-flexible — self-host the capture server, or use the hosted service when you want detection at scale without running infrastructure.

How do I avoid capturing passwords?

Sensitive input types — password, email, tel, number, search, url — are masked by default via maskInputTypes; add ignoreSelectors to skip elements entirely. The redaction engine masks values before an event is ever stored.

Is the SDK really open source?

The self-host core writes to plain files you control — audit exactly what is captured before you ship it. Source access is available on request.

Ready to capture your first session?

Create an account or jump straight into the SDK.

Get started