Skip to main content
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. 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
ScopeSettings fileApplies to
user (default)~/.claude/settings.jsonAll projects
project.claude/settings.json in cwdThis 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 EventWhat’s Tracked
SessionStartSession metadata (model, working directory)
UserPromptSubmitUser’s prompt text (each turn is a separate event)
PreToolUseTool start timestamp (used to compute duration)
PostToolUseTool call span with name, input, output, and duration
PostToolUseFailureFailed tool call span with error details
InstructionsLoadedCLAUDE.md and rules file contents
SubagentStartSubagent spawn with type and ID
SubagentStopSubagent completion with duration and result
PermissionDeniedBlocked tool call with denial reason
PostCompactContext compaction trigger and summary
StopClaude’s response + token usage, model, tools from transcript + system prompt content
StopFailureResponse with error information
SessionEndSession 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:
PropertyDescription
ai.usage.prompt_tokensInput tokens for the current turn
ai.usage.completion_tokensOutput tokens for the current turn
ai.usage.cache_read_tokensPrompt cache hits for the current turn
ai.usage.session_total.*Cumulative token totals across the session
ai.modelModel used (e.g. claude-sonnet-4-6)
ai.service_tierAPI service tier
ai.stop_reasonWhy generation stopped (end_turn, tool_use, max_tokens)
ai.tools_usedUnique tools invoked (e.g. Bash, Read, Write)
ai.turn_countNumber of API turns in the session
ai.duration_msTurn duration reported by Claude Code
ai.has_thinkingWhether extended thinking was used
claude_code.versionClaude Code CLI version
git.branchCurrent git branch
system_instructionsContents of loaded CLAUDE.md and .claude/rules/*.md files
append_system_promptContent 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

VariableDescription
RAINDROP_WRITE_KEYAPI write key (overrides config file)
RAINDROP_USER_IDUser identifier (overrides config file, defaults to OS username)
RAINDROP_CONVO_IDOverride conversation ID (groups events across sessions)
RAINDROP_EVENT_NAMECustom event name (default: claude_code_session)
RAINDROP_PROPERTIESJSON object merged into every event’s properties
RAINDROP_ENABLEDSet to "false" or "0" to disable all telemetry
RAINDROP_API_URLCustom API endpoint
RAINDROP_LOCAL_DEBUGGERLocal debugger URL (auto-detected on :5899 if not set)
RAINDROP_DEBUGSet to "true" for verbose logging
RAINDROP_SELF_DIAGNOSTICSJSON 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

CategoryWhen to use
missing_contextCritical information, credentials, or access is missing
repeatedly_broken_toolA tool has failed persistently across retries
capability_gapThe task requires a tool or permission that doesn’t exist
complete_task_failureThe agent tried and failed to deliver the result
noteworthySomething unusual worth flagging for review

Verifying

claude mcp list
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

  1. Check your write key — run raindrop-claude-code setup again or verify ~/.config/raindrop/config.json
  2. Verify hooks are installed — run /hooks inside Claude Code to list active hooks
  3. Enable debug logging — run raindrop-claude-code debug-on and check /tmp/raindrop-hooks.log
  4. Check binary is in PATH — run which raindrop-claude-code
  5. 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.