LangSmith Tracing Plugin for Claude Code

May 4, 2026 · View on GitHub

A Claude Code plugin that traces conversations, tool calls, subagent executions, and context compaction to LangSmith.

Prerequisites

Installation

As a Claude Code plugin

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

As a Claude Cowork plugin

Claude Cowork runs Claude Code in a sandboxed VM, thus the plugin needs to be added separately.

  1. Allow network egress for LANGSMITH_CC_ENDPOINT (eg. https://api.smith.langchain.com) or for all domains
  2. Add langchain-ai/langsmith-claude-code-plugins marketplace in Customize > Personal Plugins (+) > Create Plugin > Add Marketplace
  3. Edit each of the Claude Code hooks by prepending LangSmith Claude Code environment variables to command of every hook. Watch video to see step-by-step.

https://github.com/user-attachments/assets/1d44b30f-e0a8-4173-b60b-97a2d1fb95c5

Important

Make sure that 'Allow network egress' is either enabled for all domains or enabled for LANGSMITH_CC_ENDPOINT, otherwise Cowork might freeze.

From source (development)

pnpm install
pnpm build
claude --plugin-dir /path/to/langsmith-claude-code-plugins

Setting environment variables

Option 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"

Getting your LangSmith API key

  1. Go to smith.langchain.com
  2. Sign in or create an account
  3. Navigate to SettingsAPI Keys
  4. Click Create API Key
  5. Copy the key (starts with lsv2_pt_...)

What gets traced

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 the userID field 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 from os.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.

Environment variables

The plugin respects the following environment variables:

VariableRequiredDefaultDescription
TRACE_TO_LANGSMITHYesSet to "true" to enable tracing
CC_LANGSMITH_API_KEYNo*LangSmith API key (falls back to LANGSMITH_API_KEY). *Required unless CC_LANGSMITH_RUNS_ENDPOINTS is set.
CC_LANGSMITH_PROJECTNo"claude-code"LangSmith project name
LANGSMITH_ENDPOINTNohttps://api.smith.langchain.comLangSmith API base URL
CC_LANGSMITH_DEBUGNo"false"Enable debug logging
CC_LANGSMITH_PARENT_DOTTED_ORDERNoDotted-order of an existing run to nest all Claude Code traces under
CC_LANGSMITH_METADATANoJSON object of custom metadata to attach to all runs (e.g. PR URL, author)
CC_LANGSMITH_RUNS_ENDPOINTSNoJSON array of replica destinations for multi-project tracing

Usage with GitHub Actions

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 here

Make 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.

Nesting traces under an existing run

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)

Tracing to multiple destinations (Replicas)

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.

Configuration

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"}}}]'

Replica format

Each replica object supports the following fields:

FieldRequiredDescription
apiUrlYesLangSmith API URL (typically https://api.smith.langchain.com)
apiKeyYesAPI key for the destination workspace
projectNameYesProject name in the destination workspace
updatesNoOptional metadata/fields to override on the replicated runs

Known limitations

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.

Development

pnpm install
pnpm dev         # Watch mode — recompiles on changes
pnpm test        # Run tests
pnpm build       # Production build

After making changes, run pnpm build and send a new message in Claude Code to pick up the updated hooks.

License

MIT