Appo MCP
Official@appolabs/appo-mcp
Local MCP (Model Context Protocol) server for the Appo app
platform. It gives an AI agent the same app lifecycle outcomes as the appo CLI
— create, configure, preview, publish, push, rejection recovery, test builds,
resubmission — plus local code-generation dev-tools for the
@appolabs/appo SDK.
The server carries no API client of its own: every lifecycle call reuses the
CLI core (@appolabs/appo ops/api/config). Tool names mirror the canonical
/mcp AppoServer vocabulary documented in
apps-web-app/docs/CROSS-SURFACE-PARITY.md, so an agent sees one vocabulary
across both MCP surfaces.
Installation
Add to your .mcp.json:
{
"mcpServers": {
"appo": {
"command": "npx",
"args": ["-y", "@appolabs/appo-mcp"]
}
}
}Authentication
The server does not prompt for credentials or hold credential state. It resolves auth exactly as the CLI does, so both surfaces always target the same environment:
appo loginonce. After a device-flow login with the CLI, the token is stored in the active profile (~/.appo/config.json). The server reads it through the shared config module — no extra configuration.APPO_TOKENoverride. SetAPPO_TOKENto supply a PAT directly (CI / non-interactive contexts); it takes precedence over the stored profile token.Base URL / profile.
APPO_API_BASEenv → the active profile'sapi_base→http://localhost:8002. Profile selection:APPO_ENV→ configcurrent→default.
If no token can be resolved, every lifecycle tool returns a structured
{ error: "not_authenticated", message, next_actions: [] } envelope (it never
crashes) — the message tells the operator to run appo login.
Tools (20)
App lifecycle
Reuse the CLI core; names match the canonical /mcp inventory.
Tool | Outcome | Gate |
| Create an app ( | — |
| Set content fields ( | — |
| Set the app icon from an https | — |
| List the apps owned by the authenticated principal | — |
| App config, publication state, and metadata in one read; single-app default when | — |
| Open-on-device payload (iOS TestFlight URL, Android deeplink, QR target, per-platform readiness) | — |
| Poll a build by id until | — |
| Curated required action for a rejected app (never raw reviewer text) | — |
| Code-free remediation recipes for the current rejection | — |
| Start publication to the chosen stores | confirm |
| Remove an app from the chosen stores | confirm |
| Send a push to the app's devices | confirm |
| Resubmit a rejected app for review (requires a customer-owned Apple credential) | confirm |
There is intentionally no ship tool and no publish-build trigger.
Agents chain create_app → publish_app (and trigger_resubmission for
rejection cycles). Build triggering is not exposed: the store-publish-kind build
is operator-internal (Nova Release), and self-serve verification is via preview_app
(the managed preview).
Local dev-tools
Operate on the local project; no CLI or remote-MCP equivalent by design.
Tool | Description |
| Generate a React hook for an SDK feature |
| Generate a UI component with SDK integration |
| Scaffold a feature (hook + component + types) |
| Validate SDK installation and configuration |
| Analyze permission-handling patterns |
| Diagnose common SDK integration issues |
| Emit |
Confirm-gate semantics
Destructive tools (publish_app, unpublish_app, send_push,
trigger_resubmission) take an optional confirm: boolean. Without
confirm:true they perform no write and return a preview envelope
({ error: "confirm_required", will, ..., next_actions }) describing what would
happen. This mirrors the CLI's --confirm flag / exit-code-3 semantics at the
MCP idiom layer.
Error envelopes
Errors are returned as structured data, never thrown. Every tool returns
{ error, message, next_actions } (plus status for HTTP errors). HTTP status
maps to a stable code: 401 → not_authenticated, 403 → forbidden,
404 → not_found, 409 → conflict, 422 → validation_error, otherwise
request_failed. Each response carries structuredContent (the canonical
envelope) and a JSON text mirror in content for text-only clients.
Resources & prompts
URI | Description |
| SDK overview and capabilities |
| API reference per feature |
| Code examples per feature |
| Integration best practices |
| Common issues and solutions |
Prompts: setup_wizard, integrate_feature, debug_assistant.
Features: push, biometrics, camera, location, haptics, storage, share, network,
device.
Breaking changes in 2.0.0
This release adopts the canonical tool vocabulary and the CLI-shared auth chain.
get_appremoved — superseded byget_app_overview(single-call config + publication state + metadata, with a single-app default).update_appsplit intoconfigure_app(content fieldsname/base_urlviaPATCH /apps/{id}) andset_icon(POST /apps/{id}/icon, httpsicon_url).update_app's catch-all field list (splash colors, injected CSS/JS, path fields, …) is gone — webview injection is a dashboard concern and is not on the CLI/MCPconfiguresurface.Env vars renamed —
APPS_API_URL/APPS_API_TOKENare no longer read. Use the CLI-canonicalAPPO_API_BASE/APPO_TOKEN, or simplyappo loginand let the server read the stored profile.
Development
pnpm install
pnpm build # tsup (ESM + CJS + DTS)
pnpm dev # watch
pnpm typecheck # tsc --noEmit
pnpm test # vitestLicense
MIT