@raindrop-ai/claude-code
v0.0.21
Published
Raindrop observability for Claude Code CLI — automatic session, tool call, and prompt tracing via hooks
Readme
@raindrop-ai/claude-code
Raindrop observability for Claude Code CLI. Automatic session, tool call, and prompt tracing via Claude Code's native hooks system.
Install
npm install -g @raindrop-ai/claude-codeSetup
raindrop-claude-code setupThis saves your write key and configures Claude Code hooks. Every session will now send telemetry to your Raindrop dashboard.
Hooks are synchronous by default for headless/one-shot compatibility (claude -p). Use --async if you prefer non-blocking hooks in interactive mode.
What gets tracked
- Every prompt turn as a separate event, grouped by session
- Tool calls with inputs, outputs, and real durations
- Token usage per turn and per session (input, output, cache read, cache creation)
- Model name, service tier, and stop reason
- CLAUDE.md and rules file contents
--append-system-prompt/--append-system-prompt-filecontent (best-effort)- Subagent spawns and completions
- Permission denials and context compaction
- Self-diagnostics — agent-reported issues via MCP tool, with customizable signal categories
- Nested trace view (tools under root, subagent tools under subagent)
- Claude's responses and errors
Custom Properties
Tag events with product names or custom metadata via .claude/settings.json:
{
"env": {
"RAINDROP_EVENT_NAME": "design-agent",
"RAINDROP_PROPERTIES": "{\"product\":\"design\",\"team\":\"ai\"}"
}
}Tool catalog capture (ai.prompt.tools)
Claude Code hooks and transcripts never expose the request Claude Code sends to the model, so this
integration cannot observe the tool catalog and records nothing by default (the attribute stays
absent, meaning "unknown"). Supply the catalog yourself with tools — an array of tool
declarations in any shape @raindrop-ai/core recognizes ({ name, description?, parameters },
{ type: "function", name, inputSchema }, OpenAI/Anthropic wrappers, ...):
{
"tools": [
{ "name": "read_file", "description": "Read a file", "parameters": { "type": "object", "properties": { "path": { "type": "string" } }, "required": ["path"] } }
]
}Set it in ~/.config/raindrop/config.json (tools) or as JSON in the RAINDROP_TOOLS environment
variable (the variable wins). The override is recorded verbatim as ai.prompt.tools on every LLM
span reconstructed from the transcript (gen_ai.response.model spans), never on tool-call,
subagent, or permission spans, and tools: [] records an explicitly empty catalog. Nothing is
inferred from hook payloads: implicit capture is not possible here.
Custom Self-Diagnostics Signals
Replace the built-in signal categories with your own via ~/.config/raindrop/config.json:
{
"self_diagnostics": {
"signals": {
"billing_complaint": { "description": "User billing issue.", "sentiment": "NEGATIVE" },
"feature_request": { "description": "User wants a feature.", "sentiment": "POSITIVE" }
},
"guidance": "Only report billing if explicitly mentioned."
}
}Or via env var: RAINDROP_SELF_DIAGNOSTICS='{"signals":{...}}'
Projects
If your org has multiple projects, route telemetry to a specific one by setting its slug via the RAINDROP_PROJECT_ID env var or the project_id key in ~/.config/raindrop/config.json:
{
"project_id": "support-prod"
}This sets the X-Raindrop-Project-Id header on every outbound request. Leave it unset (or use "default") to use your org's default Production project — the existing behavior. Single-project orgs need nothing new.
Payload size limits & bounded hooks
Event input/output are capped at 1,000,000 characters per field (span
attributes at 32 KB) and truncated with a ...[truncated by raindrop] marker,
enforced before serialization so multi-MB prompts or tool results cost the cap
— not the payload — inside the hook process. Each hook invocation also runs
under a hard overall deadline (8s by default, covering the stdin read,
mapping, and network flush; RAINDROP_HOOK_FLUSH_DEADLINE_MS to override)
and exits explicitly, so a dead or slow network can never stall Claude Code's
hook machinery.
Debugging
raindrop-claude-code debug-on # logs hook output to /tmp/raindrop-hooks.log
raindrop-claude-code debug-off # disables loggingDocs
Full documentation: docs.raindrop.ai/sdk/claude-code
Application Git identity
Claude Code does not infer the agent-under-test revision from the edited workspace or ambient deploy/CI metadata in the hook process. By default the new canonical application revision is unknown. Configure it under app_git in ~/.config/raindrop/config.json, using commit_sha, commit_dirty, and ordinary branch, set RAINDROP_COMMIT_SHA / RAINDROP_COMMIT_DIRTY / RAINDROP_BRANCH, or set an explicit source_directory (or RAINDROP_GIT_SOURCE_DIRECTORY) that identifies the agent-under-test checkout. Set app_git to false to opt out. Automatic canonical branch discovery is off unless detect_branch is true, and the legacy git.branch workspace metadata remains unchanged.
