The @raindrop-ai/claude-code package instruments
Claude Code CLI using its native
hooks system. No wrapper or proxy
needed — your workflow stays exactly the same.
What gets tracked:
- Every prompt turn as a separate event, grouped by session
- Tool calls (Bash, Edit, Write, Read, etc.) with inputs, outputs, and real durations
- Token usage per turn and per session (input, output, cache read, cache creation)
- Model name and service tier
- CLAUDE.md and rules file contents (captured via
InstructionsLoaded)
--append-system-prompt and --append-system-prompt-file content (best-effort)
- Self-diagnostics — agent-reported issues (capability gaps, broken tools, etc.) via MCP tool, with custom signal categories
- Subagent spawns and completions with duration
- Permission denials (tool calls blocked by auto-mode)
- Context compaction events
- Claude’s final responses
- Errors and failures
- Nested trace view — tool calls appear under the root span, subagent tools nest under the subagent
Installation
There are two ways to install: as a Claude Code plugin (recommended) or via npm.
Option A: Plugin (recommended)
Install as a Claude Code plugin for clean enable/disable/uninstall without modifying settings.json:
claude plugin marketplace add raindrop-ai/claude-code-plugin
claude plugin install raindrop
Set your write key via environment variable — no setup command needed:
export RAINDROP_WRITE_KEY=your-write-key
Or add it to your project’s .claude/settings.json:
{
"env": {
"RAINDROP_WRITE_KEY": "your-write-key"
}
}
To disable, enable, or uninstall:
claude plugin disable raindrop # stop sending events
claude plugin enable raindrop # resume sending events
claude plugin uninstall raindrop # remove completely
Option B: npm + setup
Install the package globally and run the setup command:
npm install -g @raindrop-ai/claude-code
raindrop-claude-code setup --write-key=YOUR_KEY --user-id=your-username
This saves your write key to ~/.config/raindrop/config.json and adds hook entries to ~/.claude/settings.json.
Per-Project Setup
By default, hooks are installed globally (~/.claude/settings.json). To scope hooks to a single project instead, use --scope=project — this writes to .claude/settings.json in the current directory:
raindrop-claude-code setup --scope=project
| Scope | Settings file | Applies to |
|---|
user (default) | ~/.claude/settings.json | All projects |
project | .claude/settings.json in cwd | This project only |
The setup merges hooks into your existing settings file — it won’t overwrite your other hooks or settings.
That’s it. Start a Claude Code session and events will appear in your Raindrop dashboard.
How It Works
Claude Code’s hooks system fires shell commands
at lifecycle points (session start, prompt submit, tool use, etc.). The setup command registers
raindrop-claude-code hook as a synchronous command hook for each event type.
When a hook fires, Claude Code pipes a JSON payload to stdin. The handler parses it, maps it to
Raindrop’s event and trace format, and POSTs to the Raindrop API.
Hooks are synchronous by default so they complete before Claude Code exits — this is essential for
headless/one-shot usage (claude -p). For interactive use cases where you prefer non-blocking hooks,
pass --async during setup:
raindrop-claude-code setup --async
Claude Code CLI
→ fires hook (e.g. PostToolUse)
→ pipes JSON to raindrop-claude-code hook
→ maps to Raindrop event/trace format
→ POST to api.raindrop.ai
Events Captured
| Claude Code Event | What’s Tracked |
|---|
SessionStart | Session metadata (model, working directory) |
UserPromptSubmit | User’s prompt text (each turn is a separate event) |
PreToolUse | Tool start timestamp (used to compute duration) |
PostToolUse | Tool call span with name, input, output, and duration |
PostToolUseFailure | Failed tool call span with error details |
InstructionsLoaded | CLAUDE.md and rules file contents |
SubagentStart | Subagent spawn with type and ID |
SubagentStop | Subagent completion with duration and result |
PermissionDenied | Blocked tool call with denial reason |
PostCompact | Context compaction trigger and summary |
Stop | Claude’s response + token usage, model, tools from transcript + system prompt content |
StopFailure | Response with error information |
SessionEnd | Session end reason |
All events within a session share the same convoId (derived from Claude Code’s session_id),
so they appear grouped in the Raindrop dashboard.
Some events (InstructionsLoaded, StopFailure, PostCompact, PermissionDenied) require a minimum Claude Code version. Setup auto-detects your installed version and only registers supported hooks.
Enriched Properties at Stop
When a turn completes (Stop or StopFailure), the transcript JSONL file is parsed to extract data that hooks alone can’t provide:
| Property | Description |
|---|
ai.usage.prompt_tokens | Input tokens for the current turn |
ai.usage.completion_tokens | Output tokens for the current turn |
ai.usage.cache_read_tokens | Prompt cache hits for the current turn |
ai.usage.session_total.* | Cumulative token totals across the session |
ai.model | Model used (e.g. claude-sonnet-4-6) |
ai.service_tier | API service tier |
ai.stop_reason | Why generation stopped (end_turn, tool_use, max_tokens) |
ai.tools_used | Unique tools invoked (e.g. Bash, Read, Write) |
ai.turn_count | Number of API turns in the session |
ai.duration_ms | Turn duration reported by Claude Code |
ai.has_thinking | Whether extended thinking was used |
claude_code.version | Claude Code CLI version |
git.branch | Current git branch |
system_instructions | Contents of loaded CLAUDE.md and .claude/rules/*.md files |
append_system_prompt | Content from --append-system-prompt / --append-system-prompt-file flags |
A dedicated LLM span with gen_ai.* attributes is also created for backend token accounting.
append_system_prompt is captured best-effort by inspecting the parent process’s command-line arguments. On Linux this is exact; on macOS positional args may be appended. If you use --append-system-prompt-file, the file contents are read directly.
Configuration
Environment Variables
| Variable | Description |
|---|
RAINDROP_WRITE_KEY | API write key (overrides config file) |
RAINDROP_USER_ID | User identifier (overrides config file, defaults to OS username) |
RAINDROP_CONVO_ID | Override conversation ID (groups events across sessions) |
RAINDROP_EVENT_NAME | Custom event name (default: claude_code_session) |
RAINDROP_PROPERTIES | JSON object merged into every event’s properties |
RAINDROP_ENABLED | Set to "false" or "0" to disable all telemetry |
RAINDROP_API_URL | Custom API endpoint |
RAINDROP_LOCAL_DEBUGGER | Local debugger URL (auto-detected on :5899 if not set) |
RAINDROP_DEBUG | Set to "true" for verbose logging |
RAINDROP_SELF_DIAGNOSTICS | JSON object to customize self-diagnostics signal categories |
Custom Properties
To tag events with a product name, team, or any custom metadata, set RAINDROP_PROPERTIES as a JSON object:
RAINDROP_EVENT_NAME=design-agent RAINDROP_PROPERTIES='{"product":"design","team":"ai"}' claude "do something"
For per-project tagging, add these to each project’s .claude/settings.json:
{
"env": {
"RAINDROP_EVENT_NAME": "design-agent",
"RAINDROP_PROPERTIES": "{\"product\":\"design\",\"team\":\"ai\"}"
}
}
Config File
The setup command creates ~/.config/raindrop/config.json:
{
"write_key": "your-write-key",
"user_id": "your-username"
}
You can also set event_name and custom_properties in this file:
{
"write_key": "your-write-key",
"user_id": "your-username",
"event_name": "my-agent",
"custom_properties": { "product": "my-product" }
}
Precedence (low to high): config file → environment variables.
Custom Self-Diagnostics Signals
By default, the self-diagnostics MCP server exposes 5 signal categories (missing_context, repeatedly_broken_tool, capability_gap, complete_task_failure, noteworthy). You can replace these with your own domain-specific categories.
In the config file:
{
"write_key": "your-write-key",
"self_diagnostics": {
"signals": {
"billing_complaint": {
"description": "User is upset about unexpected charges or billing errors.",
"sentiment": "NEGATIVE"
},
"feature_request": {
"description": "User requesting a feature that does not exist.",
"sentiment": "POSITIVE"
}
},
"guidance": "Only report billing issues if the user explicitly mentions charges.",
"toolName": "__my_report"
}
}
Or via environment variable:
RAINDROP_SELF_DIAGNOSTICS='{"signals":{"billing_complaint":{"description":"Billing issue","sentiment":"NEGATIVE"}}}' claude "do something"
Custom signals replace the built-in defaults entirely. The noteworthy catch-all is always appended automatically. sentiment is optional ("POSITIVE" or "NEGATIVE"). guidance adds additional instructions to the tool description. toolName overrides the default tool name (__raindrop_report).
Self Diagnostics
Self Diagnostics lets your agent proactively report issues — capability gaps, missing context, broken tools, task failures — back to your team as signals in Raindrop.
It’s delivered as an MCP server that’s registered automatically during setup. Claude Code can call the __raindrop_report tool to flag issues, and each signal is attached to the current event in your dashboard.
How it works
The setup command registers a raindrop-diagnostics MCP server with Claude Code. When Claude detects an issue during a session, it calls the tool with a category and detail. The signal appears on the corresponding event in Raindrop’s Signals dashboard.
Categories
| Category | When to use |
|---|
missing_context | Critical information, credentials, or access is missing |
repeatedly_broken_tool | A tool has failed persistently across retries |
capability_gap | The task requires a tool or permission that doesn’t exist |
complete_task_failure | The agent tried and failed to deliver the result |
noteworthy | Something unusual worth flagging for review |
Verifying
You should see raindrop-diagnostics in the list. Signals appear in the Raindrop dashboard under the event they’re attached to.
Uninstalling
Plugin users:
claude plugin uninstall raindrop
npm users:
raindrop-claude-code uninstall # removes hooks from settings.json + MCP server
npm uninstall -g @raindrop-ai/claude-code
Debugging
To see exactly what each hook sends, enable debug logging:
raindrop-claude-code debug-on
This pipes hook output to /tmp/raindrop-hooks.log. Run a Claude Code session, then inspect the log:
cat /tmp/raindrop-hooks.log
To disable:
raindrop-claude-code debug-off
Troubleshooting
Events not appearing
- Check your write key — run
raindrop-claude-code setup again or verify ~/.config/raindrop/config.json
- Verify hooks are installed — run
/hooks inside Claude Code to list active hooks
- Enable debug logging — run
raindrop-claude-code debug-on and check /tmp/raindrop-hooks.log
- Check binary is in PATH — run
which raindrop-claude-code
- Headless mode — re-run
raindrop-claude-code setup to ensure hooks are sync (the default since v0.0.7)
Hook errors
Hook errors are logged to /tmp/raindrop-hooks.log when debug is enabled. Run:
raindrop-claude-code debug-on
claude -p "test"
cat /tmp/raindrop-hooks.log
That’s it! Ping us on Slack or email us if you need help.