MCP Servers¶
The Model Context Protocol (MCP) is a standard way for programs to offer tools to an AI. Connect AIA to an MCP server, such as a filesystem server, a GitHub server or a database server, and the model can call that server's tools just like local tools.
AIA supports MCP servers that run as a local process (stdio) and servers you reach over HTTP (Streamable HTTP). The older SSE and WebSocket transports aren't supported.
Configuring a server in your config file¶
List servers under mcp_servers in ~/.config/aia/aia.yml (or in any file you pass with -c):
mcp_servers:
- name: filesystem
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
timeout: 10000
Every server you configure is connected at startup, so its tools are available in every session.
| Key | Meaning |
|---|---|
name |
The name you use with --mcp-use, --mcp-skip and /mcp |
command, args |
The program to start, for stdio servers |
env |
Extra environment variables for the server process, such as API tokens |
cwd (or directory) |
Working directory for the server process |
url |
The endpoint of an HTTP server. If you give a url, the server uses Streamable HTTP |
headers, bearer_token, oauth |
Authentication for HTTP servers |
timeout |
How long to wait for the server to connect (see below) |
prefix |
A prefix added to every tool name from this server |
only, except |
Lists of tool names to keep or drop from this server |
requires_approval |
Make tool calls wait for your approval (see below) |
group |
Concurrency grouping (see Running servers concurrently) |
An HTTP server with a token:
mcp_servers:
- name: tracker
url: https://mcp.example.com/mcp
headers:
Authorization: "Bearer <your-token>"
Timeouts¶
timeout sets how long AIA waits for one server to connect and report its tools. Values of 1000 or more are milliseconds and smaller values are seconds, so 10000 and 10 both mean ten seconds. Without a timeout, a server gets 30 seconds.
All servers connect at the same time. The whole connection phase is also capped by concurrency.mcp_timeout (default 120 seconds), but never at less than your slowest server's own timeout. Servers started with npx or uvx can be slow the first time they download, so give them a generous timeout.
Naming a server class¶
An entry in mcp_servers: can also be the name of a RubyLLM::MCP subclass. The class describes its own command or URL, environment and timeout, so the entry needs nothing else. Load the file that defines the class with require_libs: (or --require); AIA loads those libraries before it connects any server.
require_libs:
- shared_tools
- shared_tools/mcp
mcp_servers:
- SharedTools::MCP::Memory
- SharedTools::MCP::GitHub
- name: filesystem # Hash entries still work alongside them
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "."]
The server is known by the class's default name (SharedTools::MCP::GitHub is github), which is the name to use with --mcp-use and --mcp-skip. If the class has an available? method that returns false, as the shared_tools classes do when their API key is missing, AIA skips the server and says why. Example 30 in the repository uses every shared_tools server this way.
Loading servers from a JSON file¶
--mcp FILE reads servers from a JSON file in the format used by Claude Desktop and VS Code. You can repeat it, and the servers are added to the ones in your config file:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "./docs"],
"timeout": 10000
}
}
}
A file without an mcpServers key is read as one server, named after the file: {"command": "my-server", "args": ["--stdio"]}. Here command may also be an array whose first element is the program. Both forms accept the same keys.
A server in a JSON file can use every key a server in the YAML config can: command, args, env, url, headers, type, timeout, group, prefix, only, except and requires_approval. A url with no type is a Streamable HTTP server.
Choosing servers for a session¶
| Option | Effect |
|---|---|
--mcp-use NAMES (--mu) |
Connect only the named servers (comma-separated, repeatable) |
--mcp-skip NAMES (--ms) |
Connect every server except these |
--no-mcp |
Connect no MCP servers at all |
--mcp-list |
List the configured servers and exit |
aia --mcp-use filesystem,github --chat
aia --mcp-skip postgres my_prompt
aia --no-mcp quick_question
If a name given to --mcp-use doesn't match any configured server, AIA warns you and lists the names it knows:
WARNING: --mcp-use specified server(s) not found in config: githb
Available servers: filesystem, github
--mcp-list shows what's configured, after --mcp-use and --mcp-skip are applied:
$ aia --mcp-list
Configured MCP servers:
filesystem
command: npx -y @modelcontextprotocol/server-filesystem /Users/me/projects
To see each server's tools, add --list-tools:
The config file equivalents are mcp_use, mcp_skip and flags.no_mcp.
What happens at startup¶
AIA starts every selected server at once and shows a spinner line for each:
A server that fails to connect is left out for the rest of the session, so AIA doesn't keep retrying it. Everything else carries on normally.
Inside a chat, /mcp shows the status of every server and the tools it offers:
> /mcp
MCP Server Status
=================
Defined: 2 Connected: 1 Failed: 1
Connected Servers:
filesystem (14 tools)
- read_file
- list_directory
...
Failed Servers:
github: timed out after 10.0s
Every robot in the session shares the same server connections, including crew members you recruit. Each server process starts only once.
Requiring approval¶
To make a server's tool calls wait for your OK, set requires_approval in the YAML config:
mcp_servers:
- name: filesystem
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "."]
requires_approval: true # every tool
- name: github
command: github-mcp-server
args: ["stdio"]
requires_approval: [create_issue, merge_pull_request] # only these tools
What happens next depends on --tool-approval (ask, approve or deny). Tools: approval explains the modes. In the same way, AIA asks you on the terminal when a server needs input from you, such as a value or a URL to visit.
Two servers with the same tool name¶
Two tools can't share a name. When a server offers a tool with the same name as one from a server that's already connected, the second server is marked failed:
Fix this by giving one of the servers a prefix:
Running servers concurrently¶
When a question needs tools from several unrelated servers, AIA can split the work. One robot works with each group of servers, all at the same time, and a final robot merges their results.
- In a chat, type
/concurrent(or/conc) before your next message. That message is handled this way. - For prompts run from the command line, add
--concurrent-auto, or setconcurrency.auto: truein your config.
This happens only when there's more than one server. Servers that share the same group value stay together in one robot, and every server without a group gets its own. With --concurrent-auto, AIA splits the work only when there are at least concurrency.threshold groups (default 2). Otherwise the prompt runs normally.
mcp_servers:
- name: github
command: github-mcp-server
args: ["stdio"]
- name: postgres
command: postgres-mcp
group: data
- name: redis
command: redis-mcp
group: data # runs together with postgres
concurrency:
auto: true
threshold: 2
mcp_timeout: 120
Troubleshooting¶
- A server shows
(timed out). Raise itstimeout. The firstnpx -y ...run downloads the package and can take a while. Running the command yourself in a terminal shows whether it starts at all. - A server shows an error message. Check
command,argsandenv. The message is the error the server reported. Run with--log-level debug(or-d) for connection details. MCP activity goes to the MCP log; see Configuration keys forlogger.mcp. --mcp-usegives no tools. Check the warning about names that weren't found. Server names are case-sensitive.- The model ignores a server's tools in chat. AIA's automatic tool filter may not have matched your message to them. Mention what you want done more explicitly, or turn the filter off with
--no-auto-tool-filter. - Too many tools. Use
only:/except:on the server, or--allowed-tools/--rejected-tools.