Follow-up from the #75 review.
McpServer runs validateToolInput() before executeToolHandler() and converts every failure (argument validation, disabled tool, unknown tool) into an isError result via createToolError() (mcp.js ~125–142 in @modelcontextprotocol/sdk 1.30). The Yavio proxy wraps the tool callback, which never runs in those cases, so no tool_call event exists at all for them — before and after #75. The model still sees an error, so this is an under-count the dashboard cannot show.
PostHog counts these because it wraps the low-level tools/call request handler. Yavio already has exactly that wrapper: intent.ts wrapCallHandler, installed only when intent capture is enabled.
Proposed: move status detection (and the tool_error classification from #75) to the protocol layer — a tools/call handler wrapper that is installed regardless of intent capture — so pre-handler failures produce a tool_call event with status: error and a category that tells validation apart from handler errors (candidate: reuse validation). Latency, inputs and client meta follow the same capture rules as today; per-tool overrides (#74) apply by tool name from request.params.name.
Spec to be written before implementation (.specs/sdk/), after #74/#75 land.
Follow-up from the #75 review.
McpServerrunsvalidateToolInput()beforeexecuteToolHandler()and converts every failure (argument validation, disabled tool, unknown tool) into anisErrorresult viacreateToolError()(mcp.js~125–142 in @modelcontextprotocol/sdk 1.30). The Yavio proxy wraps the tool callback, which never runs in those cases, so notool_callevent exists at all for them — before and after #75. The model still sees an error, so this is an under-count the dashboard cannot show.PostHog counts these because it wraps the low-level
tools/callrequest handler. Yavio already has exactly that wrapper:intent.tswrapCallHandler, installed only when intent capture is enabled.Proposed: move status detection (and the
tool_errorclassification from #75) to the protocol layer — atools/callhandler wrapper that is installed regardless of intent capture — so pre-handler failures produce atool_callevent withstatus: errorand a category that tells validation apart from handler errors (candidate: reusevalidation). Latency, inputs and client meta follow the same capture rules as today; per-tool overrides (#74) apply by tool name fromrequest.params.name.Spec to be written before implementation (
.specs/sdk/), after #74/#75 land.