🐾 fix: use the agents.yaml description as the send_message tool description

Every agent's MCP tool advertised the generic "Send a message to the {agent}
agent" fallback, because register_agent_tools only had the @fast.agent
decorator's description to fall back on — and no agent in the estate sets one
(0 of 34 agent modules across kottos, iolaus, mentor and dodona).

Meanwhile the description an operator actually wrote already sits in
agents.yaml and is published in the registry; _start_agent had it in scope
and simply never passed it through. Wire it to tool_description.

Fixes every agent in every deployment at once, with no per-repo edits:
scotty's tool description becomes "Systems administration expert —
infrastructure diagnostics, security hardening, and keeping everything
running" instead of "Send a message to the scotty agent".

Adds tests/test_tool_description.py pinning the resolution order
(agents.yaml > decorator > fallback) and the {agent} templating, including
that prose containing other braces is not passed through .format().

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-03 13:14:45 -04:00
parent 0ae0d55a8d
commit 455d3eef3d
3 changed files with 113 additions and 1 deletions

View File

@@ -283,12 +283,26 @@ async def _start_agent(name: str, agents: dict[str, dict]) -> None:
if entry.get(k) is not None
}
# The agents.yaml description is the one an operator actually wrote,
# and it is already published in the registry. Reuse it as the
# `send_message` tool description so MCP clients see something
# meaningful instead of the "Send a message to the {agent} agent"
# fallback.
#
# Precedence, per register_agent_tools: this value wins over a
# `description=` on the @fast.agent decorator, which in turn wins over
# the generic fallback. agents.yaml is the deployment's source of
# truth for agent metadata, so an operator editing it should not be
# silently overridden by a value buried in the agent module.
tool_description = entry.get("description") or None
server = MultimodalAgentMCPServer(
primary_instance=primary_instance,
create_instance=fast_instance._server_instance_factory,
dispose_instance=fast_instance._server_instance_dispose,
instance_scope="request",
server_name=f"{fast_instance.name}-MCP-Server",
tool_description=tool_description,
host="0.0.0.0",
get_registry_version=fast_instance._get_registry_version,
request_limits=request_limits,