How the agent loop works
Query submitted
You submit a query. If the active model has
tool_call enabled, TouchAI collects all enabled tool definitions from connected MCP servers and includes them in the request.Model streams a response
The model streams its response. If it decides to call one or more tools, the stream ends with
finishReason: "tool_calls" or "tool_use" and a list of toolCalls.Tools execute in parallel
TouchAI resolves each tool call to its server using the namespaced name (see Tool namespacing), then executes all tool calls for that iteration in parallel. Each call races against the server’s configured
tool_timeout.Results feed back to the model
Tool results are appended to the message history as
role: "tool" messages and a new streaming request is sent to the model.The agent loop only runs when the model’s
tool_call flag is set to 1. Models without tool call support receive no tool definitions and execute a single streaming pass.Tool namespacing
To avoid name collisions when multiple MCP servers expose tools with the same name, TouchAI prefixes every tool name with the server’s database ID before sending it to the model:read_file on server ID 3 becomes mcp__3__read_file. When the model requests a call to mcp__3__read_file, TouchAI parses the prefix to identify the server and the original tool name before executing.
Server connection status
MCP servers go through the following status states:| Status | Meaning |
|---|---|
disconnected | Default state on startup, or after an explicit disconnect |
connecting | Connection attempt is in progress |
connected | Successfully connected; tools are available |
error | Connection failed; last error message is stored |
mcpManager.autoConnect(), which sequentially connects all enabled servers. Servers are connected one at a time (not in parallel) to avoid concurrent SQLite writes. After a successful connection, the server’s tool list is synced to the local database.
Status updates are broadcast as
MCP_STATUS events so all open windows (e.g., the settings window) stay in sync without polling.Supported transport types
MCP servers can be connected over three transport types, defined in the Rust backend:| Transport | Use case |
|---|---|
stdio | Local process launched by TouchAI (command + args + env) |
sse | Remote server over Server-Sent Events (URL + optional headers) |
http | Remote server over HTTP (URL + optional headers) |
Adding an MCP server
Add a new server
Click the add button and fill in the server details: name, transport type, and the transport-specific fields (command/args for stdio, URL for SSE/HTTP).
Verify the connection
The status badge updates to
connected when the handshake succeeds. The tool list is populated automatically.The mcp_max_iterations setting
Themcp_max_iterations setting (Settings → General) controls how many times the agent loop can iterate within a single request.
| Property | Value |
|---|---|
| Default | 10 |
| Minimum | 1 |
| Maximum | 50 |
Tool call logs
Every tool call is logged to the local SQLite database and displayed inline in the conversation as a collapsibleToolCallItem. Each log entry contains:
| Field | Description |
|---|---|
| Tool name | The original (non-namespaced) tool name |
| Server name | The MCP server that owns the tool |
| Arguments | The parsed JSON arguments sent to the tool |
| Result | The text output returned by the tool |
| Status | pending → success, error, or timeout |
| Duration | Execution time in milliseconds |
FAQ
Why are my tools not showing up in the model's requests?
Why are my tools not showing up in the model's requests?
Tools are only sent to the model if:
- The model has
tool_callset to1. - The server status is
connectedat the time of the request. - The individual tool is enabled in the MCP Tools settings.
connected status badge. If it shows error, hover over it to see the last error message.What happens if a tool call times out?
What happens if a tool call times out?
Each tool call races against the server’s
tool_timeout value (configured per server). If the timeout fires first, the tool result is set to Tool execution timed out after {timeout}ms with isError: true, and the model receives that error as the tool result. The loop continues.Can I stop a running agent loop?
Can I stop a running agent loop?
Yes. Press Escape while the response is streaming to cancel the request. The
AbortSignal is forwarded to every pending tool call, so in-progress tool executions are cancelled too.What if a tool name on one server conflicts with a tool on another server?
What if a tool name on one server conflicts with a tool on another server?
TouchAI uses namespaced tool names (
mcp__{serverId}__{toolName}) so name collisions between servers are impossible. Each server’s tools are fully isolated by their unique database ID.Are tool preferences preserved when a server reconnects?
Are tool preferences preserved when a server reconnects?
Yes. When a server reconnects and its tool list is re-synced, TouchAI maps each incoming tool name to any existing enabled/disabled preference stored in the database. New tools default to enabled.