Capability matrix
What Claude Code, Codex, the Python/TS SDK, and generic OTLP agents each support in TokenJam.
TokenJam takes telemetry from four kinds of source: Claude Code, OpenAI Codex, the Python / TypeScript SDK, and any OTLP-compliant agent wired straight to the ingest endpoint. They are not equivalent. Each source exposes a different set of hooks upstream (or none), so each one lights up a different slice of the product.
This page is the honest per-capability breakdown. Rows are capabilities, columns are sources, cells say what you actually get.
Onboarding entry points
| Source | Command |
|---|---|
| Claude Code | tj init --claude-code |
| Codex CLI | tj init --codex |
| Python SDK | tj init, then @watch() + patch_*() in your code |
| Generic OTLP | None. Point your exporter at tj serve’s /api/v1/spans |
What each source supports
| Capability | Claude Code | Codex CLI | Python / TS SDK | Generic OTLP |
|---|---|---|---|---|
| Live capture | Yes. OTLP log events convert to spans | Yes. Same converter, dedicated Codex event parsers | Yes. In-process @watch() + patch_*() spans | Yes. POST /api/v1/spans with any GenAI-semconv payload |
| Historical backfill | Yes. tj backfill claude-code reads ~/.claude/projects/*.jsonl | Yes. tj backfill codex reads ~/.codex/sessions/ | N/A. SDK telemetry is live-only | Partial. tj backfill otlp --source-file replays an OTLP dump |
| Zero-token statusline | Yes. tj statusline wired into ~/.claude/settings.json | No. Codex has no custom-command status line hook | N/A. No TUI to wire | N/A. Depends on the host agent’s own UI |
| Resume-brief hook | Yes. SessionStart hook re-injects prior context | No. Codex has no hook system tj integrates with | N/A. Use record_llm_call() / record_tool_call() manually | N/A |
| Per-terminal identity | Yes. claude shell wrapper sets a distinct instance ID per terminal | No. Codex hardcodes one service name, so every terminal collapses into one tile | Yes. Caller sets agent_id per @watch() | Partial. Only if the agent sets its own resource attributes |
| Dashboard (Lens web UI) | Yes | Yes | Yes | Yes |
| Analyzers | Yes | Yes | Yes | Yes |
| In-loop MCP server | No, by design. An in-loop MCP measured +36% quota overhead on CC subscription users | No, by design. Same reasoning | Yes. This is the primary intended use | Yes, if the host agent supports MCP tool-calling |
Reading the matrix
The dashboard and analyzers are source-agnostic. They read from the local DuckDB store, not from whichever path put the spans there. Once telemetry lands, tj optimize, tj cost, and the Lens web UI treat a backfilled Claude Code session and a live SDK span the same way.
The MCP server is deliberately off for coding agents. An in-request-path MCP server pays tool-definition overhead on every turn. A measured A/B put that at +36% model-weighted quota for Claude Code subscription users, so the coding-agent paths ship a zero-token statusline instead. The MCP still fits SDK and API integrations, where tj already sits in the request path. See MCP server.
The remaining Codex gap is the statusline, and it is upstream. Codex’s status line accepts a fixed list of built-in items and has no command-backed slot to inject an external line into, so tj stays fully out of band for Codex through OTel plus the tj CLI. Historical backfill is no longer a gap: tj backfill codex reads the session transcripts Codex writes to ~/.codex/sessions/.