MCP tools reference
Every tool the RevenueHog MCP server exposes, from rh_query and rh_meta to reviews, feedback, experiments, payouts and API keys, with arguments and outputs.
The RevenueHog MCP server registers eight tools. Each one is scoped to the workspace the credential belongs to, and each returns a single text block of JSON. On failure the block is {"error": "<message>"} and the result has isError: true.
| Tool | Kind | Purpose |
|---|---|---|
rh_query | Read | Compute metrics over a window, with optional breakdown, filters and comparison. |
rh_meta | Read | Metric catalog, formulas, and data freshness. |
rh_reviews | Read | Mirrored App Store reviews with a rating trend. |
rh_feedback | Read | In-app feedback with unread and per-kind counts. |
rh_experiment_results | Read | Paywall experiments and per-variant results. |
rh_payouts | Read | Apple payout periods and the next expected payment. |
rh_create_api_key | Write | Create a feedback API key. |
rh_list_api_keys | Read | List feedback API keys. |
rh_query
The main analytics tool. It crosses one or more measures with an optional dimension, over a window, narrowed by filters.
Arguments
Prop
Type
Windows
All windows are in UTC and end today (UTC midnight).
| Preset | Window |
|---|---|
7d, 30d, 90d | The trailing 7, 30 or 90 days |
mtd | First of the current month to today |
qtd | First day of the current quarter to today |
ytd | January 1 to today |
all | All time. days is null and no prior period exists. |
Returns
{
"window": { "from": "2026-09-28", "to": "2026-10-28", "days": 31 },
"compareTo": { "from": "2026-08-28", "to": "2026-09-27" },
"currency": "USD",
"measures": [{ "id": "proceeds", "label": "Proceeds", "unit": "usd" }],
"rows": [{ "app": "app_123", "proceeds": 1840.22, "proceeds_delta": 0.12 }],
"notes": ["Prior-period comparison is unavailable for an all-time window."]
}- Without a dimension,
rowshas one totals row. - With
date, each row hasdateplus one column per measure, sorted by date. - With a categorical dimension, each row has the dimension key (for
app, the RevenueHog app ID) plus one column per measure. <measure>_deltais a fraction (0.12 means up 12%). It isnullwhen either side is unknown or there is no positive baseline.notesappears only when there is something to say.
Measure catalog
| ID | Label | Unit | Dimensions | Date series |
|---|---|---|---|---|
proceeds | Proceeds | usd | app, country, product | Yes |
gross | Gross | usd | app, country, product | Yes |
units | Units | count | app, country, product | Yes |
refunds | Refunds | count | app, country, product | Yes |
mrr | MRR | usd | app | Yes |
arr | ARR | usd | app | No |
activeSubs | Active subscribers | count | app | Yes |
trials | Trials | count | app | Yes |
arpu | ARPU | usd | app | No |
arppu | ARPPU | usd | app | No |
newCustomers | New customers | count | app | Yes |
newMrr | New MRR | usd | app | No |
churnedMrr | Churned MRR | usd | app | No |
churnRate | Churn rate | pct | app | No |
renewalRate | Renewal rate | pct | app | No |
trialConversion | Trial conversion | pct | app | No |
impressions | Impressions | count | app | Yes |
pageViews | Page views | count | app | Yes |
downloads | Downloads | count | app | Yes |
redownloads | Redownloads | count | app | Yes |
sessions | Sessions | count | app | Yes |
deletions | Deletions | count | app | Yes |
crashes | Crashes | count | app | Yes |
avgRating | Average rating | stars | app | No |
adSpend | Ad spend | usd | app, campaign | Yes |
adImpressions | Ad impressions | count | app, campaign | No |
adTaps | Ad taps | count | app, campaign | No |
installs | Installs | count | app, campaign | Yes |
roas | ROAS | ratio | app, campaign | No |
cac | CAC | usd | app, campaign | No |
payback | Payback period | days | app, campaign | No |
Formulas for every measure are on Metric definitions, and rh_meta with topic glossary returns them at runtime.
Dimensions with no measures yet
The dimension list also accepts productType, subState, source, referrer, keyword, version and cohortMonth, but no measure currently supports grouping by them, so a query using one fails with "cannot be grouped by". Use rh_meta with topic schema for the live list.
Errors
| Message | Fix |
|---|---|
At least one measure is required. | Pass a non-empty measures array. |
Unknown measure "x". Valid measures: ... | Use an ID from the catalog. IDs are case-sensitive. |
Measure "x" does not support the "date" dimension (no time series). | Drop that measure from the series query, or remove the dimension. |
Measure "x" cannot be grouped by "y". Allowed dimensions: ... | Pick an allowed dimension, or split the query. |
Invalid from/to date range: from="..." to="..." | Use ISO dates. |
from (...) is after to (...). | Swap the dates. |
Unknown timeRange "x". Valid: 7d, 30d, 90d, mtd, qtd, ytd, all, or explicit from/to. | Use a preset. |
rh_meta
Discovery and reference for rh_query.
Prop
Type
| Topic | Returns |
|---|---|
schema | { measures: [{ id, label, unit, dimensions, supportsSeries }], dimensions: [{ id, label, description }] } |
glossary | { glossary: { <measureId>: "<one-line formula>" }, note }. Includes an LTV entry, which is a concept and not a queryable measure. |
freshness | { pipelines: { revenue, subscriptions, ads }, lastSync, note }. Each pipeline has source, lastData (newest data date held), rows and a coverage note. lastSync is { source, status, startedAt, finishedAt } or null. All timestamps are UTC. |
lastData is the newest day of data, which differs from when a sync last ran. Apple sales reports settle 1 to 3 days late, the subscription report lags 1 to 2 days, and Apple Ads about 1 day.
rh_reviews
Browse mirrored App Store customer reviews, newest first.
Prop
Type
Returns { reviews, nextCursor, trend }:
- Each review:
id,appId,rating,title,body,reviewerNickname,territory,createdDate,hasResponse,responseBody,responseState,responseIsAi,responseUpdatedAt. nextCursorisnullon the last page.trendis{ avg, count, byApp: { <appId>: { avg, count } } }.avgis count-weighted and rounded to one decimal, ornullwith no reviews. It respects theappfilter but not the other filters.
Error: No app found matching "x" in this workspace.
rh_feedback
Browse in-app feedback from the SDK, the feedback API, or manual entry, newest first.
Prop
Type
Returns { feedback, nextCursor, summary }:
- Each item:
id,kind,message,status,source,platform,rating,test,attested,unread,createdAt,appId,appName,appIconUrl,customer. customeris{ id, handle, attested, plan, ltvUsd }when the write identified one, otherwisenull.summaryis{ unread, total, byKind }, excluding test feedback, scoped only byapp.
Error: No app found matching "x" in this workspace.
rh_experiment_results
Paywall A/B experiments. Two modes, chosen by experimentId.
Prop
Type
List mode returns { mode: "list", filters, count, experiments }. Each experiment has id, appId, app, entitlement, name, status, effectiveStatus, durationDays, startedAt, endsAt, targetExposures, concludedVariant, createdAt, totalExposures and variants (key, isControl, weightPct, skus, assigned, exposed). Counts use production assignments only.
Results mode returns { mode: "results", experiment, results, analysis }:
resultsis the full computed result set used by the dashboard, including health and the sample ratio mismatch check.analysis.variantsgives, per variant:exposures,conversions(paid installs),conversionRatePct,paidRate(with Wilson 95% bounds),realizedPerExposureUsd,normalizedPerExposureUsd,relativeLift(fraction versus control),absoluteLiftPct(percentage points) andsignificantVsControl(true when the Wilson intervals do not overlap).analysisalso hascontrolKey,concludedWinner,leadingSignificantVariantandsrmFlagged.- An experiment that has not started returns
results: nulland the note "This experiment has not started, so there are no results yet."
| Error | Fix |
|---|---|
No app matches "x" in this workspace. | Check the app name or use its ID. |
"x" matches more than one app (...). Pass the app id. | Use the app ID. |
No experiment matches that id in this workspace. | List experiments first. |
That experiment does not belong to the app you named. | Remove app or fix it. |
rh_payouts
What Apple actually pays, from monthly financial reports.
Prop
Type
Returns { periods, nextExpectedPayment }, newest first. Each period has period, startsAt, endsAt, expectedPaymentAt, status, earnedUsd, units, byCurrency (currency, earned), byApp (appId, name, earnedUsd; app-less lines grouped as "Other"), estimatedUsd (Sales and Trends proceeds over the same dates) and variancePct. nextExpectedPayment is { period, status, expectedPaymentAt, amountUsd } for the soonest unpaid period, or null.
open periods are the ones Apple has not reported yet: the period accruing today, plus any of the last three closed periods still waiting on a financial report. They have earnedUsd: 0, empty byCurrency and byApp, and estimatedUsd set to the Sales and Trends proceeds accrued so far. When nextExpectedPayment points at an open period, its amountUsd is that running estimate.
rh_create_api_key
Create a server-to-server feedback API key and return its secret once. Apps using the RevenueHog SDK do not need one.
Prop
Type
Returns { record, secret, warning }. secret is the full key and is never retrievable again. record is the saved summary (see below). Revoke keys in the dashboard under Settings → Connections → API KEYS; the MCP server cannot revoke.
rh_list_api_keys
No arguments. Returns { keys }, newest first, never including secrets. Each key has id, name, prefix, mode, appId (null for workspace-wide), scopes, lastUsedAt, revokedAt and createdAt. Revoked keys are included; a non-null revokedAt means the key no longer works.
Related
Last updated on
Connect an MCP client
Add the RevenueHog MCP server to claude.ai, Claude Desktop, Claude Code, Cursor, VS Code, Codex or any other MCP client, and then verify that it works.
Query recipes
Ready-made rh_query, rh_reviews, rh_feedback, rh_experiment_results and rh_payouts calls that answer common revenue, churn, ads, review and payout questions.