A.R.E.S (Agentic Runtime Extensible Server) is a composable AI agent runtime in Rust, built on the Cordis framework. Features include multi-provider LLM routing, structured tool calling, RAG, MCP integration, multi-tenant auth, and workflow orchestration. You embed the library facade of the ares-server package (Context, Execute, Tools, Llm). The ares-server binary serves the Axum HTTP layer.
Built by DIRMACS. Documentation
Features
- Multi-provider LLM: Ollama, OpenAI, Anthropic Claude, LlamaCpp (direct GGUF loading)
- TOML configuration: declarative, hot-reloading
- Configurable agents: defined 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: each agent sees only its allowed tools
- 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
- Configuration validation: circular reference detection and warnings for unused items
- 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: services register with
ctx.plugin()orctx.provide(). Handlers pull dependencies withctx.get::<T>()on a typedContext.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:
Context::injectwaits on theReflectServiceTypeId notifier (ensure_notifier+changed). A 5ms poll runs 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 configurations from
ares.toml. TOON changes notifyToolsandExecute.TenantRealmsopen-then-intercept on request paths and dispose on tenant delete. - Hot-reload: a file watch triggers automatic service refresh without restart. When the epoch changes,
Fiber::refreshreruns pluginapply. - Circuit breaker: LLM provider health tracked per-endpoint with automatic failover
Installation
You can run ARES as a standalone server. You can also use it as a library in your Rust project.
As a library
Add this dependency to your project:
[]
= "0.9"
Basic usage:
use ;
The default features of ares-server are postgres, openai, ares-vector, mcp, inventory, and rhai-policy. Embed-only builds pass --no-default-features --features openai,postgres,mcp to Cargo. 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
The CLI gives full-featured commands 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 or later. Install via rustup
- Ollama for local LLM inference (recommended). See Install Ollama
- just as the command runner (recommended). See 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
The server runs on http://localhost:3000
Feature flags
ARES 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: v0.2.5 made
swagger-uioptional. This change reduces the binary size and the build time. The feature needs network access during the build to download the 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. Cause:ort-syslinker errors. Use WSL, Linux, macOS, or 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: The
fullandfull-uibundles excludelocal-embeddingsbecause of Windows MSVC compatibility issues. On Linux and macOS usefull-local-embeddingsorfull-ui-local-embeddings.
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
ARES reads a TOML configuration file (ares.toml) with declarative configuration for all components. The server requires this file at startup.
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 server validates the configuration on load:
- Reference checks: Models must reference valid providers, and agents must reference valid models
- Circular reference detection: Workflows cannot have circular agent references
- Environment variables: All referenced environment variables must be set
The validate_with_warnings() method reports unused configuration items (providers, models, and tools with no references).
Hot reloading
The server detects configuration changes automatically and applies them without restart. Edit ares.toml. The loader picks up the changes within 500ms.
Environment variables
These environment variables must be set because ares.toml references them:
# 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 when
LLAMACPP_MODEL_PATHis set - OpenAI when
OPENAI_API_KEYis set - Ollama as the default fallback (no API key required)
Dynamic configuration (TOON)
ARES also supports TOON (Token Oriented Object Notation) files for behavioral configuration with hot-reload support. These files complement ares.toml.
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 configuration in ares.toml:
[]
= "config/agents"
= "config/models"
= "config/tools"
= "config/workflows"
= "config/mcps"
= true
The server hot-reloads TOON files automatically after a change.
User-created agents API
Users can create custom agents in the database. Import and export use the TOON format:
# Create a custom agent
# Export as TOON
# Import from TOON
Extending ARES
ARES works as a library. The ares_server lib injects Execute, Tools, and Llm on a Cordis Context. An agent runs with no HTTP service on the graph. The Axum routes live in the ares-http package.
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
The trait now lives in ares-agent (ares_agent::context_provider::ContextProvider). It injects external context into agent calls before LLM invocation. This is one focused hook, not the general extension mechanism; for broader extension, write a plugin or a loader entry (see ARCHITECTURE.md).
use ContextProvider;
use async_trait;
By default ARES uses NoOpContextProvider, which returns None.
Architecture
Composition is a Cordis Context plus loader entries. Components register into a typed Context. Handlers and engines pull Execute, Tools, Llm, and Store at call time. The ares_server lib has no axum on its graph. The kernel follows the hardening rules of the Cordis model. Guarded withdrawal protects providers against removal under active consumers. Verified hot-swap and drain-and-shift replacement give zero-downtime rebuilds through POST /admin/cordis/services/{name}/replace. Peer-dependency versioning uses provide_versioned/declare_inject_versioned. Incompatible versions leave dependents Inactive instead of a silent bind. Inject reconciliation runs eagerly. Cycle detection at load reports rings through GET /admin/cordis/entries. A metatheory property suite proves quiescence, confluence, LIFO, and reactive invariants. RhaiPolicy scripting ships default-on. TOML entries attach sandboxed script gates to capability events with fail-closed semantics. The 0.10 kernel adds: intercept meta-events (internal/get|set|config|update|listener) that veto or rewrite kernel operations; readiness barriers that rest fibers in inspectable Pending until watched providers settle; name-keyed computed properties (register_accessor) and layered intercept chains; identity-preserving entry moves with rename cascades through POST /admin/cordis/entries/{id}/move; a module graph that reloads each affected plugin exactly once per debounced batch; an in-kernel logger, fiber-scoped timers, and wired per-subtask cancellation. docs/cordis-mapping.md documents 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. It reruns plugin apply when the epoch changed or when the fiber is not already Active with satisfied dependencies. Dispose still undoes effects in LIFO order.
EventsService dispatch modes: Emit returns JSON null. Parallel joins every handler and returns JSON null on success. Handler values are discarded, and the first join or handler error propagates. 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: …} configuration interpolation — fail-open). It re-composes on every watched reload and applies the diff through the loader journal. Verified hot-swap handles same-provider rebuilds, and guarded withdrawal handles 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. They emit boundary events on the typed catalog.
Key services
| Service | What it does |
|---|---|
Execute |
Single entry point for agent runs. Chat, v1, JWT, MCP, scheduler, pipeline, and trigger delegate here after agent.admit. |
Resolver |
Crate-private three-tier agent resolution: tenant DB, community, system configuration. |
Llm |
Provider clients with a circuit breaker. ProviderRegistry remains a constructor input. |
Tools |
Merges static tools, runtime DB tools, and MCP tools. Tenant isolation via isolate::<Tools>. |
Store |
Postgres client with migrations, template seed, and tenant DB. |
EventsService |
Typed event bus. Product paths stay event-first. |
Overlay |
ares.toml overlay. Fills empty loader configurations. TOON notifies Tools/Execute. |
TenantRealms |
Per-tenant child contexts. Open-then-intercept on request paths. Dispose runs 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
The interactive Swagger UI is available at http://localhost:3000/swagger-ui/
Note: The build must enable the
swagger-uifeature:# Or use the full bundle:
Authentication
Register
Login
Response:
Chat
Deep research
Workflows
Workflows give 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)
ARES includes a complete RAG system with a pure-Rust vector store. It 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
ARES supports tool calling with all LLM providers that support function calling (OpenAI, Anthropic, and Ollama with ministral-3:3b or later):
Built-in tools
- calculator: Basic arithmetic operations
- web_search: Web search via DuckDuckGo (no API key required)
Unified ToolCoordinator
The ToolCoordinator handles multi-turn tool calling with any LLMClient in a provider-agnostic way:
use ;
use ToolRegistry;
use Arc;
async
Toolcallingconfig options
| Option | Default | Description |
|---|---|---|
max_iterations |
10 | Maximum LLM round-trips before stopping |
parallel_execution |
true | Runs 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
ARES has complete test coverage with mocked tests 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 exist, and the default run ignores them.
Prerequisites
- An Ollama server runs at
http://localhost:11434 - A model is installed. Example:
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 \
Alternatively, add OLLAMA_LIVE_TESTS=1 to your .env file.
API tests (hurl)
End-to-end API tests use Hurl:
# Install Hurl
# Run API tests (server must be running)
# Run with verbose output
# Run specific test group
See CONTRIBUTING.md for more details on testing.
Common commands (just)
ARES uses just as the 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 or more 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 have at least 32 characters. Generate it with
openssl rand -base64 32 - API_KEY: unique per deployment
- Environment variables: never commit
.envfiles to version control - HTTPS: use HTTPS in production (configure through a reverse proxy)
- Rate limiting: production deployments need rate limiting at the proxy layer
Contributing
We welcome contributions. See CONTRIBUTING.md for the 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.
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