Skip to content

Analytics — Step-by-Step Setup

Add observability to every WebMCP tool in 4 steps. One webmcp.configure covers all tools — swap the provider SDK inside the hooks.

Prefer a provider recipe? Jump to PostHog, Sentry, or GA4. This page is the generic checklist.

For hook lifecycle (before → validate → fn → after → error/denied), see Guide — Hooks. For API types, see Reference — Hooks.

Step 1 — Pick your provider

ProviderBest forHook events
PostHogProduct analytics, session replaywebmcp.invoked / succeeded / failed / denied
SentryErrors + performance spanscaptureException + startInactiveSpan
GA4Marketing, gtag eventswebmcp_invoked / succeeded / error / denied

All use the same shape — choose one or combine.

External docs:

Step 2 — Configure hooks once (global)

Add one webmcp.configure in your app entry (e.g. main.tsx or app/layout.tsx):

ts
import { webmcp } from 'simple-webmcp';

webmcp.configure({
  hooks: {
    before: [({tool, input, invocationId, metadata})=>{
      metadata.start = performance.now();
      // send "invoked" to your provider
      console.log('[hook:before]', tool.tool.name, invocationId, input);
    }],
    after: [({tool, invocationId, output, metadata})=>{
      const duration = Math.round(performance.now() - (metadata.start as number));
      console.log('[hook:after]', tool.tool.name, invocationId, duration + 'ms', output);
    }],
    error: [({tool, error, invocationId})=>{
      console.warn('[hook:error]', tool.tool.name, invocationId, error);
    }],
    denied: [({tool, reason, code, invocationId})=>{
      console.warn('[hook:denied]', tool.tool.name, invocationId, reason, code);
    }],
  }
});

Hooks wrap only the agent execute pathtool({input}) stays pure. metadata is a shared bag for one invocation (before sets start, after reads it). invocationId is crypto.randomUUID() or fallback.

To scope by tenant/route, use <WebMCPProvider> instead — see React guide.

Step 3 — Verify in the demo

  1. Run docs locally:

    bash
    npm run docs:dev
    # open /demo/
  2. Open the Hooks & HITL card in the demo. Toggle Require approval for checkout on/off.

  3. Use Inspect → Invoke checkout → watch the hook log turn green (success) or yellow (denied). Open DevTools Console → [webmcp:hook] lines.

  4. Check your provider dashboard (PostHog Activity, Sentry Issues, GA4 DebugView) — events should appear with tool, invocationId, duration.

If no events: ensure webmcp.configure runs before tool.register() / useWebMCP mount, and that the provider SDK is initialized.

Step 4 — Production checklist

  • PII redaction: Redact input/output before sending. Use an after hook to strip email/token. See pattern in Hooks — After.
  • Sampling: For high volume, wrap hooks with if (Math.random() > 0.1) return or provider sampling.
  • Tenant / route: Use WebMCPProvider to enrich input with tenantId — see React — WebMCPProvider.
  • Durations: Set metadata.start in before, compute in after (not error/denied).
  • Deny vs error: Track denied (human said no) separately from error (operational failure). denied rate = HITL friction; error rate = reliability.
  • Testing: In vitest, call resetGlobalHooks() and registry.clear() between tests — see Reference — Hooks for the singleton.

Next

Pick a provider recipe:

Or return to Analytics Overview.

See also

Released under the MIT License.