# Tools
ARES provides a type-safe tool calling framework with automatic schema generation.
## Built-in Tools
| Calculator | Mathematical expression evaluation | default |
| Web Search | Search via [Daedra](https://github.com/dirmacs/daedra) | `search-tools` |
| Web Scrape | Fetch URL and extract readable text content | `search-tools` |
## Tool Trait
Implement `Tool` to create custom tools:
```rust
use ares::tools::registry::Tool;
use async_trait::async_trait;
use serde_json::Value;
struct MyTool;
#[async_trait]
impl Tool for MyTool {
fn name(&self) -> &str { "my_tool" }
fn description(&self) -> &str { "Does something useful" }
fn parameters_schema(&self) -> Value {
serde_json::json!({
"type": "object",
"properties": {
"input": { "type": "string" }
}
})
}
async fn execute(&self, args: Value) -> ares::Result<Value> {
let input = args["input"].as_str().unwrap_or("");
Ok(serde_json::json!({ "result": format!("Processed: {}", input) }))
}
}
```
## Tool Registry
```rust
use ares::tools::ToolRegistry;
use std::sync::Arc;
// Create empty registry
let mut registry = ToolRegistry::new();
// Or create from config (auto-registers configured tools)
let mut registry = ToolRegistry::with_config(&config);
// Register a custom tool
registry.register(Arc::new(MyTool));
// Get tool definitions for LLM function calling
let definitions = registry.get_tool_definitions();
// Get definitions for specific tools only
let subset = registry.get_tool_definitions_for(&["calculator", "my_tool"]);
// Execute a tool by name
let result = registry.execute("my_tool", serde_json::json!({"input": "hello"})).await?;
// Check tool availability
assert!(registry.has_tool("calculator"));
```
## Tool Configuration
Tools support per-tool configuration (enabled/disabled, timeouts):
```rust
// Check if a tool is enabled
registry.is_enabled("web_search");
// Get tool timeout
let timeout_secs = registry.get_timeout("web_search");
```
## ToolCoordinator
The `ToolCoordinator` (in `ares::llm`) handles multi-turn tool calling conversations with any LLM provider:
```rust
use ares::llm::{ToolCoordinator, ToolCallingConfig};
let coordinator = ToolCoordinator::new(client, registry, ToolCallingConfig::default());
// Execute a conversation with automatic tool calling
let result = coordinator.execute(
Some("You are a helpful assistant."),
"What is 25 * 4 + 100?"
).await?;
println!("Response: {}", result.content);
println!("Tool calls: {}", result.tool_calls.len());
```
## Per-Agent Tool Filtering
Agents can be restricted to specific tools via TOON configuration:
```toon
[agent.math-helper]
tools = ["calculator"]
# This agent can ONLY use the calculator
```
## MCP Bridge
MCP servers are bridged into the tool ecosystem. See [MCP Integration](./mcp.md).