Upload App MCP Server
Upload App MCP Server automates Android/Google Play and iOS/App Store upload, release, and status workflows.
Upload an Android
.aabto an internal, alpha, beta, or custom closed test track.Promote an Android version code to production with optional staged rollout and release notes; without
confirm=trueit only validates.Change or halt an Android production rollout; without
confirm=trueit only validates.List Android releases for every track with version codes, status, and rollout fraction.
Upload an iOS
.ipato TestFlight without waiting for Apple processing.Attach a TestFlight build to an App Store version, create the version if needed, and submit for review; without
confirm=trueit only describes the action.Show latest iOS App Store versions and TestFlight build processing states.
Enables uploading iOS builds (.ipa) to TestFlight, attaching TestFlight builds to App Store versions (creating versions if needed), submitting versions for App Review with release notes, and checking App Store version and TestFlight build processing statuses.
Enables uploading Android App Bundles (.aab) to Google Play test tracks (internal, alpha, beta, or custom closed tracks), promoting version codes to production with staged rollouts and release notes, updating rollout fractions or halting releases, and listing release statuses across tracks.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Upload App MCP Server upload build/app-release.aab to the beta track"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Upload App MCP Server
Servidor MCP (Model Context Protocol) para enviar um .aab para uma faixa de teste da Google Play ou um .ipa para o TestFlight e depois promover para produção. O servidor não gera o build: cada projeto de app gera o próprio arquivo, e as ferramentas só recebem o caminho. Por baixo, o servidor roda lanes do fastlane que vêm dentro do pacote.
Ferramentas expostas
upload_android— envia um.aabpara uma faixa de teste (internal,alpha,betaou o nome de uma faixa fechada personalizada; padrãointernal)promote_android— promove um version code de uma faixa de teste para produção, com rollout gradual e notas da versão opcionaisupdate_rollout_android— muda a fração de uma release de produção, completa o rollout com1ou para a release comhalt=truestatus_android— lista as releases de cada faixa, com version codes, status e fração do rolloutupload_ios— envia um.ipapara o TestFlight, sem esperar o processamento da Applerelease_ios— anexa um build do TestFlight a uma versão da App Store, cria a versão se ela não existir e envia para review, com as novidades da versão opcionaisstatus_ios— mostra as últimas versões da App Store com o estado de cada uma e os últimos builds com o estado do processamentoupload_screenshots_ios— substitui as screenshots de uma versão da App Store pelas imagens de uma pastaupdate_review_info_ios— define o usuário e a senha de demonstração e as notas das informações para a equipe de revisão de uma versão da App Storeupload_screenshots_android— substitui as screenshots da ficha da Google Play pelas imagens de uma pastaupdate_age_rating_ios— responde a classificação etária da App Store da versão em preparação com as respostas de um arquivo JSON. A versão precisa existir antes
promote_android, update_rollout_android, release_ios, update_review_info_ios, update_age_rating_ios e as duas ferramentas de screenshot só publicam com confirm=true. Sem ele, as ferramentas do Android validam a mudança na Google Play sem publicar nada, release_ios e update_review_info_ios só descrevem o que vão fazer, update_age_rating_ios lista as respostas que mudariam e upload_screenshots_ios lista as imagens que encontrou.
Arquivo de classificação etária
O update_age_rating_ios recebe em answers_path um JSON com os nomes de campo e os valores do recurso ageRatingDeclarations da App Store Connect API. São os mesmos nomes que aparecem nos erros do release_ios, como userGeneratedContent:
{
"ageRatingOverrideV2": "EIGHTEEN_PLUS",
"matureOrSuggestiveThemes": "FREQUENT",
"userGeneratedContent": false
}As perguntas que não estão no arquivo ficam como estão.
Um nome de campo desconhecido faz a ferramenta parar antes de chamar a Apple e listar os nomes válidos.
Cada projeto guarda o próprio arquivo, porque as respostas dependem do conteúdo do app.
Organização das screenshots
As ferramentas de screenshot recebem uma pasta por loja, com uma subpasta por idioma. O servidor publica o padrão completo no resource MCP upload-app://screenshots/layout, para que skills e agentes leiam a regra direto do servidor.
screenshots-ios/
pt-BR/
01-home.png 1320×2868, iPhone 6,9"
02-ipad-home.png 2064×2752, iPad 13"
screenshots-android/
pt-BR/
images/
phoneScreenshots/
01-home.png
tenInchScreenshots/
01-home.pngNo iOS, o fastlane descobre o aparelho pela resolução, e as imagens ficam soltas na pasta do idioma. Para cada idioma da pasta, todas as screenshots daquele idioma são apagadas antes, em todos os aparelhos.
No Android, a subpasta diz o aparelho:
phoneScreenshots,sevenInchScreenshots,tenInchScreenshots,tvScreenshotsouwearScreenshots. Só os aparelhos com imagens na pasta são substituídos.As imagens sobem na ordem do nome do arquivo.
Os códigos de idioma seguem cada loja. Para espanhol da América Latina, use
es-MXno iOS ees-419no Android.
Related MCP server: appstore-connect-mcp
Pré-requisitos
Funciona só no macOS, porque o envio para o TestFlight depende do Xcode.
uv: baixa e executa o servidor. Se a máquina não tiver Python 3.10 ou mais novo, o
uvbaixa um sozinho.git: o
uvxusa o git para baixar o código deste repositório.fastlane: faz os envios para as lojas.
Xcode: necessário para
upload_ios.
Com Homebrew:
brew install uv git fastlaneConfiguração
1. Google Play
No Google Cloud, habilite a Google Play Android Developer API, crie uma service account e baixe a chave JSON.
No Play Console, em Usuários e permissões → Convidar novo usuário, convide o e-mail da service account com as permissões de lançamento em faixas de teste e em produção nos apps desejados. Para
upload_screenshots_android, a service account também precisa da permissão de gerenciar a presença na loja.Guarde a chave num local fixo e anote o caminho completo. O caminho vai na variável
GOOGLE_APPLICATION_CREDENTIALSquando você registrar o servidor no cliente MCP.
Se você já criou o arquivo ~/.config/google-play-console/.env para o mcp-google-play-console, este servidor lê o mesmo arquivo. Acrescente ao arquivo o caminho da chave de publicação na variável SUPPLY_JSON_KEY:
echo 'SUPPLY_JSON_KEY=/Users/voce/keys/play-publisher.json' >> ~/.config/google-play-console/.envSe a mesma service account publica e lê relatórios, use o mesmo caminho do PLAY_CONSOLE_CREDENTIALS. Para usar outro arquivo, defina PLAY_CONSOLE_ENV_FILE com o caminho dele. Variáveis já definidas no ambiente têm prioridade sobre o arquivo, mas o SUPPLY_JSON_KEY do arquivo tem prioridade sobre o GOOGLE_APPLICATION_CREDENTIALS do ambiente.
2. App Store Connect
O servidor usa as mesmas variáveis do mcp-app-store-connect:
Variável | Valor |
| Key ID da chave, ex. |
| Issuer ID, ex. |
| Caminho completo do |
Se você já criou o arquivo ~/.config/app-store-connect/.env para aquele servidor, este lê o mesmo arquivo e não precisa de mais nada. Para usar outro arquivo, defina APP_STORE_CONNECT_ENV_FILE com o caminho dele. Variáveis já definidas no ambiente têm prioridade sobre o arquivo.
A chave precisa da função App Manager ou Admin para enviar builds para review.
Instalação e uso
Claude Code
Registre o servidor. O
--scope userdeixa o servidor disponível em qualquer pasta.claude mcp add --scope user upload-app \ --env GOOGLE_APPLICATION_CREDENTIALS=/Users/voce/keys/play-publisher.json \ -- uvx --from git+https://github.com/brunosemfio/mcp-upload-app.git upload-app-mcpSe a chave do Google Play estiver no arquivo
.env, remova a linha de--env.Rode
claude mcp list. Oupload-appdeve aparecer como conectado.
Para trocar algum valor, remova o servidor com claude mcp remove --scope user upload-app e registre de novo.
Claude Desktop
Abra o arquivo de configuração em Settings → Developer → Edit Config e adicione o servidor dentro de mcpServers:
{
"mcpServers": {
"upload-app": {
"command": "/opt/homebrew/bin/uvx",
"args": [
"--from",
"git+https://github.com/brunosemfio/mcp-upload-app.git",
"upload-app-mcp"
],
"env": {
"GOOGLE_APPLICATION_CREDENTIALS": "/Users/voce/keys/play-publisher.json",
"PATH": "/opt/homebrew/bin:/usr/bin:/bin"
}
}
}
}Troque
/opt/homebrew/bin/uvxpelo resultado dewhich uvx.O
PATHdeixa o servidor encontrar ofastlane. O Claude Desktop aberto pelo Dock não enxerga o PATH do terminal.Se a chave do Google Play estiver no arquivo
.env, remova a linha doGOOGLE_APPLICATION_CREDENTIALS.
Encerre o Claude Desktop com Cmd+Q e abra de novo para carregar a configuração.
O uvx faz cache do build: para atualizar após novos commits, rode o comando uma vez com --refresh. Para fixar uma versão, aponte para uma tag ou commit: git+https://...@<tag-ou-sha>.
A partir de um clone local (desenvolvimento)
git clone https://github.com/brunosemfio/mcp-upload-app.git
cd mcp-upload-app
uv sync
uv run upload-app-mcpPara registrar no cliente MCP, use como comando o executável que o uv sync cria dentro do clone: /caminho/do/clone/.venv/bin/upload-app-mcp.
Desenvolvimento
uv sync --extra dev
uv run pytest
uv run ruff check upload_app_mcp tests
uv run mypy upload_app_mcpOs testes não chamam o fastlane nem as lojas. O CI (GitHub Actions, branch main) roda ruff, mypy e a suíte com cobertura mínima de 65% em Python 3.10 e 3.12.
Exemplos de perguntas
"Envie /caminho/app-release.aab para a faixa internal do com.example.app."
"Promova o version code 42 do com.example.app para produção com rollout de 20% e a nota 'Correções de bugs'."
"O crash rate da versão 42 subiu. Pare o rollout."
"O build 15 do com.example.app já terminou de processar? Se sim, envie a versão 1.2.0 para review."
Notas
upload_iosnão espera o processamento da Apple, que costuma levar de 10 a 30 minutos. Usestatus_ios: o build só pode ir para review quando estiverVALID.Sem
release_notes,release_iosnão altera os metadados da versão, e as novidades precisam estar preenchidas no App Store Connect. Comrelease_notes, o texto vai para todos os idiomas da versão publicada, ou para o idioma principal do app se ainda não houver versão publicada.No
promote_android,localeé o código de idioma da Play para as notas da versão, por padrãopt-BR.O
Info.plistdo app precisa declararITSAppUsesNonExemptEncryption; sem isso, a Apple pede a conformidade de exportação e o envio para review falha.update_review_info_iosmarca o início de sessão como obrigatório e não altera os dados de contato. A senha passa como parâmetro da ferramenta e fica no histórico da conversa. No Android, o equivalente é a seção "Acesso ao app" da Play Console, que a API da Play não expõe: preencha pela Play Console.rolloutaceita valores maiores que 0 e até 1. Abaixo de 1, a release entra em produção como lançamento gradual. Para retomar uma release parada, chameupdate_rollout_androidcom uma nova fração.Cada ferramenta devolve as últimas 40 linhas da saída do fastlane e tem timeout de 30 minutos.
Available Tools
7 toolspromote_androidA
Promote a version code from a Google Play test track to production. A rollout below 1 starts a staged rollout. release_notes sets the release notes in the given Play language code. Without confirm=true it only validates with Google Play and publishes nothing.
Inputs: package_name (required), version_code (required), locale, confirm, +3 more. Returns: result
release_iosA
Attach a TestFlight build to an App Store version, creating the version if needed, and submit it for review. release_notes sets What's New in every language of the live version. Without confirm=true it only describes what it would do.
Inputs: app_version (required), build_number (required), app_identifier (required), confirm, +1 more. Returns: result
status_androidB
List the Google Play releases of every track with version codes, status and rollout fraction.
Inputs: package_name (required). Returns: result
status_iosB
Show the latest App Store versions with their state and the latest builds with their processing state. A build can be submitted only after it is VALID.
Inputs: app_identifier (required). Returns: result
update_rollout_androidA
Change a Google Play production release: a new rollout fraction, 1 to complete it, or halt=true to stop it. Without confirm=true it only validates with Google Play and publishes nothing.
Inputs: package_name (required), version_code (required), halt, confirm, +1 more. Returns: result
upload_androidB
Upload an .aab to a Google Play test track: internal, alpha, beta or the name of a custom closed track.
Inputs: aab_path (required), package_name (required), track. Returns: result
upload_iosC
Upload an .ipa to TestFlight without waiting for Apple's processing.
Inputs: ipa_path (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
Each tool maps to a distinct platform and lifecycle action: iOS status/upload/release versus Android upload/promote/rollout-update/status. The closest overlap, promote_android and update_rollout_android, is clarified by one promoting to production and the other modifying an existing production rollout.
All names use snake_case with a clear action plus platform suffix pattern (status_ios, upload_android, promote_android, release_ios, etc.). The convention is predictable across both platforms.
Seven tools is well-scoped for a mobile app upload/release server. Each tool covers a meaningful lifecycle operation without redundant variants.
The surface covers core upload, status, promotion, rollout, and review-submission workflows for both iOS and Android. Minor gaps remain, such as Android build-processing status and iOS review cancellation, but the main lifecycle is covered.
Related MCP Connectors
Share iOS and Android test builds: upload, install links, testers, store readiness and releases.
Ship over-the-air updates for Capacitor apps: publish releases after your approval, control staged rollouts, read rollout health, and revert.
Manage App Store and Google Play apps: listings, screenshots, builds, releases, reviews, metrics.
Create App Store screenshots, app icons and store copy, then push them to App Store Connect.
Related MCP Servers
- AlicenseAqualityDmaintenanceManage the full Google Play Store release lifecycle directly — from uploading artifacts to managing testers, rollouts, and Android Vitals.167MIT
- AlicenseNot gradedqualityDmaintenanceEnables automated management of iOS apps, builds, TestFlight beta testing, and user access control through Apple's App Store Connect API.28 npmMIT
- AlicenseAqualityDmaintenanceAn MCP server that drives the full App Store release cycle for iOS and macOS apps: version bump, archive + TestFlight upload, metadata, review submission, and status.843 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to automate Android release workflows via the Google Play Android Publisher API, including deploying builds, managing listings, and replying to reviews.40MIT