MCP server
The RevenueHog MCP endpoint, its transport, the three ways to authenticate (OAuth, MCP tokens, sessions), token lifetimes, scoping rules and error responses.
The RevenueHog MCP server answers questions about one workspace's revenue, subscriptions, store analytics, ads, reviews, feedback, experiments and payouts. It speaks the Model Context Protocol over streamable HTTP.
Endpoint
| Property | Value |
|---|---|
| URL | https://revenuehog.dev/api/mcp |
| Transport | Streamable HTTP, stateless JSON mode (no session ID, no SSE stream) |
| Methods | POST for MCP messages. GET returns 405 with the message "Only POST requests are accepted for MCP." OPTIONS answers CORS preflight. |
| Server name | revenuehog |
| CORS | Any origin. Allowed headers: Authorization, Content-Type, mcp-protocol-version. WWW-Authenticate is exposed so browser clients can read the OAuth pointer. |
Each request builds a fresh server bound to the caller's workspace, so no server state is shared between workspaces or requests.
Authentication
Every POST must carry a credential. The server accepts three kinds and routes a bearer token by its prefix.
| Credential | Shape | Best for | How to get it |
|---|---|---|---|
| OAuth access token | mcp_at_... | claude.ai, Claude Desktop, Cursor, VS Code, any client with remote-connector OAuth | The client runs the OAuth flow when you add the server |
| MCP token (personal access token) | rh_mcp_... | Claude Code, Codex, CI, scripts, any headless client | Dashboard, Settings → MCP, Create token |
| Dashboard session | Session cookie or session bearer token | The RevenueHog mobile app and the terminal device-flow login used by the experiments skill | Signing in |
Send a token as a header:
Authorization: Bearer rh_mcp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxA token with the rh_mcp_ or mcp_at_ prefix is checked only as that kind. An invalid MCP token fails; it is never retried as a session.
Unauthenticated requests
A request without a valid credential gets HTTP 401 and a JSON-RPC error:
{ "jsonrpc": "2.0", "error": { "code": -32001, "message": "Unauthorized" }, "id": null }The response carries WWW-Authenticate: Bearer resource_metadata="https://app.revenuehog.dev/.well-known/oauth-protected-resource/api/mcp". OAuth-capable clients follow that pointer and start the sign-in flow on their own.
OAuth 2.1
RevenueHog runs a small OAuth 2.1 authorization server for MCP clients.
| Endpoint | Purpose |
|---|---|
/.well-known/oauth-protected-resource/api/mcp | Protected resource metadata for the MCP endpoint. Resource .../api/mcp, scope mcp, bearer in header. The root /.well-known/oauth-protected-resource names the bare origin, per RFC 9728. |
/.well-known/oauth-authorization-server | Authorization server metadata. |
/oauth/register | Dynamic client registration (RFC 7591). Open: any client may register. |
/oauth/authorize | Approval page for a signed-in RevenueHog user. |
/oauth/token | Exchanges a code, or a refresh token, for tokens. |
Supported options:
- Response type
code, grant typesauthorization_codeandrefresh_token. - PKCE is required, method
S256only. - Token endpoint auth method
none(public clients). redirect_urimust be anhttporhttpsURL.
The approval page
When you add the server to an OAuth client, your browser opens Connect an MCP client on RevenueHog. If you are not signed in, you are sent to the login page first and returned afterwards. The page names the workspace and says the client will "Read your revenue, subscriptions, reviews, experiments, and payouts, and create feedback API keys for this workspace. It cannot see other workspaces." It shows the email you are signed in as. Select Approve and connect to finish.
The connection is bound to the workspace that is active in your session at that moment.
Token lifetimes
| Token | Prefix | Lifetime |
|---|---|---|
| Authorization code | mcp_code_ | 5 minutes |
| Access token | mcp_at_ | 7 days |
| Refresh token | mcp_rt_ | 90 days. Each refresh returns a new access token and a new refresh token. |
Each OAuth connection is recorded when the client first exchanges its code. It appears in Settings → MCP tokens with an OAUTH tag, labelled with the client's host (for example OAuth: claude.ai). Every access token and refresh token names its connection, and RevenueHog checks it on each request:
- Revoke the connection in Settings and the client is cut off on its next request. Its refresh token stops working too, so it cannot mint new tokens.
- If the person who approved the connection is removed from the workspace, the connection stops working.
- If that person deletes their account, the connection is deleted with it.
Owners and admins can revoke any connection. A member can revoke only a connection they approved.
Reconnect after this change
Tokens issued before connections were recorded (before October 2026) carry no connection and are refused. The client sees invalid_grant on its next refresh and runs the OAuth flow again.
OAuth errors
| Error | Description | Fix |
|---|---|---|
invalid_request | response_type must be "code", redirect_uri must be an http(s) URL, code_challenge is required (PKCE), Only the S256 code_challenge_method is supported, or Expected a form-encoded request body. | A client configuration problem. Update the client, or use an MCP token instead. |
invalid_grant | Unrecognized authorization code., The authorization code is invalid or expired., PKCE verification failed., redirect_uri does not match the authorization request., Unrecognized refresh token., This connection was revoked. Connect again., The refresh token is invalid or expired. | Remove and re-add the connector to start a fresh flow. Codes last 5 minutes. |
unsupported_grant_type | Unsupported grant_type "..." | The client must use authorization_code or refresh_token. |
MCP tokens
MCP tokens are personal access tokens for clients that cannot run OAuth.
Open Settings → MCP
In the dashboard, open Settings and select the MCP tab. If the tab is not shown, go to /settings/mcp directly.
Name the token
Type a label in Token label, e.g. Claude desktop (up to 80 characters) and select Create token.
Copy the secret
A Copy your token now box shows the secret once. Select Copy and store it. "This is the only time the secret is shown." RevenueHog keeps only a SHA-256 hash.
The list shows each token's label, creation date, and either used with a relative time or never used. The card header counts tokens ("None yet" or "N active"). Select Revoke to delete a token; it stops working on the next request. used reflects the last time RevenueHog looked the token up in its database. Lookups are cached for up to 12 hours (revoking clears the cache at once), so an active token can show a use time up to 12 hours old.
Facts about MCP tokens:
- A token belongs to the workspace, not to the person who created it. It keeps working if its creator leaves the workspace. Revoke tokens you no longer need.
- Only workspace owners and admins can create MCP tokens or revoke them. Members see the list, and the create form is replaced by "Only workspace owners and admins can create tokens." The API answers
403withOnly workspace owners and admins can manage tokens and API keys. - The secret is
rh_mcp_followed by 32 URL-safe characters. - Last used is updated on a best-effort basis on each request.
- The settings list shows up to 200 tokens.
Token management API
The card calls /api/settings/mcp-tokens, which also accepts a session bearer token.
| Method | Body | Response | Errors |
|---|---|---|---|
GET | none | { "tokens": [{ "id", "label", "createdAt", "lastUsedAt" }] } | 401 |
POST | { "label": "CI" } | { "token": "rh_mcp_...", "summary": { ... } } | 400 invalid JSON, 400 missing label, 400 label too long, 401 |
DELETE | { "id": "..." } | { "ok": true } | 400 missing id, 404 not found, 401 |
Scoping and safety
- Every tool reads only the workspace the credential is bound to. A tool given an ID from another workspace answers "not found".
- To query a different workspace, connect again while that workspace is active, or create an MCP token while in it.
- Analytics tools are read-only. The only write is
rh_create_api_key, which creates a feedback API key in the same workspace. - All money values are USD.
Tool results and errors
Every tool returns one text content block containing pretty-printed JSON. A failed call returns {"error": "<message>"} with isError: true, for example Unknown measure "mmr". Valid measures: .... See MCP tools for each tool's messages.
Test with curl
curl -s https://revenuehog.dev/api/mcp \
-H "Authorization: Bearer $REVENUEHOG_MCP_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'curl -s https://revenuehog.dev/api/mcp \
-H "Authorization: Bearer $REVENUEHOG_MCP_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"rh_meta","arguments":{"topic":"freshness"}}}'Related
Last updated on
AI and MCP
Ask Claude, Cursor or any MCP client about your revenue, subscriptions, reviews, feedback and payouts through the RevenueHog MCP server and Claude skills.
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.