google-play-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example ADDED
@@ -0,0 +1,2 @@
1
+ GOOGLE_PLAY_KEY_FILE="path/to/key.json"
2
+ GOOGLE_PLAY_PACKAGE_NAME="com.example.app"
package/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # Google Play Developer API MCP Server
2
+
3
+ A Model Context Protocol (MCP) server for managing Google Play app deployment and in-app products via the Android Publisher API v3.
4
+
5
+ ## Features
6
+
7
+ ### App Deployment
8
+
9
+ - **deploy_internal**: Upload AAB and deploy to internal testing track
10
+
11
+ ### In-App Products
12
+
13
+ - **create_inapp_product**: Create or update a single in-app product
14
+ - **batch_create_inapp_products**: Create multiple products at once
15
+ - **activate_inapp_product**: Activate a draft product
16
+ - **batch_activate_inapp_products**: Activate multiple products
17
+ - **deactivate_inapp_product**: Deactivate an active product
18
+ - **list_inapp_products**: List all one-time products
19
+ - **list_subscriptions**: List all subscription products
20
+
21
+ ### App Info
22
+
23
+ - **get_app_info**: Get app track and version information
24
+
25
+ ## Requirements
26
+
27
+ - Python 3.10+
28
+ - Google Cloud service account with Google Play Developer API access
29
+ - App registered in Google Play Console
30
+
31
+ ## Installation & Usage
32
+
33
+ You can use this MCP server directly with `npx` without installing it manually.
34
+
35
+ ### Quick Start (npx)
36
+
37
+ ```bash
38
+ # Configure your API key
39
+ npx google-play-mcp init-key
40
+
41
+ # For Korean instructions (한국어 안내)
42
+ npx google-play-mcp init-key --lang ko
43
+
44
+ # Start the server
45
+ npx google-play-mcp start
46
+ ```
47
+
48
+ ### Installation (Global)
49
+
50
+ If you prefer to install it globally (from npm):
51
+
52
+ ```bash
53
+ npm install -g google-play-mcp
54
+ ```
55
+
56
+ ### Installation (Local Dev)
57
+
58
+ To install from the cloned repository:
59
+
60
+ ```bash
61
+ npm install -g .
62
+ ```
63
+
64
+ Then you can run:
65
+
66
+ ```bash
67
+ google-play-mcp init-key
68
+ google-play-mcp start
69
+ ```
70
+
71
+ ## Configuration (Antigravity & Claude Desktop)
72
+
73
+ To use this MCP server, add the following configuration to your MCP client (e.g., `claude_desktop_config.json` or Antigravity settings):
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "google-play": {
79
+ "command": "google-play-mcp",
80
+ "args": ["start"],
81
+ "env": {
82
+ "GOOGLE_PLAY_KEY_FILE": "/absolute/path/to/your-key.json",
83
+ "GOOGLE_PLAY_PACKAGE_NAME": "com.yourcompany.yourapp"
84
+ }
85
+ }
86
+ }
87
+ }
88
+ ```
89
+
90
+ > **Note:** If you haven't run `init-key` or don't have a `.env` file, you can pass environment variables directly in the configuration as shown above. If you have a `.env` file in the working directory, the server will load it automatically.
91
+
92
+ 1. Login to npm:
93
+
94
+ ```bash
95
+ npm login
96
+ ```
97
+
98
+ 1. Publish the package:
99
+
100
+ ```bash
101
+ npm publish
102
+ ```
103
+
104
+ ## Configuration
105
+
106
+ The `npm run init-key` script will automatically create a `.env` file with your configuration:
107
+
108
+ ```
109
+ GOOGLE_PLAY_KEY_FILE=/absolute/path/to/your-key.json
110
+ GOOGLE_PLAY_PACKAGE_NAME=com.yourcompany.yourapp
111
+ ```
112
+
113
+ ## Usage
114
+
115
+ To start the server manually:
116
+
117
+ ```bash
118
+ npm start
119
+ ```
120
+
121
+ ### Usage with Claude Desktop
122
+
123
+ Add to your `claude_desktop_config.json`:
124
+
125
+ ```json
126
+ {
127
+ "mcpServers": {
128
+ "google-play": {
129
+ "command": "npm",
130
+ "args": ["start"],
131
+ "cwd": "/absolute/path/to/google-play-mcp"
132
+ }
133
+ }
134
+ }
135
+ ```
136
+
137
+ ## Tool Examples
138
+
139
+ ### Deploy to Internal Testing
140
+
141
+ ```
142
+ Deploy app-release.aab to internal testing with Korean and English release notes
143
+ ```
144
+
145
+ ### Create In-App Product
146
+
147
+ ```
148
+ Create an in-app product:
149
+ - SKU: gems_100
150
+ - Korean: 보석 100개 / 보석 100개를 획득합니다
151
+ - English: 100 Gems / Get 100 gems
152
+ - Price: $0.99 USD
153
+ ```
154
+
155
+ ### Batch Create Products
156
+
157
+ ```json
158
+ [
159
+ {"sku": "gems_12", "title_ko": "보석 12개", "title_en": "12 Gems",
160
+ "description_ko": "보석 12개 획득", "description_en": "Get 12 gems", "price_usd": 0.99},
161
+ {"sku": "gems_66", "title_ko": "보석 66개", "title_en": "66 Gems",
162
+ "description_ko": "보석 66개 획득", "description_en": "Get 66 gems", "price_usd": 4.99}
163
+ ]
164
+ ```
165
+
166
+ ### Activate Products
167
+
168
+ ```json
169
+ ["gems_12", "gems_66", "gems_136"]
170
+ ```
171
+
172
+ ## Important Notes
173
+
174
+ ### Prerequisites for In-App Products
175
+
176
+ Before creating in-app products, your app must have:
177
+
178
+ 1. `com.android.vending.BILLING` permission in `AndroidManifest.xml`
179
+ 2. Play Billing Library 6.0.1+ (Flutter: `in_app_purchase` package)
180
+ 3. A bundle with these uploaded to Google Play
181
+
182
+ ### Draft Apps
183
+
184
+ Apps that have never been published can only use `status: "draft"` for deployments.
185
+ You must manually publish through Google Play Console for the first release.
186
+
187
+ ### API Migration
188
+
189
+ This server uses the new `monetization.onetimeproducts` API instead of the deprecated
190
+ `inappproducts` API which returns 403 errors.
191
+
192
+ ### Price Conversion
193
+
194
+ USD prices are automatically converted to 170+ regional currencies using
195
+ Google's `convertRegionPrices` API.
196
+
197
+ ## Tracks
198
+
199
+ | Track | Description |
200
+ |-------|-------------|
201
+ | `internal` | Internal testing (up to 100 testers) |
202
+ | `alpha` | Closed testing |
203
+ | `beta` | Open testing |
204
+ | `production` | Production release |
205
+
206
+ ## License
207
+
208
+ MIT License
package/bin/cli.js ADDED
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { spawn } = require('child_process');
6
+
7
+ // Determine the root directory of the package
8
+ const packageRoot = path.join(__dirname, '..');
9
+ const venvDir = path.join(packageRoot, '.venv');
10
+ const requirementsFile = path.join(packageRoot, 'requirements.txt');
11
+
12
+ // Platform specific paths
13
+ const isWindows = process.platform === 'win32';
14
+ const pythonExecutable = isWindows
15
+ ? path.join(venvDir, 'Scripts', 'python.exe')
16
+ : path.join(venvDir, 'bin', 'python');
17
+
18
+ const pipExecutable = isWindows
19
+ ? path.join(venvDir, 'Scripts', 'pip.exe')
20
+ : path.join(venvDir, 'bin', 'pip');
21
+
22
+ function runCommand(command, args, options = {}) {
23
+ return new Promise((resolve, reject) => {
24
+ const proc = spawn(command, args, {
25
+ stdio: 'inherit',
26
+ cwd: packageRoot,
27
+ ...options
28
+ });
29
+
30
+ proc.on('close', (code) => {
31
+ if (code === 0) {
32
+ resolve();
33
+ } else {
34
+ reject(new Error(`Command exited with code ${code}`));
35
+ }
36
+ });
37
+
38
+ proc.on('error', (err) => {
39
+ reject(err);
40
+ });
41
+ });
42
+ }
43
+
44
+ async function setupEnvironment() {
45
+ console.log('Initializing Python virtual environment...');
46
+
47
+ // Create venv if it doesn't exist
48
+ if (!fs.existsSync(venvDir)) {
49
+ console.log('Creating .venv...');
50
+ try {
51
+ await runCommand('python3', ['-m', 'venv', '.venv']);
52
+ } catch (e) {
53
+ // Try just 'python' if 'python3' fails (e.g. Windows)
54
+ await runCommand('python', ['-m', 'venv', '.venv']);
55
+ }
56
+ }
57
+
58
+ // Install dependencies
59
+ if (fs.existsSync(requirementsFile)) {
60
+ console.log('Installing dependencies...');
61
+ await runCommand(pipExecutable, ['install', '-r', 'requirements.txt']);
62
+ }
63
+ }
64
+
65
+ async function main() {
66
+ const args = process.argv.slice(2);
67
+ const command = args[0];
68
+
69
+ // Check if environment needs setup
70
+ if (!fs.existsSync(pythonExecutable)) {
71
+ try {
72
+ await setupEnvironment();
73
+ } catch (error) {
74
+ console.error('Failed to setup Python environment:', error);
75
+ process.exit(1);
76
+ }
77
+ }
78
+
79
+ // Determine which script to run
80
+ let scriptToRun;
81
+ let pythonArgs = [];
82
+
83
+ if (command === 'init-key') {
84
+ scriptToRun = 'setup_key.py';
85
+ pythonArgs = args.slice(1);
86
+ } else if (command === 'start' || !command) {
87
+ scriptToRun = 'server.py';
88
+ pythonArgs = args.slice(1);
89
+ if (command === 'start') {
90
+ pythonArgs = args.slice(1); // 'start' is consumed
91
+ } else {
92
+ pythonArgs = args; // No command provided, pass all args
93
+ }
94
+ } else {
95
+ // Unknown command, maybe it's an arg for server.py?
96
+ // Default to running server.py with these args
97
+ scriptToRun = 'server.py';
98
+ pythonArgs = args;
99
+ }
100
+
101
+ const scriptPath = path.join(packageRoot, scriptToRun);
102
+
103
+ try {
104
+ await runCommand(pythonExecutable, [scriptPath, ...pythonArgs]);
105
+ } catch (error) {
106
+ console.error('Error executing script:', error);
107
+ process.exit(1);
108
+ }
109
+ }
110
+
111
+ main();
package/locales.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "en": {
3
+ "step1_title": "Step 1: Enable Google Play API",
4
+ "step1_desc": "\n1. Create a new project or select an existing one.\n2. Click **Enable** for **\"Google Play Android Developer API\"**.\n ",
5
+ "step2_title": "Step 2: Create Service Account & Download Key",
6
+ "step2_desc": "\n1. Click **Create Service Account**.\n2. Fill in the suggested details below (Select options to copy).\n3. Click **Create and Continue**.\n4. Click **Done** (Granting Service Account User role is optional).\n5. Click on the **Email** of the newly created account.\n6. Go to the **Keys** tab (top menu).\n7. Click **Add Key** > **Create new key** > **JSON** > **Create**.\n8. The JSON file will download. **Keep this file ready.**\n ",
7
+ "step3_title": "Step 3: Grant Permissions in Play Console",
8
+ "step3_desc": "\n1. Have your **Service Account Email** ready (from Step 2).\n2. Click **Invite new users**.\n3. Paste the service account email.\n4. Grant **Admin** permissions (or at least Release & Financial).\n5. Click **Invite user**.\n ",
9
+ "open_browser": "\nOpen browser to perform this step? (Press Enter to Open) [y/N]",
10
+ "sa_details_title": "Service Account Details",
11
+ "sa_suggested_title": "[bold]Suggested Values (Double-click or drag to select):[/bold]",
12
+ "sa_name_label": "Service Account Name:",
13
+ "sa_id_label": "Service Account ID:",
14
+ "sa_desc_label": "Description:",
15
+ "copy_menu_intro": "\n[dim]You can use the menu below to copy values to your clipboard, or copy them manually from above.[/dim]",
16
+ "copy_menu_prompt": "\n[bold]Copy Actions (Optional):[/bold]\n[1] Copy Name & ID (Formatted Text)\n[2] Copy Description\n[Enter] Skip / Continue to next step",
17
+ "final_config_title": "[bold green]Final Configuration[/bold green]",
18
+ "key_path_prompt": "\n[bold]Drag and drop (or enter path)[/bold] to your downloaded JSON key file",
19
+ "key_file_error": "[bold red]Error:[/bold red] File not found at {key_path}. Please try again.",
20
+ "package_name_prompt": "Enter your [bold]App Package Name[/bold] (e.g. com.example.app)",
21
+ "success_msg": "\n[bold green]Success![/bold green] Configured .env\nKey: {key_path}\nPackage: {package_name}",
22
+ "pyperclip_install": "[yellow]pyperclip not found. Installing...[/yellow]",
23
+ "pyperclip_error": "[red]Failed to import pyperclip after installation.[/red]",
24
+ "copy_manual": "Please copy manually: [bold]{text}[/bold]",
25
+ "copy_install_fail": "[red]Failed to install pyperclip.[/red]",
26
+ "copy_success": "[green]Copied to clipboard: {text}[/green]",
27
+ "copy_fail": "[red]Failed to copy to clipboard: {e}[/red]",
28
+ "press_enter": "Press Enter key inside this terminal after you have completed the steps above..."
29
+ },
30
+ "ko": {
31
+ "step1_title": "1단계: Google Play API 활성화",
32
+ "step1_desc": "\n1. 새 프로젝트를 생성하거나 기존 프로젝트를 선택하세요.\n2. **\"Google Play Android Developer API\"**를 찾아 **사용(Enable)**을 클릭하세요.\n ",
33
+ "step2_title": "2단계: 서비스 계정 생성 및 키 다운로드",
34
+ "step2_desc": "\n1. **서비스 계정 만들기**를 클릭하세요.\n2. 아래 제안된 내용을 복사하여 입력하세요.\n3. **만들기 및 계속**을 클릭하세요.\n4. **완료**를 클릭하세요 (권한 부여는 선택 사항입니다).\n5. 새로 생성된 계정의 **이메일**을 클릭하세요.\n6. **키** 탭(상단 메뉴)으로 이동하세요.\n7. **키 추가** > **새 키 만들기** > **JSON** > **만들기**를 클릭하세요.\n8. JSON 파일이 다운로드됩니다. **이 파일을 잘 보관하세요.**\n ",
35
+ "step3_title": "3단계: Play Console에서 권한 부여",
36
+ "step3_desc": "\n1. **서비스 계정 이메일**을 준비하세요 (2단계에서 생성됨).\n2. **사용자 초대**를 클릭하세요.\n3. 서비스 계정 이메일을 붙여넣으세요.\n4. **관리자** 권한(또는 최소한 출시 및 금융 권한)을 부여하세요.\n5. **사용자 초대**를 클릭하세요.\n ",
37
+ "open_browser": "\n이 단계를 수행하기 위해 브라우저를 여시겠습니까? (엔터를 누르면 열립니다) [y/N]",
38
+ "sa_details_title": "서비스 계정 상세 정보",
39
+ "sa_suggested_title": "[bold]추천 값 (더블 클릭하거나 드래그하여 선택):[/bold]",
40
+ "sa_name_label": "서비스 계정 이름:",
41
+ "sa_id_label": "서비스 계정 ID:",
42
+ "sa_desc_label": "설명:",
43
+ "copy_menu_intro": "\n[dim]아래 메뉴를 사용하여 클립보드에 복사하거나, 위 내용을 수동으로 복사하세요.[/dim]",
44
+ "copy_menu_prompt": "\n[bold]복사 작업 (선택 사항):[/bold]\n[1] 이름 & ID 복사 (서식 포함)\n[2] 설명 복사\n[Enter] 건너뛰기 / 다음 단계로 계속",
45
+ "final_config_title": "[bold green]최종 설정[/bold green]",
46
+ "key_path_prompt": "\n다운로드한 JSON 키 파일을 이곳에 [bold]드래그 앤 드롭[/bold] (또는 경로 입력) 하세요",
47
+ "key_file_error": "[bold red]오류:[/bold red] 파일을 찾을 수 없습니다: {key_path}. 다시 시도해주세요.",
48
+ "package_name_prompt": "[bold]앱 패키지 이름[/bold]을 입력하세요 (예: com.example.app)",
49
+ "success_msg": "\n[bold green]성공![/bold green] .env 설정 완료\n키: {key_path}\n패키지: {package_name}",
50
+ "pyperclip_install": "[yellow]pyperclip을 찾을 수 없습니다. 설치 중...[/yellow]",
51
+ "pyperclip_error": "[red]설치 후 pyperclip을 가져오는데 실패했습니다.[/red]",
52
+ "copy_manual": "수동으로 복사해주세요: [bold]{text}[/bold]",
53
+ "copy_install_fail": "[red]pyperclip 설치에 실패했습니다.[/red]",
54
+ "copy_success": "[green]클립보드에 복사되었습니다: {text}[/green]",
55
+ "copy_fail": "[red]클립보드 복사 실패: {e}[/red]",
56
+ "press_enter": "위 단계를 완료한 후 이 터미널에서 Enter 키를 누르세요..."
57
+ }
58
+ }
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "google-play-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for Google Play Developer API",
5
+ "scripts": {
6
+ "start": "node bin/cli.js start",
7
+ "init-key": "node bin/cli.js init-key"
8
+ },
9
+ "bin": {
10
+ "google-play-mcp": "./bin/cli.js"
11
+ },
12
+ "files": [
13
+ "server.py",
14
+ "setup_key.py",
15
+ "requirements.txt",
16
+ "bin/cli.js",
17
+ ".env.example",
18
+ "locales.json"
19
+ ],
20
+ "preferGlobal": true,
21
+ "keywords": [
22
+ "mcp",
23
+ "google-play",
24
+ "python"
25
+ ],
26
+ "author": "",
27
+ "license": "MIT"
28
+ }
@@ -0,0 +1,5 @@
1
+ mcp[cli]>=1.0.0
2
+ google-api-python-client>=2.100.0
3
+ google-auth>=2.23.0
4
+ python-dotenv>=1.0.0
5
+ pyperclip>=1.8.0