Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
A.R.E.S is a production-grade agentic AI server built in Rust. Multi-provider LLM routing, structured tool calling, RAG, MCP integration, multi-tenant auth, and workflow orchestration. Embed the default ares facade (Context, Execute, Tools, Llm) with no axum on the graph, or enable the http feature for the Axum adapter.
Built by DIRMACS. Documentation
Features
- Multi-provider LLM: Ollama, OpenAI, Anthropic Claude, LlamaCpp (direct GGUF loading)
- TOML configuration: declarative, hot-reloading
- Configurable agents: define via TOON with custom models, tools, and prompts
- Workflow engine: declarative execution with agent routing
- Tool calling: type-safe function calling with automatic schema generation
- ToolCoordinator: provider-agnostic multi-turn tool calling for all LLM clients
- Per-agent tool filtering: restrict which tools each agent can access
- Streaming: real-time responses from all providers
- Auth: JWT with Argon2 password hashing
- Database: PostgreSQL with multi-tenant isolation, optional vector stores (ares-vector, Qdrant, LanceDB)
- MCP: pluggable Model Context Protocol server integration
- Multi-agent orchestration: specialized agent routing
- RAG: pure-Rust vector store, multi-strategy search (semantic, BM25, fuzzy, hybrid), reranking
- Memory: user personalization and context management
- Deep research: multi-step research with parallel subagents
- Web search: built-in via daedra
- OpenAPI: automatic documentation generation
- Config validation: circular reference detection and unused config warnings
- Loop detection: 3-tier escalation (warn, force alternative, halt) for repetitive outputs
- Crash recovery: checkpoint serialization, save agent state at each step, restore on restart
- Service-based architecture (0.9.x): dependency injection via typed
Context, services register withctx.plugin()orctx.provide(), handlers pull deps withctx.get::<T>().Fiber::refreshrecomputes the dependency epoch and reruns pluginapply. - Unified execution: single
Executehandles resolve, create, and execute for chat, v1 API, JWT chat, MCP, scheduler, pipeline, and trigger. Scheduler, pipeline, and trigger domain loops remain native ARES engines behindExecute. - Event-first skills (0.9.x):
Context::injectwaits on theReflectServiceTypeId notifier (ensure_notifier+changed), falling back to a 5ms poll only when the notifier is unavailable. Skills carry the requestContext, isolate tools withctx.isolate::<Tools>(tenant_id), and callTools::executeon that tenant isolate. SkillLlmCallsteps strictly useLlm::completethroughllm.complete, with no direct providergenerate_with_historyfallback.Tools,Llm,Execute, and skills stay event-first onEventsServicewaterfalls. - Quota:
agent.admit(Dispatch::Bail) is the shared gate forExecute, JWT chat, API-key middleware, and MCP. - Store / Overlay / realms: Store factory runs migrations and seeds templates. Overlay fills empty loader configs from
ares.toml. TOON changes notifyToolsandExecute.TenantRealmsopen-then-intercept on request paths and dispose on tenant delete. - Hot-reload: file-watch triggers automatic service refresh without restart.
Fiber::refreshreruns plugin apply when the epoch changes. - Circuit breaker: LLM provider health tracked per-endpoint with automatic failover
Installation
A.R.E.S can be used as a standalone server or as a library in your Rust project.
As a library
Add to your project (0.9.1):
[]
= "0.9"
Basic usage (default features: no axum, no postgres, no engines):
use ;
ares with default features does not depend on axum. Enable http to pull ares-http. ProviderRegistry remains on the constructor path for AgentRegistry / Llm until those take Llm only.
As a binary
# Install from crates.io
# Install with embedded Web UI
# Initialize a new project (creates ares.toml and config files)
# Run the server
CLI commands
A.R.E.S provides a full-featured CLI with colored output:
# Initialize a new project with all configuration files
# Initialize with custom options
# Initialize with minimal configuration
# View configuration summary
# Validate configuration
# List all configured agents
# Show details for a specific agent
# Start the server
# Start with verbose logging
# Use a custom config file
# Disable colored output
Init command options
| Option | Description |
|---|---|
--force, -f |
Overwrite existing files |
--minimal, -m |
Create minimal configuration |
--no-examples |
Skip creating TOON example files |
--provider <NAME> |
LLM provider: ollama, openai, or both |
--host <ADDR> |
Server host address (default: 127.0.0.1) |
--port <PORT> |
Server port (default: 3000) |
Quick start (development)
Prerequisites
- Rust 1.98+: Install via rustup
- Ollama (recommended): For local LLM inference - Install Ollama
- just (recommended): Command runner - Install just
1. Clone and setup
# Or use just to set up everything:
2. Start Ollama (recommended)
# Install a model
# Or: just ollama-pull
# Ollama runs automatically as a service, or start manually:
3. Build and run
# Build with default features (local-db + ollama)
# Or: just build
# Run the server
# Or: just run
Server runs on http://localhost:3000
Feature flags
A.R.E.S uses Cargo features for conditional compilation:
LLM providers
| Feature | Description | Default |
|---|---|---|
ollama |
Ollama local inference | Yes |
openai |
OpenAI API (and compatible) | No |
anthropic |
Anthropic Claude API | No |
llamacpp |
Direct GGUF model loading | No |
llamacpp-cuda |
LlamaCpp with CUDA | No |
llamacpp-metal |
LlamaCpp with Metal (macOS) | No |
llamacpp-vulkan |
LlamaCpp with Vulkan | No |
Database & vector stores
| Feature | Description | Default |
|---|---|---|
postgres |
PostgreSQL database | Yes |
ares-vector |
Pure-Rust embedded HNSW vector store | Yes |
qdrant |
Qdrant vector database | No |
pgvector |
PostgreSQL pgvector extension | No |
chromadb |
ChromaDB embedding database | No |
pinecone |
Pinecone managed vector database | No |
lancedb |
LanceDB vector database | No |
UI & documentation
| Feature | Description | Default |
|---|---|---|
ui |
Embedded Leptos web UI served from backend | No |
swagger-ui |
Interactive API documentation at /swagger-ui/ |
No |
Note:
swagger-uiwas made optional in v0.2.5 to reduce binary size and build time. The feature requires network access during build to download Swagger UI assets.
Embeddings
| Feature | Description | Default |
|---|---|---|
local-embeddings |
Local ONNX embedding models via fastembed | No |
Warning: The
local-embeddingsfeature does NOT work on Windows MSVC due toort-syslinker errors. Use WSL, Linux, or macOS for local embeddings, or use remote embedding APIs instead.
Feature bundles
| Feature | Includes |
|---|---|
all-llm |
ollama + openai + llamacpp + anthropic |
all-db |
postgres + all vector stores |
full |
All optional features (except UI and local-embeddings): ollama, openai, llamacpp, anthropic, postgres, qdrant, ares-vector, mcp, swagger-ui |
full-ui |
All optional features + UI (except local-embeddings) |
full-local-embeddings |
Full + local-embeddings (Linux/macOS only) |
full-ui-local-embeddings |
Full + UI + local-embeddings (Linux/macOS only) |
minimal |
No optional features |
Note:
local-embeddingsis excluded fromfullandfull-uibundles due to Windows MSVC compatibility issues. Usefull-local-embeddingsorfull-ui-local-embeddingson Linux/macOS.
Building with features
# Default (ollama + local-db)
# Or: just build
# With OpenAI support
# Or: just build-features "openai"
# With direct GGUF loading
# With CUDA GPU acceleration
# Full feature set
# Or: just build-all
# With embedded Web UI
# With Swagger UI (interactive API docs)
# Full feature set with UI
# Release build
# Or: just build-release
Configuration
A.R.E.S uses a TOML configuration file (ares.toml) for declarative configuration of all components. The server requires this file to start.
Quick start
# Copy the example config
# Set required environment variables
Configuration file (ares.toml)
The configuration file defines providers, models, agents, tools, and workflows:
# Server settings
[]
= "127.0.0.1"
= 3000
= "info"
# Authentication (secrets loaded from env vars)
[]
= "JWT_SECRET"
= "API_KEY"
# Database
[]
= "./data/ares.db"
# LLM Providers (define named providers)
[]
= "ollama"
= "http://localhost:11434"
= "ministral-3:3b"
[] # Optional
= "openai"
= "OPENAI_API_KEY"
= "gpt-4"
# Models (reference providers, set parameters)
[]
= "ollama-local"
= "ministral-3:3b"
= 0.7
= 256
[]
= "ollama-local"
= "ministral-3:3b"
= 0.7
= 512
[]
= "ollama-local"
= "qwen3-vl:2b"
= 0.3
= 1024
# Tools (define available tools)
[]
= true
= 10
[]
= true
= 30
# Agents (reference models and tools)
[]
= "fast"
= "You route requests to specialized agents..."
[]
= "balanced"
= ["calculator"] # Tool filtering: only calculator
= "You are a Product Agent..."
[]
= "smart"
= ["web_search", "calculator"] # Multiple tools
= "You conduct research..."
# Workflows (define agent routing)
[]
= "router"
= "product"
= 5
[]
= "research"
= 10
Per-agent tool filtering
Each agent can specify which tools it has access to:
[]
= "balanced"
= ["calculator"] # Only calculator, no web search
[]
= "balanced"
= ["calculator", "web_search"] # Both tools
If tools is empty or omitted, the agent has no tool access.
Configuration validation
The configuration is validated on load with:
- Reference checking: Models must reference valid providers, agents must reference valid models
- Circular reference detection: Workflows cannot have circular agent references
- Environment variables: All referenced env vars must be set
For warnings about unused configuration items (providers, models, tools not referenced by anything), the validate_with_warnings() method is available.
Hot reloading
Configuration changes are automatically detected and applied without restarting the server. Edit ares.toml and the changes will be picked up within 500ms.
Environment variables
The following environment variables must be set (referenced by ares.toml):
# Required
JWT_SECRET=your-secret-key-at-least-32-characters
API_KEY=your-api-key
# Optional (for OpenAI provider)
OPENAI_API_KEY=sk-...
Provider priority
When multiple providers are configured, they are selected in this order:
- LlamaCpp - If
LLAMACPP_MODEL_PATHis set - OpenAI - If
OPENAI_API_KEYis set - Ollama - Default fallback (no API key required)
Dynamic configuration (TOON)
In addition to ares.toml, A.R.E.S supports TOON (Token Oriented Object Notation) files for behavioral configuration with hot-reloading:
config/
agents/
router.toon
orchestrator.toon
product.toon
models/
fast.toon
balanced.toon
tools/
calculator.toon
workflows/
default.toon
mcps/
filesystem.toon
Example TOON agent config (config/agents/router.toon):
name: router
model: fast
max_tool_iterations: 5
parallel_tools: false
tools[0]:
system_prompt: |
You are a router agent that directs requests to specialized agents.
Enable TOON configs in ares.toml:
[]
= "config/agents"
= "config/models"
= "config/tools"
= "config/workflows"
= "config/mcps"
= true
TOON files are automatically hot-reloaded when changed. See docs/DIR-12-research.md for details.
User-created agents API
Users can create custom agents stored in the database with TOON import/export:
# Create a custom agent
# Export as TOON
# Import from TOON
Extending ARES
ARES is designed as a library. The default ares facade injects Execute, Tools, and Llm on a Cordis Context and runs an agent with no HTTP stack. HTTP routes live behind the optional http feature (ares-http).
Library (no axum)
use ;
use PluginRegistry;
let ctx = new_root;
let reg = new;
register_plugins;
// provide in-memory or real Execute + Tools + Llm, then Execute::run(&req, &ctx)
Custom routes (feature http)
use Arc;
use Context;
use Http;
let ctx: = /* your configured context with Http provided */;
// Http::apply builds the Axum router; the ares-server binary binds it.
Custom context provider
Inject external context into agent calls before LLM invocation:
use ContextProvider;
use async_trait;
By default, ARES uses NoOpContextProvider (returns None).
Architecture
0.9.x composition is Cordis Context plus loader entries. Components register into a typed Context. Handlers and engines pull Execute, Tools, Llm, and Store at call time. The default ares facade has no axum. The kernel is hardened per the Cordis model: guarded withdrawal (providers can't be removed under active consumers), verified hot-swap and drain-and-shift provider replacement (zero-downtime rebuilds, POST /admin/cordis/services/{name}/replace), peer-dependency versioning (provide_versioned/declare_inject_versioned — incompatible versions leave dependents Inactive instead of silently binding), eager inject reconciliation, dependency-cycle detection at load (GET /admin/cordis/entries reports rings), and a metatheory property suite proving quiescence/confluence/LIFO/reactive invariants. RhaiPolicy scripting ships default-on: TOML entries attach sandboxed script gates to capability events with fail-closed semantics. See docs/cordis-mapping.md for the full Cordis surface (§10–§19).
request / job
-> TenantRealms.open then intercept (HTTP/MCP/JWT) or isolate only (background)
-> agent.admit (Execute, JWT chat, API-key middleware, MCP)
-> Execute::run
-> Tools / Llm / skills via EventsService waterfalls
-> response
Fiber, events, and capabilities
Fiber::refresh recomputes the dependency epoch and reruns plugin apply when the epoch changed or the fiber is not already Active with dependencies satisfied. Dispose still LIFO-undoes effects.
EventsService dispatch: Emit returns JSON null. Parallel joins every handler and returns JSON null on success (handler values are discarded; the first join/handler error is propagated). Serial (same path as Bail) stops at the first non-null handler result. Waterfall is around-middleware with next.
Tools, Llm, Execute, and skills remain event-first. Public methods run through waterfall_around when EventsService is on ctx.
agent.admit is the shared quota gate for Execute::run, JWT /api/chat, API-key middleware, and MCP. Deny maps to HTTP 429 or an MCP tool error.
Store, Overlay, realms, boot
The Store loader factory connects, runs SQL migrations, and seeds default agent templates. Overlay copies ares.toml sections into loader entries only when entry.config is empty. TOON reloads call ReflectService::notify for Tools and Execute.
TenantRealms open-then-intercept on request paths. Background jobs open/isolate only. Admin tenant delete calls dispose then SQL delete.
run_server composes the entries program at boot (@include splice, @group flatten, ${rhai: …} config interpolation — fail-open) and re-composes on every watched reload, then applies the diff via the loader journal: verified hot-swap for same-provider rebuilds, guarded withdrawal for retire. Inventory-collected factories are the primary registration path (manual chains are the no-default-features fallback). Scheduler, pipeline, and trigger domain loops remain native ARES engines behind Execute, emitting boundary events on the typed catalog.
Key services
| Service | What it does |
|---|---|
Execute |
Single entry point for running agents. Chat, v1, JWT, MCP, scheduler, pipeline, and trigger delegate here after agent.admit. |
Resolver |
Crate-private 3-tier agent resolution: tenant DB, community, system config. |
Llm |
Provider clients with circuit breaker. ProviderRegistry remains a constructor input. |
Tools |
Merges static, runtime DB, and MCP tools. Tenant isolation via isolate::<Tools>. |
Store |
Postgres client, migrations, template seed, tenant DB. |
EventsService |
Typed bus. Product paths stay event-first. |
Overlay |
ares.toml overlay; fills empty loader configs; TOON notifies Tools/Execute. |
TenantRealms |
Per-tenant child contexts. Open-then-intercept on request; dispose on tenant delete. |
ReflectService |
Hot-reload coordination. File changes propagate without restart. |
Adding a service
// Register in a plugin apply / loader factory
root_ctx.provide;
// Use from a handler or engine (HTTP types require feature `http`)
async
See ARCHITECTURE.md for full details.
API documentation
Interactive Swagger UI available at: http://localhost:3000/swagger-ui/
Note: Swagger UI requires the
swagger-uifeature to be enabled at build time:# Or use the full bundle:
Authentication
Register
Login
Response:
Chat
Deep research
Workflows
Workflows enable multi-agent orchestration. Define workflows in ares.toml:
[]
= "router" # Starting agent
= "orchestrator" # Used if routing fails
= 5 # Maximum agent chain depth
= 10 # Maximum total iterations
List available workflows
Response:
Execute a workflow
Response:
Workflow with Context
Admin & deployment API
Admin endpoints require the X-Admin-Secret header.
Trigger deploy
Response:
Check deploy status
List recent deploys
Service health
Response:
Service logs
RAG (retrieval augmented generation)
A.R.E.S includes a complete RAG system with a pure-Rust vector store. Requires the ares-vector feature. For local files, use the generic Rust CLI and pass every deployment-specific path or collection explicitly:
Ingest documents
Search documents
Search Strategies:
semantic: Vector similarity searchbm25: Traditional keyword matchingfuzzy: Typo-tolerant searchhybrid: Weighted combination of semantic + BM25
List collections
Tool calling
A.R.E.S supports tool calling with all LLM providers that support function calling (OpenAI, Anthropic, Ollama with ministral-3:3b+, etc.):
Built-in tools
- calculator: Basic arithmetic operations
- web_search: Web search via DuckDuckGo (no API key required)
Unified ToolCoordinator
The ToolCoordinator provides a provider-agnostic way to handle multi-turn tool calling with any LLMClient:
use ;
use ToolRegistry;
use Arc;
async
Toolcallingconfig options
| Option | Default | Description |
|---|---|---|
max_iterations |
10 | Maximum LLM round-trips before stopping |
parallel_execution |
true | Execute multiple tool calls in parallel |
tool_timeout |
30s | Timeout for individual tool execution |
include_tool_results |
true | Include tool results in final context |
stop_on_error |
false | Stop on first tool error vs continue |
Testing
A.R.E.S has complete test coverage with both mocked and live tests.
Unit & integration tests (mocked)
# Run all tests (no external services required)
# Or: just test
# Run with verbose output
# Or: just test-verbose
Live Ollama tests
Tests that connect to a real Ollama instance are available but ignored by default.
Prerequisites
- Running Ollama server at
http://localhost:11434 - A model installed (e.g.,
ollama pull ministral-3:3b)
Running live tests
# Set the environment variable and run ignored tests
OLLAMA_LIVE_TESTS=1
# Or: just test-ignored
# All tests (normal + ignored)
# With verbose output
# With custom Ollama URL or model
OLLAMA_URL=http://192.168.1.100:11434 OLLAMA_MODEL=mistral OLLAMA_LIVE_TESTS=1 \
Or add OLLAMA_LIVE_TESTS=1 to your .env file.
API tests (hurl)
End-to-end API tests using Hurl:
# Install Hurl
# Run API tests (server must be running)
# Run with verbose output
# Run specific test group
See CONTRIBUTING.md for more testing details.
Common commands (just)
A.R.E.S uses just as a command runner. Run just --list to see all available commands:
# Show all commands
# Build & Run
# CLI Commands
# Testing
# Code Quality
# Docker
# UI Development
# Ollama
# Info
Troubleshooting
Configuration file not found
# Error: Configuration file 'ares.toml' not found!
# Solution: Initialize a new project
Port already in use
# Error: Address already in use (os error 48)
# Find the process using port 3000
|
# Kill the process
Ollama connection failed
# Check if Ollama is running
# Start Ollama
# Or start via Docker
Missing environment variables
# Error: MissingEnvVar("JWT_SECRET")
# Solution: Set up environment variables
# Edit .env and set JWT_SECRET (min 32 characters) and API_KEY
UI build errors (node.js runtime required)
# Error: npx: command not found
# Solution: Install a Node.js runtime
# Option 1: Install Bun (recommended)
|
# Option 2: Install Node.js
# or download from https://nodejs.org
WASM build errors
# Error: target `wasm32-unknown-unknown` not found
# Solution: Add the WASM target
# Install trunk
Requirements
Minimum requirements
- Rust: 1.98 or later
- Operating System: Linux, macOS, or Windows
- Memory: 2GB RAM (4GB+ recommended for larger models)
Optional requirements
- Ollama: For local LLM inference (recommended)
- Node.js runtime: Bun, npm, or Deno (required for UI development)
- Docker: For containerized deployment
- GPU: NVIDIA (CUDA) or Apple Silicon (Metal) for accelerated inference
Security considerations
- JWT_SECRET: Must be at least 32 characters. Generate with:
openssl rand -base64 32 - API_KEY: Should be unique per deployment
- Environment Variables: Never commit
.envfiles to version control - HTTPS: Use HTTPS in production (configure via reverse proxy)
- Rate Limiting: Consider adding rate limiting for production deployments
Contributing
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Quick contribution guide
# 1. Fork and clone the repository
# 2. Create a feature branch
# 3. Make your changes and run tests
# 4. Commit and push
# 5. Open a Pull Request
Development setup
# Install development dependencies
# Run pre-commit checks before pushing
Changelog
See CHANGELOG.md for a list of changes in each version.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Ollama - Local LLM inference
- llama.cpp - GGUF model support
- Axum - Web framework
- Leptos - Reactive web UI framework
- TOON Format - Token-optimized configuration format
Ecosystem
| Project | What |
|---|---|
| pawan | Self-healing CLI coding agent (29 tools, streaming TUI) |
| daedra | Web search MCP server (7 backends, automatic fallback) |
| thulp | Execution context engineering (11 crates, tool abstraction) |
| lancor | llama.cpp toolkit (API client, HF Hub, server orchestration) |
| eruka | Context intelligence engine (knowledge graph, memory tiers) |
License
MIT