import { PostHog, type PostHogOptions } from 'posthog-node'; import type { InitializeCaptureData, MissingCapabilityCaptureData, PreparedToolCall, PrepareToolListOptions, ToolCallCaptureData, ToolsListCaptureData } from '../types'; import { type ContextInjectableTool } from './context-parameters'; /** * Options for {@link PostHogMCP}. A superset of `posthog-node`'s options, plus * MCP-specific knobs. */ export interface PostHogMCPOptions extends PostHogOptions { /** * Name of the virtual "report a missing capability" tool injected by * {@link PostHogMCP.prepareToolList} and detected by * {@link PostHogMCP.prepareToolCall}. Set once here so injection and detection * can't drift. Defaults to `get_more_tools`. */ missingCapabilityToolName?: string; } /** * A `posthog-node` client with first-class MCP analytics. Use this when there is * no `Server`/`McpServer` to wrap (e.g. a custom HTTP or hono dispatcher): the * host resolves identity + context per request and calls the capture methods * directly. * * It **extends `PostHog`**, so it's a drop-in replacement for your existing * `posthog-node` client — `capture`, `identify`, `flush`, `shutdown`, feature * flags, etc. all work unchanged — with `captureToolCall` / `captureInitialize` * added on top. The MCP methods build canonical `$mcp_*` events and run them * through the same sanitize → truncate → `$exception` fan-out pipeline as * `instrument()`, then hand them to the inherited `capture()` (so the client's * own `beforeSend` applies). * * @example * ```ts * import { PostHogMCP } from "@posthog/mcp" * * const posthog = new PostHogMCP("phc_your_project_token", { host: "https://us.i.posthog.com" }) * * posthog.captureToolCall({ * toolName: "search_docs", * durationMs: 42, * isError: false, * distinctId: "user_123", * groups: { organization: "org_1" }, * }) * * // inherited from posthog-node * posthog.capture({ distinctId: "user_123", event: "feedback_submitted", properties: { rating: 5 } }) * await posthog.shutdown() * ``` */ export declare class PostHogMCP extends PostHog { #private; constructor(apiKey: string, options?: PostHogMCPOptions); /** Capture a tool invocation. Emits `$mcp_tool_call` (+ an `$exception` sibling on error). */ captureToolCall(data: ToolCallCaptureData): void; /** Capture the connection handshake. Emits `$mcp_initialize`. */ captureInitialize(data: InitializeCaptureData): void; /** * Capture a `tools/list` response. Emits `$mcp_tools_list` carrying the * advertised tool names (`$mcp_listed_tool_names`), which powers * "advertised but never called" analysis. Pass the names you're about to * return — typically the result of {@link prepareToolList}. */ captureToolsList(data: ToolsListCaptureData): void; /** * Decorate your `tools/list` response with PostHog's analytics affordances: * injects the `context` argument into every tool (so agents state their intent, * captured as `$mcp_intent`) and, when `reportMissing` is on, appends the * `get_more_tools` virtual tool (rename it via the `missingCapabilityToolName` * constructor option). Returns a new array; your tools are untouched. * * The appended `get_more_tools` descriptor carries only the base MCP tool fields * (name, description, input schema) — not any framework-specific fields your * `TTool` may add (e.g. a `handler`). It is meant to be detected via * {@link prepareToolCall}'s `isMissingCapability`, not dispatched through a handler. * * Call this when there is no `Server` to wrap — it does for a custom dispatcher * what `instrument()` does for a `Server`. Pair it with {@link prepareToolCall} * on the inbound side. * * @example * ```ts * // building your tools/list response * return { tools: posthog.prepareToolList(myTools, { reportMissing: true }) } * ``` */ prepareToolList(tools: TTool[], options?: PrepareToolListOptions): TTool[]; /** * Read an incoming `tools/call` before you dispatch it: pulls the agent's * intent off the injected `context` argument, strips `context` from the * arguments (so your handler and its schema validation never see it), and flags * whether the call targeted the `get_more_tools` virtual tool. * * Pass the returned `intent` / `intentSource` to {@link captureToolCall}, and * dispatch the returned `args` to your tool. * * This only extracts the explicit `context` argument (`intentSource: * 'context_parameter'`); it does not infer intent. If you run your own * inference, pass that string with `intentSource: 'inferred'` straight to * {@link captureToolCall} (the `instrument()` path's `intentFallback` * equivalent). * * @example * ```ts * const { intent, intentSource, args, isMissingCapability } = posthog.prepareToolCall(name, rawArgs) * if (isMissingCapability) { * posthog.captureMissingCapability({ context: intent, ...identity }) * return getMoreToolsResult() * } * const result = await runTool(name, args) * posthog.captureToolCall({ toolName: name, intent, intentSource, ...identity }) * ``` */ prepareToolCall(name: string, args?: Record): PreparedToolCall; /** * Capture a `get_more_tools` call as a missing-capability report. Emits * `$mcp_missing_capability` with the agent's description as `$mcp_intent`. Reply * to the agent with `getMoreToolsResult()`. */ captureMissingCapability(data: MissingCapabilityCaptureData): void; } //# sourceMappingURL=posthog-mcp.d.ts.map