confirmed with mcp evidence. The instrumentMcp function from @agent-feedback/node/mcp wraps your server’s registerTool method and registers report_product_outcome as a first-class protocol tool that agents can call after knowing the outcome.
When to use
Use MCP instrumentation when your product exposes tools through the Model Context Protocol. You get:confirmedclassification — every intercepted tool call is recorded as a confirmed agent interaction, not a best-effort HTTP opportunity.- Explicit feedback tool —
report_product_outcomeis registered as a real MCP tool with a typed schema. Agents do not need to parse HTTP headers or HTML. - Session auto-detection — if
ctx.sessionIdis present on the MCP context, it is used automatically without any callback.
Installation
The MCP instrumentation ships in the same package as the Express and Fastify middleware. Install it once.@modelcontextprotocol/server package is an optional peer dependency. Install it separately.
Usage
CallinstrumentMcp with your server instance and an options object. The function patches server.registerTool in-place and immediately registers report_product_outcome. It returns a { shutdown } handle for graceful teardown.
How it works
instrumentMcp intercepts server.registerTool before your own tool registrations. For every tool you register (except report_product_outcome itself):
- The wrapper records a telemetry event with
surface: "mcp",classification: "confirmed", andconfirmationMethod: "mcp". - It appends a
_agentFeedbackfield tostructuredContentcontaining the feedback handle, fields, and expiry. - It appends a plain-text reminder to the
contentarray instructing the agent to callreport_product_outcome.
report_product_outcome tool receives the feedbackHandle from step 2, POSTs the outcome directly to the Agent Feedback API, and returns a structured confirmation. Agents that support structured content read it from there; agents that only read text content see the reminder in content.
report_product_outcome is never double-wrapped. instrumentMcp checks the tool name before patching and calls the original registerTool directly for that tool.McpInstrumentationOptions
string
required
Your Agent Feedback product key. Must match the pattern
af_live_<keyId>_<secret>. Store this in an environment variable.string
Override the Agent Feedback API endpoint. Useful for staging environments.
"auto" | "ask" | "off"
default:"\"auto\""
Controls the
required flag in the feedback envelope sent to the agent."auto"— the envelope setsrequired: true; the agent is instructed to submit autonomously."ask"— the envelope setsrequired: false; the agent submits only when the outcome is known."off"— instrumentation is disabled entirely.
(args: unknown, ctx: McpContext) => string | undefined | null
Callback that extracts an opaque customer identifier from the tool arguments and MCP context. Both parameters are passed; use whichever carries the account ID. Exceptions are caught and logged as warnings — they never surface to the tool caller.
(args: unknown, ctx: McpContext) => string | undefined | null
Callback that extracts a session identifier. When this callback is omitted,
instrumentMcp falls back to ctx.sessionId automatically if it is a string.(args: unknown, ctx: McpContext) => string | undefined | null
Callback that returns a hint about the agent runtime (e.g.
"claude", "gpt-4o"). Used for runtime-level breakdown in the dashboard.Session auto-detection
You do not need to provide asessionRef callback if your MCP server already populates ctx.sessionId. instrumentMcp checks ctx.sessionId automatically and uses it as the session reference when the callback is absent or returns nothing.
Graceful shutdown
Callshutdown() before your process exits to drain the telemetry queue.
report_product_outcome tool schema
The tool is registered with the following Zod input schema and annotations:
readOnlyHint: false, destructiveHint: false, idempotentHint: true.
The agent must pass the feedbackHandle value from the _agentFeedback.feedbackHandle field of the tool result — not the full authorization token. The SDK strips the Bearer prefix automatically when embedding the handle in the structured content.