Configuration
MCP Client Setup
Add to your claude_desktop_config.json:
Add to .kiro/settings/mcp.json:
Docker
docker run -e GOOGLE_APPLICATION_CREDENTIALS=/creds/key.json \
-v /path/to/service-account.json:/creds/key.json:ro \
ghcr.io/lusky3/play-store-mcp:latest
For HTTP transport with Docker:
docker run -p 8000:8000 \
-e GOOGLE_APPLICATION_CREDENTIALS=/creds/key.json \
-v /path/to/service-account.json:/creds/key.json:ro \
ghcr.io/lusky3/play-store-mcp:latest \
--transport streamable-http --host 0.0.0.0 --port 8000
Warning:
--host 0.0.0.0binds the MCP tool-invocation endpoint (/mcp) itself, which has no built-in authentication — only/credentialsis gated (see Per-Request Credentials below). Exposing this port directly, as above, gives anyone with network access to it full read/write access to the Google Play account configured viaGOOGLE_APPLICATION_CREDENTIALS. Put a reverse proxy with its own authentication in front before exposing this port beyond localhost/a private network.
Environment Variables
| Variable | Description | Required | Default |
|---|---|---|---|
GOOGLE_APPLICATION_CREDENTIALS |
Path to service account JSON key file | Yes (or use per-request credentials) | — |
GOOGLE_PLAY_STORE_CREDENTIALS |
Inline JSON credentials string | Alternative to file path | — |
PLAY_STORE_MCP_LOG_LEVEL |
Log level: DEBUG, INFO, WARNING, ERROR |
No | INFO |
PLAY_STORE_MCP_DISABLE_DNS_REBINDING |
Disable DNS rebinding protection (for cloud/reverse-proxy deployments) | No | — |
PLAY_STORE_MCP_ADMIN_TOKEN |
Require Authorization: Bearer <token> on the /credentials endpoint (needed behind a reverse proxy, where the localhost check is insufficient) |
No | — |
PLAY_STORE_MCP_READ_ONLY |
Disable all write operations | No | — |
PLAY_STORE_MCP_DOWNLOAD_DIR |
Directory that APK/AAB downloads are confined to (guards against path traversal / arbitrary-file overwrite). Downloads are always confined; a destination outside this directory is rejected. Recommended for network/hosted deployments (sse/streamable-http) — the server warns if it is unset and falls back to the working directory, which may be read-only on some hosts (e.g. set it to /tmp/play-store-downloads on Render). |
No (defaults to cwd) | cwd |
CODE_MODE |
Set to 0 to opt out of the code-mode transform and use the classic tool list |
No | on |
HTTP Transport
For remote access or public deployments:
The server exposes a /health endpoint for monitoring.
See Remote Credentials for per-request credential configuration.
Per-Request Credentials
For multi-tenant deployments, clients can pass their own Google service account credentials on each request via HTTP headers. This is the primary mechanism for public instances where each user brings their own credentials.
| Header | Description |
|---|---|
X-Google-Credentials-Base64 |
Base64-encoded service account JSON key (recommended) |
X-Google-Credentials |
Raw JSON service account key string |
To encode your credentials:
Configure your MCP client to send the header:
{
"mcpServers": {
"play-store": {
"url": "https://your-server.com/mcp",
"transport": "http",
"headers": {
"X-Google-Credentials-Base64": "YOUR_BASE64_ENCODED_CREDENTIALS"
}
}
}
}
Per-request credentials are isolated — each request uses only the credentials provided in its headers. This isolation applies only to the per-request header path. If you also configure a server-side fallback (the GOOGLE_PLAY_STORE_CREDENTIALS env var, or a /credentials POST), that fallback client is process-global and is shared by every request that does not send a credential header — such a request executes under the shared identity rather than failing. For multi-tenant or public deployments, do not configure fallback credentials, so a request missing its credential header fails closed instead of using another identity.
Read-Only Mode
Enable read-only mode to guarantee the server performs no writes against the Play Developer API — useful for demos, audits, or pointing at a production app. When active, all write/mutating tools (deploy, promote, rollout control, review replies, listing/tester updates, catalog create/update/delete, purchase management, uploads, etc.) return an error and never contact the API; all read and validation tools work normally.
Enable it with the CLI flag:
Or the environment variable (truthy values: 1, true, yes, on):
Code Mode (Experimental, enabled by default)
Experimental — enabled by default
Code mode wraps the tool surface in FastMCP's experimental code-mode
transform, and is enabled by default (breaking change from earlier
releases, which shipped it opt-in). Set CODE_MODE=0 to opt out.
Code mode replaces the individual tools with three meta-tools — search,
get_schema, and execute — so the client discovers tools on demand and runs a
short script that calls them in a sandbox, rather than receiving the full tool
list on every request. This cuts the per-request tool-list token overhead.
Pair with read-only unless you need writes
Under code mode a single execute call can invoke up to 50 tool calls —
including mutating operations (deploy_app, refund_order, delete_*,
batch_*) — behind one approval, rather than the client approving each call.
Read-only enforcement still applies inside the sandbox, so if the deployment
does not need writes, run code mode with --read-only /
PLAY_STORE_MCP_READ_ONLY=1 to block those operations.
The execute meta-tool runs in the Monty sandbox, which is a base
dependency — no extra install needed; a plain pip install play-store-mcp
or uvx play-store-mcp includes it.
To opt out and get the classic full tool surface instead, set the
environment variable to an opt-out value (0, false, no, or off,
case-insensitive):
CODE_MODE is an environment variable only — there is no CLI flag — because the
transform is fixed when the server is constructed (before command-line arguments
are parsed).
Logging
Logs are written to stderr (stdout is reserved for MCP JSON-RPC communication). The server uses structlog for structured logging.
To enable debug logging:
Or set it in your MCP client config:
{
"mcpServers": {
"play-store": {
"command": "uvx",
"args": ["play-store-mcp"],
"env": {
"GOOGLE_APPLICATION_CREDENTIALS": "/path/to/service-account.json",
"PLAY_STORE_MCP_LOG_LEVEL": "DEBUG"
}
}
}
}
Retry Behavior
The client automatically retries failed API calls with exponential backoff:
- Retries on HTTP 429 (rate limit), 500, and 503 errors
- Maximum 3 retries per request
- Backoff starts at 1 second, doubles each retry (max 32 seconds)
- Random jitter is added to prevent thundering herd
Docker Environment Variables
When running in Docker, the following additional environment variables control the MCP transport:
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT |
Transport mode: stdio, sse, or streamable-http |
stdio |
MCP_HOST |
Host address to bind to | 0.0.0.0 |
MCP_PORT |
Port to listen on | 8000 |
Note: MCP_HOST and MCP_PORT only apply when using a network transport (streamable-http or sse). The Dockerfile defaults to stdio.