Skip to content

Project structure

carmy new creates this layout:

shop/
├── Cargo.toml
├── carmy.toml # name, address, timeout; CARMY_* env vars override
├── README.md
├── .gitignore
└── src/
├── main.rs # the entry point
└── tools/
├── mod.rs # one `mod` line per tool
└── hello.rs # a tool and its tests
mod tools;
#[tokio::main]
async fn main() -> carmy::Result {
carmy::run().await
}

carmy::run() is shorthand for carmy::app().run().await. carmy::app() does three things:

  • reads configuration from carmy.toml and the environment
  • registers every tool declared with #[carmy::tool]
  • chooses the transport from the first command-line argument

To register shared dependencies, use the builder:

#[tokio::main]
async fn main() -> carmy::Result {
let db = Db::connect("postgres://localhost/shop").await.expect("database");
carmy::app().state(db).run().await
}

The convention is one file per tool. Declare each file in src/tools/mod.rs:

//! One file per tool. Declare each file here; `#[carmy::tool]` registers it.
mod hello;
mod search;

Keep a tool’s tests in the same file (see Testing).

name = "shop" # CARMY_NAME
address = "127.0.0.1:3000" # CARMY_ADDR
timeout_secs = 30 # CARMY_TIMEOUT_SECS
command effect
cargo run or cargo run -- server serve HTTP on the configured address
cargo run -- mcp serve MCP over stdin/stdout
cargo run -- tools print the tool catalog as JSON
cargo test run the tests