# app-publish-mcp

Unified MCP server for App Store Connect & Google Play Console

- **Type:** MCP server
- **Trust:** 60/100 (B), scored on the package rubric
- **Verification:** community-indexed — nobody has claimed this listing
- **Version:** 0.6.0
- **Author:** mikusnuz
- **License:** MIT
- **npm:** app-publish-mcp
- **Source:** https://github.com/mikusnuz/app-publish-mcp
- **Compatible clients:** claude-code, cursor, copilot, gemini (basis: transport)

## Trust

60/100 (B), scored on the package rubric
- Publisher verified: no
- Install scripts: nothing suspicious found
- Prompt-injection scan: not run
- Obfuscation scan: not run
- Evidence age: 1 day

## Security scan

- **Status:** clean
- **Scanned:** 2026-10-13T23:16:22.291Z
- **Version scanned:** 0.6.0
- **CVEs:** none found by OSV at scan time

## Tools

40 declared. Statically extracted from the shipped source — a floor on the surface, not a census.
- `apple_get_asset_library` — Get the reusable App Asset Library for an app before uploading screenshots, previews, or creative assets
- `apple_get_asset_specs` — Read Apple’s current asset specifications, placement types, device groups, and limits; use the returned IDs instead of hard-coded device sizes
- `apple_list_assets` — List all image or video assets in an App Asset Library, following every page; use this to reuse files and find interrupted uploads
- `apple_get_asset` — Read an image or video asset’s processing state, matched specId, and delivery errors without exposing presigned upload URLs
- `apple_wait_for_asset` — Resume waiting for an uploaded asset to become ready; optionally check that Apple matched the intended specification
- `apple_upload_asset` — Upload an image or video once to the App Asset Library, commit uploaded=true, and verify processing against a specId from apple_get_asset_specs. Create placemen
- `apple_list_asset_placements` — List every placement that uses an image or video, including other localizations, before deleting or replacing that asset
- `apple_list_placements` — List all placements for a localization in display order, including their image/video assets
- `apple_create_placement` — Place a ready library asset on an editable localization using a placement type and group from apple_get_asset_specs. Reuses an existing identical placement.
- `apple_reorder_placements` — Set the complete display order for one localization and placement group, then read back and verify the order. In-app event localizations are not orderable.
- `apple_delete_placement` — Remove a placement from its localization; the reusable library asset and its other placements remain intact
- `apple_delete_asset` — Delete an unplaced image or video from the library. Refuses to delete if any localization still uses it; delete the intended placements first.
- `apple_list_apps` — List all apps in App Store Connect
- `apple_get_next_page` — Fetch the next App Store Connect page using the exact links.next URL returned by another Apple list tool
- `apple_get_app` — Get detailed info about an app including latest version state
- `apple_update_app` — Update app-level submission settings: the content-rights declaration and primary locale
- `apple_get_app_info` — Get app info (categories, age rating, etc)
- `apple_update_category` — Update app primary/secondary category
- `apple_list_bundle_ids` — List registered bundle IDs
- `apple_create_bundle_id` — Register a new bundle ID
- `apple_list_versions` — List all App Store versions for an app
- `apple_create_version` — Create a new App Store version for submission
- `apple_update_version` — Update an existing App Store version's version, copyright, or release timing
- `apple_list_version_localizations` — List all localizations for a version
- `apple_create_version_localization` — Create a new localization for a version
- `apple_update_version_localization` — Update localization fields (description, keywords, whatsNew, etc)
- `apple_list_screenshot_sets` — Legacy: list screenshot sets for a localization. Apple deprecated this API in 4.5.1; use apple_list_placements for Asset Library media.
- `apple_create_screenshot_set` — Legacy: create a screenshot set for a specific display type. Deprecated by Apple; prefer apple_upload_asset and apple_create_placement.
- `apple_upload_screenshot` — Legacy: upload and commit a screenshot while preserving its ID for recovery. Deprecated by Apple; prefer apple_upload_asset and apple_create_placement.
- `apple_delete_screenshot` — Legacy: delete a screenshot from the deprecated screenshot-set API. Use apple_delete_placement and apple_delete_asset for Asset Library media.
- `apple_list_builds` — List builds uploaded to App Store Connect
- `apple_get_build_upload` — Get the current state of a Build Uploads API operation, including the imported build when available
- `apple_delete_build_upload` — Explicitly discard an AWAITING_UPLOAD or FAILED Build Upload after checking it with apple_get_build_upload; do not use for PROCESSING or COMPLETE uploads
- `apple_wait_for_build_upload` — Wait until a Build Uploads API operation completes or fails, returning the imported build relationship on success
- `apple_upload_build` — Upload a signed IPA through the App Store Connect Build Uploads API: reserve the upload and file, send every presigned range, commit its SHA-256 checksum, and o
- `apple_set_build_encryption` — Set a processed build's usesNonExemptEncryption answer before submission; true may also require an app encryption declaration or supporting export-compliance do
- `apple_assign_build` — Assign a build to an App Store version
- `apple_get_age_rating` — Get age rating declaration for an app info
- `apple_update_age_rating` — Update the current App Store age-rating questionnaire. Prefer NONE, INFREQUENT, or FREQUENT for frequency fields; legacy values remain accepted by Apple for com
- `apple_update_review_detail` — Update app review info (contact info, notes, demo account for reviewer)

## Install

**Verdict: review** — Installable, but 1 thing to check first: No publisher has proved control of this listing; it is indexed, not vouched for.
**Cautions** (coverage gaps and advisories — never blocking)
- No publisher has proved control of this listing; it is indexed, not vouched for.
**Config** (claude-code):
```json
"{\n  \"mcpServers\": {\n    \"app-publish\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"app-publish-mcp\"\n      ],\n      \"env\": {\n        \"APPLE_KEY_ID\": \"<YOUR_APPLE_KEY_ID>\",\n        \"APPLE_ISSUER_ID\": \"<YOUR_APPLE_ISSUER_ID>\",\n        \"GOOGLE_CLIENT_SECRET\": \"<YOUR_GOOGLE_CLIENT_SECRET>\",\n        \"GOOGLE_REFRESH_TOKEN\": \"<YOUR_GOOGLE_REFRESH_TOKEN>\"\n      }\n    }\n  }\n}"
```
**Credentials it will ask for** (names only — Forge never holds a value):
- `APPLE_KEY_ID` — Apple Key ID (optional)
- `APPLE_ISSUER_ID` — Apple Issuer ID (optional)
- `GOOGLE_CLIENT_SECRET` — Google Client Secret (optional)
- `GOOGLE_REFRESH_TOKEN` — Google Refresh Token (optional)
Placeholders only. Forge never holds, brokers, or transmits a credential value — replace each <YOUR_NAME> in your own config file. Do not send a value back to Forge; no Forge endpoint accepts one.
- This entry needs 4 credentials (0 required). The generated config carries placeholders, so it will fail in the editor rather than at runtime if they are left unset.

## Blast radius

Critical blast radius — deletes data; holds an oauth grant.
- Floor 66, ceiling 66 (tier: critical)
- This is impact, not likelihood. A high radius is not a defect: a filesystem server is supposed to write files. It is never part of the trust score.

## Machine-readable views of this entry

- Signed JSON: https://forgeregistry.com/api/v1/packages/app-publish-mcp
- Install plan: https://forgeregistry.com/api/v1/packages/app-publish-mcp/install-plan
- Alternatives: https://forgeregistry.com/api/v1/alternatives/app-publish-mcp
- HTML page: https://forgeregistry.com/registry/app-publish-mcp
- MCP: POST https://forgeregistry.com/api/mcp → `forge_get_package` / `forge_install_plan`

## About this document

Generated by Forge (https://forgeregistry.com) — a compact rendering of the same record served, signed, at the JSON URL above. Trust and scan facts are the registry's own measurements; anything Forge did not measure is named as unmeasured rather than omitted.
