interface AgentCatOptions { enableReportMissing?: boolean; enableTracing?: boolean; enableToolCallContext?: boolean; customContextDescription?: string; /** * Default false. Set true to inject a required agent_id parameter into every * tool. Agents self-generate the value (model|harness|nonce, e.g. * "opus-4.80-1m|claude-code|k3n9x"); it is echoed back in mcp_session * and stamped on events as tags. Omission never rejects a call server-side — * the event is simply published without agent identity. The intended * enforcement is client-side: a strict schema-validating MCP client will * refuse to send a call that omits a required agent_id in the first place. */ enableAgentTracking?: boolean; /** * Hook mode: you manage task state. When configured, AgentCat injects no * session_id parameter and prepends no issuance text; the returned value is * combined with the project ID into a deterministic ses_ KSUID. Nullish * returns and throws mint silently — a configured hook should answer every * request. */ resolveSessionId?: (request: any, extra?: CompatibleRequestHandlerExtra) => string | null | Promise; identify?: (request: any, extra?: CompatibleRequestHandlerExtra) => Promise; redactSensitiveInformation?: RedactFunction; redactEvent?: RedactEventFunction; exporters?: Record; apiBaseUrl?: string; disableDiagnostics?: boolean; eventTags?: (request: any, extra?: CompatibleRequestHandlerExtra) => Record | null | Promise | null>; eventProperties?: (request: any, extra?: CompatibleRequestHandlerExtra) => Record | null | Promise | null>; } type RedactFunction = (text: string) => Promise; type RedactEventFunction = (event: Event) => Event | null | Promise; interface ExporterConfig { type: string; [key: string]: any; } interface Exporter { export(event: Event): Promise; } declare enum AgentCatIDPrefixes { Session = "ses",// Session IDs deliberately keep this prefix Event = "evt", Agent = "agt" } interface Event { id: string; sessionId: string; projectId?: string; eventType: string; timestamp: Date; duration?: number; ipAddress?: string; sdkLanguage?: string; agentcatVersion?: string; serverName?: string; serverVersion?: string; clientName?: string; clientVersion?: string; identifyActorGivenId?: string; identifyActorName?: string; identifyActorData?: object; resourceName?: string; parameters?: any; response?: any; userIntent?: string; isError?: boolean; error?: ErrorData; tags?: Record | null; properties?: Record | null; actorId?: string; eventId?: string; identifyData?: object; } /** * Duck type over the second argument the MCP SDK passes to request handlers, * covering both supported majors: * - v1 (`@modelcontextprotocol/sdk`): the SDK's `RequestHandlerExtra` — * e.g. `sessionId`, `authInfo`, `requestId`. * - v2 (`@modelcontextprotocol/server`): the SDK's `ServerContext` — * `{ sessionId, mcpReq, http }`; note `http?.req?.headers` is a Web * `Headers` object (use `.get("x-header")`, not bracket access). * * Only `sessionId` is common to both; everything else is reached through the * index signature and is SDK-version-specific. */ interface CompatibleRequestHandlerExtra { /** * The MCP transport session, assigned by the SDK and reset on reconnect. * NOT AgentCat's `session_id` handle, which outlives the transport — that * one is the agent-echoed tool parameter stored in `Event.sessionId`. */ sessionId?: string; [key: string]: any; } interface UserIdentity { userId: string; userName?: string; userData?: Record; } interface AgentCatData { projectId: string; options: AgentCatOptions; } interface StackFrame { filename: string; function: string; lineno?: number; colno?: number; in_app: boolean; abs_path?: string; context_line?: string; } interface ChainedErrorData { message: string; type?: string; stack?: string; frames?: StackFrame[]; } interface ErrorData { message: string; type?: string; stack?: string; frames?: StackFrame[]; chained_errors?: ChainedErrorData[]; platform?: string; } interface CustomEventData { /** Session ID to attribute this event to. Takes precedence over a session-id string argument. */ sessionId?: string; resourceName?: string; parameters?: any; response?: any; message?: string; duration?: number; isError?: boolean; error?: any; tags?: Record; properties?: Record; } /** * Integrates AgentCat analytics into an MCP server to track tool usage patterns and user interactions. * * @param server - The MCP server instance to track. Must be a compatible MCP server implementation. * Both TypeScript SDK majors are supported with the same call — `@modelcontextprotocol/sdk` >=1.11 <2 * (v1 `Server`/`McpServer`) and `@modelcontextprotocol/server` >=2 <3 (v2 `McpServer`, including * instances built inside `createMcpHandler`/`serveStdio` factories). The SDK major is auto-detected * per server object. * @param projectId - Your AgentCat project ID obtained from agentcat.com when creating an account. Pass null for telemetry-only mode. * @param options - Optional configuration to customize tracking behavior. * @param options.enableReportMissing - Adds a "get_more_tools" tool that allows LLMs to automatically report missing functionality. * @param options.enableTracing - Enables tracking of tool calls and usage patterns. * @param options.enableToolCallContext - Injects a "context" parameter to existing tools to capture user intent. The context parameter is appended after the injected `session_id`/`agent_id` parameters. * @param options.customContextDescription - Custom description for the injected context parameter. Only applies when enableToolCallContext is true. Use this to provide domain-specific guidance to LLMs about what context they should provide. * @param options.enableAgentTracking - Injects an optional `agent_id` parameter so each agent (including every spawned subagent) is individually identifiable. Agent IDs are minted by the server on an agent's first call and echoed back on subsequent calls. Defaults to false (opt-in). The agent ID rides on events as the `agentcat_agent_id` tag. * @param options.resolveSessionId - Hook mode: supply your own session identifier per request (e.g. from your auth or workflow state) and AgentCat steps back — no `session_id` parameter is injected and no issuance text is prepended to results. The returned string is combined with your project ID into a deterministic KSUID, so the same identifier always maps to the same task. Return null to mint silently (avoid: the agent can never learn a silently minted ID). Receives the same `(request, extra)` arguments as `identify`. * @param options.identify - Async function to identify the actor behind a tool call. Runs on every tool call; the result is stamped directly onto that call's event. * @param options.redactSensitiveInformation - Function to redact sensitive data before sending to AgentCat. * @param options.redactEvent - Event-level redaction hook invoked with the full event (inspect `resourceName`, `eventType`, `parameters`, `response`, etc.) before it is published. Return a modified event, or null to drop the event entirely. May be sync or async. Runs before `redactSensitiveInformation`, so it sees raw, unredacted values; the string-level hook, sanitization, and truncation still run on its output. The system-managed fields `id`, `sessionId`, `projectId`, `eventType`, and `timestamp` cannot be changed (`id` is assigned after redaction and is empty at hook time). If the hook throws, the event is dropped and the error is logged to `~/agentcat.log`. * @param options.eventTags - Callback invoked on every auto-captured tool call to attach string key-value tags. Tags are intended to be indexed and queryable in the AgentCat dashboard — use them for structured metadata you'll want to filter or group by (e.g., trace IDs, environments, regions). Tags are validated client-side: keys must be ≤32 chars matching `[a-zA-Z0-9$_.:\- ]`, values must be strings ≤200 chars with no newlines, max 50 entries per event. Invalid entries are silently dropped with a warning logged to `~/agentcat.log`. If the callback throws or returns null, tags are omitted. Receives the same `(request, extra)` arguments as `identify`. * @param options.eventProperties - Callback invoked on every auto-captured tool call to attach flexible JSON metadata (device info, feature flags, nested context). No constraints beyond standard JSON types. If the callback throws or returns null, properties are omitted. Receives the same `(request, extra)` arguments as `identify`. * @param options.apiBaseUrl - Custom API base URL for sending events. Falls back to the `AGENTCAT_API_URL` environment variable if not set (then legacy `MCPCAT_API_URL`), then to the default `https://api.agentcat.com`. * @param options.disableDiagnostics - Disables AgentCat's internal SDK diagnostics (anonymous error/telemetry reporting used to monitor SDK setup failures). Diagnostics are on by default, automatically disabled in test environments (`VITEST`, `JEST_WORKER_ID`, or `NODE_ENV=test`), and can also be disabled with the `DISABLE_DIAGNOSTICS` environment variable. Local `~/agentcat.log` logging is unaffected. * @param options.exporters - Configure telemetry exporters to send events to external systems. Available exporters: * - `otlp`: OpenTelemetry Protocol exporter (see {@link ../modules/exporters/otlp.OTLPExporter}) * - `datadog`: Datadog APM exporter (see {@link ../modules/exporters/datadog.DatadogExporter}) * - `sentry`: Sentry Monitoring exporter (see {@link ../modules/exporters/sentry.SentryExporter}) * - `posthog`: PostHog analytics exporter (see {@link ../modules/exporters/posthog.PostHogExporter}) * * @returns The tracked server instance. * * @remarks * Analytics data and debug information are logged to `~/agentcat.log` since console logs interfere * with STDIO-based MCP servers. * * Do not call `track()` multiple times on the same server instance as this will cause unexpected behavior. * * @example * ```typescript * import * as agentcat from "agentcat"; * * const mcpServer = new Server({ name: "my-mcp-server", version: "1.0.0" }); * * // Track the server with AgentCat * agentcat.track(mcpServer, "proj_abc123xyz"); * * // Register your tools * mcpServer.setRequestHandler(ListToolsRequestSchema, async () => ({ * tools: [{ name: "my_tool", description: "Does something useful" }] * })); * ``` * * @example * ```typescript * // MCP SDK v2 (@modelcontextprotocol/server) — same call, auto-detected * import { McpServer } from "@modelcontextprotocol/server"; * import { z } from "zod"; * import * as agentcat from "agentcat"; * * const server = new McpServer( * { name: "my-mcp-server", version: "1.0.0" }, * { capabilities: { tools: {} } }, * ); * * server.registerTool( * "my_tool", * { description: "Does something useful", inputSchema: z.object({ msg: z.string() }) }, * async (args) => ({ content: [{ type: "text", text: args.msg }] }), * ); * * agentcat.track(server, "proj_abc123xyz"); * ``` * * @example * ```typescript * // MCP 2026-07-28 era (createMcpHandler / serveStdio): call track() inside * // the factory so every per-request instance is tracked. * import { createMcpHandler, McpServer } from "@modelcontextprotocol/server"; * import * as agentcat from "agentcat"; * * const handler = createMcpHandler(() => { * const server = new McpServer({ name: "my-server", version: "1.0.0" }, { capabilities: { tools: {} } }); * // register tools... * return agentcat.track(server, "proj_abc123xyz"); // track every per-request instance * }); * ``` * * @example * ```typescript * // With user identification * agentcat.track(mcpServer, "proj_abc123xyz", { * identify: async (request, extra) => { * const user = await getUserFromToken(request.params.arguments.token); * return { * userId: user.id, * userData: { plan: user.plan, company: user.company } * }; * } * }); * ``` * * @example * ```typescript * // With custom context description * agentcat.track(mcpServer, "proj_abc123xyz", { * enableToolCallContext: true, * customContextDescription: "Explain why you're calling this tool and what business objective it helps achieve" * }); * ``` * * @example * ```typescript * // With sensitive data redaction * agentcat.track(mcpServer, "proj_abc123xyz", { * redactSensitiveInformation: async (text) => { * return text.replace(/api_key_\w+/g, "[REDACTED]"); * } * }); * ``` * * @example * ```typescript * // With event-level redaction * agentcat.track(mcpServer, "proj_abc123xyz", { * redactEvent: (event) => { * // Drop events from tools that handle secrets entirely * if (event.resourceName === "get_credentials") { * return null; * } * // Strip response payloads from a specific tool * if (event.resourceName === "export_report") { * return { ...event, response: undefined }; * } * return event; * } * }); * ``` * * @example * ```typescript * // With event tags and properties. The `extra` shape is SDK-version-specific: * // on v2 it is the SDK's ServerContext ({ sessionId, mcpReq, http }) as shown * // here; on v1 it is the SDK's RequestHandlerExtra. * agentcat.track(mcpServer, "proj_abc123xyz", { * eventTags: async (request, extra) => ({ * request_id: String(extra?.mcpReq?.id ?? ""), * env: process.env.NODE_ENV, * region: "us-east-1", * }), * eventProperties: async (request, extra) => ({ * device: "desktop", * app_version: "2.1.0", * feature_flags: ["dark_mode", "beta_ui"], * }), * }); * ``` * * @example * ```typescript * // Telemetry-only mode (no AgentCat account required) * agentcat.track(mcpServer, null, { * exporters: { * otlp: { * type: "otlp", * endpoint: "http://localhost:4318/v1/traces" * } * } * }); * ``` * * @example * ```typescript * // Dual mode - send to both AgentCat and telemetry exporters * agentcat.track(mcpServer, "proj_abc123xyz", { * exporters: { * datadog: { * type: "datadog", * apiKey: process.env.DD_API_KEY, * site: "datadoghq.com" * } * } * }); * ``` */ declare function track(server: any, projectId: string | null, options?: AgentCatOptions): any; /** * Publishes a custom event to AgentCat with flexible session management. * * @param serverOrSessionId - Either a tracked MCP server instance or a session ID string. * A session ID string is used verbatim as the event's session — it is never derived or hashed. * @param projectId - Your AgentCat project ID (required) * @param eventData - Optional event data to include with the custom event. Set `eventData.sessionId` * to attribute the event to a task; it takes precedence over a session ID string passed as the * first argument. When a tracked server is passed without `eventData.sessionId`, the event is * published without a session (the server assigns one). * * @returns Promise that resolves when the event is queued for publishing * * @remarks * When a tracked server is passed, the `redactEvent` hook configured via `track()` * is applied to the custom event before it is published. Events published with a * bare session ID string bypass redaction, since no tracked configuration exists. * * @example * ```typescript * // With a tracked server, attributed to a task * await agentcat.publishCustomEvent( * server, * "proj_abc123xyz", * { * sessionId: "ses_2cOHEO0LYGADMzRvWTXXVbbgxgm", * resourceName: "custom-action", * parameters: { action: "user-feedback", rating: 5 }, * message: "User provided feedback" * } * ); * ``` * * @example * ```typescript * // With a session ID string * await agentcat.publishCustomEvent( * "ses_2cOHEO0LYGADMzRvWTXXVbbgxgm", * "proj_abc123xyz", * { * isError: true, * error: { message: "Custom error occurred", code: "ERR_001" } * } * ); * ``` * * @example * ```typescript * // With a tracked server and no session ID: published without a session * await agentcat.publishCustomEvent( * server, * "proj_abc123xyz", * { * resourceName: "feature-usage", * } * ); * ``` */ declare function publishCustomEvent(serverOrSessionId: any | string, projectId: string, eventData?: CustomEventData): Promise; type IdentifyFunction = AgentCatOptions["identify"]; export { type AgentCatData, AgentCatIDPrefixes, type AgentCatOptions, type CustomEventData, type Exporter, type ExporterConfig, type IdentifyFunction, type RedactEventFunction, type RedactFunction, type UserIdentity, publishCustomEvent, track };