Skip to main content
Glama
Upload App MCP Server

Upload App MCP Server

by brunosemfio

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 .aab para uma faixa de teste (internal, alpha, beta ou o nome de uma faixa fechada personalizada; padrão internal)

  • promote_android — promove um version code de uma faixa de teste para produção, com rollout gradual e notas da versão opcionais

  • update_rollout_android — muda a fração de uma release de produção, completa o rollout com 1 ou para a release com halt=true

  • status_android — lista as releases de cada faixa, com version codes, status e fração do rollout

  • upload_ios — envia um .ipa para o TestFlight, sem esperar o processamento da Apple

  • release_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 opcionais

  • status_ios — mostra as últimas versões da App Store com o estado de cada uma e os últimos builds com o estado do processamento

  • upload_screenshots_ios — substitui as screenshots de uma versão da App Store pelas imagens de uma pasta

  • update_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 Store

  • upload_screenshots_android — substitui as screenshots da ficha da Google Play pelas imagens de uma pasta

  • update_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.png
  • No 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, tvScreenshots ou wearScreenshots. 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-MX no iOS e es-419 no 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 uv baixa um sozinho.

  • git: o uvx usa 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 fastlane

Configuração

1. Google Play

  1. No Google Cloud, habilite a Google Play Android Developer API, crie uma service account e baixe a chave JSON.

  2. 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.

  3. Guarde a chave num local fixo e anote o caminho completo. O caminho vai na variável GOOGLE_APPLICATION_CREDENTIALS quando 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/.env

Se 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

APP_STORE_CONNECT_KEY_ID

Key ID da chave, ex. 2X9R4HXF34

APP_STORE_CONNECT_ISSUER_ID

Issuer ID, ex. 57246542-96fe-1a63-e053-0824d011072a

APP_STORE_CONNECT_PRIVATE_KEY_PATH

Caminho completo do .p8

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

  1. Registre o servidor. O --scope user deixa 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-mcp

    Se a chave do Google Play estiver no arquivo .env, remova a linha de --env.

  2. Rode claude mcp list. O upload-app deve 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/uvx pelo resultado de which uvx.

  • O PATH deixa o servidor encontrar o fastlane. 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 do GOOGLE_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-mcp

Para 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_mcp

Os 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_ios não espera o processamento da Apple, que costuma levar de 10 a 30 minutos. Use status_ios: o build só pode ir para review quando estiver VALID.

  • Sem release_notes, release_ios não altera os metadados da versão, e as novidades precisam estar preenchidas no App Store Connect. Com release_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ão pt-BR.

  • O Info.plist do app precisa declarar ITSAppUsesNonExemptEncryption; sem isso, a Apple pede a conformidade de exportação e o envio para review falha.

  • update_review_info_ios marca 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.

  • rollout aceita 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, chame update_rollout_android com 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 tools
promote_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

    A3.7/5.0

    Scored across 7 tools

    Disambiguation5/5

    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.

    Naming Consistency5/5

    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.

    Tool Count5/5

    Seven tools is well-scoped for a mobile app upload/release server. Each tool covers a meaningful lifecycle operation without redundant variants.

    Completeness4/5

    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

    Related MCP Servers