Skip to main content
By the end you will have written a small Aomi App, deployed it to the public community platform, and handed it to ops to load onto the live runtime. An App is a Rust crate the runtime loads as a plugin. You write the tools, the platform runs them. This is the happy path, start to finish.

Before you start

1

Check Rust

The SDK uses the 2024 edition, which needs Rust 1.85 or newer. A recent stable toolchain works.
rustc --version
No Rust yet? Install it from rustup.rs.
2

Check git and the GitHub CLI

aomi-git uses git to push your App and your gh login to reach the platform repo.
git --version
gh auth status
If gh says you are not logged in, run gh auth login.
3

Install the toolchain

This installs the builder binaries. The cli feature builds aomi-build and aomi-git, the tool that ships your App. Add dev-runtime to also get aomi-run, which lets you chat with your App locally before you ship.
cargo install --git https://github.com/aomi-labs/aomi-sdk --features cli,dev-runtime aomi-sdk
There is no --version flag, so confirm the install with --help:
aomi-git --help

Write your App

Your App is three small files. Make a folder and add them.
1

Create the folder

mkdir hello-aomi && cd hello-aomi && mkdir src
The folder name is your slug. Use kebab-case.
2

aomi.toml

This tells the platform who your App is and where it ships.
aomi.toml
[app]
name         = "hello-aomi"
display_name = "Hello Aomi"
platform     = "community"
git          = "https://github.com/aomi-labs/community-apps"
public       = true
3

Cargo.toml

Your App compiles to a cdylib. Pin aomi-sdk to the exact version the platform requires, today =0.1.20.
Cargo.toml
[package]
name = "hello-aomi"
version = "0.1.0"
edition = "2024"

[lib]
crate-type = ["cdylib"]

[dependencies]
aomi-sdk   = "=0.1.20"
schemars   = "1"
serde      = { version = "1", features = ["derive"] }
serde_json = "1"
The exact version lives in platform.json in the community-apps repo, under required_sdk_version. The runtime loads a plugin only if it was built against that version.
4

src/lib.rs

One tool plus the dyn_aomi_app! macro that registers it. This tool takes a name and returns a greeting.
src/lib.rs
use aomi_sdk::schemars::JsonSchema;
use aomi_sdk::*;
use serde::Deserialize;
use serde_json::{Value, json};

#[derive(Clone, Default)]
pub struct HelloApp;

#[derive(Debug, Deserialize, JsonSchema)]
pub struct GreetArgs {
    /// The name of the person to greet.
    pub name: String,
}

pub struct Greet;

impl DynAomiTool for Greet {
    type App = HelloApp;
    type Args = GreetArgs;
    const NAME: &'static str = "greet";
    const DESCRIPTION: &'static str =
        "Use when the user wants a friendly greeting. Takes a name and returns a hello message.";

    fn run(_app: &HelloApp, args: GreetArgs, _ctx: DynToolCallCtx) -> Result<Value, String> {
        Ok(json!({ "message": format!("Hello, {}! Welcome to Aomi.", args.name) }))
    }
}

const PREAMBLE: &str =
    "When the user asks to be greeted, call the greet tool with their name.";

dyn_aomi_app!(
    app = HelloApp,
    name = "hello-aomi",
    version = "0.1.0",
    preamble = PREAMBLE,
    tools = [Greet,],
    namespaces = []
);
The DESCRIPTION is what the model reads to decide when to call your tool, so write it as a trigger. namespaces = [] means your App asks for no host powers like wallet signing.

Build and ship

1

Build it

cargo build --release
Expected output:
Compiling aomi-sdk v0.1.20
Compiling hello-aomi v0.1.0
Finished `release` profile [optimized] target(s) in 12.6s
2

Commit your files

Deploy works from a clean commit. Add a .gitignore so build output does not dirty the tree.
printf '/target\n/.aomi\nCargo.lock\n' > .gitignore
git init && git add . && git commit -m "init hello-aomi"
3

Check the plan

A dry run shows the plan and runs the checks. It pushes nothing.
AOMI_BACKEND_URL=https://staging-api.aomi.dev aomi-git deploy --dry-run
Every Preflight line should read [ok]:
Preflight
  [ok]   workspace git_clean
  [ok]   manifest  platform_declared, git_declared
  [ok]   platform  backend_reachable, platform_resolved, branch_matches_contract
  [ok]   backend   server_tags_subset
If a line fails, fix what it names in your aomi.toml and run the dry run again.
4

Deploy

aomi-git deploy
This pushes your source to the community platform and starts CI. CI builds your plugin and cuts a release tagged apps-hello-aomi-<short-commit>.
5

Watch CI

aomi-git status
When the ci line reads [ok] green and release says it is ready to activate, you are set. A build takes a few minutes.
6

Get access (first time only)

The first time you ship to a platform, ask ops for access. This runs once, not per deploy.
aomi-git request --email you@example.com --git-account your-github-user
This posts a request to the Aomi apps Discord. Ops then do two things: they invite your GitHub account to the platform repo as a collaborator, and they email you a per-app activation code. The code arrives by email, never over Discord.
7

Activate your release

Once CI is green and you hold your per-app code, you activate the release yourself. Set the code as AOMI_APP_ACTIVATION_TOKEN.
AOMI_APP_ACTIVATION_TOKEN=<your per-app code> \
AOMI_BACKEND_URL=https://staging-api.aomi.dev \
  aomi-git activate
The backend fetches your release, validates it, and loads it. Within a few minutes your greet tool appears in the agent for new chats.

What you have now

You have a deployed Aomi App on the live runtime. You wrote three files, deployed with aomi-git deploy, and activated the release with your per-app code. Your greet tool now runs inside real chats.
To go further:

Building an App

The anatomy: tools, arguments, the preamble, and host namespaces.

Deploy and activate

The full shipping process, the validation pipeline, and troubleshooting.

Common errors

The errors you are most likely to hit, each with its fix.
Last modified on June 10, 2026