What Kind of Telemetry Data Does Context Hub Collect? A Complete Technical Breakdown

Context Hub collects two distinct categories of telemetry data: anonymous usage analytics via PostHog (including event names, platform metadata, and CLI version) and explicit user feedback containing ratings, optional comments, and contextual information about documentation or skills, with both streams respecting user opt-out settings.

The Context Hub CLI tool, maintained in the andrewyng/context-hub repository, implements a transparent telemetry system designed to balance product improvement with user privacy. Understanding what kind of telemetry data Context Hub collects requires examining the source code in cli/src/lib/analytics.js and cli/src/lib/telemetry.js, which handle the two distinct data streams.

Anonymous Usage Analytics via PostHog

What Gets Tracked

The analytics system captures event-based telemetry through the trackEvent function in cli/src/lib/analytics.js. Each event includes:

  • Event name – Caller-defined identifiers such as command_run, search, doc_fetched, skill_fetched, or fetch_error
  • Caller-provided payload – Context-specific data supplied by the CLI command (e.g., search parameters, document IDs, error types)
  • Global properties – Automatically appended metadata including platform (operating system), node_version (Node.js runtime version), and cli_version (Context Hub CLI version)

The system uses a stable client ID generated by getOrCreateClientId() in cli/src/lib/identity.js for deduplication purposes. This identifier is a machine-specific UUID, not a personal identifier or user account.

Implementation Details

The trackEvent function lazily initializes a PostHog client and fires fire-and-forget events:

// cli/src/lib/analytics.js (simplified)
export async function trackEvent(event, properties = {}) {
  const client = await getClient();      // Returns null when disabled
  if (!client) return;
  const { getOrCreateClientId } = await import('./identity.js');
  const distinctId = await getOrCreateClientId();

  client.capture({
    distinctId,
    event,
    properties: {
      ...properties,
      platform: process.platform,
      node_version: process.version,
      cli_version: _cliVersion || undefined,
    },
  });
  await client.flush();                  // Immediate send due to short CLI lifecycle
}

Because the payload is entirely controlled by the calling code, no user-generated content is transmitted unless explicitly included by the CLI command implementation.

Explicit Feedback Collection

Feedback Payload Structure

When users run the chub feedback command, the sendFeedback function in cli/src/lib/telemetry.js transmits structured data to the Context Hub API. The payload includes:

  • Entry identificationentry_id and entry_type (e.g., openai/chat, doc or skill)
  • User rating"up" or "down" indicating satisfaction
  • Documentation context – Optional doc_lang, doc_version, target_file, and labels
  • User commentary – Optional free-text comment and structured labels
  • Agent metadata – Auto-detected or provided agent object containing name, version, and model
  • Client informationcli_version, source registry, and X-Client-ID header (the stable UUID)

The sendFeedback Implementation

The feedback system requires explicit opt-in and performs an enabled-check before transmission:

// cli/src/lib/telemetry.js (simplified)
export async function sendFeedback(entryId, entryType, rating, opts = {}) {
  if (!isFeedbackEnabled()) return { status: 'skipped', reason: 'feedback_disabled' };
  
  const { getOrCreateClientId, detectAgent, detectAgentVersion } = await import('./identity.js');
  const clientId = await getOrCreateClientId();
  
  const res = await fetch(`${getTelemetryUrl()}/feedback`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Client-ID': clientId,
    },
    body: JSON.stringify({
      entry_id: entryId,
      entry_type: entryType,
      rating,
      doc_lang: opts.docLang || undefined,
      doc_version: opts.docVersion || undefined,
      target_file: opts.targetFile || undefined,
      labels: opts.labels || undefined,
      comment: opts.comment || undefined,
      agent: {
        name: opts.agent || detectAgent(),
        version: detectAgentVersion(),
        model: opts.model || undefined,
      },
      cli_version: opts.cliVersion || undefined,
      source: opts.source || undefined,
    }),
  });
  // ... response handling
}

Opt-Out Mechanisms and Configuration

Environment Variables vs Config File

Both telemetry streams respect dual opt-out mechanisms. The isTelemetryEnabled() and isFeedbackEnabled() functions in cli/src/lib/telemetry.js check environment variables before falling back to configuration file settings:

// cli/src/lib/telemetry.js
export function isTelemetryEnabled() {
  if (process.env.CHUB_TELEMETRY === '0' || process.env.CHUB_TELEMETRY === 'false') return false;
  const config = loadConfig();
  return config.telemetry !== false;
}

export function isFeedbackEnabled() {
  if (process.env.CHUB_FEEDBACK === '0' || process.env.CHUB_FEEDBACK === 'false') return false;
  const config = loadConfig();
  return config.feedback !== false;
}

Environment variables take precedence:

  • CHUB_TELEMETRY=0 or false disables anonymous analytics
  • CHUB_FEEDBACK=0 or false disables rating submissions

Configuration file settings (in config.yaml) provide persistent controls:

  • telemetry: false
  • feedback: false

Default Settings

According to cli/src/lib/config.js, the default configuration enables anonymous analytics while keeping feedback disabled unless explicitly opted-in:

// cli/src/lib/config.js
export const DEFAULTS = {
  telemetry: true,
  telemetry_url: DEFAULT_TELEMETRY_URL,
  feedback: false,
  // ... other defaults
};

Key Source Files and Architecture

Understanding what telemetry data Context Hub collects requires familiarity with these specific modules:

Code Examples: Practical Usage

Checking Telemetry Status

Determine programmatically whether data collection is active:

import { isTelemetryEnabled, isFeedbackEnabled } from './lib/telemetry.js';

if (isTelemetryEnabled()) {
  console.log('Anonymous usage analytics are enabled');
}

if (isFeedbackEnabled()) {
  console.log('Explicit feedback collection is enabled');
}

Emitting Custom Analytics Events

CLI command implementations can emit custom telemetry using the analytics module:

import { trackEvent } from './lib/analytics.js';

await trackEvent('search_executed', {
  query: userQuery,
  results_count: results.length,
  duration_ms: elapsedTime,
});

Only the global properties (platform, node_version, cli_version) are appended automatically; all other payload fields are caller-defined.

Submitting User Feedback Programmatically

Integrate feedback collection into custom workflows:

import { sendFeedback } from './lib/telemetry.js';

const result = await sendFeedback('openai/chat', 'doc', 'up', {
  comment: 'Excellent code examples provided',
  labels: ['accuracy', 'clarity'],
  docVersion: '1.2.0',
  cliVersion: '2.5.0',
});

if (result.status === 'skipped') {
  console.log('Feedback disabled by user configuration');
}

Summary

  • Anonymous analytics transmit event names, platform metadata (OS, Node.js version, CLI version), and caller-provided properties to PostHog only when telemetry is enabled (default: true)
  • Explicit feedback sends ratings (up/down), optional comments, documentation context, and agent metadata to the Context Hub API only when feedback is enabled (default: false)
  • Opt-out controls function via environment variables (CHUB_TELEMETRY, CHUB_FEEDBACK) or configuration file settings, with environment variables taking precedence
  • No PII collection occurs; identifiers are stable machine UUIDs, and user content is only transmitted when explicitly provided for feedback purposes

Frequently Asked Questions

Is the telemetry data anonymous?

Yes, according to the andrewyng/context-hub source code, telemetry data is anonymous. The system uses a stable machine-specific UUID generated by getOrCreateClientId() for deduplication, but this identifier is not linked to personal information, user accounts, or repository content. Anonymous usage analytics only capture event types, platform metadata, and CLI versions, while explicit feedback requires user-initiated action.

How do I completely disable telemetry in Context Hub?

Set the environment variable CHUB_TELEMETRY=0 or CHUB_TELEMETRY=false to disable anonymous analytics, and CHUB_FEEDBACK=0 or CHUB_FEEDBACK=false to disable feedback collection. Alternatively, add telemetry: false and feedback: false to your config.yaml file. Environment variables take precedence over configuration file settings, ensuring you can disable collection system-wide regardless of project-specific configurations.

What is the difference between telemetry and feedback in Context Hub?

Telemetry refers to automatic, anonymous usage analytics sent to PostHog, including events like command_run, search, and doc_fetched along with system metadata (platform, Node.js version). Feedback refers to explicit user-initiated ratings (up/down) and comments sent to the Context Hub API when running chub feedback. Telemetry is enabled by default but can be opted out, while feedback is disabled by default and requires explicit opt-in.

Does Context Hub collect my search queries or code content?

The anonymous analytics system in cli/src/lib/analytics.js does not automatically collect search queries or source code content. The trackEvent function only captures event names and explicitly provided properties from the calling command. However, specific CLI commands may choose to include search terms in the properties payload (e.g., the search command may log query parameters). Explicit feedback only transmits content you voluntarily provide in the comment field or contextual metadata about documentation entries you choose to rate.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →