Skip to main content
aomi-build scaffolds, compiles, deploys, and activates a plugin. It ships as a binary from the aomi-sdk crate on crates.io. A deployed plugin combines its tools and system prompt on the runtime. Aomi calls this deployed unit an App, which is the term used in CLI output, aomi.toml, and the Developer Platform. This page takes a plugin from your own GitHub repo to live on Aomi. 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. The walkthrough comes first; the complete command reference follows it.
Verified 2026-09-22 against published aomi-sdk 5.1.1 at commit 2ef3e04. Version numbers move: always trust aomi-build sdk check over any number written here.
Prefer a browser? The Developer Platform at build.aomi.dev supports connect, deploy, activate, and status. It also manages secrets, model provider keys, bots, and usage. The CLI and platform use the same backend, so you can move between them.
The whole flow is four commands:
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 plugin 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.
That is the full list. No GitHub personal access token. No database access. No admin key.

Step 1: install the CLI

Confirm it is there:
The binary has no --version flag; --help is how you confirm the install. The cli feature builds aomi-build; add dev-runtime (--features cli,dev-runtime) to also get aomi-run, the local dev runtime for chatting with your plugin before you ship. There is no aomi-build on crates.io or npm: it is a binary built from the aomi-sdk crate, which is why the install command points at that crate.
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.
You can also run it without installing: prefix with cargo run -p aomi-sdk --features cli --bin aomi-build --. The install is just a convenience.

Step 2: lay out your repo

Your plugin is a normal Rust cdylib. Put Cargo.toml, aomi.toml, and src/ at the root of the repo:
The CLI builds the plugin from the git repo root. It does not deploy a plugin that lives in a subdirectory such as app/ or apps/my-app/. If your plugin 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.
Your aomi.toml:
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:
When your pin matches, you see:
When it is stale, it tells you exactly what is wrong and stops:
Let the CLI rewrite the pin for you:
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.
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 for what happens to an App that is already live when the number moves.

Step 4: commit and 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

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

Step 6: deploy

From the root of your repo:
Prefer env vars for repeat runs? Export once, then the short command works every time:
One command runs the whole lifecycle:
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:
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.

Step 7: check status and see it live

Add --json for machine readable output. You want active, artifact_ready, and loaded all true. Open 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:
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:
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:
If it reports a required version higher than your pin, that is the cause. The fix is a normal redeploy against the new version:
Your App is back once you see active=true artifact_ready=true loaded=true.
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.

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

Secrets: API keys your plugin needs

If your plugin calls an outside API, declare the key in your plugin code, not on the platform. In src/lib.rs:
The third argument marks whether the key is required. Use false when the plugin still loads and does useful work without it. The Binance App in aomi-sdk is the reference for this pattern. For an operator-owned credential, read the value at tool call time with resolve_secret_value, which checks three sources in order:
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. If every user supplies a separate credential, mark the declaration and use the context-only resolver:
User-owned credentials never fall back to a tool argument or process environment variable. A missing user value therefore cannot silently use an operator credential.
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. Never log, persist, or return values from either secret resolver.

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

Open the chat

Go to https://chat.aomi.dev and sign in.
The Aomi chat home screen

chat.aomi.dev, where your deployed App runs

2

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

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.
Goal Digger's tool kit listed in the Aomi chat

Goal Digger listing its tools in the chat

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

When something goes wrong

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.

Command reference

Reference verified against published aomi-sdk 5.1.1 at commit 2ef3e04 on 2026-09-22. deploy status and deploy activate are the canonical forms.
Beyond deploying, aomi-build scaffolds, compiles, and end to end tests a plugin. The full path from “external API docs” to “tested plugin” is a six stage pipeline. Every stage runs on its own, and new-app is the one shot orchestrator for the first stages plus the compile.
Stages 1 through 3 and 5 are pure CLI. Stage 4 (curate) and the test.json authoring in stage 6 are done with the authoring skills, not the binary.

Subcommands

Running aomi-build with no subcommand launches an interactive wizard that walks connect then deploy then activate. Build and scaffold: Deploy and activate: Here <p> is the platform slug, for example petstore or khalani.

Flags

Spec generation stages default to app local: every artifact lives under apps/<p>/. Pass --shared only when several plugins wrap the same upstream (say, multiple Apps over one exchange) and should reuse one client under ext/.

Scaffold and compile a new plugin

After new-app finishes, the plugin compiles but its tools are mechanical, one per endpoint, with machine names. You make it useful by curating the tool layer (stage 4) with the authoring skills, then rebuilding.
aomi-build compile builds the apps inside an aomi-sdk style workspace and writes them into plugins/. If you are building a single standalone plugin crate, the kind you publish to community-apps, you do not need aomi-build. Build it with cargo build --release and find the plugin in target/release/.

Sharpen and validate the spec

The end to end test

Each plugin carries one canonical e2e spec at apps/<platform>/test.json. It describes a real LLM run: an optional wallet seed, a list of user prompts, the tools expected per turn, optional wallet callbacks, and a final state assertion. The runner lives in the backend repo, not here. You point it at your compiled plugin with an env var:
The spec runs turn by turn. expected_tools checks must_call (all listed) or any_of (at least one). final_assertion checks the user state, tool responses, and turn cap.
Two limits worth knowing. Host tools (stage_tx, simulate_batch, commit_txs) carry a model set topic arg, so listing them in must_call will not match; the runtime fires them internally during routed enforcement. And a terminal wallet:tx_complete callback consumes pending_txs, so assert max_count: 0 after a callback rather than min_count: 1.

Deploy and activate reference

The deploy half of aomi-build publishes your plugin source through the backend, then activates the resulting release. The CLI never clones a platform repo or pushes branches. It is a thin relay: deploy POSTs to the backend, and the backend reads your source through the connected Aomi GitHub App, opens a pull request, and lets CI build the cdylib and cut the release. Run these from your source repo, the crate that holds aomi.toml and src/lib.rs.
The backend identifies your source through the GitHub App install, recorded as app_source_id. The deployed App lands at apps/<installation-id>/<repo-key>/<app>/ on the community-apps publish branch, and CI publishes a release tagged apps-<installation-id>-<repo-key>-<app>-<short-commit>.

connect

The first step for a new contributor. connect installs the Aomi GitHub App on your source repo and saves the activation token you use to activate releases. Run it once, before your first deploy.
It prints a browser URL to install the Aomi GitHub App. Install it on the repo that holds your plugin, then paste back the installation_id GitHub shows you. After that, every deploy reads your source through this install.

deploy

deploy sends POST /api/platforms/:platform/deploy carrying your app_source_id. The backend reads your source through the GitHub App, opens a pull request, and CI builds and publishes the release. A successful deploy writes .aomi/deployment.json with the backend’s deployment record, including the release tags activate reads later.
--dry-run is an alias of --preflight. Both preview the plan and run the checks without deploying.

deploy status

deploy status reads .aomi/deployment.json and, when a backend URL is configured, reports the backend load state for each release tag.

deploy activate

Run by the app author with the activation token saved during connect. It tells the backend to fetch a release by tag, validate it, and load it. Run it from your source repo and it reads the release tags from .aomi/deployment.json, so usually you set only AOMI_APP_ACTIVATION_TOKEN and AOMI_BACKEND_URL and run aomi-build deploy activate.
deploy activate sends POST /api/platforms/:platform/apps/activate. By default it uses the release tags recorded in .aomi/deployment.json.
When you pass app names with --release-tag, their count must match the tag count, and the backend verifies each app name matches its release tag.

The validation pipeline

Every deploy, including --dry-run, runs a validation pipeline and records the result in .aomi/deployment.json. It runs in four ordered stages. Each stage is a precondition for the next, so a failing gate short circuits the rest and downstream stages are recorded as skipped. Stages 1 and 2 are offline, computed from local git and aomi.toml. Stages 3 and 4 are online: they only run when a backend URL is available, and otherwise stay skipped. Each check is error (a gate that fails the stage and should block the deploy) or warn (advisory; downgrades the stage to warning but does not block). The two warn checks are git_declared and git_url_matches_platform, since a backend lookup can supply the repo and forks are tolerated. The big one to watch is branch_matches_contract: if your target branch is not the platform’s contractual deployment_branch, the push will not auto deploy.
The human summary prints one line per stage:
A stage rolls up to passed (all checks passed), failed (an error check failed, blocked here), warning (only warn checks failed), or skipped (an upstream gate failed or inputs were absent, such as no backend URL).

The deployment.json artifact

.aomi/deployment.json is the deployment record the backend writes back next to your aomi.toml after a successful deploy. It carries the resolved plan, the release tags, and independent state flags:
  • deployed: the backend accepted the deploy and opened the pull request that CI builds.
  • activated: the backend wrote the app row with is_active = true.
A --dry-run deploy previews the plan and runs the checks but does not record a deploy. activate reads this file for its defaults, including the release tags, so running it from the same directory as a prior deploy lets you drop most flags.
Add .aomi/ to your .gitignore. It is a local artifact, and committing it tends to dirty your tree and trip git_clean on the next deploy.

Next

aomi-run

Chat with your compiled plugin locally against a real LLM before you ship.

Add the chat widget

Drop the React widget into a frontend so people can chat with your deployed App.

Aomi App

The full authoring walkthrough, from spec to curated tools to test.

Rust SDK

The plugin SDK that your plugin compiles against.

Common errors

The errors you are most likely to hit, each with its fix.

Client CLI

The npm aomi command for chatting with and driving a deployed App from your terminal.
Last modified on September 9, 2026