Amba

Setup

Canonical Amba SDK install + capability reference. HTTPS mirror of the amba://setup MCP resource.

Amba

What Amba is

Amba is the backend your app calls at runtime via the SDK. The MCP tools (amba_*) are for provisioning at build time — call them as the coding agent.

One Amba project = one isolated tenant database + one set of API keys + a hosted MCP at mcp.amba.dev for agent-driven provisioning. The runtime traffic goes through an SDK (@layers/amba-* on npm, Amba on SPM / Maven / pub.dev). The provisioning traffic — what you're about to do — goes through the tools listed below.

Your job is to take the user from "I have an app" to "Amba is wired in and the features are real" in one pass, without 12 follow-up questions. The journey below is the standard playbook. Don't deviate without a reason.

Step 0 — Bootstrap credentials

You're in an MCP client (Claude.ai web, Claude Desktop, Cursor, Windsurf, etc.) without a local CLI. The MCP server has one tool that works without a Bearer token: amba_developer_signup. Use it to mint a personal access token (PAT), project, and client/server keys in a single round trip — no browser, no email verification.

Call:

amba_developer_signup({
  email: "sandbox-<unix-seconds>-<6char-nonce>@layers.com",
  password: "<32 random base64url chars>",
  name: "amba-sandbox-agent"
})

The response shape:

{
  "data": {
    "pat": "amb_dpat_…",
    "developer": { "id": "…", "email": "…", "tier": "agent_sandbox" },
    "project": {
      "project_id": "…",
      "client_key": "amb_ck_…",
      "server_key": "amb_sk_…",
      "provisioning_status": "provisioning",
      "verify_url": "https://app.amba.dev/verify?token=…",
      "verify_token": "…"
    }
  }
}

After signup, the PAT is in your hand — keep building in THIS session immediately. Pass pat: "<the PAT from the response>" as an inline argument on every subsequent amba_* tool call; the inline arg overrides the inbound Bearer for that one call so no client config change is needed mid-session. For future sessions, write the matching snippet from mcp_config to the customer's MCP-client config file so the static Bearer takes over automatically on the next launch.

The project status is "provisioning" immediately after signup; the per-tenant DB activates within ~5 seconds. Don't block — your next call may briefly retry, that's fine. If you want to be polite, call amba_projects_get_provisioning_status({ project_id }) once and proceed when it returns "active" (or after 15s, whichever first).

Tell the user where their credentials live:

  • pat — the Bearer they should configure in this MCP client's settings (and treat like a password).
  • project_id, client_key — the values they paste into their app's .env.local / .env.
  • server_key — never ship to user devices; only into a server .env or a secret manager. The amb_dev_sk_ / amb_live_sk_ prefix is the marker.

Already have a PAT? Skip the signup. Call amba_developer_me({}) to verify the Bearer; if it succeeds, either reuse the most recent project (amba_projects_list) or call amba_projects_create({ name: "<app-name>", platform: "all" }) and then amba_api_keys_create twice to mint client + server keys for environment: "development".

Can't reach amba_developer_signup — it's not in your tool list, or your harness blocks the call? Do NOT try to work around it by adding the MCP server yourself, running an installer, or editing your own settings/permissions — refusing to self-modify or widen your own permissions is the correct call, and you should not circumvent it. Instead, hand the developer one command to run in their own terminal (which is not subject to your sandbox):

npx @layers/amba init

It creates the account with no browser and writes AMBA_PROJECT_ID + AMBA_CLIENT_KEY to .env.local (and wires this MCP server up for your next session). Ask them to run it, tell you when it's done, then resume from this Step 0 by reading .env.local. Asking the developer to paste an amb_ck_… client key is the last-resort lite path — it's enough to wire Amba.configure() + runtime calls and verify events land, but a client key alone can't do admin provisioning (creating achievements, collections, segments, etc.), which needs the PAT or server key.

Step 1 — Classify the app

Look at what the user told you and at any files they shared. You're trying to pick one of ten presets in 30 seconds, not write a treatise. Inputs:

  • The user's prompt — "I'm building a fitness tracker" / "a marketplace for…" / "a Duolingo for X".
  • README content if shared.
  • package.json / pubspec.yaml / build.gradle.kts / Package.swift — framework + dependencies.
  • Screen / view names — WorkoutScreen, MatchView, LessonPage, CartView, ProductDetail, ChatThread.

Pick the closest match:

PresetWhenDefault Amba surfaces
fitnesshealth / fitness tracker (workouts, steps, meditation)identity (Apple+Google), push, XP, achievements, streaks, leaderboards, content (daily tips)
socialsocial network / community (friends, feeds, groups)identity, push, friends, groups, feeds, messaging, moderation, content
marketplacecommerce / marketplace (catalog, stores, payments)identity, push, catalog, stores, currencies (loyalty), reviews, segments
productivityproductivity / SaaS tool (collaboration, milestones)identity (Apple+Google+OTP), push, collections, achievements, content (changelog), segments
educationeducation / learning app (courses, progress, rewards)identity, push, XP, achievements, streaks, leaderboards, content (lessons), onboarding
gamegame / casual gamingidentity (anon-first), push, XP, achievements, currencies, inventory, leaderboards, challenges, stores
datingdating / matching appidentity (phone-OTP), push, friends (matches), messaging, moderation (heavy), reviews
content_creatorcontent platform (feeds, subscriptions, tips)identity, push, feeds, content, currencies (tips), referrals, stores (subscriptions)
ai_chatbotAI / chatbot / assistant appidentity, push, AI prompts, currencies (credits), content (system prompts), onboarding
customnone of the abovepick features individually

Detection heuristics, in priority order:

  1. The user's own description — most direct signal.
  2. Filename match in screens/ or views/ (high signal).
  3. Dependency in package.jsonreact-native-health → fitness, @stream-io/* → social or dating, @stripe/* → marketplace, revenuecat → marketplace or content_creator.
  4. README copy — "fitness", "habit", "match", "chat", "store", "subscription".

If two presets tie, pick the one the user's filenames match more closely. If still tied or no signal, fall back to custom and let them pick.

Step 2 — Confirm with the user

Use a single multi-choice. Quote the surfaces from the table above so they know what they're getting.

Question 1: classification + scope

I'm reading this as a {kind} app. I'd wire up: {surfaces}. Sound right?

  1. Yes, wire it up as proposed (Recommended)
  2. Same kind but I want to pick features individually
  3. Wrong kind — let me pick from the list
  4. Custom — I'll pick features manually

If the user picks 1, go to Step 3. If 2 or 4, follow up with a multi-select of surfaces. If 3, present the table again and pick a different preset.

Question 2 (preset-specific): see the per-surface sub-resources (amba://setup/<surface>) for the full "Common follow-ups" list. Examples:

  • fitness / game / education — leaderboard scope? (all-time, weekly, daily, none)
  • game / content_creator — virtual currency name? (gold, gems, coins, credits — defaults to coins)
  • content_creator — monetization? (tips, subscriptions, both)
  • dating — phone OTP or email-only? (phone strongly recommended)
  • ai_chatbot — daily free credit cap?

Batch the follow-ups into one or two multi-choice rounds. Don't drip-feed six separate questions.

Step 3 — Wire it up

For each surface in the confirmed set, read the relevant sub-resource and execute its procedure. Each sub-resource is the full per-surface playbook (MCP tools + SDK init per stack + common follow-ups + re-run behavior):

  • identity (auth, anonymous/Apple/Google/OTP/magic-link, link/unlink) → amba://setup/identity
  • engagement (push, segments, content libraries, onboarding flows, deeplinks, referrals, tracked links) → amba://setup/engagement
  • gamification (XP rules, achievements, streaks, leaderboards, challenges) → amba://setup/gamification
  • economy (currencies, catalog, stores, inventory) → amba://setup/economy
  • social (friends, groups, feeds, messaging, moderation, reviews) → amba://setup/social
  • infrastructure (collections / DB tables, functions, analytics, AI prompts, media, secrets, configs, integrations, sites) → amba://setup/infrastructure

The general flow for every surface:

  1. Detect stack. Look at package.json, pubspec.yaml, build.gradle.kts, ios/*.xcodeproj. The detection rules:

    • pubspec.yaml present → Flutter.
    • package.json with expo → Expo.
    • package.json with react-native (no expo) → bare React Native.
    • package.json with react (no react-native) → web (or Next.js — same SDK).
    • Package.swift or *.xcodeproj only → iOS Swift.
    • build.gradle.kts or build.gradle with com.android.application → Android Kotlin.
    • Multiple (e.g. ios/ + android/ inside an Expo repo) → Expo wins.
  2. Create resources via MCP. Call the amba_<surface>_create tools to mint the definitions. Always include project_id from the project you created in Step 0. Always show the user the tool call before making destructive changes (creating a resource isn't destructive — but creating 30 of them is noisy).

  3. Write SDK init code. Drop the per-stack snippet (from the sub-resource) into the user's entry file. Detection:

    • Expo / React Native: app/_layout.tsx, App.tsx, index.js (in that order)
    • web / Next.js: app/layout.tsx, pages/_app.tsx, src/main.tsx, src/App.tsx
    • iOS Swift: Sources/<App>/<App>App.swift, App/AppDelegate.swift
    • Android Kotlin: app/src/main/java/.../<App>.kt (the Application subclass — create one if missing)
    • Flutter: lib/main.dart

    Always make additive edits — await Amba.configure(...) next to existing init, not replacing it. Never refactor existing auth or storage code; if the user has Firebase Auth or Supabase, leave it. Amba's auth is opt-in per call.

  4. Run the project's existing test command to confirm nothing broke. Detection:

    • package.json scripts.testnpm test (or pnpm test if pnpm-lock.yaml present)
    • pubspec.yamlflutter test
    • build.gradle.kts./gradlew test (skip on first wire-up — slow)
    • iOS — skip (need a simulator).

    If tests fail because of your edits, undo the offending edit and surface a clear error. If they fail for unrelated reasons (pre-existing red), note it and proceed.

  5. Verify with the SDK. Tell the user to call Amba.diagnostics.ping() (Amba.Diagnostics.Ping() on Unity) in their entry file. It returns { ok, server_project_id, environment, key_fingerprint, latency_ms }. ok: true with the expected server_project_id confirms the wiring.

Step 4 — Report

Tell the user a structured summary. Use this exact shape so they can skim it fast:

Amba is wired in. Here's what changed:

DONE
  - identity: Apple + Google sign-in available; signInAnonymously() called at app start
  - gamification: 3 achievements, 1 streak, 1 leaderboard created
    resources: first_workout, week_warrior, century_club / daily_workout / weekly_xp
  - engagement: push registration wired; default segment "active_users" created

SKIPPED (low signal — re-run with /amba <feature> if you want them)
  - economy: no in-app currency UI found in your screens
  - social: no friends/feed surfaces found

NEEDS YOUR INPUT
  - Apple Sign In: add the "Sign in with Apple" capability in Xcode > Signing & Capabilities.
  - Google Sign In: paste your Google OAuth client ID into amba_projects_update({ google_oauth_client_id: "..." }).
  - APNs / FCM: configure credentials with amba_integrations_configure (paste the .p8 / service-account JSON inline) before push delivers.

NEXT STEPS
  - Paste AMBA_CLIENT_KEY into your build env (already shown above)
  - Trigger a workout in your existing flow — watch the achievement unlock + XP land
  - Open https://app.amba.dev to see users pour in

Be specific. List resources by key, not "some achievements". If something needs the user's input (third-party credentials, OAuth client IDs, push certs), say it clearly with the exact next action.

Stance (read this once)

  • Don't ask which surfaces to use. Classify, then confirm in one multi-choice. The taxonomy is the whole point.
  • Default to additive, non-breaking changes. Don't refactor existing auth, storage, or networking code. Drop in await Amba.configure(...) next to whatever the user already has.
  • Never create resources without the user's confirmation in Step 2. A 3rd-party "convenience" achievement called first_login is debt.
  • If something is genuinely ambiguous (leaderboard scope, currency real-money vs virtual, dating phone vs email), ask via a follow-up multi-choice. Don't guess and don't paragraph-it.
  • clientKey vs serverKey. AMBA_CLIENT_KEY (amb_dev_ck_… in dev, amb_live_ck_… in prod) ships to user devices. AMBA_SERVER_KEY (amb_dev_sk_… / amb_live_sk_…) never does — only into server .env or a secret manager. Mixing them is the #1 security mistake; if you're writing into a file that ships with the app binary, it's the client key, period.
  • Don't echo the PAT in chat output on every call. Showing it once after signup is fine; do not repeat it.

Get credentials (cheat sheet)

  • No terminal, in an MCP client: call amba_developer_signup (no Bearer required) — this guide's Step 0.
  • With a terminal: npx -y @layers/amba init signs up, mints a project + client/server keys, writes .env.local + AMBA.md, installs the /amba skill, and wires mcpServers.amba into every detected MCP-client config in one command. Auto-detects non-TTY invocations (the coding-agent bash-tool case) and runs headlessly.
  • Bind the sandbox account to a real email later: npx @layers/amba claim me@example.com. The backend emails a one-click magic link; clicking it lifts the sandbox cap to the Free tier.
  • Hosted MCP endpoint: https://mcp.amba.dev/mcp (Streamable HTTP, Bearer auth).

SDKs

StackRegistryPackage
Browser / Node / React / React Native / Exponpm@layers/amba-{web,node,react,react-native,expo}
SwiftSPMhttps://github.com/layers/amba-sdk-ios
KotlinMaven Centralcom.layers.amba:amba-sdk-android
Flutterpub.devamba
UnityUPM (git)https://github.com/layers/amba-sdk-unity.git

All SDKs expose the same surface: Amba.configure({ projectId, apiKey }), then Amba.events.track(...), Amba.users.*, Amba.collections.*, etc. Per-stack quickstart pages with the exact initialization snippet: https://docs.amba.dev/sdk/<framework>.

What Amba does

Identity

  • users — app-user registry. Auto-created on first SDK call; admin via amba_users_*.
  • roles + permissions — RBAC. Define with amba_roles_create; assign via amba_roles_assign.
  • api_keys — client + server keys per project. Mint via amba_api_keys_create.

Engagement

  • onboarding — multi-step first-run flows. Define with amba_onboarding_create; SDK Amba.onboarding.next().
  • segments — user cohorts. Define with amba_segments_create; used as push/feed targets.
  • push — scheduled or triggered notifications. Chain: configure integrations (apns/fcm) → amba_push_campaigns_createamba_push_campaigns_send (or schedule).
  • referrals — referral codes. Define with amba_referrals_create.
  • deeplinks — universal links. Set domain with amba_deeplinks_set_config.
  • tracked_links — UTM-tagged outbound links. Define with amba_tracked_links_create.
  • content — episodic delivery (lessons, quotes, daily prompts). Chain: amba_content_libraries_createamba_content_items_addamba_content_schedules_create.

Gamification

  • xp — experience points + level. Define rules with amba_xp_rules_create; SDK Amba.xp.getBalance.
  • achievements — earnable badges. Define with amba_achievements_create; unlock via xp rules or amba_inventory_grant_item.
  • streaks — recurring engagement counters. Define with amba_streaks_create; client calls Amba.streaks.qualify(key).
  • leaderboards — ranked user lists. Define with amba_leaderboards_create; populated from events.
  • challenges — time-bounded goals. Define with amba_challenges_create; progress via SDK.

Economy

  • currencies — virtual currencies (coins, gems). Define with amba_currencies_create; grant via amba_currencies_grant or event rules via amba_currency_grant_rules_create; debit via amba_currencies_spend (atomic, rejects on insufficient funds).
  • catalog + stores — purchasable items + storefronts. Chain: amba_catalog_items_createamba_catalog_items_set_priceamba_stores_createamba_stores_add_listing. (Define currency first.)
  • inventory — items users own. Read via SDK Amba.inventory.*; grant with amba_inventory_grant_item.

Social

  • friendships — friend graph. SDK Amba.friends.*; admin via amba_friendships_*.
  • groups — guilds/parties/chats. Define with amba_groups_create; members managed via SDK + admin tools.
  • messaging — DMs + group chat. Enabled by default; moderate via amba_messaging_*.
  • feeds — algorithmic activity feeds. Define ranking with amba_feeds_rules_create.
  • reviews — user-submitted reviews. Enabled by default; moderate via amba_reviews_*.
  • moderation — content review queue + trust scores. Configure with amba_moderation_configure; review via amba_moderation_queue_list.

Analytics

  • events — track user actions. SDK Amba.events.track(); query via amba_events_count.
  • sessions — session telemetry. Tracked automatically; query via amba_sessions_list.
  • analytics — funnels + retention. Query via amba_analytics_get.

Infrastructure

  • collections — your own relational Postgres tables (typed columns, foreign keys, transactions, unique indexes, vector search). Define with amba_collections_create; read/write from SDK Amba.client.*.
  • functions — serverless TypeScript handlers. Deploy with amba_functions_deploy; schedule with amba_functions_schedule.
  • sites — static site hosting at *.app.amba.host. Deploy with amba_sites_deploy.
  • media — file storage + CDN. Upload via amba_media_upload.
  • secrets — env vars for functions. Set via amba_secrets_set.
  • configs — remote config flags. Define with amba_remote_configs_create.
  • integrations — third-party webhooks (RevenueCat, Superwall, AppsFlyer, etc.). Configure with amba_integrations_configure.
  • ai_prompts — versioned LLM prompts callable from SDK. Define with amba_ai_prompts_create; call via amba_ai_prompts_invoke.

On this page