trackmcp
All posts
EngineeringJan 22, 2026·8 min read

Instrumenting the MCP protocol layer

How to capture every call without touching a single tool: wrap the transport, not the handlers.

Krishna GoyalKrishna GoyalFounder, TrackMCP
Key takeaways
  • Wrap the transport once instead of editing every tool.
  • One seam captures name, arguments, result, timing, and client.
  • Redact in-process, sample high volume, and always fail open.

The naive way to add analytics to an MCP server is to edit every tool. It does not scale, it drifts, and new tools ship uninstrumented. There is a better seam: the protocol itself.

One seam, total coverage

Every tool call flows through the same request/response path. If you wrap the server once at that boundary, you see every call, its arguments, its result, timing, and the client, with no per-tool code.

import { withTrackMCP } from "@trackmcp/sdk";
import { server } from "./mcp";

export default withTrackMCP(server, {
  apiKey: process.env.TRACKMCP_KEY,
  service: "acme-mcp-server",
});

What the wrapper sees

One wrapper at the request/response boundary sees every call.
  • The tool name and arguments (after local redaction)
  • The result and whether it carried isError
  • Client type, duration, and transport status
  • A session id, so calls can be replayed in order

Keep it safe and cheap

Redact sensitive fields in-process before anything leaves. Sample if volume is high. Fail open: analytics should never be able to break a tool call. Done right, instrumentation costs a line of code and a sub-millisecond hop.

See this on your own server

TrackMCP turns your MCP server's calls into adoption, workflows, and outcomes. One line to install.

Keep reading