From claude-code-tracing
Set up and configure Arize tracing for Claude Code sessions or Agent SDK applications. Use when users want to set up tracing, configure Arize AX or Phoenix, create a new Arize project, get an API key, enable/disable tracing, or troubleshoot tracing issues. Triggers on "set up tracing", "configure Arize", "configure Phoenix", "enable tracing", "setup-claude-code-tracing", "create Arize project", "get Arize API key", "agent sdk tracing", or any request about connecting Claude Code or the Agent SDK to Arize or Phoenix for observability.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-code-tracing:manage-claude-code-tracingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Configure OpenInference tracing for Claude Code sessions or Agent SDK applications to Arize AX (cloud) or Phoenix (self-hosted). Spans are sent directly to the backend from hooks -- no background process or backend-specific dependencies are needed in the user's environment.
Configure OpenInference tracing for Claude Code sessions or Agent SDK applications to Arize AX (cloud) or Phoenix (self-hosted). Spans are sent directly to the backend from hooks -- no background process or backend-specific dependencies are needed in the user's environment.
This skill follows a decision tree workflow. Start by asking the user where they are in the setup process:
Are they using the Claude Code CLI or the Agent SDK?
Do they already have credentials?
Which backend do they want to use?
Are they troubleshooting?
Important: Only follow the relevant path for the user's needs. Don't go through all sections.
Phoenix is self-hosted. No Python dependencies are needed for tracing -- spans are sent directly via send_span() using stdlib urllib.
Ask if they already have Phoenix running. If not, walk through:
# Option A: pip
pip install arize-phoenix && phoenix serve
# Option B: Docker
docker run -p 6006:6006 arizephoenix/phoenix:latest
Phoenix UI will be available at http://localhost:6006. Confirm it's running:
curl -sf http://localhost:6006/v1/traces >/dev/null && echo "Phoenix is running" || echo "Phoenix not reachable"
Then proceed to Configure Settings with the Phoenix endpoint.
Arize AX is available as a SaaS platform or as an on-prem deployment. Users need an account, a space, and an API key.
First, ask the user: "Are you using the Arize SaaS platform or an on-prem instance?"
otlp.arize.com:443). Continue below.otlp.mycompany.arize.com:443). Ask for it and note it for the Configure Settings step.If the user doesn't have an Arize account:
Walk the user through finding their credentials:
Both api_key and space_id are required for the shared config.
No Python dependencies are needed. Both Phoenix and Arize AX use HTTP/JSON — no additional Python dependencies are needed.
Then proceed to Configure Settings. If the user is on an on-prem instance, remind them to provide their custom endpoint.
Important: For marketplace installs, users must run this setup skill before tracing will work. The send_span() function requires ~/.arize/harness/config.json to exist for backend credential resolution.
Configuration has two parts:
~/.arize/harness/config.json) -- backend credentials and per-harness settings, read by send_span(). This skill creates it.~/.claude/settings.json or .claude/settings.local.json) -- tracing feature flags and user-level env vars~/.claude/settings.json) or project-local (.claude/settings.local.json)http://localhost:6006), optional API keyotlp.arize.com:443."claude-code", stored under harnesses.claude-code.project_nameARIZE_USER_ID to identify spans by user (useful for teams)The config file at ~/.arize/harness/config.json is the single source of truth for backend credentials and per-harness settings. Create the directory structure if needed: mkdir -p ~/.arize/harness/{bin,run,logs}
Important: read-merge-write. If ~/.arize/harness/config.json already exists, read it first, then merge in the new or updated fields (e.g., add/update the harnesses.claude-code entry) while preserving existing backend credentials. Only prompt for backend credentials if no existing config is found.
Phoenix:
{
"harnesses": {
"claude-code": {
"project_name": "claude-code",
"target": "phoenix",
"endpoint": "<endpoint>",
"api_key": ""
}
}
}
Arize AX:
{
"harnesses": {
"claude-code": {
"project_name": "claude-code",
"target": "arize",
"endpoint": "otlp.arize.com:443",
"api_key": "<key>",
"space_id": "<id>"
}
}
}
If the user has a custom OTLP endpoint, set it in harnesses.claude-code.endpoint.
Determine the config file:
~/.claude/settings.json.claude/settings.local.json (create directory if needed: mkdir -p .claude)Read the file (or create {} if it doesn't exist), then merge env vars into the "env" object.
{
"env": {
"ARIZE_TRACE_ENABLED": "true"
}
}
If a custom project name was provided, set it in harnesses.claude-code.project_name in the config (~/.arize/harness/config.json), not as an env var.
If a user ID was provided, also set "ARIZE_USER_ID": "<id>". This adds a user.id attribute to all traced spans.
Example workflow:
# For project-local
mkdir -p .claude
echo '{}' > .claude/settings.local.json
# Then use an editor to add env vars
cat ~/.arize/harness/config.json to verify the config file exists and has correct backend credentials.curl -sf <endpoint>/v1/traces >/dev/null to check connectivity.Tell the user:
~/.arize/harness/config.json~/.claude/settings.json.claude/settings.local.jsonARIZE_DRY_RUN=true to test without sending dataARIZE_VERBOSE=true for debug output~/.arize/harness/logs/claude-code.log; set ARIZE_VERBOSE to "true" under env in ~/.claude/settings.json to also capture routine hook activity (session_start, span emits, state transitions)Note: Project-local settings override global settings for the same variables.
For users building with the Claude Agent SDK (Python or TypeScript), the tracing plugin loads as a local plugin. This section provides code and configuration for the developer to add to their application -- the agent cannot set this up at runtime since plugin paths and settings must be configured before the SDK session starts.
Important: The user must use ClaudeSDKClient -- the standalone query() function does not support hooks, so tracing will not work with it.
When a user asks about Agent SDK tracing setup, provide them with the steps below to integrate into their own code. Do NOT try to execute export commands or modify their application source -- instead, give them the snippets to copy.
Ask the user which backend they want. If they don't have credentials yet, walk them through Set Up Phoenix or Set Up Arize AX first, then return here.
Ask the user: "Have you already installed this plugin via the Claude Code CLI?"
If yes (already installed via the install.sh / install.bat flow): The plugin lives inside the harness install directory at ~/.arize/harness/tracing/claude_code.
If yes (installed via the Claude marketplace): They can reference it from the CLI cache. Tell them to check ~/.claude/plugins/installed_plugins.json for the exact path.
If no: Tell them to clone the repo into their project:
git clone https://github.com/Arize-ai/coding-harness-tracing.git
The plugin path will be ./coding-harness-tracing/tracing/claude_code.
Tip:
tracing.claude_code.agent_sdk.claude_options()returns a pre-configuredClaudeAgentOptionswith the plugin path andsetting_sources=["user"]already wired in, so users can skip the manual plumbing in step 5 below when the harness is installed viainstall.sh.
No Python dependencies are needed -- both Phoenix and Arize AX use HTTP/JSON.
Ensure ~/.arize/harness/config.json has the correct backend credentials (see Configure Settings above).
The Agent SDK spawns a Claude Code subprocess that does not inherit the user's shell environment variables. Tracing env vars must be passed via a settings file referenced in the ClaudeAgentOptions.
Tell the user to create a settings.local.json file (or similar):
{
"env": {
"ARIZE_TRACE_ENABLED": "true"
}
}
Optional env vars that can also be added to the settings file:
ARIZE_USER_ID: User identifier added as user.id attribute to all spans (useful for teams)ARIZE_DRY_RUN: Set to "true" to test without sending dataARIZE_VERBOSE: Set to "true" for debug outputTo customize the project name, set it in harnesses.claude-code.project_name in the config (~/.arize/harness/config.json) rather than as an env var.
Give the user the appropriate snippet to add to their application. They must use ClaudeSDKClient and pass both the plugin path (from step 2) and the settings file (from step 4):
Python:
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
PLUGIN_PATH = "./coding-harness-tracing/tracing/claude_code" # or ~/.arize/harness/tracing/claude_code if installed via install.sh
options = ClaudeAgentOptions(
plugins=[{"type": "local", "path": PLUGIN_PATH}],
settings="./settings.local.json",
)
async with ClaudeSDKClient(options=options) as client:
await client.query("Your prompt here")
async for message in client.receive_response():
print(message)
TypeScript:
import { ClaudeSDKClient } from "@anthropic-ai/claude-agent-sdk";
const PLUGIN_PATH = "./coding-harness-tracing/tracing/claude_code"; // or ~/.arize/harness/tracing/claude_code if installed via install.sh
const client = new ClaudeSDKClient({
plugins: [{ type: "local", path: PLUGIN_PATH }],
settings: "./settings.local.json",
});
await client.connect();
await client.query("Your prompt here");
for await (const message of client.receiveResponse()) {
console.log(message);
}
await client.close();
Tell the user to add "ARIZE_DRY_RUN": "true" to their settings file to verify hooks fire without sending data, and check ~/.arize/harness/logs/claude-code.log for output.
For full Agent SDK documentation, see: https://platform.claude.com/docs/en/agent-sdk/overview
ClaudeSDKClient -- the standalone query() function does not support hooks and tracing will not work.HookEvent enum / type for the events your SDK version supports.SessionStart, SessionEnd, Notification, and PermissionRequest. The plugin handles this automatically -- session state is lazily initialized on the first UserPromptSubmit, so core tracing (LLM spans, tool spans, subagent spans) works fully.ClaudeAgentOptions -- the SDK subprocess does not inherit shell environment variables.~/.arize/harness/logs/claude-code.log), verifying the settings file contains the correct env vars, verifying ~/.arize/harness/config.json has correct backend credentials, or enabling dry-run mode.Common issues and fixes:
| Problem | Fix |
|---|---|
| Traces not appearing | Check ARIZE_TRACE_ENABLED is "true" in Claude settings, and verify config exists: cat ~/.arize/harness/config.json |
| Config missing | Run the installer or create ~/.arize/harness/config.json manually (include harnesses section) |
| Phoenix unreachable | Verify Phoenix is running: curl -sf <endpoint>/v1/traces |
| No output in terminal | Hook stderr is discarded by Claude Code; check ~/.arize/harness/logs/claude-code.log |
| Want to test without sending | Set ARIZE_DRY_RUN to "true" in env config |
| Want verbose logging | Set ARIZE_VERBOSE to "true" in env config |
| Wrong project name | Set harnesses.claude-code.project_name in ~/.arize/harness/config.json (default: "claude-code") |
| Spans missing user attribution | Set ARIZE_USER_ID in env config to add user.id to all spans |
Guides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.
Dispatches multiple subagents concurrently for independent tasks without shared state. Use when facing 2+ unrelated failures or subsystems that can be investigated in parallel.
npx claudepluginhub arize-ai/coding-harness-tracing --plugin claude-code-tracing