Skip to main content
Glama
petropentsak

play-store-mcp

by petropentsak
README.md
# play-store-mcp

Local stdio MCP server for **Google Play Console**. Credentials (a Google service-account
key) come only from environment variables; OAuth tokens are minted locally by
`google-auth-library`; every request goes directly to `*.googleapis.com`. Nothing is sent to
any third party.

TypeScript reimplementation — the Kotlin project [`antoniolg/play-store-mcp`](https://github.com/antoniolg/play-store-mcp)
was used only as a reference for the API flow and tool design.

## Available tools

23 tools, grouped by capability.

### Releases & rollout

| Tool | Description | Key inputs |
|------|-------------|------------|
| `get_releases` | Current releases/deployments per track | `packageName` |
| `deploy_app` | Upload an APK/AAB and assign it to a track (optional staged rollout) | `packageName`, `track`, `filePath`, `versionCode`, `releaseNotes?`, `rolloutPercentage?` |
| `promote_release` | Promote an existing version from one track to another | `packageName`, `fromTrack`, `toTrack`, `versionCode` |
| `update_track_rollout` | Change a staged-rollout fraction, or halt/complete the in-progress release | `packageName`, `track`, `userFraction?`, `status?` |
| `complete_all_rollouts` | Batch-complete the in-progress staged rollout across multiple apps | `packageNames[]`, `track?`, `versionCode?` |
| `update_release_notes` | Set release notes on the current release of a track (no redeploy) | `packageName`, `notes[]`, `track?` |

### Store listing

| Tool | Description | Key inputs |
|------|-------------|------------|
| `get_listings` | Store listing text (title, short/full description) for every locale | `packageName` |
| `update_listing` | Update a store listing for one locale and commit | `packageName`, `language`, `title?`, `shortDescription?`, `fullDescription?` |
| `get_app_details` | App-level details (default language, contact email/phone/website) | `packageName` |
| `upload_listing_image` | Upload a store-listing graphic (icon, screenshots, feature graphic, …) for a locale | `packageName`, `language`, `imageType`, `filePath` |

### Reviews

| Tool | Description | Key inputs |
|------|-------------|------------|
| `get_reviews` | Recent user reviews (rating, text, app version, device) | `packageName`, `maxResults?`, `translationLanguage?` |
| `reply_to_review` | Post a developer reply to a user review | `packageName`, `reviewId`, `replyText` |

### Monetization

| Tool | Description | Key inputs |
|------|-------------|------------|
| `list_in_app_products` | List managed in-app products (SKUs) | `packageName` |
| `list_subscriptions` | List subscription products | `packageName` |
| `update_in_app_product` | Update an existing managed IAP (status / default price) and commit | `packageName`, `sku`, `status?`, `defaultPrice?` |
| `get_voided_purchases` | List refunded/revoked (voided) purchases | `packageName` |
| `refund_order` | Refund a single order, optionally revoking the entitlement | `packageName`, `orderId`, `revoke?` |

### Testers

| Tool | Description | Key inputs |
|------|-------------|------------|
| `manage_testers` | Read (omit groups) or set the Google Groups of testers for a closed track | `packageName`, `track`, `googleGroups?` |

### Analytics & reports

| Tool | Description | Key inputs |
|------|-------------|------------|
| `get_users_by_version` | Distinct users per app version over N days (Reporting API) | `packageName`, `days?` |
| `get_app_vitals` | Latest crash rate and ANR rate (Reporting API) | `packageName`, `days?` |
| `get_install_stats` | Install base per app version + monthly net growth, from the statistics GCS reports | `packageName`, `month?` |
| `get_install_reports` | Raw install/uninstall report rows for one month and dimension, from the statistics GCS reports | `packageName`, `month`, `dimension?` |

### Meta

| Tool | Description | Key inputs |
|------|-------------|------------|
| `search_apps` | List the apps this service account can access (Reporting API) | — |

> `get_users_by_version` uses the Reporting API's vitals-scoped `distinctUsers` metric — a
> proxy for the active user base, ideal for the version-adoption split, **not** an exact
> install count (the Reporting API has no install-count metric; real install counts live in
> the statistics GCS reports, read by `get_install_stats` and `get_install_reports`).
>
> `get_install_reports` reads `stats/installs/installs_{package}_{YYYYMM}_{dimension}.csv`
> (`dimension` ∈ `overview` | `country` | `app_version`, default `overview`) from the reports
> bucket. These CSVs are UTF-16LE with a BOM; the server decodes and parses them. Set
> `PLAY_REPORTS_BUCKET` (Play Console → Download reports → Statistics → Copy Cloud Storage URI;
> the `pubsite_prod_*` value) and grant the service account Storage Object Viewer on it.

## Setup

1. **Google Cloud:** create a project, enable **Google Play Android Developer API** and
   **Google Play Developer Reporting API**, create a **service account**, and download its
   **JSON key**.
2. **Play Console → Users and permissions:** invite the service-account email; grant it the
   apps and the "View app information / bulk reports" + "Releases" permissions.
3. **Configure the MCP** (`~/.claude.json`):

```json
{
  "mcpServers": {
    "play-store": {
      "command": "npx",
      "args": ["-y", "github:petropentsak/play-store-mcp"],
      "env": {
        "PLAY_SERVICE_ACCOUNT_KEY_PATH": "/absolute/path/to/service-account-key.json",
        "PLAY_DEFAULT_TRACK": "internal"
      }
    }
  }
}
```

`PLAY_SERVICE_ACCOUNT_KEY` (raw or base64 JSON) is accepted as an alternative to the path.

## Build / release

`dist/` is committed so `npx github:` works with no build step. The config is **not** pinned to a
tag — it tracks the default-branch HEAD, so every commit must be installable (build + commit `dist/`).
To ship: `npm run build` → commit (incl. `dist/`) → push HEAD to the default branch → clear
`~/.npm/_npx` if a stale tarball is cached → reconnect / cold-start the MCP client.

Maintenance

ActivitySlowing
ResponsivenessNo issues