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, orfetch_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), andcli_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 identification –
entry_idandentry_type(e.g.,openai/chat,docorskill) - User rating –
"up"or"down"indicating satisfaction - Documentation context – Optional
doc_lang,doc_version,target_file, andlabels - User commentary – Optional free-text
commentand structuredlabels - Agent metadata – Auto-detected or provided
agentobject containingname,version, andmodel - Client information –
cli_version,sourceregistry, andX-Client-IDheader (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=0orfalsedisables anonymous analyticsCHUB_FEEDBACK=0orfalsedisables rating submissions
Configuration file settings (in config.yaml) provide persistent controls:
telemetry: falsefeedback: 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:
cli/src/lib/telemetry.js– Core opt-out logic, feedback API client, and telemetry URL handlingcli/src/lib/analytics.js– PostHog wrapper implementation andtrackEventfunctioncli/src/lib/config.js– Default configuration values and settings merge logiccli/src/lib/identity.js– Client ID generation and agent detection utilitiescli/src/commands/feedback.js– CLI interface that invokessendFeedbackcli/src/commands/search.js– Example consumer oftrackEventfor search analytics
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
telemetryis enabled (default: true) - Explicit feedback sends ratings (
up/down), optional comments, documentation context, and agent metadata to the Context Hub API only whenfeedbackis 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →