toolkit/packages/skills/langfuse-setup/SKILL.md
Set up or disable Langfuse observability for Claude Code sessions. Manages hook configuration, credential verification, and connection testing.
npx skillsauth add stevengonsalvez/agents-in-a-box langfuse-setupInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Set up, check, or disable Langfuse observability tracing for Claude Code hook-based sessions.
| Command | Action |
|---------|--------|
| /langfuse-setup | Interactive setup wizard |
| /langfuse-setup:status | Check current Langfuse configuration status |
| /langfuse-setup:disable | Remove Langfuse hooks and disable tracing |
When invoked without a sub-command, run the full setup flow.
I'll walk you through setting up Langfuse observability for your Claude Code sessions.
This will:
1. Verify your Langfuse credentials
2. Configure PreToolUse / PostToolUse hooks in settings.json
3. Test the connection to your Langfuse instance
Let me check your current environment.
Look for LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY in the current environment:
# Check if credentials are set (print existence only, never echo values)
if [ -n "$LANGFUSE_PUBLIC_KEY" ] && [ -n "$LANGFUSE_SECRET_KEY" ]; then
echo "LANGFUSE_PUBLIC_KEY is set"
echo "LANGFUSE_SECRET_KEY is set"
else
echo "LANGFUSE_PUBLIC_KEY is ${LANGFUSE_PUBLIC_KEY:+set}${LANGFUSE_PUBLIC_KEY:-NOT SET}"
echo "LANGFUSE_SECRET_KEY is ${LANGFUSE_SECRET_KEY:+set}${LANGFUSE_SECRET_KEY:-NOT SET}"
fi
If either key is missing, stop and instruct the user:
One or more Langfuse credentials are missing from your environment.
Add the following to your shell profile (~/.zshrc or ~/.bashrc):
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
# Optional: set a custom Langfuse host (defaults to https://cloud.langfuse.com)
# export LANGFUSE_HOST="https://your-self-hosted-instance.example.com"
After adding them, run `source ~/.zshrc` (or restart your terminal) and invoke
/langfuse-setup again.
Do NOT proceed past this step until both keys are present.
echo "LANGFUSE_ENABLED=${LANGFUSE_ENABLED:-NOT SET}"
If LANGFUSE_ENABLED is not set or is not true, instruct the user:
To activate Langfuse tracing, add this to your shell profile (~/.zshrc or ~/.bashrc):
export LANGFUSE_ENABLED=true
Then run `source ~/.zshrc` (or restart your terminal).
If already set to true, confirm and continue.
Read the user's Claude Code settings file and merge the hook entries.
SETTINGS_FILE="$HOME/.claude/settings.json"
# Check if the file exists
if [ -f "$SETTINGS_FILE" ]; then
echo "Found settings file: $SETTINGS_FILE"
else
echo "No settings.json found -- will create one."
fi
Read the current contents of ~/.claude/settings.json (or start with {} if absent).
Merge the following hook entries into the hooks object, preserving any existing hooks:
{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "uv run ~/.claude/hooks/pre_tool_use.py"
}
]
}
],
"PostToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "uv run ~/.claude/hooks/post_tool_use.py"
}
]
}
]
}
}
Important merge rules:
hooks.PreToolUse or hooks.PostToolUse already contain entries, append the Langfuse
hook entry rather than replacing existing hooks.uv run ~/.claude/hooks/pre_tool_use.py or
uv run ~/.claude/hooks/post_tool_use.py) already exists, skip adding a duplicate.After writing, show the user the updated hooks section for confirmation.
# Check that the hook scripts are in place
for hook in pre_tool_use.py post_tool_use.py; do
if [ -f "$HOME/.claude/hooks/$hook" ]; then
echo "Found: ~/.claude/hooks/$hook"
else
echo "MISSING: ~/.claude/hooks/$hook"
fi
done
If any hook script is missing, warn the user:
The hook scripts referenced by settings.json are not yet installed.
Ensure the following files exist before Langfuse tracing will work:
~/.claude/hooks/pre_tool_use.py
~/.claude/hooks/post_tool_use.py
These are typically deployed by the toolkit bootstrap process. Run the toolkit
installer or copy them manually from the repository.
Run a quick Python snippet to verify the credentials can reach Langfuse:
uv run --with langfuse python3 -c "
from langfuse import Langfuse
import os, sys
try:
lf = Langfuse(
public_key=os.environ['LANGFUSE_PUBLIC_KEY'],
secret_key=os.environ['LANGFUSE_SECRET_KEY'],
host=os.environ.get('LANGFUSE_HOST', 'https://cloud.langfuse.com'),
)
lf.auth_check()
print('Connection successful -- Langfuse credentials are valid.')
except Exception as e:
print(f'Connection FAILED: {e}', file=sys.stderr)
sys.exit(1)
"
Present a final summary:
Langfuse Setup Complete
-----------------------
Credentials: OK
LANGFUSE_ENABLED: true
Hooks (PreToolUse): configured
Hooks (PostToolUse): configured
Hook scripts: present
Connection test: passed
Langfuse observability is now active. Tool calls in future Claude Code sessions
will be traced automatically.
To check status later: /langfuse-setup:status
To disable tracing: /langfuse-setup:disable
If any step failed, list the failures clearly and provide remediation instructions.
When invoked with :status, perform a read-only check of the current setup.
echo "LANGFUSE_ENABLED=${LANGFUSE_ENABLED:-NOT SET}"
echo "LANGFUSE_PUBLIC_KEY is ${LANGFUSE_PUBLIC_KEY:+set}${LANGFUSE_PUBLIC_KEY:-NOT SET}"
echo "LANGFUSE_SECRET_KEY is ${LANGFUSE_SECRET_KEY:+set}${LANGFUSE_SECRET_KEY:-NOT SET}"
echo "LANGFUSE_HOST=${LANGFUSE_HOST:-https://cloud.langfuse.com (default)}"
SETTINGS_FILE="$HOME/.claude/settings.json"
if [ -f "$SETTINGS_FILE" ]; then
# Look for Langfuse hook commands
grep -c "pre_tool_use.py" "$SETTINGS_FILE" && echo "PreToolUse hook: configured" || echo "PreToolUse hook: NOT configured"
grep -c "post_tool_use.py" "$SETTINGS_FILE" && echo "PostToolUse hook: configured" || echo "PostToolUse hook: NOT configured"
else
echo "settings.json: NOT FOUND"
fi
for hook in pre_tool_use.py post_tool_use.py; do
[ -f "$HOME/.claude/hooks/$hook" ] && echo "$hook: present" || echo "$hook: MISSING"
done
SESSION_DIR="$HOME/.claude/langfuse/sessions"
if [ -d "$SESSION_DIR" ]; then
LATEST=$(ls -t "$SESSION_DIR" 2>/dev/null | head -1)
if [ -n "$LATEST" ]; then
echo "Latest session file: $LATEST"
cat "$SESSION_DIR/$LATEST" 2>/dev/null
else
echo "No active session files found."
fi
else
echo "Session directory does not exist: $SESSION_DIR"
fi
Langfuse Status
---------------
LANGFUSE_ENABLED: true / false / not set
Credentials: set / missing
Host: https://cloud.langfuse.com
PreToolUse hook: configured / not configured
PostToolUse hook: configured / not configured
Hook scripts: present / missing
Active session: <trace ID> / none
When invoked with :disable, remove the Langfuse hook configuration.
Read ~/.claude/settings.json and remove only the Langfuse-specific hook entries:
hooks.PreToolUse whose command contains pre_tool_use.pyhooks.PostToolUse whose command contains post_tool_use.pyhooks object becomes empty, remove it entirelyShow the user the before/after diff of the hooks section.
Hooks have been removed from settings.json. Langfuse tracing is now disabled.
To also unset the environment variable, remove or comment out this line in your
shell profile (~/.zshrc or ~/.bashrc):
export LANGFUSE_ENABLED=true
Or set it to false:
export LANGFUSE_ENABLED=false
Note: Your LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY can remain in your
environment -- they are harmless without the hooks in place.
Langfuse Disabled
-----------------
PreToolUse hook: removed
PostToolUse hook: removed
LANGFUSE_ENABLED: user action needed (see above)
Credentials: left in place (harmless)
To re-enable later, run /langfuse-setup.
~/.claude/settings.json unless explicitly requested.documentation
Report reflect drain spend over a time window — tokens split by cached (cache_read), uncached writes (cache_creation), and io (input+output), with a $ estimate, grouped by day / outcome / model / transcript. Reads the drainer's cost log and surfaces outlier runs and cache-reuse health (the 41.5M-token failure mode = low cache reuse + high cache writes). Use to answer "what is reflection costing me" for the last day / week.
development
Show fleet status — every claude session running on the host, merged across ainb + claude-peers broker + background jobs. Use when you need to enumerate sessions before composing an action, see which sessions have a peer registered (broker-routable) vs tmux-only, check the `summary` of each session, or pipe the list into jq for filtering. Default output: text table. Pass --format json for LLM consumption.
testing
Ordered multi-step prompts to fleet targets, ack-gated between steps via JSONL assistant-turn-end detection. Use for cycles like disconnect→reconnect→verify, or any flow where step N+1 requires step N to have completed first. The skill BLOCKS until each target's transcript shows the next assistant turn finishing OR per-step timeout fires (default 300s).
development
Center control panel — enumerate every claude session that is blocked waiting on something: a user answer (AskUserQuestion fired), an API error retry, an idle assistant turn-end with no follow-up, or an explicit WAITING: marker. Returns rich JSON with signal kind + context per session. Use this when you've stepped away from the fleet and want one place to see everything that wants your attention and answer it.