Tools¶
Tools let the model do things while it answers: read the clock, look up DNS records, count words, query a database. You load them when you start AIA, and the model decides when to call them.
AIA can use any tool written for RubyLLM, meaning a Ruby class that subclasses RubyLLM::Tool. You can load tools from a gem, from your own .rb files, or from MCP servers (see MCP Servers).
Loading tools from a gem¶
Use --require (short form --rq) to load a gem at startup. AIA finds every tool the gem defines and gives them to the model.
The shared_tools gem has a ready-made collection:
Some of the tools it provides:
| Tool name | What it does |
|---|---|
current_date_time_tool |
Current date, time and time zone |
system_info_tool |
OS, CPU, memory and disk details |
dns_tool |
DNS lookups |
cron_tool |
Parse and explain cron expressions |
calculator |
Arithmetic |
weather_tool |
Weather lookups |
disk_tool |
File and directory operations |
clipboard_tool |
Read or write the system clipboard |
doc_tool, database_tool, browser_tool, computer_tool, ... |
More specialised tools |
To load several gems, separate them with commas (--rq shared_tools,my_tools) or repeat the option. To load gems every time, put them in your config file:
Some tools act on your machine
Tools such as disk_tool, computer_tool and eval_tool can change files or run code. Load only the tools you trust, and use --allowed-tools to keep the list short. See Security.
Loading your own tool files¶
Use --tools to load .rb files directly. You can pass a single file, a directory (AIA loads every *.rb file in it), or a comma-separated list of either:
aia --tools ~/my_tools/word_count_tool.rb my_prompt
aia --tools ~/my_tools --chat
aia --tools ~/my_tools,./project_tools --chat
AIA exits with an error if a path doesn't exist, or if you name a file that doesn't end in .rb.
To load the same files every time, list them in your config file:
Writing a simple tool¶
A tool is a small Ruby class. Give it a name, a description the model can read, its parameters, and an execute method that returns a result:
# ~/my_tools/word_count_tool.rb
require 'ruby_llm/tool'
class WordCountTool < RubyLLM::Tool
def self.name = 'word_count'
description <<~DESC
Count words, characters, lines, and sentences in a given text.
Useful for text analysis and content length checks.
DESC
parameter :text, type: :string, description: 'The text to analyze', required: true
def execute(text:)
words = text.split(/\s+/).reject(&:empty?)
sentences = text.split(/[.!?]+/).reject { |s| s.strip.empty? }
{ words: words.size, characters: text.length,
lines: text.lines.size, sentences: sentences.size }
end
end
Then ask for it in a prompt:
Some tips:
- Write the description for the model. The model chooses tools by their descriptions, and AIA's automatic tool filter (below) matches your prompt against them too. Say plainly what the tool does and when to use it.
- Return data, not prose. A Hash or String is fine; the model turns it into an answer.
- Raise or return an error message when something goes wrong. The model sees the error and can explain it or try again.
- A tool can define an
available?method. If it returnsfalse, AIA skips the tool at startup and printsInfo: Tool '<name>' is not available, skipping.
See the RubyLLM tools guide for parameter types and other details.
Seeing which tools are loaded¶
From the command line, --list-tools prints your local tools and exits:
Add --mcp-list to include the tools offered by your MCP servers, grouped by server:
On a terminal the list is plain text. When you pipe it or redirect it to a file, it's Markdown:
Inside a chat, /tools lists every loaded tool, local and MCP. Give it a word to filter by name or description:
Your AIA crew-management tools (AIA::RecruitRobotTool and AIA::ReskillRobotTool) always show up in these lists. They let the model add crewmates on its own; see Crews.
--list-tools loads tools the way a session does, including gems such as shared_tools that load their tools lazily, and applies --allowed-tools and --rejected-tools (below). /tools shows everything that's loaded, not only what the model is allowed to use.
Limiting which tools the model sees¶
Large tool collections can confuse a model, and some models stop calling tools at all when they get dozens of them. Narrow the set down:
# Only these tools
aia --rq shared_tools \
--allowed-tools current_date_time_tool,system_info_tool,dns_tool \
my_prompt
# Everything except these
aia --rq shared_tools --rejected-tools computer_tool,eval_tool --chat
The short forms are --at and --rt. A few details:
- Matching is a case-insensitive substring match on the tool name, so
--allowed-tools datekeepscurrent_date_time_tool. - Both options take comma-separated lists and can be repeated.
- If you use both,
--allowed-toolsis applied first and--rejected-toolsthen removes from what's left. - The crew-management tools are filtered like any other tool.
--allowed-toolsdrops them unless one of your terms matches their names (for examplerecruitorreskill), and then the chief can't recruit crewmates on its own.
The config file equivalents are tools.allowed and tools.rejected.
Automatic tool filtering in chat¶
In a chat session AIA picks the tools that fit each turn. It compares your message with every tool's name, description and parameter names (local and MCP tools alike) and sends the model only the tools that score high enough, up to 30 per turn. This is on by default.
- When no tool matches a turn, the model gets no tools for that turn. This keeps a large tool set from going over a provider's limit on tools per request. If the model ignores a tool you expected it to use, name the tool or describe what it does in your message.
- To see which tools were chosen for each turn, run with
--verboseor--debug:
- Turn it off to always send every allowed tool:
The config file key is flags.auto_tool_filter: false.
Tools that need your approval¶
Some tool calls must be approved before they run. That happens when an MCP server is configured with requires_approval (see MCP Servers), or when a tool declares that it needs approval (with RubyLLM's requires_approval). MCP servers can also ask you for input mid-task.
--tool-approval decides what happens:
| Mode | Behaviour |
|---|---|
ask (default) |
AIA stops and asks on the terminal. With no terminal (for example in a script or pipe), the call is refused. |
approve |
Every call that needs approval runs without asking. MCP input requests are still asked on the terminal. |
deny |
Every call that needs approval is refused, and every MCP input request is declined. |
In ask mode a prompt looks like this:
Only y or yes approves the call. Questions go to stderr, so they don't mix with the model's answer.
When AIA refuses a call because nobody can answer, it says so:
[AIA] Refused: tool 'delete_file' requires approval and there is no terminal to ask. Set tools.approval (--tool-approval) to approve or deny.
Set the default in your config file with tools.approval: ask|approve|deny, or with the AIA_TOOLS__APPROVAL environment variable.
See also¶
- MCP Servers: tools served by external processes
- Crews: give recruited robots the same tools
- Security: running tools safely
- CLI reference and Configuration keys