A minimal, modular AI-agent framework written in Rust. It provides a small core library, pluggable storage backends, an event-driven architecture, and a batteries-included CLI with an embedded TUI.
Status: in active development, the API might be changing in the future.
| Crate | Purpose |
|---|---|
microagents-core |
Agent definition, tool trait, skill loading, LLM generation loop |
microagents-events |
Event types (AgentEventAny, SessionInitEvent, …) and JSON-RPC serialization |
microagents-storage |
Session persistence: in-memory, JSONL, or SQLite |
microagents-cli |
Interactive terminal UI + built-in tools (read, write, edit, shell_execute, search) |
- Multi-provider LLM support — OpenAI (and chat completions-compatible providers), OpenRouter, Groq and Ollama out of the box (via
ultrafast-models-sdk). - Tool-use loop — the agent can call tools, wait for results, and continue the conversation. Supports parallel tool calls.
- Skills — drop-in markdown skill packs with front-matter (
name,description,allowed-tools, …) loaded from./.agents/skillsor~/.agents/skills. - AGENTS.md — Load an AGENTS.md as part of your agent's custom instructions
- Session storage — resume conversations by persisting events to JSONL files, SQLite, or keep them in memory (not recommended).
- Built-in tools for
microagents-cliread— read plain text or extract text from PDFs / Office docs / images (vialiteparse).write— create or overwrite files (with auto-created parent directories).edit— exact-string replacement in a file.shell_execute— run shell commands with a dangerous-command regex guard.search— semantic (code and text embeddings) + sparse (BM25) hybrid search over the workspace, powered byqdrant-edge,fastembed-rsandastchunk, using TurboQuant quantization.
- Embedded TUI for
microagents-cli—ratatui-based chat interface with streaming deltas, tool-call visualization, scrolling history, and session resume.
Rust 1.91.1+ is necessary.
Installation from crates.io coming soon!
Clone the repository and install from source:
cargo +nightly install microagents-cliThis will install the microag binary.
Run the TUI with default settings:
microagRun the TUI customizing model/provider/storage backend:
microag --provider ollama --model gemma4:latest --storage sqliteRun the TUI resuming a previous session:
microag --session-id <session-id>Run in headless mode, printing JSON-RPC-serialized events to the console, using the -p/--prompt flag:
microag -p 'Where is AgentStorage defined and which storage backends implement it?'Run in verbose mode to see codebase indexing progression:
microag --verbose -p 'Where is AgentStorage defined and which storage backends implement it?'Infer provider from the environment:
export OPENROUTER_API_KEY="..."
# uses OpenRouter automatically
microag --model "anthropic/claude-opus-4.6"┌─────────────────┐
│ microagents-cli │ ← TUI + built-in tools + vector search indexing
│ (binary: microag)│
└────────┬────────┘
│
┌────────▼────────┐
│ microagents-core │ ← Agent trait, MicroAgent builder, tool loop, skill loader
└────────┬────────┘
│
┌────────▼────────┐
│microagents-events│ ← Structured events → JSON-RPC notifications
└────────┬────────┘
│
┌────────▼────────┐
│microagents-storage│ ← In-memory / JSONL / SQLite session backends
└─────────────────┘
Add the libraries with:
cargo add microagents-events microagents-storage microagents-coreuse microagents_core::{
agent::{MicroAgentBuilder, SupportedProvider},
types::{Agent, ToolExecutionContext},
};
use microagents_storage::types::AgentStorageChoice;
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let agent = MicroAgentBuilder::new(ToolExecutionContext::new(()))
.provider("openrouter".to_string())?
.model("anthropic/claude-opus-4.7".to_string())
.storage(AgentStorageChoice::Sqlite)
.await?
.find_skills()?
.load_agents_md()?
.build()?;
let mut stream = agent.run("Hello!".to_string(), None).await?;
while let Some(event) = stream.next().await {
match event {
Ok(ev) => println!("{:?}", ev),
Err(e) => eprintln!("Error: {}", e),
}
}
Ok(())
}Implement ToolFunction<Ctx> from microagents_core::types and register it on the MicroAgentBuilder:
use microagents_core::types::{ToolFunction, ToolExecutionContext, AgentError};
use microagents_events::types::ToolResult;
use serde_json::Value;
use std::sync::Arc;
#[derive(Debug)]
struct MyTool;
#[async_trait::async_trait]
impl ToolFunction<()> for MyTool {
fn name(&self) -> &'static str { "my_tool" }
fn description(&self) -> &'static str { "Does something useful" }
fn input_schema(&self) -> Value {
serde_json::json!({ "type": "object", "properties": {} })
}
async fn execute(&self, input: Value, _ctx: &Arc<ToolExecutionContext<()>>) -> Result<ToolResult, AgentError> {
Ok(ToolResult::Ok("done".into()))
}
}
// Then add it when building the agent:
// let agent = MicroAgentBuilder::new(...)
// .add_tool(Arc::new(MyTool))?
// .build()?;| Variable | Required for | Description |
|---|---|---|
OPENROUTER_API_KEY |
OpenRouter | API key for OpenRouter (default provider) |
OPENAI_API_KEY |
OpenAI | API key for OpenAI |
OPENAI_API_KEY and OPENAI_BASE_URL |
OpenAI-Compatible providers | API key and base URL for OpenAI-compatible providers |
GROQ_API_KEY |
Groq | API key for Groq |
OLLAMA_BASE_URL |
Ollama | Base URL for Ollama (defaults to http://localhost:11434/v1) |
MIT