A Claude Code plugin that traces conversations, tool calls, subagent executions, and context compaction to LangSmith.
- Node.js v18+
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
Claude Cowork runs Claude Code in a sandboxed VM, thus the plugin needs to be added separately.
- Allow network egress for
LANGSMITH_CC_ENDPOINT(eg.https://api.smith.langchain.com) or for all domains - Add
langchain-ai/langsmith-claude-code-pluginsmarketplace in Customize > Personal Plugins (+) > Create Plugin > Add Marketplace - Edit each of the Claude Code hooks by prepending LangSmith Claude Code environment variables to
commandof every hook. Watch video to see step-by-step.
Claude.Cowork.Tutorial.mp4
Important
Make sure that 'Allow network egress' is either enabled for all domains or enabled for LANGSMITH_CC_ENDPOINT, otherwise Cowork might freeze.
pnpm install
pnpm build
claude --plugin-dir /path/to/langsmith-claude-code-pluginsOption 1: Claude Code settings file (recommended)
Add the following to a .claude/settings.local.json file in your project folder or ~/.claude/settings.json globally:
{
"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"- Go to smith.langchain.com
- Sign in or create an account
- Navigate to Settings → API Keys
- Click Create API Key
- Copy the key (starts with
lsv2_pt_...)
Each LLM run includes:
- Inputs: accumulated conversation messages
- Outputs: assistant response content
- Metadata:
ls_provider: "anthropic",ls_model_name,ls_invocation_params(model, stop reason), token usage
All runs (LLM, tool, turn, subagent) automatically include identity metadata so you can attribute traces in LangSmith:
anthropic_user_id— read from theuserIDfield in~/.claude.json(the Claude Code installation's stable hashed user ID). Omitted if the file is missing or unreadable.local_username— the local OS username fromos.userInfo().
To override either field, supply your own value via CC_LANGSMITH_METADATA — user-supplied keys always win.
Tool 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 |
No* | — | LangSmith API key (falls back to LANGSMITH_API_KEY). *Required unless CC_LANGSMITH_RUNS_ENDPOINTS is set. |
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 |
CC_LANGSMITH_METADATA |
No | — | JSON object of custom metadata to attach to all runs (e.g. PR URL, author) |
CC_LANGSMITH_RUNS_ENDPOINTS |
No | — | JSON array of replica destinations for multi-project tracing |
You can use this plugin with anthropics/claude-code-action to trace Claude Code runs in CI. Add the following to your workflow:
- uses: anthropics/claude-code-action@v1
env:
TRACE_TO_LANGSMITH: "true"
CC_LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }}
CC_LANGSMITH_PROJECT: "my-project"
CC_LANGSMITH_METADATA: |
{
"pr_url": "${{ github.event.pull_request.html_url || '' }}",
"pr_number": "${{ github.event.pull_request.number || '' }}",
"pr_author": "${{ github.event.pull_request.user.login || '' }}",
"repository": "${{ github.repository }}",
"commit_sha": "${{ github.sha }}",
"trigger": "${{ github.event_name }}"
}
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
plugin_marketplaces: |
https://github.com/langchain-ai/langsmith-claude-code-plugins.git
plugins: |
langsmith-tracing@langsmith-claude-code-plugins
prompt: |
Your prompt hereMake sure to add LANGSMITH_API_KEY and ANTHROPIC_API_KEY as repository secrets.
See .github/workflows/claude-code-review.yml for a full working example.
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:
Your outer run (chain)
└── Claude Code Turn (chain)
├── Claude (llm)
├── Read (tool)
└── Claude (llm)
You can trace to multiple LangSmith projects or workspaces simultaneously using the CC_LANGSMITH_RUNS_ENDPOINTS environment variable. This is useful for:
- Sending traces to both a production and staging project
- Tracing to multiple workspaces with different API keys
- Adding extra metadata to specific replica destinations
For more information on replicas, see the LangSmith documentation.
Set CC_LANGSMITH_RUNS_ENDPOINTS to a JSON array of replica configurations. This will override other client settings.
Option 1: Claude Code settings file (recommended)
In your local .claude/settings.local.json or global ~/.claude/settings.json:
{
"env": {
"TRACE_TO_LANGSMITH": "true",
"CC_LANGSMITH_RUNS_ENDPOINTS": "[{\"apiUrl\":\"https://api.smith.langchain.com\",\"apiKey\":\"ls__key_workspace_a\",\"projectName\":\"project-prod\"},{\"apiUrl\":\"https://api.smith.langchain.com\",\"apiKey\":\"ls__key_workspace_b\",\"projectName\":\"project-staging\",\"updates\":{\"metadata\":{\"environment\":\"staging\"}}}]"
}
}Tip: To generate the escaped JSON string, use:
echo '[{"apiUrl":"...","apiKey":"...","projectName":"..."}]' | jq -cR .
Option 2: Shell environment variable
Add to your ~/.zshrc, ~/.bashrc, or ~/.bash_profile:
export CC_LANGSMITH_RUNS_ENDPOINTS='[{"apiUrl":"https://api.smith.langchain.com","apiKey":"ls__key_workspace_a","projectName":"project-prod"},{"apiUrl":"https://api.smith.langchain.com","apiKey":"ls__key_workspace_b","projectName":"project-staging","updates":{"metadata":{"environment":"staging"}}}]'Each replica object supports the following fields:
| Field | Required | Description |
|---|---|---|
apiUrl |
Yes | LangSmith API URL (typically https://api.smith.langchain.com) |
apiKey |
Yes | API key for the destination workspace |
projectName |
Yes | Project name in the destination workspace |
updates |
No | Optional metadata/fields to override on the replicated runs |
Currently, subagents are only traced upon completion. This means if you interrupt a conversation turn during a subagent run, the subagent runs will not be traced.
pnpm install
pnpm dev # Watch mode — recompiles on changes
pnpm test # Run tests
pnpm build # Production buildAfter making changes, run pnpm build and send a new message in Claude Code to pick up the updated hooks.
MIT
