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.
integer
default:"100"
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.
string
Narrow discovery to a specific event. Omit to sample across all events.
TimeRange
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.
enum
required
What to measure:
events, unique_visitors, unique_sessions, …string
required
Event to filter on, or
"" for all events.'breakdown' | 'timeseries'
required
breakdown groups by dimension; timeseries trends over time.string[]
Dimensions to group by (breakdown mode). Use
[] for timeseries.Filter[]
Property filters. Supported operators:
eq, neq, gt, lt, gte, lte.TimeRange
required
{ last: '7d' } or { from: ISO, to: ISO }.integer
default:"10"
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.
TimeRange
required
Current window.
TimeRange
required
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.
string
required
The event that starts the funnel.
string
required
The event that completes it.
integer
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:
If an agent hits the budget mid‑session, it receives a structured error and typically asks you to narrow the question.
See also
Security & scopes
How scopes gate these tools.
Query API
The raw HTTP API these tools wrap.