Skip to main content
Glama
inzention-team

indie-metrics-mcp

indie-metrics-mcp

Ask Claude how your apps are doing. This is a small MCP server that reads your own App Store Connect sales, RevenueCat subscribers and PostHog events, and answers with this week against last week. It runs on your machine with your keys.

Shipping an app and want the checklist? The App Store launch kit.

Tools

Tool

Answers

downloads(app?, days)

First-time downloads, last days against the days before (App Store Connect Sales and Trends)

proceeds(app?, days)

Developer proceeds by currency, same two windows

revenuecat_projects()

Your RevenueCat project ids

subscribers(project, days)

Active subscriptions, trials, MRR and 28-day revenue now; active subscriptions at the end of each window

events(project, names?, days)

PostHog event counts, same two windows (HogQL)

days is 1 to 30. Windows are whole days ending yesterday. Apple's report days are Pacific time; PostHog days are UTC. Apple posts a day's report the next day, so a missing day is listed under days_without_report.

Related MCP server: mcp-marketing-analytics

Set up

  1. Install Python 3.10 or newer.

  2. git clone this repository and cd into it.

  3. python3 -m venv .venv && .venv/bin/pip install .

  4. App Store Connect: in Users and Access, Integrations, create a key with the Sales role. Download the .p8 file and note the key id, the issuer id and your vendor number (Payments and Financial Reports).

  5. RevenueCat: create a v2 secret API key with read-only access to projects, customers and charts.

  6. PostHog: create a personal API key with read access to query. Note your numeric project id.

  7. Give the server your keys as environment variables or as macOS Keychain items (service indie-metrics.<NAME>; security add-generic-password -s indie-metrics.<NAME> -a "$USER" -w prompts for the value). Names: ASC_KEY_ID, ASC_ISSUER_ID, ASC_KEY_PATH (path to the .p8), ASC_VENDOR_NUMBER, REVENUECAT_API_KEY, POSTHOG_API_KEY, and optionally POSTHOG_HOST (default https://us.posthog.com; use https://eu.posthog.com for the EU cloud).

  8. Add it to Claude Code: claude mcp add indie-metrics -- /full/path/to/.venv/bin/indie-metrics-mcp. Any MCP client that starts a stdio server works the same way.

  9. Ask: "How many downloads did I get this week against last week?"

You only need the keys for the sources you use. A tool without its key says which setting is missing.

What this will not do

  • No writes. It only reads; it never changes an app, a price, a product or an event.

  • No hosted service, no account, no telemetry. It talks to Apple, RevenueCat and your PostHog host and nothing else.

  • No Google Play in this version.

  • No keys in this repository, and none printed in output or errors.

  • No guesses. When an API answers with an error the tool says so; it does not fill the gap.

Tests

pip install ".[test]" && pytest. The tests use recorded response shapes with invented ids and a throwaway signing key made at test time.

Licence

MIT. Dependency licences: LICENCES.md.

Available Tools

5 tools
downloadsA

First-time downloads from App Store Connect Sales and Trends: the last days whole days against the days before. app filters by title, SKU or Apple id (substring); leave it out for all apps. Days run 1 to 30.

NameRequiredDescriptionDefault
appNo
daysNo

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description does add real behavioral context: it discloses that the result is a period-over-period comparison (last N days vs. the N before), that it counts first-time rather than repeat downloads, and that `days` is capped at 1-30. It does not cover auth requirements, aggregation granularity, or what the response contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the metric and comparison logic front-loaded, followed by the filtering and range constraints. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema and no annotations, so the description is the only source of truth, yet it never says what the return looks like — per-day series vs. totals, per-app breakdown, or units. For a metric-reporting tool with zero structured support, that is a meaningful gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry the parameters, and it does: `app` is a substring match against title, SKU, or Apple id with null meaning all apps, and `days` is bounded to 1-30 whole days. Only the default value (7) is left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific metric ('first-time downloads') from a specific source ('App Store Connect Sales and Trends') and states the comparison window. An agent can distinguish it from proceeds/subscribers/events by the resource, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the `app` filter behavior ('leave it out for all apps') and the valid `days` range, which implies usage but never states when to pick this tool over `proceeds` or `subscribers`. Usage is inferable from the metric name rather than guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

eventsA

PostHog event counts: the last days whole days against the days before. project is the numeric PostHog project id; names limits it to those event names, otherwise the top 50 events.

NameRequiredDescriptionDefault
daysNo
namesNo
projectYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose two real behavioral traits: the comparison window ('`days` whole days against the `days` before') and the default enumeration behavior ('otherwise the top 50 events'). It stops short of stating read-only/safety profile, auth or project-access requirements, rate limits, or the shape of the returned comparison.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences, front-loaded with the operation and comparison window before parameter meanings. Every clause carries information; nothing is repeated from the schema or padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter read tool with no annotations and no output schema, the description covers parameter meaning, default behavior, and the comparison basis, which is nearly everything needed to call it correctly. The main gap is what the response actually contains (per-event current/prior counts, deltas, ordering), which the absence of an output schema leaves unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate and largely does: it defines `days` as the window width for both the current and prior period, `project` as the numeric PostHog project id, and `names` as a filter with top-50 fallback when null. The only friction is that `project` is typed as a string in the schema while described as numeric, a minor inconsistency.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description resolves an otherwise vague tool name ('events') into a specific operation: PostHog event counts over the last `days` whole days compared against the preceding `days` window. The resource and the comparison semantics are clear, and no sibling tool (downloads, proceeds, subscribers, revenuecat_projects) overlaps, so explicit differentiation isn't needed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the stated output (period-over-period event counts for a PostHog project), but there is no explicit when-to-use or when-not-to-use guidance, nor any mention of how it relates to the other analytics siblings. An agent can infer intent but is given no routing rules.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

proceedsA

Developer proceeds from App Store Connect Sales and Trends, by currency: the last days against the days before. app filters by title, SKU or Apple id (substring); leave it out for all apps. Days run 1 to 30.

NameRequiredDescriptionDefault
appNo
daysNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the behavioral burden. It does disclose the data source, currency dimension, and comparison semantics, plus the 1-30 day constraint — meaningful context. It omits whether this is a read-only report, what permissions/reporting access are needed, data freshness/lag, and whether proceeds are gross or net of Apple's cut.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, with the core comparison semantics front-loaded and parameter details following. The phrase 'the last `days` against the `days` before' is slightly compressed and requires a second read, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description should sketch the return shape; 'by currency' hints at grouping but doesn't say whether results are per-currency totals, per-app breakdowns, or deltas/percentages. For a zero-annotation, zero-output-schema tool, that leaves an agent guessing about what it will actually receive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it largely does: `app` is defined as a substring match on title, SKU, or Apple id with omit-for-all behavior, and `days` is bounded to 1-30. The only gap is that the default (7) is only visible in the schema and not reinforced, and the matching behavior for multi-app ambiguity isn't addressed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific metric (developer proceeds) from a specific source (App Store Connect Sales and Trends) with an explicit comparison window (last `days` vs. the `days` before). That distinguishes it from siblings like downloads, subscribers, and events, though the verb is implied rather than stated ('proceeds from...' rather than 'fetch/calculate proceeds').

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explains the optional `app` filter ('leave it out for all apps') and the day range, which is useful usage context. But there is no guidance on when to pick this over `downloads` or `subscribers`, nor any prerequisites (App Store Connect credentials, data lag) that would tell an agent whether it can call it now.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

revenuecat_projectsA

The RevenueCat projects this key can read (id and name). Use an id with subscribers.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does disclose that results are limited to what “this key can read,” which is useful permission-scope context. It implies a read-only operation and states returned fields, but it does not cover pagination, empty results, or explicit safety behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single compact sentence that front-loads the resource and its scope. Every clause contributes useful information: access scope, returned fields, and how to use the ID with another tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read tool with no output schema, the description gives the essential return fields (id and name), access scope, and a clear downstream use. It could be slightly more complete by mentioning ordering, pagination, or what happens when no projects are visible, but the core information is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. The description appropriately does not invent input semantics, and the empty schema already makes the parameter situation clear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies a specific resource, RevenueCat projects, and states the scope and return fields: projects this key can read with id and name. It also links the output to the `subscribers` sibling, though it does not explicitly use a verb like “list” or differentiate from all other siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase “Use an id with `subscribers`” gives downstream context, implying this tool supplies project IDs needed by the subscribers tool. However, it does not explicitly say when to call this tool versus alternatives or describe prerequisites beyond that implication.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

subscribersB

RevenueCat active subscriptions, trials, MRR and 28-day revenue now, plus active subscriptions at the end of this window against the end of the previous one. project is a RevenueCat project id.

NameRequiredDescriptionDefault
daysNo
projectYes

TDQS

B3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It describes the metric set and the current-vs-previous-window comparison, but never states that this is a read-only report, what the window length is, whether data is cached or rate-limited, or what the response looks like.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the metric inventory, and no filler. Dense but every clause carries information about what comes back.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema the description usefully enumerates return values, and it clarifies the one required parameter. However, the window parameter that determines the entire time scope is left undefined, which is a material gap for calling the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It explains `project` as a RevenueCat project id, but never mentions `days`, its unit, or its default of 7 — 'this window' is gestured at without tying it to the parameter that controls it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific metrics returned (active subscriptions, trials, MRR, 28-day revenue) plus the period-over-period comparison, so the resource and output are clear. The verb is implicit rather than stated ('returns/reports'), and it never names a sibling like `proceeds` to draw the boundary, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Listing the metrics implies when the tool is appropriate, but there is no explicit when-to-use, no exclusions, and no routing against `proceeds` or `events`, which overlap on revenue figures. The agent must infer the choice from the metric names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.1.0
    • First observeddownloads
    • First observedevents
    • First observedproceeds
    • First observedrevenuecat_projects
    • First observedsubscribers

TDQS

A3.5/5.0

Scored across 5 tools

Disambiguation4/5

Each tool maps to a distinct metric/data source: App Store downloads, App Store proceeds, RevenueCat subscriptions, RevenueCat project listing, and PostHog events. The only mild overlap is downloads vs proceeds, which share the same parameter shape and source, but the descriptions make the metric difference explicit. revenuecat_projects is clearly a helper for subscribers, which is stated in both descriptions.

Naming Consistency4/5

All names are lowercase snake_case nouns, which is consistent and readable. The minor deviation is that one tool carries a vendor prefix (revenuecat_projects) while the sibling RevenueCat tool (subscribers) and the other source-specific tools (downloads, proceeds, events) do not, so the source-to-name mapping is slightly uneven.

Tool Count5/5

Five tools is well-scoped for a compact cross-source metrics server: one per metric plus a project-discovery helper. No redundant or trivial tools, and each has a clear job.

Completeness3/5

Coverage spans three sources but is thin within each: App Store lacks ratings/reviews/refunds, RevenueCat lacks a revenue breakdown or churn detail beyond the summary, and PostHog has only event counts. A notable asymmetry is that RevenueCat has a project-discovery tool (revenuecat_projects) but PostHog's events requires a numeric project id with no tool to list PostHog projects, creating a dead end for agents that don't already know the id.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides statistical analysis and usage tracking for Claude Code, enabling users to query daily/monthly stats, compare users, analyze trends, detect anomalies, and generate usage reports through natural language.
    1
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables querying and analyzing marketing data from Google Analytics 4, Search Console, YouTube, and optionally Google Ads and Meta Ads, stored in a unified DuckDB database, via natural language in Claude.
    1
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    MCP server for Claude Desktop that exposes App Store Connect and RevenueCat APIs, enabling indie iOS developers to query portfolio metrics, sales reports, subscriptions, and customer reviews directly in chat.
    17
    MIT