> ## Documentation Index
> Fetch the complete documentation index at: https://raindrop.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Overview

> Query your Raindrop data directly from your AI coding assistant.

Raindrop's MCP server puts your whole Raindrop org in your coding assistant: query events, signals, issues, conversations, and memory directly, or hand the investigation to **Raindrop Triage** (our expert investigator for AI applications) and go from "something looks off" to a code fix without leaving your editor.

The server is hosted at `https://mcp.raindrop.ai/mcp`. There's nothing to install: add the configuration to your editor and start asking.

## Connect your editor

**Claude Code**

Run this command in your project directory:

```bash theme={null}
claude mcp add raindrop --transport http https://mcp.raindrop.ai/mcp
```

Claude Code supports OAuth natively: it will open a browser window to authenticate on first use.

To use an API key instead:

```bash theme={null}
claude mcp add raindrop --transport http https://mcp.raindrop.ai/mcp --header "Authorization: Bearer YOUR_API_KEY"
```

**Codex**

Add the server, then authenticate with OAuth:

```bash theme={null}
codex mcp add raindrop --url https://mcp.raindrop.ai/mcp
codex mcp login raindrop
```

Codex [supports Streamable HTTP MCP servers and OAuth](https://developers.openai.com/codex/mcp). Current Codex versions discover Raindrop's OAuth resource automatically. Codex opens a browser window to authenticate, and the CLI and IDE extension share the same MCP configuration.

To use an API key instead, set `RAINDROP_API_KEY` in the environment used to launch Codex, then add the server:

```bash theme={null}
codex mcp add raindrop --url https://mcp.raindrop.ai/mcp --bearer-token-env-var RAINDROP_API_KEY
```

Codex stores the environment variable name, not the API key. For CLI use, configure the variable in your shell profile or secret manager. For the IDE extension, ensure your editor inherits it from its launch environment. Do not commit the key.

**Devin**

You must be an **Admin** of your Devin account to add a custom MCP server.

In Devin, go to **Settings → Connectors → MCP Marketplace → Add Custom MCP** and fill out the form:

| Field | Value |
| - | - |
| **Name** | `Raindrop` |
| **Description** | Raindrop is an observability platform for AI agents. |
| **Transport type** | `HTTP` |
| **Server URL** | `https://mcp.raindrop.ai/mcp` |
| **Authentication method** | `Authorization header` |
| **Authorization header** | `Authorization: Bearer YOUR_API_KEY` |

Devin requires an API key. Generate one at [app.raindrop.ai](https://app.raindrop.ai) under **Settings → API Keys → Create personal key**.

**Cursor**

Add to your Cursor MCP settings (`.cursor/mcp.json`):

```json theme={null}
{
  "mcpServers": {
    "raindrop": {
      "url": "https://mcp.raindrop.ai/mcp"
    }
  }
}
```

Cursor handles OAuth automatically. Restart Cursor to activate.

To use an API key instead, add a `headers` field:

```json theme={null}
{
  "mcpServers": {
    "raindrop": {
      "url": "https://mcp.raindrop.ai/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```

**VS Code**

Add to your VS Code settings (`.vscode/mcp.json`):

```json theme={null}
{
  "servers": {
    "raindrop": {
      "type": "http",
      "url": "https://mcp.raindrop.ai/mcp"
    }
  }
}
```

VS Code handles OAuth automatically.

To use an API key instead, add a `headers` field:

```json theme={null}
{
  "servers": {
    "raindrop": {
      "type": "http",
      "url": "https://mcp.raindrop.ai/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```

**Windsurf**

Add to your Windsurf MCP configuration (`~/.codeium/windsurf/mcp_config.json`):

```json theme={null}
{
  "mcpServers": {
    "raindrop": {
      "serverUrl": "https://mcp.raindrop.ai/mcp"
    }
  }
}
```

Windsurf handles OAuth automatically.

To use an API key instead, add a `headers` field:

```json theme={null}
{
  "mcpServers": {
    "raindrop": {
      "serverUrl": "https://mcp.raindrop.ai/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```

**Other**

Any MCP-compatible client can connect using:

* **Transport**: Streamable HTTP
* **URL**: `https://mcp.raindrop.ai/mcp`
* **Auth**: API key, or OAuth 2.1 for supported clients

If you're connecting a custom hosted client that uses its own HTTPS OAuth callback, [contact us](mailto:support@raindrop.ai) with the client name and exact callback URL so we can enable OAuth for it. Otherwise, use an API key as `Authorization: Bearer <key>`.

Consult your client's documentation for its MCP server configuration.

## Investigate with Raindrop Triage

The Raindrop agent continuously analyzes your traces, signals, and user feedback to surface broader distribution changes and one-off unique failure modes: not just metrics, but concrete findings with root-cause hypotheses and the events that demonstrate them.

Through the MCP server, your local coding agent can pull those investigations in and collaborate on the fix:

1. **Ask Raindrop what's wrong.** "Ask Raindrop agent what issues happened today" checks both Issue Detection reports for broader distribution changes and Stumbles for individual interactions where something bad happened.
2. **Drill in.** Your local agent pulls the full trace for any flagged event: prompts, tool calls, model outputs, timings, errors.
3. **Fix it in code.** With the investigation and trace in context, your local agent can locate the relevant prompt or handler in your repo and propose a patch. You stay in your editor the whole time.

Example session:

```
You:        Ask Raindrop agent what issues happened today.
Assistant:  Raindrop flagged 3 issues. The top one is "Tool calls failing
            with malformed JSON," 47 events, started ~9am.
You:        Pull the trace for one of those events and find the root cause.
Assistant:  The model is emitting trailing commas in the arguments object.
            It's our `search_orders` tool prompt, line 42 of tools/orders.ts.
            Want me to tighten the schema and add a repair step?
```

## Available tools

Triage is one way in. The MCP server also exposes your Raindrop data directly, so your local agent can query events, signals, issues, and more on its own, grouped below by what they do:

Events, issues, signals, Stumbles, and conversations read with `get_conversation` (including each turn) come back with a `url`: an absolute `https://app.raindrop.ai` link that opens the item for any signed-in member of your org. Your agent can paste it as-is into a ticket, a Linear comment, or a chat.

### Investigate

* `ask_agent_question`: ask Raindrop Triage to investigate and return findings with root-cause hypotheses
* `get_agent_progress`, `get_agent_conversation`, `list_agent_conversations`: poll or revisit a triage investigation

### Events and traces

* `list_events`, `get_event`: list or fetch a specific event
* `search_events`: find events matching a description, e.g. "users frustrated by load times"
* `get_event_count`, `get_event_timeseries`, `get_event_facets`, `get_error_span_facets`: counts, trends, and breakdowns
* `run_rql`: counts, `GROUP BY` breakdowns, trends, and comparisons over events, traces, users, and conversations with read-only RQL; see the [RQL guide](https://raindrop.ai/docs/mcp/rql.md)
* `query_cost`: LLM spend and token totals, breakdowns by model or provider, hourly/daily trends, and paginated recent events with spend. Pass explicit `from` and `to` ISO timestamps, up to 31 days (7 days for hourly trends), and a single `project`. Results report pricing coverage; unpriced model calls make totals incomplete. With `operation: "events"`, `event_filters` selects events by user, conversation, event name, model, properties, user traits, feature flags, or signals. For example, `event_filters: { convo_id: [{ $eq: "conversation-123" }] }` returns event costs within that conversation and the requested time window. Matching events from excluded users are omitted. Pass the same filters with `next_cursor` to continue; one page is not a cohort total. Event filters are unsupported for summary, breakdown, and timeseries.
* `get_trace`: full execution tree for an event: prompts, tool calls, timing, errors

### Conversations and stumbles

* `list_conversations`, `get_conversation`: browse a user's conversation history
* `search_stumbles`: one-off interactions where something went wrong

### Signals

* `list_signals`, `get_signal`, `list_signal_groups`, `get_signal_group`: list or inspect signals
* `get_application_overview`: activity overview of event trends, recent issues, top signals (renamed from `get_dashboard`)
* `get_dashboard`: saved dashboard definition, panel queries, visualizations, and revision
* `preview_dashboard_panel_query`: validate an exact panel query over a bounded preview window
* `create_dashboard`: save a new organization-shared dashboard
* `edit_dashboard`: save dashboard edits with revision checks

### Create a signal

* `create_signal`: create a signal in the background from an `intent` and a specific `project` (write)
* `get_signal_creation_status`: check creation once when asked, using the returned `session_id` and the same `project` (read)

Include `positive_event_ids` for events that should match and `negative_event_ids` for similar
non-matches when you have already inspected clear examples. Both lists are optional, default
to empty arrays, and accept up to 25 event IDs each. Examples must belong to the selected
project and be from the last 30 days; an event cannot appear in both lists. `org` is optional.

Use one RQL query to read up to 100 events from the selected project over the
last 24 hours. Use those events to understand the requested signal, clarify
scope, and create it.

Before creating, the MCP client should establish what counts, what is excluded,
and whether to judge the current turn or the conversation. Broad requests such as
"detect hallucinations" need one or two focused questions when boundaries remain
unclear; wait for the answers instead of choosing an unstated boundary. Preserve explicit scope rules and
exclusions; ask before changing them or adding an exception. Reuse information
already supplied.
For an ambiguous inspected example, ask:
"Should this event count because the user is still frustrated, or should it be excluded
because the assistant resolved the problem?" Include the clarified boundary in `intent`
and seed the inspected event as positive or negative according to the answer. Leave
uncertain examples unlabeled. A clear request needs no clarification or extra search.

Keep `intent` close to the user's detection goal, adding only scope clarifications
they supplied. Do not expand agent context or examples into extra rules, a case
list, or implementation instructions. Put inspected examples in the seed lists.

For example, call `create_signal` with:

```json theme={null}
{
  "project": "default",
  "intent": "Detect users who remain frustrated after the assistant attempts a resolution.",
  "positive_event_ids": ["frustrated-user-event-id"],
  "negative_event_ids": ["resolved-request-event-id"]
}
```

Use real event IDs from your investigation, or omit both lists to create from an idea alone.
Raindrop authors, tests, and installs the signal automatically. The response
includes `status: "creating"` and a `session_id`; acknowledge the start, retain the ID,
and return to the conversation. Do not wait, sleep, or poll.

When the user asks for an update, call `get_signal_creation_status` once with that ID
and the same project. Report `data.status` and `data.phase` and return. The phase
identifies preparation, scanning, review, installation, or a terminal state.
Scan totals apply to the current classifier revision and reset after refinement;
a zero total does not mean earlier revisions scanned no events.
`data.scan.scanned_total` counts events in completed batches, and
`data.scan.matched_total` counts confirmed examples. Optional `data.progress`
describes the current batch: its phase, activity note, scanned/total events, and
provisional matches. Those matches are not confirmed results, and the batch total
is not a completion percentage for creation. If it is `creating`, do not wait or
repeat the check. Only `created` confirms installation and includes `signal_id`. Report `failed` or `cancelled` without
automatically retrying creation. A `data: null` result means the session could not
be found in that project. Creation runs without an MCP review app or a follow-up close call.

### Refine an existing signal

* `refine_signal`: update an existing accepted, user-created JavaScript signal in the background (write)

Start from a signal investigation: inspect its matched events, identify false positives, then
use those event IDs as `negative_event_ids` when you want to change the signal. Add a `comment`
to explain the boundary. Positive examples are optional; include them when there is specific
behavior to preserve. You can also request refinement directly with examples or a clear comment.
Keep `comment` brief and close to the user's requested change. Add only scope clarifications
they supplied; do not expand it into a policy, case list, or implementation instructions.

For example, call `refine_signal` with:

```json theme={null}
{
  "signal_id": "22222222-2222-4222-8222-222222222222",
  "project": "default",
  "negative_event_ids": ["false-positive-event-id"],
  "comment": "Exclude routine bug fixes that have no production incident being investigated."
}
```

Use a real signal ID and event IDs from the same project. `signal_id` and a specific `project`
are required; `org` is optional. Both event-ID fields accept arrays of up to 500 IDs each.
Provide at least one event ID or a nonblank `comment` (up to 4,000 characters).

The call returns `{ "signal_id": "...", "status": "refining" }` when the background run starts.
It uses the same headless refinement flow as the Signals page and applies the resulting version
to the same signal automatically. Acknowledge that the update started; completion happens later.
There is no polling or `close_signal_session` step.

### Issues

* `list_issues`, `get_issue`: Issue Detection reports for broader distribution changes
* `update_issue`: resolve, ignore, reopen, or reprioritize an issue (write)
* `get_issue_events`, `get_issue_timeseries`: events behind an issue and its trend over time

### Memory

* `list_memories`, `create_memory`, `update_memory`, `delete_memory`: the customer-specific context Raindrop uses across product surfaces (write)

### Datasets

* `list_datasets`, `create_dataset`, `update_dataset`, `update_dataset_members`, `annotate_items`: curated collections of events (write)

### Experiments

* `create_experiment`: save a named comparison with cohort filters and an optional outcome rule (write).
* `get_experiment`: list saved experiments, or pass a name or ID to read results.

Choose which signals define success, separately from cohort filters. Experiments compare event
rates by default; use user rates when needed. Results use the same saved rule and verdict as
the experiment page.

See [Experiments](https://raindrop.ai/docs/platform/experiments.md) for more.

### Projects, users, and orgs

* `list_projects`, `list_organizations`: projects and orgs you have access to
* `list_users`, `get_user`: browse users
* `list_feature_flag_keys`, `list_feature_flag_values`: flags seen in your events
* `get_write_key`: fetch a project's write key

### Docs and feedback

* `search_docs`: search Raindrop's documentation
* `submit_feedback`: send feedback to the Raindrop team

### Meta

* `raindrop_skills`: load workflow guidance for a task (exploring data, writing RQL, delegating to Triage, or authoring a signal) before the first call in that workflow. Your agent calls this automatically; you don't need to invoke it yourself.

More prompts to try:

* "Show me an overview from Raindrop of what's happening in my app"
* "Find Raindrop events where users are getting bad responses"
* "How many Raindrop events matched the 'tool\_failure' signal this week?"
* "Create a signal in the Support project for users reporting they were charged twice."
* "These matches are false positives. Refine this signal to exclude routine bug fixes."
* "List Raindrop conversations for user \[ID]"
* "Show me what Raindrop remembers about this project"
* "Mark that Raindrop issue as resolved, I just deployed the fix"

> [!NOTE]
>
> Tools marked **(write)** above, plus creating a signal, are write actions. These are available to
> **API-key** callers and to **OAuth** clients that were granted the matching write scope
> (`write:issues`, `write:datasets`, `write:memories`, `write:signals`, or `write:experiments`). Read-only tools need no
> special scope. Creating and refining signals require `write:signals` for OAuth callers.
> API keys and OAuth users can create and edit organization-shared dashboards without a separate dashboard write scope.

## Project and org scope

Most tools take optional `org` and `project` arguments. Omit both and a call runs against your default org and [default project](https://raindrop.ai/docs/platform/projects.md). Pass an org from `list_organizations` if you belong to more than one, and a known project slug to target a specific project. Use `list_projects` to discover projects or verify the selection when needed.

Some read tools accept `project: "*"` to read across every active project in the org at once, each row still tagged with its owning project (see [The All projects view](https://raindrop.ai/docs/platform/projects.md#the-all-projects-view)). Tools that require a single project, like `get_trace`, reject `*` with a clear error. A few tools, like `get_agent_progress` and dataset tools, are org-scoped only and don't take a `project` argument at all.

## Authentication

**OAuth 2.1** is the default. Supported MCP clients handle it automatically: on first connection, your editor opens a browser window to authenticate. No tokens to manage.

**API key** is the alternative for clients that don't support OAuth, or for non-interactive environments (CI, shared setups). At [app.raindrop.ai](https://app.raindrop.ai), go to **Settings → API Keys → Create personal key** and pass the key as a Bearer token:

```
Authorization: Bearer <your-api-key>
```

A personal key belongs to you and follows your role. Owners and admins can also create org-wide keys there for CI and servers. When an owner or admin turns on **Limit to owners and admins** on the same page, the MCP accepts only owners' and admins' sign-ins and personal keys. Org-wide keys and members' keys get a 403, and the page stops creating them.

## Troubleshooting

**Tools not showing up in my editor**

Verify your MCP configuration is correct and restart your editor. Check that the server URL is exactly `https://mcp.raindrop.ai/mcp`. In Claude Code, run `claude mcp list` or `/mcp`. In Codex, run `codex mcp list`.

**Authentication failed**

If using OAuth, try disconnecting and re-authenticating: your editor will reopen the browser auth flow. If using an API key, check that the header format is exactly `Authorization: Bearer <token>` with no extra whitespace.

**Dynamic registration reports `invalid_redirect_uri`**

Raindrop only accepts OAuth callbacks configured for trusted MCP clients. [Email support](mailto:support@raindrop.ai) with the client name and exact redirect URI so we can enable OAuth for it. Otherwise, use an API key.

### Build dashboards directly

Load `raindrop_skills` with `topic: "dashboards"`. Use `list_dashboards` to find a dashboard and
`get_dashboard` to read its definition before editing. Preview exact panel queries with
`preview_dashboard_panel_query`, then save with `create_dashboard` or `edit_dashboard`.
Both write tools save immediately and support API keys and OAuth without a separate dashboard write scope.
API keys create organization-shared dashboards with no human owner and can edit shared dashboards.
Private dashboards remain accessible only to their signed-in owner.

Pass a concrete `project` on every authoring call. Previews use an explicit `time_range: {from, to}`
of at most seven days; raw-text filters require at most 24 hours. Saved panels receive their time
range from the dashboard, so omit `timestamp` and `end_timestamp` predicates from saved panel queries. Edits require `expected_revision` from the latest `get_dashboard` read.
On conflict, reload and rebuild the edit. The saved result includes the dashboard link.

Use the `set_filters` action in `edit_dashboard` to save dashboard-wide default filters.
Read `filters` from `get_dashboard` and supply the complete replacement list, preserving filters
you want to keep; `[]` clears them. Combine filter and panel actions to save both atomically.
Filter-only edits need no query preview. Previews do not apply dashboard filters. Named dashboard
snapshots apply saved filters and report unsupported kinds in each query's `skippedDashboardFilters`.

The former overview tool `get_dashboard` is now `get_application_overview`, with the same overview
inputs and output. Update existing callers and refresh cached tool inventories. `get_dashboard`
now requires a saved dashboard ID or name and a project. Hosted Triage remains available through
`ask_agent_question` when the user explicitly delegates work.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.