How the UsageTracker in Desktop Commander MCP Collects and Reports Telemetry Data While Protecting Sensitive Information
Desktop Commander MCP's UsageTracker class aggregates anonymous tool usage statistics in memory and persists them non-blocking, while the capture utility sanitizes all outbound telemetry by stripping file paths, stack traces, and container identifiers before transmission.
The Desktop Commander MCP repository implements a privacy-first telemetry pipeline that captures high-level usage patterns without compromising user security. Understanding how the UsageTracker collects and reports telemetry data while ensuring no sensitive information is captured requires examining the interaction between the aggregation layer in src/utils/usageTracker.ts, the configuration management system, and the sanitization protocols in src/utils/capture.ts. This implementation guarantees that file paths, system identifiers, and error details never leave the local environment.
Anonymous Usage Aggregation Architecture
The telemetry system separates data collection from transmission, ensuring sensitive information never enters the aggregation layer.
In-Memory Statistics with UsageTracker
The UsageTracker class in src/utils/usageTracker.ts maintains a ToolUsageStats object that counts tool invocations by category. When developers call trackSuccess() or trackFailure(), the utility updates per-tool counters and session timestamps in memory, then queues the data for background persistence via configManager.setValueNonBlocking (lines 58-84). This non-blocking approach ensures that recording usage never delays the actual tool execution.
The class also implements feedback heuristics in getStats() (lines 71-78), surfacing prompts only when users meet specific thresholds—typically after three days of activity and at least ten tool calls—preventing intrusive onboarding interruptions.
Persistent Client Identification
Configuration management in src/config-manager.ts stores two critical telemetry values: a randomly generated UUID clientId (lines 26-34) that remains stable across sessions, and the boolean telemetryEnabled flag (lines 13-18). The system initializes telemetryEnabled to true by default, making telemetry opt-out rather than opt-in, though users retain full control through environment variables.
Privacy-First Transmission Pipeline
Before any data reaches the network, the capture utility in src/utils/capture.ts applies a multi-stage sanitization process.
Telemetry Enablement Checks
The capture utility returns immediately without network activity if DESKTOP_COMMANDER_DISABLE_TELEMETRY is set in the environment, or if telemetryEnabled is false in the persisted configuration. This dual-gate mechanism allows both temporary CI/CD disabling and permanent user preference enforcement.
Context Enrichment Without Exposure
When enabled, capture attaches metadata to every event including the client type (desktop-commander, remote device, etc.) and container context from src/utils/system-info.ts. The system detects Docker and Smithery environments (lines 19-33) to segment usage by deployment type, but deliberately excludes host-level identifiers that could fingerprint specific machines.
Deep Data Sanitization
The sanitization engine removes three categories of sensitive data before transmission:
- Error scrubbing: The
sanitizeErrorfunction (lines 57-70) strips stack traces and file paths from error objects, preventing accidental disclosure of local directory structures. - Path key removal: Any property key suggesting a file system location—such as
path,filePath, ordirectory—is removed from the payload entirely, with exceptions only for innocuous keys likefileExtension(lines 61-69). - Container anonymization: Long hex strings and UUIDs within container names or image references are collapsed to the placeholder
IDand truncated to prevent leakage of deployment specifics (lines 91-100).
Fire-and-Forget Delivery
Sanitized payloads are posted to https://telemetry.desktopcommander.app/mp/collect using a short-lived HTTPS request with a strict three-second timeout (lines 99-107). The system silently ignores network failures, ensuring that telemetry transmission never blocks the user-facing workflow or generates error noise in the application logs.
Implementation Examples
The following patterns demonstrate how to interact with the telemetry system while respecting its privacy constraints:
// Record a successful tool call (aggregates locally, persists in background)
import { usageTracker } from './utils/usageTracker.js';
await usageTracker.trackSuccess('read_file');
// Returns updated stats; actual storage is non-blocking via configManager
// Manually emit sanitized telemetry (internal use only)
import { capture } from './utils/capture.js';
await capture('tool_used', {
tool: 'execute_command',
args: ['ls', '-la'],
// Automatically removes path-like keys and attaches client/container metadata
});
// Disable telemetry for CI environments
process.env.DESKTOP_COMMANDER_DISABLE_TELEMETRY = 'true';
Summary
- UsageTracker (
src/utils/usageTracker.ts) aggregates tool statistics in memory and persists them via non-blocking configuration updates, triggering feedback prompts only after usage thresholds are met. - Configuration management (
src/config-manager.ts) maintains a stable anonymous client ID and telemetry preferences, defaulting to enabled but respecting explicit opt-out signals. - Capture utility (
src/utils/capture.ts) enforces mandatory data sanitization by removing file paths, stack traces, and container identifiers before any network transmission. - Delivery mechanism uses fire-and-forget HTTPS requests with short timeouts to ensure telemetry never impacts application performance or reliability.
- Opt-out controls exist at both the environment variable level (
DESKTOP_COMMANDER_DISABLE_TELEMETRY) and persistent configuration level (telemetryEnabled).
Frequently Asked Questions
How can I completely disable telemetry in Desktop Commander MCP?
Set the environment variable DESKTOP_COMMANDER_DISABLE_TELEMETRY to any truthy value before starting the application, or set telemetryEnabled to false in the configuration store via configManager. Either method causes the capture utility to return immediately without network activity, and UsageTracker will continue local aggregation without attempting remote transmission.
What specific sensitive data does the capture utility remove before transmission?
The sanitizer strips three categories of sensitive information: stack traces and file paths from error objects via sanitizeError, any object property with keys suggesting file system locations (path, filePath, directory), and identifiable container metadata by replacing hex strings and UUIDs with the placeholder ID. File extensions are preserved intentionally as they contain no personal information while providing useful usage statistics.
How does the UsageTracker determine when to surface feedback prompts?
The getStats() method checks aggregated statistics against thresholds defined in src/utils/usageTracker.ts (lines 71-78), typically requiring at least three days of recorded activity and a minimum of ten tool calls. This heuristic ensures that feedback requests only appear for active users with substantial experience using the toolset.
Where is telemetry data stored locally before being transmitted?
Statistics are stored in the shared configuration file managed by config-manager.ts, accessed via configManager.setValueNonBlocking. The data includes per-tool counters, session timestamps, and total call counts—never including arguments, file contents, or execution results. The clientId UUID is also persisted here to maintain consistent anonymous identification across application restarts.
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 →