Skip to content

Publishing To Stores

Sia edited this page May 31, 2026 · 2 revisions

Publishing to Stores (Play Console / TestFlight)

vibe-coder-server can hand off finished artifacts to Google Play (Internal / Alpha / Beta / Production) and Apple TestFlight by delegating the work to MCP servers instead of calling the store APIs directly. This keeps secrets off the server code path and stays consistent with the rest of the tool ("Claude + MCP does external integrations").

Store MCP server Trigger location
Google Play google-play-publisher Build detail page (after SUCCESS)
Apple TestFlight app-store-connect Build detail page (always)

Why MCP delegation, not direct API

  • The Play Publishing API and App Store Connect API both involve OAuth / Service Account JSON / .p8 keys whose lifecycle is annoying to manage in server code.
  • An MCP server already exists for each; reusing them gives us:
    • Encapsulated authentication (vibe-coder server never sees the Service Account JSON contents — only the file path).
    • Natural-language progress and error reporting through the existing Claude console.
    • Same MCP catalog UX used for everything else (MCP Catalog).
  • Adds zero new runtime dependencies to the slim image.

Google Play

Precheck

The build detail page calls PlayPublishService.precheck(packageName) which reports:

  • MCP installation status (installed / registered only / missing).
  • Whether GOOGLE_PLAY_SERVICE_ACCOUNT_JSON is set.
  • Whether the configured GOOGLE_PLAY_PACKAGE_NAME matches the project's package — single-admin tools that publish multiple apps will intentionally mismatch this; the warning is informational, not blocking.

Trigger

Form on the build detail page (only when status=SUCCESS):

  • AAB path (project-root relative). Default app/build/outputs/bundle/release/app-release.aab. The trigger does not verify existence; Claude will report if the file is missing.
  • Track: internal / alpha / beta / production (whitelisted to block prompt injection).
  • Release notes (optional). If empty Claude pulls them from the most recent commit message.

Clicking the button sends a structured prompt to the project's Claude session asking it to use the google-play-publisher MCP. You are redirected to the project console to follow progress live.

The publish step is asked to leave the release in a review-required state rather than auto-publishing, so a human still checks the staging upload before promoting.

Endpoint + audit

POST /projects/{id}/builds/{buildId}/play-upload

CSRF-protected SSR form. Audit actions:

  • publish.play.upload OK / FAIL.

TestFlight

Why no iOS build pipeline

vibe-coder-server is Linux-only — iOS builds require macOS + Xcode and a full code-signing setup. The realistic scenario is:

  • Use a macOS host (Mac mini build farm or your own laptop) to produce the .ipa.
  • Push or scp the .ipa into the project workspace (e.g. out/app-release.ipa).
  • Trigger the upload from vibe-coder.

If you want the macOS build automated, the fastlane MCP entry can be combined with this — but that's outside the scope here.

Precheck + trigger

TestFlightPublishService.precheck() checks app-store-connect MCP status + ASC_KEY_ID + ASC_ISSUER_ID + ASC_PRIVATE_KEY_FILE (.p8) presence.

The form (always shown on build detail) accepts:

  • .ipa path (default out/app-release.ipa).
  • External tester groups (comma-separated names, optional).
  • Release notes (optional).
POST /projects/{id}/builds/{buildId}/testflight-upload

The prompt explicitly asks Claude to not auto-progress through compliance / export-compliance prompts; surface them and wait for a human.

Audit: publish.testflight.upload OK / FAIL.

Roadmap

  • fastlane MCP integration to wrap the macOS build itself.
  • apk-signature-verify MCP for sanity checks before upload — currently vibe-coder runs apksigner verify inline (APK Signing) so this is lower priority.
  • Per-app Service Account JSON (one MCP entry per package). Today the catalog has one google-play-publisher entry which limits multi-app publishing from one host.

Clone this wiki locally