feat(mcp): instrument the remote tool-dispatch chokepoint with PostHog events - #6358
Conversation
…g events handleMcpRequest is the single point every remote MCP tool invocation passes through, so it now calls the JSONbored#6235 PostHog wrapper once per tools/call request with the tool name, callerType "remote", success/ failure, and coarse latency -- reusing the same startedAt/toolName signals the existing product-usage telemetry already derives here. The call is wrapped in its own try/catch so a telemetry failure can never affect the tool response, on top of the wrapper's own no-op guarantee. Closes JSONbored#6237
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-16 04:23:57 UTC
Review summary Nits — 4 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6358 +/- ##
=======================================
Coverage 95.60% 95.60%
=======================================
Files 598 598
Lines 47202 47208 +6
Branches 15022 15024 +2
=======================================
+ Hits 45128 45134 +6
Misses 1290 1290
Partials 784 784
Flags with carried forward coverage won't be shown. Click here to find out more.
|
…6548) New McpToolUsageCard, wired into MaintainerPanel's qualityDashboard, showing per-tool call counts, success/failure rates, and a local-vs-remote split over the dashboard's window. The backend aggregation (from the PostHog telemetry wrappers #6235/ #6236/#6358 already write to) is tracked separately -- matching AcceptanceRateCard's own established precedent, this card assumes qualityDashboard.mcpToolUsage may be absent from the payload today and degrades to a "not yet available" empty state until that aggregation lands, rather than assuming a value or blocking on it shipping first. Uses AnalyticsCardShell for chrome/state handling and TableScroll's accessible-table pattern (caption, scope=col headers, focusable region) for the per-tool breakdown, matching this codebase's existing dashboard conventions. Closes #6241
Summary
handleMcpRequest(src/mcp/server.ts) is the single chokepoint every remote MCP request — including everytools/callinvocation — already passes through; it already derivesstartedAt,usageMetadata.toolName, and success/failure to record a DB-based product-usage event. This PR reuses those exact same signals to also call the feat(mcp): add a typed PostHog wrapper module for src/mcp/server.ts (remote) #6235 PostHog wrapper'srecordMcpToolCallexactly once per real tool call, taggedcallerType: "remote".usageMetadata.toolNameis a string (i.e. an actualtools/call, notping/tools/list/etc.) triggerrecordMcpToolCall, mirroring the existingeventName: "mcp_tool_called"vs"mcp_request"guard already in this function.recordMcpToolTelemetryhelper with its own try/catch, so a telemetry failure can never affect the tool response — a second, defensive layer on top of the wrapper's own no-throw guarantee from feat(mcp): add a typed PostHog wrapper module for src/mcp/server.ts (remote) #6235.c.env,usageMetadata.toolName,response.status,startedAt) and never touches the returnedResponse/thrownerror.Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateIf any required check was skipped, explain why:
wrangler(cf-typegen:checkfails with a pre-existing, change-unrelatedspawnSync wrangler ENOENT), which blocks the chainednpm run test:cifrom reaching later steps locally. Each step was therefore run individually:git diff --check,actionlint,db:migrations:check,db:schema-drift:check,selfhost:env-reference:check,miner:env-reference:check,selfhost:validate-observability, engine build,typecheck,test:engine-parity,test:live-gate-parity, andtest:driver-parityall pass clean on this branch. Coverage was verified by scoping--coverage.includetosrc/mcp/server.tsand running just the touched test file: every new line and both sides of both newif (typeof usageMetadata.toolName === "string")branches are fully covered. The broadertest/unit/mcp-*.test.ts+test/integration/routes-errors.test.tssweep passes cleanly aside from 3 pre-existing, change-unrelated Windows-only symlink-permission failures (EPERM: operation not permitted, symlink) inmcp-cli-lint-pr-text.test.ts/mcp-cli-slop-risk.test.ts.Safety
UI Evidencesection below — N/A, no UI change.UI Evidence
N/A — backend-only observability change, no visible UI change.
Notes
src/mcp/telemetry.ts'srecordMcpToolCall).