Skip to content

ToolSearch always returns nothing: deferred is hardcoded false for every MCP server #793

Description

@jaaacki

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.rsMcpServerConfig::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.rsToolSearch 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

  1. Register any MCP server and enable it for a conversation.
  2. Ask the model to do something requiring a tool it must discover.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions