app-console-mcp
by Alekla0126
README.md
# app-console-mcp
**Google Play Console, App Store Connect and AdMob from your terminal or from Claude — no browser.**
[Español](README.es.md)
Driving store consoles through a browser agent burns tokens on screenshots and page snapshots and breaks
whenever the UI changes. This project talks to the official APIs instead and answers in a few lines of plain
text. Every tool exists twice, with identical output:
- as an **MCP tool** for Claude Code, Claude Desktop or any MCP client, and
- as a **CLI command** (`appconsole ...`) for you, your scripts and CI.
It ships as three Claude Code plugins (Google Play, App Store Connect, AdMob), each with its MCP server and a
skill that teaches Claude the safe workflows. It also comes built into
[Alchemist Coder](https://github.com/Alekla0126/alchemist-coder), the open-source desktop app for Claude Code and
Codex: every agent there gets these tools for the services you have set up.
<!-- mcp-name: io.github.Alekla0126/app-console-mcp -->
```text
$ appconsole play vitals com.example.app
com.example.app (data up to 2026-10-19):
crash: 0.31% 28-day user-perceived (ok, threshold 1.09%)
newest versions (last 28 d): v42 0.12% (35% of users) · v41 0.44% (60% of users)
anr: 0.52% 28-day user-perceived (ABOVE THRESHOLD, threshold 0.47%)
newest versions (last 28 d): v42 0.21% (35% of users) · v41 0.70% (60% of users)
$ appconsole admob report --days 7 --by format --currency USD
AdMob 2026-10-20 to 2026-10-26 by format: 128.40 USD (+9% vs previous 7 d: 117.80), 61210 impressions
interstitial: 71.10 USD, 9340 impr, eCPM 7.61, match 88%, show 31%
banner: 39.75 USD, 47880 impr, eCPM 0.83, match 95%, show 52%
```
## What it can do
| Google Play (`play`) | App Store Connect (`appstore`) | AdMob (`admob`) |
|---|---|---|
| `apps` list apps the key can see | `apps` list apps | `accounts` publisher accounts |
| `listing` / `update-listing` title, short, full description, new languages | `listing` / `update-listing` name, subtitle, keywords, description, promo text, what's new | `apps` apps and ad unit ids |
| `tracks` releases per track | `versions` versions and review state | `report` earnings, eCPM, match/show rate by app, ad unit, country, format, platform, date, month or ad source, vs. previous period |
| `upload` .aab/.apk to any track (staged or draft) | `create-version` new editable version | |
| `promote` between tracks | `builds` processing state, export compliance | |
| `rollout` change %, complete, halt, resume | `submit` attach build + submit to App Review | |
| `reviews` / `reply` | `release` release an approved manual-release version | |
| `vitals` crash and ANR rates (Google's 28-day numbers) | `reviews` / `reply` | |
| `products` subscriptions, base plans, prices | `sales` downloads, IAP units, proceeds per app | |
| `search-rank` public search position | `search-rank` public search position | |
**Safe by default.** Every tool that changes something is a dry run unless you pass `confirm=true`
(`--confirm` in the CLI). Google Play dry runs build the change in a draft edit and let Google validate it
before discarding it, so you see real errors before anything is published. MCP tools carry
`readOnlyHint`/`destructiveHint` annotations so clients can auto-approve reads and ask before writes.
## Install
You need [uv](https://docs.astral.sh/uv/getting-started/installation/) (it fetches Python and the dependencies).
### Claude Code plugins (recommended)
```text
/plugin marketplace add Alekla0126/app-console-mcp
/plugin install google-play@app-console
/plugin install app-store-connect@app-console
/plugin install admob@app-console
```
Install only the ones you use. Each plugin asks for its credentials (paths and ids; you can leave them empty and
use `appconsole config` instead), adds its MCP server and skill, and puts `appconsole` on the PATH of Claude's
Bash tool.
### Any MCP client (Claude Desktop, Cursor, Codex, VS Code…)
```json
{
"mcpServers": {
"google-play": {
"command": "uvx",
"args": ["--from", "git+https://github.com/Alekla0126/app-console-mcp", "appconsole", "mcp", "play"],
"env": { "GOOGLE_PLAY_SERVICE_ACCOUNT": "/path/to/service-account.json" }
},
"app-store-connect": {
"command": "uvx",
"args": ["--from", "git+https://github.com/Alekla0126/app-console-mcp", "appconsole", "mcp", "appstore"]
},
"admob": {
"command": "uvx",
"args": ["--from", "git+https://github.com/Alekla0126/app-console-mcp", "appconsole", "mcp", "admob"]
}
}
}
```
`appconsole mcp all` serves the three services as a single server, for clients that take only one.
Or with the Claude Code CLI:
`claude mcp add google-play -- uvx --from git+https://github.com/Alekla0126/app-console-mcp appconsole mcp play`
### CLI only
```bash
uv tool install git+https://github.com/Alekla0126/app-console-mcp
appconsole --help
appconsole play reviews com.example.app --unanswered-only
```
## Credentials
Settings are read from environment variables first, then from `~/.config/appconsole/config.json`
(`appconsole config set KEY VALUE`, stored with `600` permissions). Only file paths and ids are stored; keys stay
where you keep them. Run `appconsole doctor` to check all three services.
### Google Play setup
1. In a Google Cloud project enable the **Google Play Android Developer API** and the
**Google Play Developer Reporting API**.
2. Create a service account (IAM & Admin > Service accounts) and a JSON key for it.
3. In Play Console > **Users and permissions** > Invite new users, add the service account's email and grant
what you need: *View app information* (read and vitals), *Manage store presence* (listings), *Release apps to
testing tracks* / *Release to production* (uploads and rollouts), *Reply to reviews*.
4. `appconsole config set GOOGLE_PLAY_SERVICE_ACCOUNT /path/to/key.json`
### App Store Connect setup
1. App Store Connect > **Users and Access** > Integrations > **App Store Connect API** > Team Keys > generate a
key. Role *App Manager* covers everything here except sales, which needs *Sales* or *Finance*.
2. Download `AuthKey_<KEY_ID>.p8` (Apple lets you download it only once) and note the Key ID and the Issuer ID.
3. Configure:
```bash
appconsole config set ASC_KEY_ID ABC123XYZ
appconsole config set ASC_ISSUER_ID 00000000-0000-0000-0000-000000000000
appconsole config set ASC_PRIVATE_KEY_PATH ~/.appstoreconnect/private_keys/AuthKey_ABC123XYZ.p8
appconsole config set ASC_VENDOR_NUMBER 12345678 # optional, for `appstore sales`
```
Already use fastlane? Point `ASC_API_KEY_JSON` to your `api_key.json` instead. If the `.p8` file sits in
`~/.appstoreconnect/private_keys` or `~/private_keys`, the path is optional.
### AdMob setup
AdMob does not accept service accounts, only a Google user, so you authorize once:
1. In a Google Cloud project enable the **AdMob API**.
2. Configure the OAuth consent screen (External; add yourself as a test user) and set its publishing status to
**In production** — refresh tokens of apps left in *Testing* expire after 7 days. For your own use you will see
an "unverified app" warning; that is expected.
3. Create an OAuth client ID of type **Desktop app** and download its JSON.
4. `appconsole admob login --client-secrets client_secret.json` (opens the browser once; the token is saved in
`~/.config/appconsole/admob-token.json`).
Alternative: gcloud application-default credentials with the AdMob scopes —
`gcloud auth application-default login --scopes=https://www.googleapis.com/auth/admob.readonly,https://www.googleapis.com/auth/admob.report,https://www.googleapis.com/auth/cloud-platform`.
With several publisher accounts set `ADMOB_PUBLISHER_ID=pub-...`.
### All settings
| Setting | Used by |
|---|---|
| `GOOGLE_PLAY_SERVICE_ACCOUNT` | Google Play (falls back to `GOOGLE_APPLICATION_CREDENTIALS`) |
| `ASC_KEY_ID`, `ASC_ISSUER_ID`, `ASC_PRIVATE_KEY_PATH` or `ASC_PRIVATE_KEY` | App Store Connect |
| `ASC_API_KEY_JSON` | App Store Connect, fastlane-format key file instead of the three above |
| `ASC_VENDOR_NUMBER` | `appstore sales` |
| `ADMOB_PUBLISHER_ID`, `ADMOB_TOKEN_FILE` | AdMob, optional |
| `APPCONSOLE_HOME` | config directory, default `~/.config/appconsole` |
| `APPCONSOLE_DEBUG=1` | show full tracebacks in the CLI |
## What the official APIs cannot do
These still need the website, and the tools say so when you hit them:
- **Google Play**: the *Publish* button when managed publishing is on (and *Send for review* when Google demands
it by hand), creating apps, data safety / content rating / ads declarations, custom store listings and listing
experiments, replying to reviews older than about a week.
- **App Store Connect**: creating the app record, App Privacy labels, age rating, pricing and in-app purchase
setup, Resolution Center messages. Screenshots are possible through the API but not implemented yet.
- **AdMob**: creating ad units and mediation groups (closed beta API), privacy & messaging, app-ads.txt, payments.
## Development
```bash
uv venv && uv pip install -e '.[dev]'
.venv/bin/pytest && .venv/bin/ruff check src tests
claude plugin validate .
```
`bin/appconsole` and the plugins run the package with `uvx --from <repo>`, which caches the build; after editing
the sources use the `.venv` or add `--refresh-package app-console-mcp`. For a release, bump the version in
`pyproject.toml`, `src/app_console_mcp/__init__.py` and the three entries of `.claude-plugin/marketplace.json`.
Tagging `v*` runs `.github/workflows/publish.yml`, which publishes to PyPI and then to the official MCP Registry
(`server.json`). It is off until PyPI trusts the workflow: on pypi.org add a pending trusted publisher (project
`app-console-mcp`, owner `Alekla0126`, repository `app-console-mcp`, workflow `publish.yml`, environment `pypi`), then
`gh variable set PUBLISH_PYPI --body true` and re-run the workflow.
A tool is one function decorated with `@tool()` (or `@tool(write=True)` with a `confirm` argument) in
`src/app_console_mcp/{play,appstore,admob}.py`. Its signature and Google-style docstring become both the MCP
schema and the CLI options. Keep outputs short: they are read by a model.
Issues and pull requests are welcome.
## License
MIT. Not affiliated with Google or Apple. Google Play, AdMob and App Store Connect are trademarks of their owners.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues