Summary
ToolSearch can never return a result in AionUi. Every MCP server is constructed with deferred: Some(false), so no tool is ever marked deferred, and ToolSearch's filter matches nothing — while the tool is still advertised to the model and the system prompt still tells it that deferred tools exist.
Models that follow that instruction get stuck in a retry loop.
Root cause
aionrs implements deferred tools correctly:
crates/aion-config/src/config.rs — McpServerConfig::deferred: Option<bool>, documented as "Defaults to true when omitted"
crates/aion-mcp/src/tool_proxy.rs:135 — reads the per-server flag
crates/aion-tools/src/tool_search.rs — ToolSearch filters tool_defs on .filter(|d| d.deferred)
crates/aion-agent/src/bootstrap.rs:361 — registers ToolSearchTool unconditionally
AionCore overrides the flag at every construction site in crates/aionui-ai-agent/src/factory/aionrs.rs:
| Function |
Lines |
row_to_mcp_server_config (DB-configured servers) |
534, 560, 586 |
session_server_to_mcp_server_config |
615, 630, 645, 660 |
team_mcp_to_config |
749 |
All deferred: Some(false), with no conditional and no explanatory comment.
Result: .filter(|d| d.deferred) yields an empty set on every call, and ToolSearch returns No deferred tools matching "<query>" found.
Reproduction
- Register any MCP server and enable it for a conversation.
- Ask the model to do something requiring a tool it must discover.
ToolSearch returns "No deferred tools matching …" — always, regardless of tool count or how the server was installed.
I also verified from the outside that this is not user-configurable: adding "deferred": true to the server's transport_config JSON persisted across a full app + backend restart, the server connected normally, and ToolSearch still returned nothing — because row_to_mcp_server_config does not read the key.
Impact
Observed across ~20 sessions on AionUi 2.1.50 / AionCore v0.1.61, with 12 MCP servers (~1,300 tools):
| model |
sessions |
ToolSearch calls |
real tool calls |
| glm-5.2 |
13 |
204 |
17 |
| glm-5.1-cloud |
5 |
1 |
17 |
| gpt-5.5 |
2 |
0 |
16 |
Worst single session: 53 ToolSearch calls, 8 real tool calls. Several sessions made 10–20 ToolSearch calls and accomplished nothing before giving up and telling the user to "enable the file/exec tools".
The failure is model-dependent, which is likely why it has gone unnoticed: gpt-5.5, kimi-k27-code and glm-5.1-cloud ignore ToolSearch and call tools directly. glm-5.2 trusts the system prompt, searches, finds nothing, and retries.
Suggested fix
Read deferred from the server config instead of hardcoding it — PR attached. Absent key keeps today's behaviour exactly, so there is no default change.
Separately, it may be worth not registering ToolSearchTool (or injecting the "some tools are deferred" prompt) when nothing in the snapshot is deferred — that would have prevented the symptom regardless of this setting. That belongs in aionrs.
Summary
ToolSearchcan never return a result in AionUi. Every MCP server is constructed withdeferred: Some(false), so no tool is ever marked deferred, andToolSearch's filter matches nothing — while the tool is still advertised to the model and the system prompt still tells it that deferred tools exist.Models that follow that instruction get stuck in a retry loop.
Root cause
aionrsimplements deferred tools correctly:crates/aion-config/src/config.rs—McpServerConfig::deferred: Option<bool>, documented as "Defaults to true when omitted"crates/aion-mcp/src/tool_proxy.rs:135— reads the per-server flagcrates/aion-tools/src/tool_search.rs—ToolSearchfilterstool_defson.filter(|d| d.deferred)crates/aion-agent/src/bootstrap.rs:361— registersToolSearchToolunconditionallyAionCore overrides the flag at every construction site in
crates/aionui-ai-agent/src/factory/aionrs.rs:row_to_mcp_server_config(DB-configured servers)session_server_to_mcp_server_configteam_mcp_to_configAll
deferred: Some(false), with no conditional and no explanatory comment.Result:
.filter(|d| d.deferred)yields an empty set on every call, andToolSearchreturnsNo deferred tools matching "<query>" found.Reproduction
ToolSearchreturns "No deferred tools matching …" — always, regardless of tool count or how the server was installed.I also verified from the outside that this is not user-configurable: adding
"deferred": trueto the server'stransport_configJSON persisted across a full app + backend restart, the server connected normally, andToolSearchstill returned nothing — becauserow_to_mcp_server_configdoes not read the key.Impact
Observed across ~20 sessions on AionUi 2.1.50 / AionCore v0.1.61, with 12 MCP servers (~1,300 tools):
Worst single session: 53 ToolSearch calls, 8 real tool calls. Several sessions made 10–20 ToolSearch calls and accomplished nothing before giving up and telling the user to "enable the file/exec tools".
The failure is model-dependent, which is likely why it has gone unnoticed: gpt-5.5, kimi-k27-code and glm-5.1-cloud ignore
ToolSearchand call tools directly. glm-5.2 trusts the system prompt, searches, finds nothing, and retries.Suggested fix
Read
deferredfrom the server config instead of hardcoding it — PR attached. Absent key keeps today's behaviour exactly, so there is no default change.Separately, it may be worth not registering
ToolSearchTool(or injecting the "some tools are deferred" prompt) when nothing in the snapshot is deferred — that would have prevented the symptom regardless of this setting. That belongs inaionrs.