Skip to main content
Glama
appolabs

Appo MCP

Official
by appolabs

@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:

  1. appo login once. 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.

  2. APPO_TOKEN override. Set APPO_TOKEN to supply a PAT directly (CI / non-interactive contexts); it takes precedence over the stored profile token.

  3. Base URL / profile. APPO_API_BASE env → the active profile's api_basehttp://localhost:8002. Profile selection: APPO_ENV → config currentdefault.

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_app

Create an app (name, base_url)

configure_app

Set content fields (name, base_url); content-only, mirrors CLI apps update

set_icon

Set the app icon from an https icon_url

list_apps

List the apps owned by the authenticated principal

get_app_overview

App config, publication state, and metadata in one read; single-app default when app_id is omitted. Start here

preview_app

Open-on-device payload (iOS TestFlight URL, Android deeplink, QR target, per-platform readiness)

get_build_status

Poll a build by id until ready/failed

get_rejection

Curated required action for a rejected app (never raw reviewer text)

get_fix_recipe

Code-free remediation recipes for the current rejection

publish_app

Start publication to the chosen stores

confirm

unpublish_app

Remove an app from the chosen stores

confirm

send_push

Send a push to the app's devices

confirm

trigger_resubmission

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_apppublish_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_hook

Generate a React hook for an SDK feature

generate_component

Generate a UI component with SDK integration

scaffold_feature

Scaffold a feature (hook + component + types)

validate_setup

Validate SDK installation and configuration

check_permissions

Analyze permission-handling patterns

diagnose_issue

Diagnose common SDK integration issues

generate_universal_links

Emit apple-app-site-association + assetlinks.json with hosting instructions

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

appo://overview

SDK overview and capabilities

appo://api/{feature}

API reference per feature

appo://examples/{feature}

Code examples per feature

appo://best-practices

Integration best practices

appo://troubleshooting

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_app removed — superseded by get_app_overview (single-call config + publication state + metadata, with a single-app default).

  • update_app split into configure_app (content fields name/base_url via PATCH /apps/{id}) and set_icon (POST /apps/{id}/icon, https icon_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/MCP configure surface.

  • Env vars renamedAPPS_API_URL / APPS_API_TOKEN are no longer read. Use the CLI-canonical APPO_API_BASE / APPO_TOKEN, or simply appo login and 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        # vitest

License

MIT