Quick start
-
Install the CLI
Terminal window cargo install carmy-cliCarmy requires Rust 1.88 or newer.
-
Create an application
Terminal window carmy new shopcd shopThe project follows the Carmy conventions:
src/main.rs, one file per tool insrc/tools/, and acarmy.toml. -
Serve it over HTTP
Terminal window cargo runTerminal window $ curl localhost:3000/.well-known/agent{"capabilities":["tools","streaming","idempotency"],"execute_url":"/agent/execute","protocol":"carmy/1","server":"shop","tools_url":"/agent/tools","tools_version":"…"}$ curl localhost:3000/agent/execute -H 'content-type: application/json' \-d '{"tool":"hello","arguments":{"name":"Ada"}}'{"execution_id":"exec_…","status":"completed","data":{"message":"Hello, Ada!"},"_agent":{"cacheable":true,"next_actions":[]}} -
Serve the same app over MCP
Terminal window cargo run -- mcpAny MCP client, such as Claude Desktop or Cursor, can now list and call your tools. See MCP.
-
Run the tests
Terminal window cargo testThe generated
hellotool ships with tests that call it through the real runtime.
Your first tool
Section titled “Your first tool”Create src/tools/search.rs:
use carmy::prelude::*;
#[derive(Deserialize, JsonSchema)]struct SearchInput { /// Search expression. query: String,}
#[derive(Serialize, JsonSchema)]struct SearchOutput { results: Vec<String>,}
#[carmy::tool(description = "Search the catalog", effect = "read", idempotent = true)]async fn search(input: SearchInput) -> AgentResult<SearchOutput> { Ok(SearchOutput { results: vec![format!("Result for {}", input.query)], })}Then add mod search; to src/tools/mod.rs. That’s it: the tool registers itself and
is available over HTTP and MCP.
Next: Project structure.