Skip to content

fix(mcp): make signals shortcut tools return data via templated selections#300

Merged
zer0stars merged 5 commits into
mainfrom
fix/mcp-signal-tool-overrides
Jun 12, 2026
Merged

fix(mcp): make signals shortcut tools return data via templated selections#300
zer0stars merged 5 commits into
mainfrom
fix/mcp-signal-tool-overrides

Conversation

@zer0stars

Copy link
Copy Markdown
Member

Problem

telemetry_get_signals_time_series and telemetry_get_latest_signals returned empty data. The underlying GraphQL fields (signals, signalsLatest) name signals by field-selection (e.g. speed(agg: AVG)), which mcpgen's static per-tool query strings can't express — so both tools shipped selecting only timestamp / lastSeen.

Fix

OverrideMCPTools patches the two generated ToolDefinitions at startup using server-garage v0.3.0 features:

  • SelectionTemplate renders the concrete selection set at call time from the supplied signal list (__MCPGEN_SELECTION__ placeholder in the query).
  • ToolOnly args (signalRequests / signalNames) let the model pass the signal list to the tool without the argument flowing through to the GraphQL executor.

GraphQL schema untouched. Bumps server-garage v0.1.1 → v0.3.0.

Testing

  • go build ./... and full go test ./... pass.

🤖 Generated with Claude Code

…tions

telemetry_get_signals_time_series and telemetry_get_latest_signals
selected only timestamp/lastSeen because mcpgen cannot express
field-selection arguments, so both returned empty data.

Override the two ToolDefinitions at startup using server-garage v0.3.0
SelectionTemplate + ToolOnly args: the model passes a signal list to
the tool, the selection set is rendered at call time, and the GraphQL
schema stays untouched.
…ools

OverrideMCPTools now returns an error if either expected tool name is
absent, so an mcpgen rename breaks startup instead of silently shipping
the original empty-selection tools. Tests cover patching, input
immutability, the missing-tool error, and that rendered templates parse
as valid GraphQL.
The MCP path used a bare executor, bypassing everything registered on
the HTTP GraphQL server: DCX credit tracking, complexity limit, query
recording, metrics, and the error presenter. With the shortcut tools now
returning real data, that gap meant unbilled, unrecorded, uncapped
signal access over MCP.

configureGQLExtensions holds the single shared extension list and is
applied to both *handler.Server and *executor.Executor (via the new
server-garage ExecutorOption hook).

server-garage is pinned to a pre-release commit of
DIMO-Network/server-garage#38; bump to the tagged release once it
lands.
@zer0stars

Copy link
Copy Markdown
Member Author

Two follow-up commits from review findings:

  1. Startup guardOverrideMCPTools now errors if mcpgen output renames either target tool, instead of silently shipping the broken empty-selection versions. Unit tests added (patching, input immutability, missing-tool error, rendered templates parse as valid GraphQL).
  2. MCP billing/extension parity — the MCP executor previously bypassed every extension on the HTTP GraphQL server (DCX credit tracking, complexity limit, query recording, metrics, error presenter). Both paths now share one extension list via configureGQLExtensions.

⚠️ go.mod temporarily pins server-garage to a pre-release commit of DIMO-Network/server-garage#38 (adds the ExecutorOption hook + missingkey=error on selection templates). Bump to the tagged release before merging this PR.

@zer0stars zer0stars merged commit edce41a into main Jun 12, 2026
4 checks passed
@zer0stars zer0stars deleted the fix/mcp-signal-tool-overrides branch June 12, 2026 02:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant