Skip to main content
The Claude Agent SDK (claude-agent-sdk) runs a tool-use loop against the Claude Code engine. It exposes no global callback system, so DecimalAI traces it by wrapping the message stream: every message passes through to your code unchanged while the SDK accumulates one trace per query() run — model turns, tool calls with inputs and results, token usage, and cost. This page also covers Claude Code as a skill runtime: skills reach it from disk, through its own skill loader, not through the live router.

Install

Trace every run

query() returns an async iterator, so consuming it takes async for — and async for is only legal inside an async def. At module level it is a SyntaxError, not a runtime error: the file will not even import. asyncio.run() is the shortest way to get that function; from inside an event loop you already have (a notebook cell, a FastAPI handler) await main() instead. The flag form monkeypatches claude_agent_sdk.query. Call init() before binding query by name (from claude_agent_sdk import query), or call it off the module (claude_agent_sdk.query(...)), so you get the patched symbol.

Explicit form — wrap a stream you already have

No monkeypatch; useful when you only want some runs traced or you’re using ClaudeSDKClient.receive_response():
There’s also traced_query(prompt=..., options=..., agent_name=...) — a convenience that calls query() and wraps it in one step.

What gets captured

  • One trace per query() run: every assistant turn as an LLM call, tool calls matched to their results (with latency and per-tool error status)
  • Cumulative token usage and cost from the final ResultMessage, including cache-read/creation input tokens
  • Auto-detected manifest from ClaudeAgentOptions + the init message: model, system prompt, allowed tools (names), and subagents
  • Run status: a failed tool doesn’t fail the run — the ResultMessage is authoritative
  • Skills Claude Code loads from your installed skills, as activations with their version (SDK 0.16.0+; see Skills)
The wrapper is observability-only: it never alters or swallows messages, and an ingest failure never breaks your run.

Skills: Claude Code loads them from disk

Claude Code reads skills from disk itself, so a registry skill reaches it as files. Install it into the project (SDK 0.15.0+):

Load installed skills as a Claude Code plugin

decimalai skills keeps .agents/ as a Claude Code plugin named decimalai-skills, with the installed skills in its skills/ folder. Pass that folder to the Agent SDK as a local plugin with skills_plugin() (SDK 0.16.0+):
skills="all" also offers the model Claude Code’s own built-in skills alongside yours. To offer only your installed skills, list them by their plugin-qualified names instead, skills=["decimalai-skills:acme-refund-policy", ...] (the folder names under .agents/skills/). A list has to be updated when you add a skill: one left off is hidden from the model, and nothing reports it. Interactively, the same plugin loads with:
The path must be absolute: a relative --plugin-dir started from a subdirectory loads nothing and shows no error. skills_plugin() returns an absolute one from anywhere in the project.
  • Each load is an activation (SDK 0.16.0+). With the stream traced (init(claude_agent_sdk=True) or trace_stream), each skill body the CLI hands the model is recorded as an activation carrying its version, and the DecimalAI skills in the CLI’s skill catalog as offered. The frontmatter never reaches your process, so the version comes from the lock, by the hash of the delivered body. After decimalai skills update, Claude Code serves the new version.
  • Skill names carry the plugin’s prefix. Claude Code lists the skills as decimalai-skills:acme-refund-policy. The plugin is not called decimalai because the marketplace plugin already has that name, and two plugins with one name replace each other.
  • Only skills your org wrote pre-approve tools. While a skill is active, Claude Code runs the tools its allowed-tools lists without asking. The registry keeps that list whole only for a skill your org wrote itself; for any other, a fork or an import included, it keeps only Read, Grep and Glob, so running that skill’s scripts needs your permission.
  • On-demand skills stay on demand. A skill the registry marks on-demand carries disable-model-invocation: true. Claude Code lists it but runs it only when you invoke it; of the native loaders, only Claude Code and the Pydantic AI harness honour that key.
There is no hosted-routing path on this integration. Skill selection happens inside Claude Code itself, so there is no DecimalAI skill router here to step aside and no routing decision on the trace. Installing a skill to disk is counted separately, as a fetch, and earns no use. What a run does with a skill is on its trace: the Skill tool call with its input, and from SDK 0.16.0 the load itself as an activation on the usage ladder. See Native skill loaders for how the version is decided and how the other frameworks compare.
Updating is a command too: decimalai skills update moves the project’s skills to their newest version, and decimalai skills install --frozen reproduces the locked files in CI. See Skills on disk. SDK-routed runtimes don’t need any of this: router.use() (or router.fork(), for an editable copy) puts the skill in your workspace, and the router serves it to the agents it reaches: use() to every agent unless you name some, and fork() to the agents you add it to (SDK 0.25.1+). router.install() is deprecated, and from SDK 0.15.0 it no longer forks. See Vocabulary.

Caveats

  • DECIMAL_AUTO_TRACE has no claude-agent-sdk value — use init(claude_agent_sdk=True) in code.
  • Tool schema depth in the manifest is names only (allowed_tools is a name list). Use register_manifest() if you need schema-aware regression checks.
  • This adapter is distinct from decimalai.anthropic (agent_config() for the raw Messages API) and from init(anthropic=True) (raw provider tracing). The Claude Agent SDK is Anthropic-native; pair it with the anthropic provider only.
Checkpoint: run one query() to completion. Startup logs show DecimalAI Claude Agent SDK tracing installed globally, and the run appears in Traces with one LLM call per assistant turn and your tool calls matched to results.

What’s next

Skills

Installing skills to disk, native loaders, and the offered → delivered → activated ladder.

Manifests

Register a manifest explicitly to capture tool schemas.