MCP Telemetry Collection and Data Pseudonymization: How DesktopCommanderMCP Protects User Privacy
DesktopCommanderMCP implements privacy-first telemetry that pseudonymizes every event using a randomly generated UUID, ensuring no personally identifiable information links usage data to individual users while maintaining transparent opt-out controls.
DesktopCommanderMCP is an open-source MCP (Model Context Protocol) server that handles file system operations and command execution. Understanding its approach to MCP telemetry collection and data pseudonymization reveals how the project balances product analytics with strict privacy protections. The implementation uses a proxy-based architecture, opaque identifiers, and explicit user consent mechanisms to ensure data minimization.
Core Telemetry Architecture
The Telemetry Proxy Pattern
Rather than connecting directly to analytics backends, DesktopCommanderMCP routes all events through a lightweight proxy. In [src/utils/capture.ts](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts), the primary endpoint https://telemetry.desktopcommander.app/mp/collect handles ingestion, while a fallback URL ensures redundancy. This proxy strips request-origin metadata before forwarding to BigQuery, preventing the analytics store from receiving raw client IP addresses or direct connection details.
Client Identifier and Pseudonymization
The pseudonymization layer centers on a randomly generated UUID stored as clientId in the user's configuration. Defined in the ServerConfig interface in [src/config-manager.ts](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts) (line 16), this identifier persists across sessions but never correlates to email addresses, usernames, or OS-level identifiers. The UUID lives in the standard config directory (~/.config/desktop-commander/config.json by default), ensuring that every telemetry event remains anonymous.
Opt-Out Controls via telemetryEnabled
User agency is enforced through the telemetryEnabled boolean flag, located in the same ServerConfig interface at line 13 of [src/config-manager.ts](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/config-manager.ts). Defaulting to enabled for first-run experience, this setting is respected by every telemetry call through the isTelemetryDisabledValue helper (lines 43-45), which normalizes string values like "false" or "FALSE" to boolean equivalents.
Graceful Fallback Mechanisms
The system implements silent failure principles to prevent telemetry from impacting core functionality. If the primary proxy fails, the code automatically retries TELEMETRY_PROXY_FALLBACK_URL, and all network calls are wrapped in try/catch blocks. Guard clauses in [src/utils/capture.ts](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/capture.ts) (lines 106-115) ensure that disabled telemetry returns early without throwing errors.
Data Pseudonymization Implementation
The clientId UUID Strategy
Every telemetry payload includes four core fields: event (string name), clientId (UUID), version (application version), and timestamp. The clientId is the sole identification mechanism—an opaque string generated during initial configuration that contains no encoded personal data. This approach ensures that event streams cannot be reverse-engineered to reveal user identities while still allowing aggregate analysis of usage patterns.
Transmission Security
Events transmit over HTTPS to the proxy endpoint, where TLS encryption protects data in transit. The proxy architecture adds a sanitization layer between the DesktopCommanderMCP client and the analytics warehouse, ensuring that backend storage never receives direct client fingerprints or network metadata.
Absence of Personal Data
The telemetry system explicitly excludes personal identifiers. When [track-installation.js](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/track-installation.js) captures installation events, it only records the clientId, operating system type, and timestamp—never capturing home directory paths, environment variables containing usernames, or machine hostnames.
Telemetry Lifecycle in Practice
The capture() Function Implementation
The capture() function in src/utils/capture.ts (lines 92-110) serves as the central emission point. It constructs payloads by merging the event name with configuration values retrieved through configManager.getValue():
// src/utils/capture.ts – simplified flow
export async function capture(eventName: string, payload: any) {
const telemetryEnabled = await configManager.getValue('telemetryEnabled');
if (isTelemetryDisabledValue(telemetryEnabled)) return; // respect opt-out
const clientId = await configManager.getValue('clientId');
const body = {
event: eventName,
clientId,
version: VERSION,
timestamp: Date.now(),
...payload,
};
try {
await fetch(TELEMETRY_PROXY_URL, {
method: 'POST',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' }
});
} catch (e) {
// Fail silently; retry with fallback URL if implemented
}
}
Installation Tracking Example
Real-world usage appears in [track-installation.js](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/track-installation.js), which builds an installation payload and calls capture('install', payload). This demonstrates how the system records adoption metrics without exposing sensitive system information.
Managing Telemetry Preferences
Programmatic Opt-Out
Users can disable telemetry without editing configuration files manually. The configManager.updateConfig() method provides a clean API for toggling the telemetryEnabled flag:
import { configManager } from './src/config-manager.js';
async function disableTelemetry() {
await configManager.updateConfig({ telemetryEnabled: false });
console.log('Telemetry disabled successfully');
}
disableTelemetry();
When set to false, all subsequent capture() calls return at the guard clause, guaranteeing zero network traffic to analytics endpoints.
Checking Current Settings
Verify your current telemetry status and pseudonymized ID using the configuration manager:
import { configManager } from './src/config-manager.js';
async function checkTelemetryStatus() {
const enabled = await configManager.getValue('telemetryEnabled');
const clientId = await configManager.getValue('clientId');
console.log(`Telemetry enabled: ${enabled}`);
console.log(`Pseudonymous client ID: ${clientId}`);
}
checkTelemetryStatus();
Code Examples for Developers
Sending Custom Events
Extend the telemetry system for custom monitoring while maintaining the same privacy protections:
import { capture } from './src/utils/capture.js';
async function reportCustomAction(action: string, details: Record<string, any>) {
await capture('custom_action', { action, ...details });
}
// Usage
await reportCustomAction('batch_rename', { fileCount: 150 });
Reading the Pseudonymized Client ID
Access the anonymous identifier for debugging or correlation purposes:
import { configManager } from './src/config-manager.js';
async function getClientId() {
const id = await configManager.getValue('clientId');
console.log('Your pseudonymous client ID:', id);
// Example output: 550e8400-e29b-41d4-a716-446655440000
}
getClientId();
Summary
- Proxy Architecture: DesktopCommanderMCP routes telemetry through
https://telemetry.desktopcommander.app/mp/collectvia thecapture()function insrc/utils/capture.ts, adding a privacy layer between clients and analytics storage. - Pseudonymization: The
clientIdUUID insrc/config-manager.tsprovides the only identification, containing no personal data and persisting in~/.config/desktop-commander/config.json. - Opt-Out Control: The
telemetryEnabledflag inServerConfigallows immediate cessation of data collection, respected by guard clauses in every telemetry call. - Silent Operation: All telemetry failures are caught and ignored, with fallback URL support ensuring that network issues never block core functionality.
- Transparency: Installation tracking in
track-installation.jsdemonstrates real-world usage limited to system type and timestamp, excluding sensitive path or identity information.
Frequently Asked Questions
What data does DesktopCommanderMCP collect through its telemetry system?
DesktopCommanderMCP collects event data including the action type (e.g., "install"), a pseudonymized clientId UUID, application version, operating system type, and timestamp. As implemented in src/utils/capture.ts, the system explicitly excludes file paths, usernames, environment variables, and other personally identifiable information from every payload.
How does the pseudonymization mechanism protect my identity?
The system generates a random UUID stored as clientId in your configuration file during first run. This identifier, defined in src/config-manager.ts, contains no encoded personal information and never links to your email, username, or hardware identifiers. When combined with the proxy architecture that strips request metadata, this ensures that telemetry events cannot be traced back to individual users.
Can I completely disable telemetry collection?
Yes. Set telemetryEnabled to false using the configuration API, which updates your config.json file. The isTelemetryDisabledValue helper in src/config-manager.ts ensures that once disabled, the capture() function returns immediately without emitting network requests, guaranteeing zero data transmission to the proxy endpoints.
Where is my configuration and client ID stored?
The clientId and telemetryEnabled settings persist in a JSON configuration file located at ~/.config/desktop-commander/config.json by default, as defined in src/config.ts. This standard directory location keeps sensitive configuration separate from application code while remaining accessible for user inspection or modification.
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 →