import type { AnalyticsParameterOwnership, CompatibleRequestHandlerExtra, CompatibleToolsListLike, MCPAnalyticsData, MCPRequestLike, MCPServerLike } from '../types'; import { MCPAnalyticsEventType } from './event-types'; import type { LoggerFn } from './logger'; /** * Single instrumentation core shared by the low-level (`Server`) and high-level * (`McpServer`) wrappers. The two entrypoints differ only in how they reach the * underlying tool — they both funnel the tool-call lifecycle through * {@link captureToolCall}, so error handling, conversation-id minting, session * attribution, and event capture are defined exactly once. */ type MCPRequestHandler = (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => Promise; /** Runs the underlying tool with SDK-owned analytics arguments removed. */ type ToolExecutor = (downstreamRequest: MCPRequestLike) => Promise; interface TraceToolCallParams { server: MCPServerLike; data: MCPAnalyticsData; request: MCPRequestLike; extra?: CompatibleRequestHandlerExtra; execute: ToolExecutor; /** Optional schema-derived ownership override for adapters with direct registry access. */ parameterOwnership?: AnalyticsParameterOwnership; /** * Event type to capture. Defaults to a tool call; the `get_more_tools` virtual * tool passes `mcpMissingCapability` so it records a capability gap rather than * a tool invocation. */ eventType?: MCPAnalyticsEventType; /** * When set, used verbatim as the captured intent (source `context_parameter`) * instead of running `resolveToolCallIntent`. Used by the `get_more_tools` * virtual tool, which carries its intent in the `context` argument. */ explicitContextIntent?: string; /** * Optional accessor for an error the executor captured out-of-band. The * high-level SDK turns thrown tool errors into `isError: true` results before * they reach us, so the wrapped callback stashes the original error and we * read it here to capture the real stack rather than the result envelope. */ takeCapturedError?: () => unknown; } /** * The shared tool-call lifecycle: resolve conversation id, build + enrich the * analytics event, run the tool, then capture success/failure. * * Analytics is isolated from the tool path on both sides — a failure while * preparing or publishing the event can never change what the tool returns or * throws, and the tool's own errors are always re-thrown to the caller. */ export declare function captureToolCall(params: TraceToolCallParams): Promise; /** * A method's patch: runs the original handler and captures analytics. `server` * and `originalHandler` are bound by {@link patchRequestHandlers}; the SDK * supplies `request` and `extra` per call. */ export type HandlerPatch = (server: MCPServerLike, originalHandler: MCPRequestHandler, request: MCPRequestLike, extra: CompatibleRequestHandlerExtra | undefined) => Promise; /** * Registers a synthetic fallback handler for `handlerName`, already wrapped in * `patch`, by writing straight into `_requestHandlers` instead of going through * `setRequestHandler`. * * Bypassing the SDK setter is deliberate, on three counts: * * - **Capability assertion.** `setRequestHandler` refuses a method the server * never declared a capability for, so instrumenting a low-level server built * without `capabilities.tools` used to throw `Server does not support tools` * and leave instrumentation half-applied. Our fallback is not a capability the * server offers — it exists only so a call for a tool nobody claims is still * captured — so the assertion has nothing to protect here. * - **Schema validation.** The setter also wraps the handler in request/result * parsing, which a handler that can only ever throw `Unknown tool` never needs. * - **Portability.** The setter's first argument is a Zod schema on SDK v1 and a * method string on v2; the map key is the same string on both, so this is the * one registration form that does not need to know which major it is talking * to — and it drops the last runtime `@modelcontextprotocol/sdk` import from * the shipped bundle. */ export declare function registerFallbackRequestHandler(server: MCPServerLike, handlerName: string, fallbackHandler: MCPRequestHandler, patch: HandlerPatch): void; /** * Applies the `patches` (keyed by method, e.g. `initialize`, `tools/list`) to the * handlers already registered, and patches `setRequestHandler` so matching * handlers registered later are patched too. The latter is what makes adapters * that register handlers post-construction work — e.g. `@rekog/mcp-nest` hands a * bare server to instrument() and only then registers its handlers. */ export declare function patchRequestHandlers(server: MCPServerLike, patches: Record): void; /** * Checks the server's raw listing for a real owner of a candidate virtual tool. * This does not depend on a previous client request and does not call the * instrumented list wrapper, so it neither injects PostHog tools nor captures a * synthetic tools/list event. `undefined` fails open to the real dispatcher. */ export declare function isToolAdvertised(server: MCPServerLike, toolName: string, extra: CompatibleRequestHandlerExtra | undefined, logger: LoggerFn): Promise; /** * Captures each `tools/list` and injects the SDK-managed tools (context * parameter, conversation id, `get_more_tools`) into the returned list. */ export declare function handleListToolsRequest(server: MCPServerLike, originalListToolsHandler: MCPRequestHandler, request: MCPRequestLike, extra: CompatibleRequestHandlerExtra | undefined, logger: LoggerFn): Promise; export declare function cacheToolDescriptions(cache: Map, tools: CompatibleToolsListLike['tools'] | undefined): void; /** * Category declared on a tool's `_meta` block (the MCP spec allows arbitrary * `_meta` keys). Declaring `_meta: { category: "Logs" }` on a tool definition * is all a server needs for every call to carry `$mcp_tool_category`. */ export declare function readToolMetaCategory(meta: unknown): string | undefined; export declare function cacheToolCategories(cache: Map, tools: CompatibleToolsListLike['tools'] | undefined): void; /** * Captures the connection handshake (and resolves identity) on `initialize` * before the original handler runs. */ export declare function handleInitializeRequest(server: MCPServerLike, originalInitializeHandler: MCPRequestHandler, request: MCPRequestLike, extra: CompatibleRequestHandlerExtra | undefined, logger: LoggerFn): Promise; export {}; //# sourceMappingURL=instrumentation.d.ts.map