Skip to main content
Glama
qalvinahmad

App Store Publisher MCP

by qalvinahmad
README.md
# App Store Publisher MCP

**MCP server to publish Android apps to Samsung Galaxy Store and Huawei AppGallery straight from AI agents** โ€” Claude Code, Claude Desktop, Cursor, VS Code, Google Antigravity, and OpenCode.

Wraps the [Samsung Galaxy Store Developer (Seller) API](https://developer.samsung.com/galaxy-store/galaxy-store-developer-api.html) and the [Huawei AppGallery Connect API](https://developer.huawei.com/consumer/en/doc/AppGallery-connect-Guides/agcapi-publish_api_overview-0000001111685332) as [Model Context Protocol](https://modelcontextprotocol.io) tools, so your AI coding agent can check app status, upload binaries, update store listings, submit apps for review, and verify Samsung IAP receipts โ€” without you ever leaving the editor.

Bonus: [`docs/app-store-publish-apis.md`](docs/app-store-publish-apis.md) is a field-tested reference for publishing APIs across **7 stores** โ€” Samsung Galaxy Store, Huawei AppGallery, RuStore, Amazon Appstore, vivo, OPPO, and APKPure โ€” including auth flows, endpoints, signing code, and the undocumented gotchas below.

## Features

- ๐Ÿช **Samsung Galaxy Store Seller API** โ€” app list & details, arbitrary Content Publish API calls (binaries, metadata, submission, staged rollout), JWT service-account auth handled for you
- ๐Ÿ“ฑ **Huawei AppGallery Connect Publishing API** โ€” appid lookup, app info, file upload URLs, submission; supports all three Huawei credential types (Connect API client, service-account key JSON, public API key)
- ๐Ÿงพ **Samsung IAP receipt verification** โ€” validate purchase receipt JWTs against your IAP public key
- ๐Ÿ” Tokens cached and auto-refreshed; credentials stay in a local `.env`, never in code
- ๐Ÿค– Works with any MCP client: Claude Code, Claude Desktop, Cursor, VS Code, Antigravity, OpenCode

## Tools

| Tool | What it does |
|---|---|
| `samsung_get_access_token` | Create/refresh a Seller API access token (JWT RS256 service account) |
| `samsung_get_app_details` | `GET /seller/contentInfo` for a contentId |
| `samsung_api_request` | Any Galaxy Store Developer API request (list apps, add binary, submit, โ€ฆ) |
| `samsung_iap_verify_receipt` | Verify a Samsung IAP receipt JWT |
| `appgallery_get_access_token` / `huawei_get_access_token` | Connect API client token (**the only token type the Publish API accepts**) |
| `appgallery_api_request` / `huawei_api_request` | Any AppGallery Connect API request (`/api/publish/v2/*`) |
| `huawei_get_service_account_token` | JWT-bearer token from a service-account key JSON |
| `huawei_sa_api_request` | Call Huawei/AGC service APIs with the service-account token |
| `huawei_public_api_request` | Call Huawei public APIs with an API key (`key=` param) |

## Quick start

```bash
git clone https://github.com/qalvinahmad/app-store-publisher-mcp.git
cd app-store-publisher-mcp
npm install
cp .env.example .env   # fill in your credentials
```

### Claude Code

```bash
claude mcp add app-store-publisher -- node /path/to/app-store-publisher-mcp/index.js
```

### Claude Desktop / Cursor (`mcp.json`)

```json
{
  "mcpServers": {
    "app-store-publisher": {
      "command": "node",
      "args": ["/path/to/app-store-publisher-mcp/index.js"]
    }
  }
}
```

### VS Code (`~/Library/Application Support/Code/User/mcp.json`)

```json
{
  "servers": {
    "app-store-publisher": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/app-store-publisher-mcp/index.js"]
    }
  }
}
```

### Google Antigravity (`~/.antigravity/mcp_config.json`)

```json
{
  "mcpServers": {
    "app-store-publisher": {
      "command": "node",
      "args": ["/path/to/app-store-publisher-mcp/index.js"]
    }
  }
}
```

### OpenCode (`~/.config/opencode/opencode.jsonc`)

```json
{
  "mcp": {
    "app-store-publisher": {
      "type": "local",
      "command": ["node", "/path/to/app-store-publisher-mcp/index.js"],
      "enabled": true
    }
  }
}
```

## Getting credentials

**Samsung Galaxy Store** โ€” [Seller Portal](https://seller.samsungapps.com/) โ†’ Assistance โ†’ API Service โ†’ create a service account (requires commercial seller status). You get a service-account ID and a private key โ†’ `SAMSUNG_SERVICE_ACCOUNT_ID`, `SAMSUNG_PRIVATE_KEY`.

**Huawei AppGallery** โ€” [AppGallery Connect](https://developer.huawei.com/consumer/en/service/josp/agc/index.html) โ†’ Users and permissions โ†’ API key โ†’ **Connect API** โ†’ create a client with **Project = N/A** (team-level; anything else returns 403) โ†’ `APPGALLERY_CLIENT_ID`, `APPGALLERY_CLIENT_SECRET`. Optionally add a service-account key JSON and/or an API key from Console โ†’ Credentials.

## Gotchas we learned the hard way (all verified against the live APIs)

1. **Huawei's Publish API only accepts Connect API *client* tokens.** Service-account (JWT-bearer) tokens are rejected with `205524993 "client token auth failed"` โ€” no matter which headers you send.
2. **Huawei's client token endpoint wants a JSON body.** Sending `application/x-www-form-urlencoded` fails with an *empty* error body.
3. **Huawei service-account JWTs must be RS256.** PS256 (which the JSON key format suggests) is rejected with `sub_error 20504`.
4. **Send both headers on Connect API calls:** `Authorization: Bearer <token>` *and* `client_id: <id>`.
5. **zod v4 breaks single-argument `z.record()`.** If your MCP server's `tools/list` dies with `Cannot read properties of undefined (reading '_zod')`, change `z.record(z.any())` to `z.record(z.string(), z.any())`.
6. **Samsung tokens:** the Seller API JWT needs `scopes: ["publishing", "gss"]` and the access token must be sent together with a `service-account-id` header.

## Security

- Credentials live only in `.env` / the service-account JSON โ€” both are gitignored. Use `chmod 600` on them.
- Never put store-publishing credentials in app runtime config; they are deploy-time secrets.
- If a key leaks (chat, screenshot, log), rotate it in the store console.

## Related documentation

Full 7-store publishing API reference (RuStore signature auth, Amazon Appstore edit flow, vivo HMAC signing with working code, OPPO and APKPure manual-only notes): [`docs/app-store-publish-apis.md`](docs/app-store-publish-apis.md)

## License

[MIT](LICENSE) ยฉ Alvin Ahmad

TDQS

C2.3/5.0

Scored across 11 tools

Disambiguation2/5

Multiple tools are aliases (appgallery_api_request / huawei_api_request, appgallery_get_access_token / huawei_get_access_token), causing ambiguity. Additionally, there are three different token-related tools for Huawei with overlapping purposes, making it hard for an agent to choose the correct one without deep knowledge.

Naming Consistency2/5

Naming is inconsistent: tools for AppGallery use 'appgallery_' prefix, but some have 'huawei_' duplicates, and Samsung tools have 'samsung_' prefix. Verb patterns vary (api_request, get_access_token, get_app_details, iap_verify_receipt), lacking a unified structure.

Tool Count3/5

11 tools is a moderate count, but the presence of redundant aliases inflates it unnecessarily. The effective count of distinct functionalities is lower, suggesting the set could be streamlined.

Completeness2/5

The tools only provide low-level API requests and token management for three app stores. High-level publishing operations like uploading, updating, or submitting apps are missing, leaving significant gaps for a publishing workflow.

Maintenance

ActivityStale
ResponsivenessNo issues