Trace Claude Code conversations, tool calls, subagent executions, and context compaction to LangSmith
npx claudepluginhub langchain-ai/langsmith-claude-code-pluginsTraces Claude Code conversations to LangSmith, including subagent and tool executions
Share bugs, ideas, or general feedback.
A Claude Code plugin that traces conversations, tool calls, subagent executions, and context compaction to LangSmith.

From within Claude Code, run:
/plugin marketplace add langchain-ai/langsmith-claude-code-plugins
/plugin install langsmith-tracing@langsmith-claude-code-plugins
/reload-plugins
To update, run:
/plugin marketplace update langsmith-claude-code-plugins
/reload-plugins
pnpm install
pnpm build
claude --plugin-dir /path/to/langsmith-claude-code-plugins
Option 1: Claude Code settings file (recommended)
Add to ~/.claude/settings.json:
{
"env": {
"TRACE_TO_LANGSMITH": "true",
"CC_LANGSMITH_API_KEY": "lsv2_pt_...",
"CC_LANGSMITH_PROJECT": "my-project"
}
}
Option 2: Export to shell
Add to your ~/.zshrc, ~/.bashrc, or ~/.bash_profile:
export TRACE_TO_LANGSMITH="true"
export CC_LANGSMITH_API_KEY="lsv2_pt_..."
export CC_LANGSMITH_PROJECT="my-project"
lsv2_pt_...)Each LLM run includes:
ls_provider: "anthropic", ls_model_name, ls_invocation_params (model, stop reason), token usageTool runs include the tool name, inputs, and output content.
Interrupted turns (where the user cancels mid-response) are marked with status "interrupted" in LangSmith.
The plugin respects the following environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
TRACE_TO_LANGSMITH | Yes | — | Set to "true" to enable tracing |
CC_LANGSMITH_API_KEY | Yes | — | LangSmith API key (falls back to LANGSMITH_API_KEY) |
CC_LANGSMITH_PROJECT | No | "claude-code" | LangSmith project name |
LANGSMITH_ENDPOINT | No | https://api.smith.langchain.com | LangSmith API base URL |
CC_LANGSMITH_DEBUG | No | "false" | Enable debug logging |
CC_LANGSMITH_PARENT_DOTTED_ORDER | No | — | Dotted-order of an existing run to nest all Claude Code traces under |
Set CC_LANGSMITH_PARENT_DOTTED_ORDER to nest all Claude Code traces as children of an existing LangSmith run. This is useful when Claude Code is invoked programmatically as part of a larger traced workflow.
Python
import subprocess
from langsmith import traceable, get_current_run_tree
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "..."
os.environ["LANGSMITH_PROJECT"] = "claude-code"
@traceable
def run_claude(prompt: str):
run_tree = get_current_run_tree()
subprocess.run(
["claude", "-p", prompt],
env={
**os.environ,
"TRACE_TO_LANGSMITH": "true",
"CC_LANGSMITH_API_KEY": "...",
"CC_LANGSMITH_PROJECT": "claude-code",
"CC_LANGSMITH_PARENT_DOTTED_ORDER": run_tree.dotted_order,
},
)
TypeScript
import { traceable, getCurrentRunTree } from "langsmith/traceable";
import { execSync } from "node:child_process";
process.env.LANGSMITH_TRACING = "true";
process.env.LANGSMITH_API_KEY = "...";
process.env.LANGSMITH_PROJECT = "claude-code";
const runClaude = traceable(
async (prompt: string) => {
const runTree = getCurrentRunTree();
const pluginDir = new URL(".", import.meta.url).pathname;
const res = execSync(`claude -p "${prompt}" --plugin-dir '${pluginDir}'`, {
env: {
...process.env,
TRACE_TO_LANGSMITH: "true",
CC_LANGSMITH_API_KEY: "...",
CC_LANGSMITH_PROJECT: "claude-code",
CC_LANGSMITH_PARENT_DOTTED_ORDER: runTree.dotted_order,
},
});
return res.toString();
},
{ name: "run_claude" },
);
The resulting trace hierarchy looks like: