@extenshi/mcp
Version:
Extenshi MCP server — bring the extension catalog (search, security, market research) and pre-publish scanning into your AI tools
85 lines • 4.36 kB
TypeScript
/**
* Anonymous, opt-out usage telemetry — VENDORED, kept byte-identical between
* @extenshi/cli and @extenshi/mcp (same pattern as validate-artifact.ts). Edit
* one, copy to the other.
*
* Why it exists: we want to know which commands/tools are used most, which fail,
* and what errors recur — without shipping a heavyweight client or leaking PII.
*
* What it sends (and ONLY this):
* - command/tool name, surface ('cli' | 'mcp'), package + Node version,
* coarse os/arch, a CI bool
* - the NAMES of CLI flags used (never their values — see flagsFromArgv)
* - a coarse error_kind classification + durations
* - a path-redacted exception signature (message + stack, $HOME stripped)
*
* What it NEVER sends: file paths, artifact names/contents, API keys, manifest
* data, or raw user input.
*
* Identity is an anonymous per-install UUID in ~/.extenshi/config.json
* (`anonId`) — it identifies an install, not a person, and is never linked to
* the API key client-side.
*
* On by default: the shared-project ingestion key is embedded (see
* EMBEDDED_KEY), so telemetry is active unless the user opts out. Disabled
* (no-op, never blocks the command) when ANY holds:
* - DO_NOT_TRACK is truthy (industry standard, https://consoledonottrack.com)
* - EXTENSHI_TELEMETRY in {0,false,off,no}
* - config file has "telemetry": false
* - the key is cleared (EMBEDDED_KEY emptied AND no EXTENSHI_POSTHOG_KEY)
*
* Everything here is fail-soft: any throw inside telemetry is swallowed so a
* PostHog/network/disk problem can never break or slow the actual command.
*/
import { PostHog } from 'posthog-node';
/** Record the surface + version once at process startup. */
export declare function initTelemetry(opts: {
surface: string;
version: string;
}): void;
export declare function telemetryEnabled(): boolean;
/**
* The shared posthog-node client, or null when telemetry is disabled. Exposed so
* the MCP package's PostHog MCP Analytics instrumentation (mcp-analytics.ts)
* rides this same client: one opt-out, one flush path (flushTelemetry).
*/
export declare function telemetryClient(): PostHog | null;
/** Strip absolute home paths from any string before it leaves the machine. */
export declare function redactText(s: string): string;
/**
* Coarse error bucket. Driven by a numeric status when the error carries one
* (ScanError `status`, tRPC `data.httpStatus`), else by message patterns (both
* surfaces also throw plain Errors). Order matters — status first, then
* transport, then semantic buckets.
*
* Follows the `cause` chain, because both surfaces re-throw a failure wrapped in
* an error of their own so it renders for the caller — the MCP tool layer wraps
* in fastmcp's `UserError` (readError() in its tools.ts) — and the wrapper's own
* message can carry no status. The origin hangs off `cause`, so an
* unclassifiable wrapper defers to what it wraps; without this, a BFF 500 behind
* a wrapper reads as `unexpected`.
*/
export declare function classifyError(err: unknown): string;
/**
* The NAMES of long flags the user passed, with values stripped. `--out=/x`
* becomes `--out`; the separate-token value of `--output /x` is never a `--`
* token, so it is never collected. No flag VALUE can leak through here.
*/
export declare function flagsFromArgv(argv?: string[]): string[];
/**
* `distinctId` overrides the per-install anonymous id. The CLI never passes it —
* one install IS one identity there. The hosted MCP connector must: it is one
* process serving many accounts, so the install id would collapse every user of
* the service into a single person and re-mint on each redeploy. It passes the
* authenticated account id instead (never an email — that stays in our own
* database, see tools/extenshi-mcp-server/src/legal.ts).
*/
export declare function captureEvent(event: string, properties?: Record<string, unknown>, distinctId?: string): void;
export declare function captureError(err: unknown, context?: Record<string, unknown>): void;
/**
* Flush buffered events and close the client. Hard-capped so a slow/hung
* PostHog endpoint can never delay the command's exit. Safe to call when
* telemetry is disabled (no-op) or more than once.
*/
export declare function flushTelemetry(): Promise<void>;
//# sourceMappingURL=telemetry.d.ts.map