Skip to content

Telemetry

Telemetry is opt-in and works with both stdio and HTTP MCP connections. It exports request spans, operational events and request count/duration metrics to an OTLP collector. It does not export tool arguments, results, page content or exception text.

Setup

With an HTTP/protobuf collector listening on port 4318:

export JUSTPEN_BROWSER_OTEL_ENABLED=true
export JUSTPEN_BROWSER_OTEL_PROTOCOL=http/protobuf
export JUSTPEN_BROWSER_OTEL_ENDPOINT=http://127.0.0.1:4318
export JUSTPEN_SESSION_ID=pentest-example
export JUSTPEN_BROWSER_OTEL_RESOURCE_ATTRIBUTES=justpen.run.id=run-example,deployment.environment.name=local
export JUSTPEN_BROWSER_OTEL_REQUIRE_SESSION=true
uv run justpen-browser-mcp

The endpoint is the telemetry collector, separate from the MCP listener and the browser's inspection proxy. For a client-spawned stdio server, pass these variables through its MCP configuration: Codex or Claude Code.

Session identity

justpen.session.id is a resource attribute on all three signals, taken only from JUSTPEN_SESSION_ID. The server removes that key from additional resource attributes, including encoded and duplicate entries. Missing or invalid session values never fall back to request metadata, HTTP headers or a native client session. Set JUSTPEN_BROWSER_OTEL_REQUIRE_SESSION=true to reject enabled startup without it.

The launcher owns these IDs: retain the same session for a pentest and its retests, and optionally supply a different justpen.run.id per run. One server process has one fixed session/run resource. Each process generates a new service.instance.id unless explicitly supplied. Session and run IDs accept 1–128 ASCII letters, digits, periods, underscores, colons and hyphens. Additional resource fields use comma-separated key=value pairs with percent encoding for reserved characters.

Filter the backend by the resource field justpen.session.id. Native client session/thread IDs remain separate. Retention, sampling and collector delivery determine which records are available; session tagging does not guarantee delivery.

Settings

All suffixes below use the prefix JUSTPEN_BROWSER_OTEL_. JUSTPEN_SESSION_ID is the dedicated exception. Booleans accept true or false, case-insensitively. Invalid values produce diagnostics without printing their contents.

Suffix Meaning / default
ENABLED Master switch; false.
TRACES_ENABLED, LOGS_ENABLED, METRICS_ENABLED Individual signals; each true when master is enabled.
REQUIRE_SESSION Require a valid session when enabled; false.
SERVICE_NAME justpen-browser-mcp; overrides additional service.name.
RESOURCE_ATTRIBUTES Additional fields, such as justpen.run.id; excludes justpen.session.id.
PROTOCOL http/protobuf (default) or grpc.
ENDPOINT Collector base URL; SDK defaults to localhost:4318 for HTTP or localhost:4317 for gRPC.
HEADERS Collector headers as comma-separated, percent-encoded key=value pairs.
TIMEOUT Positive exporter timeout in seconds; SDK default 10.
CERTIFICATE, CLIENT_CERTIFICATE, CLIENT_KEY CA and optional client certificate/key file paths.
COMPRESSION, INSECURE none/gzip/deflate; gRPC insecure-channel boolean.
TRACES_*, LOGS_*, METRICS_* Per-signal overrides for protocol and the exporter options above.
TRACES_SAMPLER, TRACES_SAMPLER_ARG Sampler; parentbased_always_on. Ratio argument between 0 and 1.
BSP_MAX_QUEUE_SIZE, BLRP_MAX_QUEUE_SIZE Trace/log queue capacity; SDK default 2048.
BSP_MAX_EXPORT_BATCH_SIZE, BLRP_MAX_EXPORT_BATCH_SIZE Batch size; SDK default 512, capped at queue capacity.
BSP_SCHEDULE_DELAY, BLRP_SCHEDULE_DELAY Batch delay in milliseconds; SDK defaults 5000/1000.
BSP_EXPORT_TIMEOUT, BLRP_EXPORT_TIMEOUT SDK batch flush timeout in milliseconds; default 30000.
METRIC_EXPORT_INTERVAL, METRIC_EXPORT_TIMEOUT Milliseconds; SDK defaults 60000/30000.
SHUTDOWN_TIMEOUT_MS Total telemetry cleanup budget after browser cleanup; 5000.

Per-signal options take precedence. An HTTP base endpoint gains /v1/traces, /v1/logs or /v1/metrics; a signal-specific endpoint is used exactly as supplied. Samplers accept always_on, always_off, traceidratio and their parentbased_ variants. Invalid protocols disable the affected signal. Queue, batch and interval values must be positive integers. Use exporter TIMEOUT to bound network attempts; SDK batch flush settings do not interrupt an exporter already blocked in a call.

Raw OTEL_* variables do not configure this server. Enabled CLI startup clears them in its own process before applying the validated browser settings; the parent client is unaffected. Leave FastMCP's telemetry mode at its default native.

Trace continuity and correlation

A valid HTTP traceparent takes priority over MCP request params._meta context. Otherwise, valid _meta.traceparent is used. Valid tracestate is retained. With neither, the request starts a new root trace. Each call has a new server span whose parent is the supplied span; concurrent calls keep independent context.

The server enriches FastMCP's existing spans with request IDs, browser operation UUIDs and resolved instance/page/frame IDs when available. Codex _meta.callId and Claude _meta["claudecode/toolUseId"] map to gen_ai.tool.call.id; conflicting IDs are flagged rather than merged. Native session/thread/turn/item IDs are retained separately when present. No new tool arguments or browser HTTP headers are required.

Measured client limits

Headless probes on 2026-09-14, using Codex 0.154.0 (codex exec) and Claude Code 2.1.270 (claude -p), observed:

Client stdio HTTP
Codex No W3C context; independent MCP trace with call-ID correlation. W3C context from a separate transport-worker trace, not its native tool trace.
Claude Code No W3C context; independent MCP trace with call-ID correlation. W3C context continued the native tool-execution trace.

The MCP continues the context it receives; it cannot reconstruct an upstream parent that the client did not send. These probes do not establish interactive, subagent, resume or retest behavior. Those require separate launcher integration tests.

Runtime behavior

Operational logs contain fixed request/lifecycle events; ordinary Python logs remain on stderr. Stdio stdout stays reserved for MCP. Request metrics are justpen.mcp.requests and justpen.mcp.request.duration (seconds), labeled only by method, transport and outcome. Logs retain active trace/span IDs even when the trace is unsampled. Errors and cancellations preserve available operation IDs.

Disabled telemetry creates no providers or exporter threads. Enabled export uses bounded queues; a slow or unavailable collector can lose records without failing browser calls. Shutdown attempts all signal flushes within one budget after browser cleanup; blocked exporters cannot keep the interpreter alive indefinitely.