The names below (
grain.query, grain.segment.compare, …) are the identifiers the LLM sees. You almost never type them yourself — the model picks the right tool from your natural‑language prompt.Discovery — mcp:read
Zero‑cost tools that describe what’s in the workspace. Agents typically call these first on an unfamiliar workspace.
grain.events.list
Lists distinct event names the workspace has ingested. Returns up to 100 names, alphabetical.
Maximum number of events to return. Range: 1–100.
grain.dimensions.discover
Samples recent events and returns the dimensions (properties) you can filter or group by, with cardinality hints and redacted sample values.
Narrow discovery to a specific event. Omit to sample across all events.
Window to sample from. Defaults to the last 7 days.
signup down by?”
grain.integration.status
Checks whether the Grain analytics tag is reporting correctly — useful before an investigation so you know the data itself is trustworthy.
Good prompt: “Is my tracking healthy?”
Query — mcp:query
The workhorses. These wrap Grain’s query engine with the same surprise‑detection layer Kai uses in the dashboard, so responses include structured hints (_surprises, _narrativeHints) about what’s concentrated, volatile, or shifting in rank.
grain.query
Breakdown or timeseries query with filters and grouping.
What to measure:
events, unique_visitors, unique_sessions, …Event to filter on, or
"" for all events.breakdown groups by dimension; timeseries trends over time.Dimensions to group by (breakdown mode). Use
[] for timeseries.Property filters. Supported operators:
eq, neq, gt, lt, gte, lte.{ last: '7d' } or { from: ISO, to: ISO }.Max rows for breakdown. 1–500.
grain.query.count
Total count of events matching filters over a window. Cheaper than grain.query when you don’t need rows.
Good prompt: “How many signups did I get this week?”
grain.query.compare
Runs the same query twice — current window and a previous window — and returns both plus a comparison with deltas and percent changes.
Current window.
Prior window to compare against. Often the preceding period of the same length.
grain.query.digest
Generates an end‑of‑period digest: top metrics, biggest movers, and anomalies. This is the tool behind the “daily briefing” pattern.
Good prompt: “Give me yesterday’s digest.”
Investigation — mcp:investigate
The heavy‑hitters. These power the kind of “why did X happen?” questions that normally take a human an hour of dashboard clicking.
grain.correlate_event
Given a target event, finds other events whose occurrence correlates with it above baseline. Great for “what did users do right before they converted” style questions.
Good prompt: “What events do users fire in the 10 minutes before purchase_completed?”
grain.track.analyze
Analyzes a Track — Grain’s two‑step funnel primitive (start_event → goal_event within a time window). Returns conversion rate, biggest drop‑off dimensions, and per‑segment breakdowns.
The event that starts the funnel.
The event that completes it.
How long the user has to complete. Default: 1 hour.
checkout_started finished with purchase_completed within 30 minutes last week? Where did they drop off?”
grain.segment.compare
Compares two cohorts (defined by filters) on a metric and surfaces the dimensions where they differ most.
Good prompt: “Compare users who converted vs users who bounced on the pricing page. What’s different about them?”
grain.sessions.cluster
Clusters sessions by behavioral signature. Returns representative sessions per cluster so an agent can summarize “users in cluster A hit the pricing page twice then left; cluster B…”.
Good prompt: “Cluster sessions from users who abandoned checkout yesterday.”
Shared shapes
All query‑family tools speak the same vocabulary.Filter
in and contains aren’t supported by the backend yet. If your agent hallucinates one, call grain.query will reject it with a clear error.TimeRange
Default event properties
Every event Grain ingests carries these properties automatically — filter or group by them without any setup:direct | organic | paid | social | email | referral.
Budgets and limits
Grain enforces a per‑request budget so a chatty agent can’t accidentally saturate your workspace:| Budget | Limit | What counts |
|---|---|---|
| Query calls | 16 per MCP request | grain.query, grain.query.count, investigation tools (grain.query.compare = 2) |
| Compute time | 20 s per MCP request | Wall‑clock for Next.js‑native analysis (not yet exposed over MCP) |
| Row cap | 500 | grain.query breakdown limit ceiling |
See also
Security & scopes
How scopes gate these tools.
Query API
The raw HTTP API these tools wrap.