Tool discovery runs on every turn, for a surface that almost never changes #102

Closed
opened 2026-08-12 17:50:49 +00:00 by coilysiren · 2 comments
Owner

Span counts over 24h: mcp.tools.list 46, community.turn 46 — exactly one discovery per turn — against mcp.tool.call 8. On the Discord path that is four MCP round-trips before the model is even called, and it is where the F6 cancellation lands.
RecommendationCache the roster's tool list in-process and invalidate on notifications/tools/list_changed. Removes 4 round-trips per turn and shrinks the F6 blast radius.

Span counts over 24h: mcp.tools.list 46, community.turn 46 — exactly one discovery per turn — against mcp.tool.call 8. On the Discord path that is four MCP round-trips before the model is even called, and it is where the F6 cancellation lands. RecommendationCache the roster's tool list in-process and invalidate on notifications/tools/list_changed. Removes 4 round-trips per turn and shrinks the F6 blast radius.
Author
Owner
https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/issues/163
Member

Agent Proxy is not in Deep's roster, so the four round-trips per turn are not this repository's. Deep reaches sirens-deep-forgejo-mcp and sirens-deep-steam-mcp, and two servers times initialize plus tools/list is exactly the four.

The cache belongs to the MCP client, which is coilyco-gaming/sirens-echo#163. What Agent Proxy owes that cache is a guarantee it can rely on, and it already holds one: /mcp declares tools.listChanged: false and never sends notifications/tools/list_changed.

That is not an accident of the current two-tool roster. The transport is stateless Streamable HTTP, which gives the server no channel for an unsolicited notification, so a client that cached the roster and waited for invalidation would wait forever. #103 makes it a tested contract, because a silent flip to true would break every caching client without any error to show for it. list_models reads the live catalog at call time, but that is a tool result rather than a definition, so rediscovery can never return anything a first discovery did not.

One correction worth carrying to sirens-echo#163: invalidating on notifications/tools/list_changed is not needed and would not work. Both of Deep's roster servers are static surfaces pinned by image tag, forgejo being a ward-mcp guardfile wrap generated at build and steam a fixed reader with no write surface, so neither can change its tool list while its pod lives, and a rollout replaces the pod. A process-lifetime cache with no invalidation subscription is correct and simpler. That is now recorded in the Deploy roster files, coilyco-bridge/deploy#405.

Agent Proxy is not in Deep's roster, so the four round-trips per turn are not this repository's. Deep reaches `sirens-deep-forgejo-mcp` and `sirens-deep-steam-mcp`, and two servers times initialize plus `tools/list` is exactly the four. The cache belongs to the MCP client, which is coilyco-gaming/sirens-echo#163. What Agent Proxy owes that cache is a guarantee it can rely on, and it already holds one: `/mcp` declares `tools.listChanged: false` and never sends `notifications/tools/list_changed`. That is not an accident of the current two-tool roster. The transport is stateless Streamable HTTP, which gives the server no channel for an unsolicited notification, so a client that cached the roster and waited for invalidation would wait forever. #103 makes it a tested contract, because a silent flip to true would break every caching client without any error to show for it. `list_models` reads the live catalog at call time, but that is a tool result rather than a definition, so rediscovery can never return anything a first discovery did not. One correction worth carrying to sirens-echo#163: invalidating on `notifications/tools/list_changed` is not needed and would not work. Both of Deep's roster servers are static surfaces pinned by image tag, forgejo being a ward-mcp guardfile wrap generated at build and steam a fixed reader with no write surface, so neither can change its tool list while its pod lives, and a rollout replaces the pod. A process-lifetime cache with no invalidation subscription is correct and simpler. That is now recorded in the Deploy roster files, coilyco-bridge/deploy#405.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/agent-proxy#102
No description provided.