@raindrop-ai/mcp instruments any TypeScript Model Context Protocol server. Each tool call becomes a tool span; the calls a model makes for one user prompt are grouped into a single mcp_activity event, so you can see what agents actually do with your server and catch failing tools.
Installation
@modelcontextprotocol/sdk (v1) and @modelcontextprotocol/server (v2).
Quick start
Wrap the server before registering tools, then register tools as usual.Wrapping a server you don’t construct
For third-party servers that build their ownMcpServer, wrap the class once before the server loads:
Turn tracking
MCP has no notion of a “turn”, so by default the package adds an optionalraindrop_turn_id parameter to every tool and appends the id to each result. The model copies it into its next call, and all calls carrying the same id land on one event. The parameter is stripped before your handler runs.
If a client sends _meta["io.modelcontextprotocol/aiInvocation"].turnId, that is used instead and nothing is appended.
Set turnTracking: false to leave tool schemas and results untouched; every call then becomes its own event.
Configuration
call passed to the resolvers is { toolName, args, sessionId, extra }, where extra is the SDK’s per-request object (v1 RequestHandlerExtra, v2 ServerContext).
What gets captured
- One
mcp_activityevent per turn with propertiesmcp.turn_id,mcp.tool(latest tool in the turn),mcp.is_error,mcp.session_idwhen the transport has one, plus anything fromproperties. - One tool span per call with the tool name, arguments and result (after redaction), and the error message when the handler fails.
raindrop.shutdown() on process exit to drain pending deliveries.
Known limitations
wrap()interceptsregisterTool, so tools registered before wrapping are not instrumented.raindrop_turn_idis added by extending the tool’s schema. Zod object schemas, raw Zod shapes and Standard Schemas are supported; a schema that cannot be extended (a Zod union, or a raw shape from a different Zod major) is registered unchanged and its calls each open their own event.- Grouping depends on the model echoing
raindrop_turn_id; clients that strip unknown result blocks start a new event per call.