Open-source agent tracing
A TypeScript library for LangGraph and LangChain. Traces land in your files or AWS account, and a local viewer opens them.

Fits the stack you already run
The viewer serves an MCP endpoint on localhost. Claude Code reads the run tree, searches payloads and points at the call that broke.
claude mcp add --transport http \ m4trix-traces http://127.0.0.1:4319/mcpThe tracer speaks the LangChain callback API. Pass it to invoke and every chain, model and tool call lands in ./.traces.
.traces/traces/f19bca0d/runs.ndjson
{"name":"intake","type":"chain","status":"success"}
{"name":"plan_work","type":"chain","status":"success"}
{"name":"documentation_search","type":"tool","status":"success"}
{"name":"repository_search","type":"tool","status":"success"}
{"name":"draft_answer","type":"llm","status":"success"}
{"name":"final_review","type":"chain","status":"success"}
import { FsPayloadStoreAdapter, FsStructureStoreAdapter, TraceStore, Tracer, toLangGraph,} from '@m4trix/tracing';
const traceStore = TraceStore.of({ structureStoreAdapter: new FsStructureStoreAdapter({ path: './.traces' }), payloadStoreAdapter: new FsPayloadStoreAdapter({ path: './.traces' }),});
const tracer = Tracer.from(traceStore).adapt(toLangGraph);
await graph.invoke(input, { callbacks: [tracer] });await tracer.flush();pnpm add @m4trix/tracingnpx @m4trix/trace-viewer \ --adapter fs --path ./.tracesSmall rows for lists and filters, full payloads when you open a run, and notes that stay with the trace.
Profiles turn raw JSON into messages, tool calls and tables. A model drafts the mapping from samples of your traces, with your own key, straight from the browser.

No sign-up, no API key, no upload queue. Grep it, commit a fixture, or mount it in Docker.
Structure rows stay small, so lists and filters are fast. Prompts and completions are blobs, fetched by ref when you open a run. The adapters that wrote them serve both back.
Structure rows (files or DynamoDB)
Payload blobs (files or S3)
Annotate traces and single runs after the fact. Notes live next to the structure rows, not in another tool.
annotation: { review: 'approved' }Same Tracer, same viewer at every stage. Only the adapters change.
Filesystem adapters write to a folder. On a laptop that is the whole setup.
A companion container uploads payloads before structure, so the app needs no AWS credentials.
The same viewer and MCP server read straight from your account.
Swap any adapter without touching the tracer or the viewer.
Tracer.from(traceStore) implements the callback surface LangGraph expects. Pass tracer.adapt(toLangGraph) to callbacks. Every chain, LLM, tool, and retriever span lands in your store without rewriting agent code.import { Tracer, toLangGraph } from '@m4trix/tracing';
const tracer = Tracer.from(traceStore);const lgTracer = tracer.adapt(toLangGraph);
await graph.invoke(input, { callbacks: [lgTracer] });await lgTracer.flush();Not by default. The filesystem adapters write to a folder you choose. Data only moves if you configure the S3 and DynamoDB adapters or run the sidecar. AI profiles call the model provider directly from your browser, with your key.
No. The Tracer implements the LangChain callback methods without importing LangChain, so anything that emits those callbacks works. LangGraph gets a typed adapter through toLangGraph.
Those are platforms: a hosted service, or a database and web app you operate. m4trix tracing is a library. Traces are files or rows in your own AWS account, and the viewer is a CLI you start when you need it.
The sidecar pattern is built for it: the app writes locally and a companion container ships to S3 and DynamoDB. Sampling, PII redaction, viewer auth and retention policies are not included yet.
Nothing. It is MIT licensed with no seats or usage tiers. You pay only for the storage you choose to use.
Each package works on its own. Together they share one TypeScript model.