> ## Documentation Index
> Fetch the complete documentation index at: https://aomi.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy and activate on aomi CLI

> Ship an Aomi App from your own GitHub repo to live, using the aomi-build CLI. Connect, deploy, activate, and check status, with the real output at every step.

This guide takes an App from your own GitHub repo to live on Aomi, using the `aomi-build` CLI. You work in your own repo the whole time. You never open a PR against `aomi-labs/community-apps`, and you never need write access to it. The backend does that part for you through the Aomi GitHub App.

<Info>
  **Verified 2026-07-14** against a live community deploy on `https://api.aomi.dev`. Command output on this page is real, not illustrative. Version numbers move: always trust `aomi-build sdk check` over any number written here.
</Info>

The whole flow is four commands:

```text theme={null}
connect  →  deploy  →  activate  →  status
```

`aomi-build deploy` runs the middle of that chain in one shot. Learn each step anyway, because when something fails you fix one step, not the whole flow.

## What you need

* Rust and cargo installed.
* A GitHub repo that holds your Aomi App with `Cargo.toml` and `aomi.toml` at the repo root.
* An activation token issued by the Aomi team. Ask in Discord if you do not have one. Deploying to the `prod` tier needs a platform token; see [Tokens](#tokens).

That is the full list. No GitHub personal access token. No database access. No admin key.

## Step 1: install the CLI

```bash theme={null}
cargo install --git https://github.com/aomi-labs/aomi-sdk --features cli aomi-sdk
```

Confirm it is there:

```bash theme={null}
aomi-build deploy --help
```

<Note>
  Installed it before July 2026? Run the command again to update. Older builds are missing the `--activation-token` flag and a fix that lets `deploy` finish on its own after CI passes. Without them you will get stuck.
</Note>

## Step 2: lay out your repo

The Aomi App is a normal Rust cdylib. Put `Cargo.toml`, `aomi.toml`, and `src/` at the **root** of the repo:

```text theme={null}
my-app/
|-- aomi.toml
|-- Cargo.toml
|-- src/
|   `-- lib.rs
`-- .gitignore
```

<Warning>
  The CLI builds the App from the git repo root. It does not deploy an App that lives in a subdirectory such as `app/` or `apps/my-app/`. If your App sits in a subfolder today, move `Cargo.toml`, `aomi.toml`, and `src/` up to the repo root before you deploy. You can keep other folders, a `ui/` frontend for example, alongside them.
</Warning>

Your `aomi.toml`:

```toml theme={null}
[app]
name         = "my-app"
display_name = "My App"
platform     = "community"
git          = "https://github.com/you/my-app"
public       = true
server_tags  = ["prod"]
```

The settings that matter:

* `name` is the App slug. It must match the `name` in your `dyn_aomi_app!` macro.
* `platform` is `community`.
* `git` is your own source repo, the one you deploy from.
* `public = true` lists your App in the community catalog. Set `false` to keep it private to you.
* `server_tags` picks the tier your release loads on. `["prod"]` goes live on production. Omit it and it defaults to `["staging"]`, which loads only on staging backends. Test on `staging`, then switch to `prod` to go live.

## Step 3: match the SDK version

The platform requires a specific `aomi-sdk` version. Check your pin against the backend:

```bash theme={null}
aomi-build sdk check --backend https://api.aomi.dev
```

When your pin matches, you see:

```text theme={null}
Required aomi-sdk: 3.0.3
Manifest: /path/to/my-app/Cargo.toml
Dependency: exact 3.0.3
Lockfile: matches 3.0.3
SDK check passed.
```

When it is stale, it tells you exactly what is wrong and stops:

```text theme={null}
  - Cargo.toml pins aomi-sdk 3.0.2, but this backend requires 3.0.3.
  - Cargo.lock resolves aomi-sdk 3.0.2, but this backend requires 3.0.3.

Fix: aomi-build sdk fix --path /path/to/my-app/Cargo.toml
Error: SDK check failed
```

Let the CLI rewrite the pin for you:

```bash theme={null}
aomi-build sdk fix --backend https://api.aomi.dev
```

```text theme={null}
    Updating crates.io index
    Updating aomi-sdk v3.0.2 -> v3.0.3
Required aomi-sdk: 3.0.3
Manifest: /path/to/my-app/Cargo.toml
Dependency: exact 3.0.3
Lockfile: matches 3.0.3
SDK check passed.
```

Do not skip this. A version mismatch fails the platform build, not your local one, so it is easy to miss until the deploy dies.

<Warning>
  The version numbers above are only an example of the output shape. **The required version moves often**, sometimes more than once a week. Never hardcode it and never copy a number out of this page: run `aomi-build sdk check` and use whatever it reports. See [When the platform bumps the SDK](#when-the-platform-bumps-the-sdk) for what happens to an App that is already live when the number moves.
</Warning>

## Step 4: commit and push

```bash theme={null}
cargo test
git add aomi.toml Cargo.toml Cargo.lock src
git commit -m "Prepare Aomi deploy"
git push
```

The backend deploys the commit you pushed to GitHub. Local changes you did not push do not exist as far as the deploy is concerned. If a deploy ever picks up old code, this is why.

## Step 5: connect your repo

```bash theme={null}
aomi-build connect --platform community --repo you/my-app
```

This opens the install page for the Aomi Build GitHub App. In GitHub:

1. Pick the account or org that owns your repo.
2. Choose **Only select repositories** and select your App repo.
3. Click **Install**.

After you click install, GitHub sends you to a page that can look unrelated, even a 404. Ignore what the page shows. It is a callback, nothing more. The value you need is in the address bar: the URL ends in `/installations/<number>`. That number is your installation id.

Back in the terminal, paste the installation id when the CLI asks, then paste your activation token. The CLI saves the backend URL, platform, and token to local config so later commands can drop those flags.

If the browser cannot open from your terminal, print the URL instead:

```bash theme={null}
aomi-build connect --platform community --repo you/my-app --no-browser
```

## Step 6: deploy

From the root of your repo:

```bash theme={null}
aomi-build deploy \
  --platform community \
  --repo you/my-app \
  --backend https://api.aomi.dev \
  --activation-token <your-token> \
  --target-tag prod
```

Prefer env vars for repeat runs? Export once, then the short command works every time:

```bash theme={null}
export AOMI_BACKEND_URL=https://api.aomi.dev
export AOMI_APP_ACTIVATION_TOKEN=<your-token>
aomi-build deploy --platform community --repo you/my-app --target-tag prod
```

One command runs the whole lifecycle:

```text theme={null}
sdk check → preflight → deploy run → wait for ready → activate → verify loaded
```

It opens a PR on the platform repo for you, waits for the platform build, activates the release, and verifies the runtime loaded it. A full run looks like this:

```text theme={null}
Resolved source `you/my-app` to app_source_id 1554.
Preflight passed for platform `community`.
  source_commit : 7601d95b9abd37ccbd7047509782331171e844b3
  - my-app -> apps-144438915-r0ed7523bdf-my-app-7601d95b9abd
Deployment started.
  id            : dep_144438915_r0ed7523bdf_7601d95b9abd
  pr            : https://github.com/aomi-labs/community-apps/pull/85
  deployment    : /path/to/my-app/.aomi/deployment.json
Waiting for release readiness...
  build         : building
  build         : ready
Release is ready.
  - my-app : active=true artifact_ready=true loaded=true
Deployment verified: all activated apps are active, artifact-ready, and loaded.
```

The `Waiting for release readiness` step can sit for a few minutes while the platform build runs; that is normal. You are done when you see `active=true artifact_ready=true loaded=true` and the final `Deployment verified` line. The `pr` link is the platform PR the backend opened for your release; you can watch the build there. If it stops partway, do not rerun the whole thing blindly. Go to the step that failed; see [When something goes wrong](#when-something-goes-wrong).

## Step 7: check status and see it live

```bash theme={null}
aomi-build deploy status
```

```text theme={null}
Deployment status
  platform      : community
  deployment_id : dep_144438915_r0ed7523bdf_7601d95b9abd
  pr            : https://github.com/aomi-labs/community-apps/pull/85
  deploy_branch : publish
  local state   : deployed=true activated=true
  backend       : https://api.aomi.dev
  deploy state  : ready
  - my-app (apps-144438915-r0ed7523bdf-my-app-7601d95b9abd)
      local     : activated=true
      backend   : active=true artifact_ready=true loaded
```

Add `--json` for machine readable output. You want `active`, `artifact_ready`, and `loaded` all true.

Open [chat.aomi.dev](https://chat.aomi.dev), find your App, and talk to it. If you deployed an update to an existing App, the new version replaces the old one. You will not see a duplicate.

## Step 8: ship an update

Updates are the same loop, shorter:

```bash theme={null}
cargo test
git add -A && git commit -m "Update my app" && git push
aomi-build deploy --platform community --repo you/my-app --target-tag prod
```

The CLI remembers your backend, token, and source from the first run.

## When the platform bumps the SDK

This is the most common reason a working App stops working, and it happens without you touching anything.

The platform pins a required `aomi-sdk` version. When that requirement moves, every release built against the old version **stops being loadable**. Your App disappears from the App picker in chat with no warning and no error message.

The tell is in `aomi-build deploy status`:

```text theme={null}
  - my-app (apps-...-my-app-...)
      backend   : active=true artifact_ready=false not loaded
```

`active=true` still looks healthy, which is what makes this easy to miss. The signal is **`artifact_ready=false`** and **`not loaded`**. Confirm it with:

```bash theme={null}
aomi-build sdk check --backend https://api.aomi.dev
```

If it reports a required version higher than your pin, that is the cause.

The fix is a normal redeploy against the new version:

```bash theme={null}
aomi-build sdk fix --backend https://api.aomi.dev
cargo build --release
git add Cargo.toml Cargo.lock && git commit -m "Bump aomi-sdk" && git push
aomi-build source sync --platform community --repo you/my-app
aomi-build deploy --platform community --repo you/my-app --target-tag prod
```

Your App is back once you see `active=true artifact_ready=true loaded=true`.

<Note>
  This applies to every deployed App, not just yours. If you deployed once and walked away, check `aomi-build deploy status` before assuming your App is still live.
</Note>

## Activate by hand

`aomi-build deploy` activates for you. You only run activate yourself if you stopped after the build, or you are activating a specific release:

```bash theme={null}
aomi-build deploy activate \
  --backend https://api.aomi.dev \
  --activation-token <your-token> \
  --target-tag prod
```

It reads the release tag from `.aomi/deployment.json`, so run it from the repo root. Success prints `release is ready`. An App that built but never activated shows `activate: false` in status and never appears in chat.

## Tokens

Your activation token authorizes the deploy. There are two kinds:

* An **app token** is scoped to one App. It works for building and app level actions.
* A **platform token** authorizes platform level actions, including activation onto the `prod` tier.

<Note>
  Activation is a platform level action. If you activate with an app token you will see `app token is not authorized for platform-level actions`. Ask the Aomi team for a platform token and use that. The same platform token works across every App on the platform, so you do not need a new one per App.
</Note>

## Secrets: API keys your App needs

If your App calls an outside API, declare the key in your App code, not on the platform. In `src/lib.rs`:

```rust theme={null}
const API_FOOTBALL_KEY: Secret = Secret::new(
    "API_FOOTBALL_KEY",
    "API-FOOTBALL key for live fixtures. Optional: the app still runs without it.",
    false,
);

dyn_aomi_app!(
    app = tool::MyApp,
    // ...
    secrets = [API_FOOTBALL_KEY],
    namespaces = ["evm-core"]
);
```

The third argument marks whether the key is required. Use `false` when the App still loads and does useful work without it. The Binance App in aomi-sdk is the reference for this pattern.

Read the value at tool call time with `resolve_secret_value`, which checks three sources in order:

```rust theme={null}
let key = resolve_secret_value(ctx, arg_value, "API_FOOTBALL_KEY", "no key set")?;
// order: explicit tool argument → host secret vault → API_FOOTBALL_KEY env var
```

That order is why the same code path works locally, where the value comes from an env var, and deployed, where it comes from the host vault. For a key you own and are comfortable shipping in a public App, a fourth option is to add a default in code as the final fallback, so every user gets live data without setting anything.

<Warning>
  Only bundle a key in code if you are fine with it being public. A public App's source and its built release are readable. Never hardcode a credential you would not put in a public repo.
</Warning>

## Find and test your App

Once your App is active it shows up as a selectable agent in the Aomi chat. Here is how to open it and put it through its paces, using Goal Digger, a World Cup betting agent, as the example.

<Steps>
  <Step title="Open the chat">
    Go to `https://chat.aomi.dev` and sign in.

    <Frame caption="chat.aomi.dev, where your deployed App runs">
      <img src="https://mintcdn.com/aomilabs/FjgM0xR-bcXWv_sr/images/chat-home.png?fit=max&auto=format&n=FjgM0xR-bcXWv_sr&q=85&s=19ec925ecd9e2ff21d5bb2a952c7ddc9" alt="The Aomi chat home screen" width="2914" height="1524" data-path="images/chat-home.png" />
    </Frame>
  </Step>

  <Step title="Pick your App from the agent picker">
    At the bottom of the chat is the agent picker, the dropdown showing the current agent's name. Open it and select your App. In the example that is Goal Digger.
  </Step>

  <Step title="Put it to work">
    Ask it what it can do, then give it a real task. For Goal Digger:

    * `list your tools` shows the full tool surface.
    * `simulate Spain vs Germany` runs its 50,000-simulation match engine.
    * `who wins the World Cup?` returns tournament odds.
    * `best World Cup bet on Polymarket right now?` finds the biggest edge versus the live market price.

    <Frame caption="Goal Digger listing its tools in the chat">
      <img src="https://mintcdn.com/aomilabs/FjgM0xR-bcXWv_sr/images/goal-digger-toolkit.png?fit=max&auto=format&n=FjgM0xR-bcXWv_sr&q=85&s=4238937d0aba7d69b4c52865b3b8a3e3" alt="Goal Digger's tool kit listed in the Aomi chat" width="1029" height="947" data-path="images/goal-digger-toolkit.png" />
    </Frame>
  </Step>
</Steps>

That is the whole loop: you wrote an App, deployed it, activated it, and now anyone can select it in the chat and use it.

## When something goes wrong

| You see                                                                                          | It means                                                               | Do this                                                                                                              |
| ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `deploy needs an activation token`                                                               | The CLI has no token.                                                  | Pass `--activation-token <token>`, export `AOMI_APP_ACTIVATION_TOKEN`, or rerun `aomi-build connect`.                |
| `app token is not authorized for platform-level actions`                                         | Your token is app scoped; activation needs platform scope.             | Ask the Aomi team for a platform token and use it. See [Tokens](#tokens).                                            |
| `no Cargo.toml found at <repo>/Cargo.toml`                                                       | Your App is in a subdirectory.                                         | Move `Cargo.toml`, `aomi.toml`, and `src/` to the repo root and push again. See [Step 2](#step-2-lay-out-your-repo). |
| SDK mismatch                                                                                     | Your pin differs from the platform.                                    | Run `aomi-build sdk fix --backend https://api.aomi.dev`, commit, deploy again. Or pass `--fix-sdk` on deploy.        |
| Deploy hangs at "waiting" after CI is green                                                      | Old CLI without the CI fallback.                                       | Reinstall the CLI (Step 1). As a one off, kill the process and run `aomi-build deploy activate` by hand.             |
| `deploy needs an app source id`                                                                  | The backend cannot find your connected repo.                           | Pass `--repo you/my-app`, or run `aomi-build source sync --platform community --repo you/my-app`.                    |
| Status shows `activate: false`                                                                   | Activate never ran or failed.                                          | Run [Activate by hand](#activate-by-hand).                                                                           |
| App vanished from the picker; status shows `artifact_ready=false not loaded` while `active=true` | The platform bumped the required SDK, so your release no longer loads. | Redeploy against the new version. See [When the platform bumps the SDK](#when-the-platform-bumps-the-sdk).           |
| Deploy endpoint returns `502 Bad Gateway`                                                        | The deploy call failed while resolving your source inline.             | Run `aomi-build source sync --platform community --repo you/my-app` first, then deploy again.                        |
| Deploy uses old code                                                                             | You did not push your latest commit.                                   | `git push`, deploy again.                                                                                            |
| Everything true except `loaded`                                                                  | The runtime did not load the plugin.                                   | Run `aomi-build deploy status --json` and share the deployment id and release tag with the team.                     |

## Reporting a failed deploy

When you ask for help, send three clean blocks, each a command plus its output: the connect step, the deploy step, and the activate step. Leave out help text, compile logs, and doc excerpts. Isolated commands and their exact output are what let us reproduce your problem fast.

## Next

<CardGroup cols={2}>
  <Card title="The builder toolchain" href="/docs/reference/cli-toolchain">
    The full reference for the two Rust binaries: `aomi-build` and `aomi-run`.
  </Card>

  <Card title="Add the chat widget" href="/docs/guides/widget-installation">
    Drop the React widget into a frontend so people can chat with your deployed App.
  </Card>

  <Card title="Common errors" href="/docs/build/common-errors">
    The errors you are most likely to hit, each with its fix.
  </Card>
</CardGroup>
