Skip to main content
Glama

DollhouseMCP

by DollhouseMCP
TELEMETRY_BEST_PRACTICES_AND_RECOMMENDATIONS.md49.2 kB
# Telemetry Best Practices and Recommendations for DollhouseMCP **Date**: October 15, 2025 **Version**: 1.0 **Status**: Investigation and Recommendations **Related Issues**: #739 (OAuth Telemetry), #441 (Update Success Rate Telemetry) --- ## Executive Summary This document provides comprehensive guidance for implementing privacy-respecting, opt-in installation telemetry for DollhouseMCP. The goal is to track installation metrics, platform distribution, AI tool usage, and crash information to improve user experience without compromising privacy or trust. ### Key Recommendations 1. **Opt-in by default with explicit consent** - Never collect data without user knowledge 2. **Minimal data collection** - Only collect what's necessary for improving the product 3. **Anonymous by design** - No personally identifiable information (PII) 4. **Transparent disclosure** - Clear documentation of what is collected and why 5. **User control** - Easy opt-out, data viewing, and deletion 6. **AGPL-compliant** - Ensure telemetry respects dual-license requirements --- ## Table of Contents 1. [What to Collect](#what-to-collect) 2. [What NOT to Collect](#what-not-to-collect) 3. [Privacy-First Design Principles](#privacy-first-design-principles) 4. [Technical Implementation](#technical-implementation) 5. [AGPL and Dual-License Considerations](#agpl-and-dual-license-considerations) 6. [User Communication](#user-communication) 7. [Industry Examples](#industry-examples) 8. [Implementation Roadmap](#implementation-roadmap) 9. [Legal and Compliance](#legal-and-compliance) 10. [FAQ](#faq) --- ## What to Collect ### Installation Metrics (Core Priority) #### Basic Installation Data ```typescript interface InstallationMetrics { // Unique installation ID (generated locally, never linked to user) installId: string; // UUID v4, generated on first install // Installation timestamp installedAt: string; // ISO 8601 format // Package version version: string; // e.g., "1.9.16" // Installation method installMethod: 'npm' | 'npx' | 'git-clone' | 'docker' | 'unknown'; // First-time install vs upgrade installType: 'new' | 'upgrade' | 'reinstall'; // Previous version (if upgrade) previousVersion?: string; } ``` #### Platform Information ```typescript interface PlatformMetrics { // Operating system (generic) os: 'windows' | 'macos' | 'linux' | 'unknown'; // OS version (major version only, no specific builds) osVersion: string; // e.g., "Windows 11", "macOS 14", "Ubuntu 22" // Node.js version (major.minor only) nodeVersion: string; // e.g., "20.10" // Architecture arch: 'x64' | 'arm64' | 'x86' | 'unknown'; // MCP client being used mcpClient: 'claude-desktop' | 'claude-code' | 'gemini' | 'other' | 'unknown'; // MCP client version (if detectable, major.minor only) mcpClientVersion?: string; } ``` #### Usage Context (Optional, User-Controlled) ```typescript interface UsageContext { // Installation environment environment: 'development' | 'production' | 'ci' | 'unknown'; // Is this a CI/CD installation? isCi: boolean; // Package manager used packageManager: 'npm' | 'yarn' | 'pnpm' | 'unknown'; } ``` ### Update and Upgrade Metrics ```typescript interface UpdateMetrics { // Update attempt updateAttemptId: string; // UUID for this specific update installId: string; // Link to installation // Version transition fromVersion: string; toVersion: string; // Update result success: boolean; // Error category (if failed) errorCategory?: 'network' | 'permissions' | 'dependencies' | 'corruption' | 'unknown'; // Update duration (milliseconds) durationMs: number; // Timestamp timestamp: string; // ISO 8601 } ``` ### Crash and Error Reporting ```typescript interface CrashReport { // Crash ID crashId: string; // UUID installId: string; // Link to installation // Crash timestamp timestamp: string; // ISO 8601 // Error category (sanitized, no stack traces with PII) errorType: 'startup' | 'runtime' | 'shutdown' | 'unknown'; // Error category details errorCategory: string; // e.g., "MODULE_NOT_FOUND", "PERMISSION_DENIED" // Sanitized error message (no paths, no usernames) errorMessage: string; // e.g., "Failed to load configuration" // Component that crashed component: string; // e.g., "PortfolioManager", "MCPServer", "GitHubAuth" // Was recovery possible? recovered: boolean; // Platform context (same as installation) platform: PlatformMetrics; } ``` ### Aggregated Usage Statistics (Weekly Summary) ```typescript interface WeeklySummary { // Installation ID installId: string; // Week identifier weekStart: string; // ISO 8601, Monday of the week // Usage frequency (counts, not detailed logs) activeDays: number; // How many days was it used this week? sessionCount: number; // How many distinct sessions? // Feature usage (aggregate counts) features: { personasUsed: number; skillsUsed: number; templatesUsed: number; agentsUsed: number; memoriesUsed: number; portfolioSyncs: number; collectionBrowses: number; }; // Performance indicators avgStartupTime: number; // milliseconds avgResponseTime: number; // milliseconds // Health indicators crashCount: number; errorCount: number; } ``` --- ## What NOT to Collect ### Absolutely NO Collection of: 1. **Personal Identifiable Information (PII)** - Usernames - Email addresses - GitHub usernames or OAuth tokens - Real names - IP addresses (even anonymized) - Geographic location (beyond country-level aggregation) 2. **User Content** - Persona content or descriptions - Skill definitions - Template content - Memory content - File paths containing usernames - Any user-generated content 3. **Detailed System Information** - Full OS version strings (e.g., "Windows 11 Pro Build 22621.2428") - Computer name or hostname - CPU model or serial numbers - MAC addresses - Disk serial numbers - Network adapter information 4. **Behavioral Tracking** - Specific commands executed - Detailed interaction logs - Screen recordings or screenshots - Keystroke logging - Mouse movement tracking 5. **Third-Party Integrations** - GitHub API keys or tokens - OAuth credentials - Other service credentials - Private repository information ### Privacy-First Rules ```typescript // GOOD: Generic, anonymous { os: "macos", nodeVersion: "20.10", installMethod: "npm" } // BAD: Contains PII { os: "macOS 14.1.2 on John's MacBook Pro", nodeVersion: "20.10.0", installPath: "/Users/john.doe/mcp-servers/", githubUser: "johndoe123" } ``` --- ## Privacy-First Design Principles ### 1. Opt-In by Default **Never collect telemetry without explicit user consent.** ```typescript // First-run experience interface TelemetryConsent { // Show clear, non-intrusive prompt on first run promptShown: boolean; consentGiven: boolean; consentTimestamp: string; // What they consented to (version of privacy policy) policyVersion: string; // e.g., "1.0" } ``` **Implementation:** ```typescript // On first run or upgrade async function promptForTelemetryConsent(): Promise<boolean> { console.log(` ╔══════════════════════════════════════════════════════════════╗ ║ DollhouseMCP Telemetry ║ ╠══════════════════════════════════════════════════════════════╣ ║ ║ ║ Help us improve DollhouseMCP by sharing anonymous usage ║ ║ data. We collect: ║ ║ ║ ║ ✓ Installation platform (OS, Node version) ║ ║ ✓ Installation success/failure ║ ║ ✓ Crash reports (sanitized, no personal info) ║ ║ ✓ Weekly usage summaries (feature counts only) ║ ║ ║ ║ We DO NOT collect: ║ ║ ✗ Personal information (names, emails, usernames) ║ ║ ✗ Your content (personas, skills, templates) ║ ║ ✗ Detailed usage logs or commands ║ ║ ✗ IP addresses or location data ║ ║ ║ ║ Full details: https://dollhousemcp.com/privacy/telemetry ║ ║ ║ ║ Enable anonymous telemetry? [Y/n] ║ ║ (You can change this anytime with: ║ ║ dollhousemcp telemetry enable/disable) ║ ║ ║ ╚══════════════════════════════════════════════════════════════╝ `); const response = await prompt('Enable telemetry? [Y/n]: '); return response.toLowerCase() !== 'n'; } ``` ### 2. Data Minimization **Only collect what's necessary to improve the product.** ```typescript // Principle: Can we answer the question without this data? // Question: "How many macOS users are experiencing startup crashes?" // Needed: os="macos", errorType="startup", errorCategory="MODULE_NOT_FOUND" // NOT needed: specific module path, user home directory, exact timestamp interface MinimalCrashReport { os: 'macos'; // Generic OS type errorCategory: 'MODULE_NOT_FOUND'; // Error category component: 'PortfolioManager'; // Component // NO: Full error message with paths // NO: Stack trace with file paths // NO: Environment variables } ``` ### 3. Anonymous by Design **No way to link telemetry data back to individual users.** ```typescript // Installation ID generation function generateInstallId(): string { // UUID v4 - cryptographically random // Generated locally, never linked to user identity // Can't be reversed to find user return crypto.randomUUID(); } // Example: Two installations by same user = two different IDs // Installation 1: 550e8400-e29b-41d4-a716-446655440000 // Installation 2: f47ac10b-58cc-4372-a567-0e02b2c3d479 // No way to know these are the same person ``` ### 4. Transparent Collection **Users know exactly what is collected and when.** ```typescript // Local telemetry log (user can view anytime) interface TelemetryLog { timestamp: string; eventType: string; data: object; sentToServer: boolean; } // Command: dollhousemcp telemetry show function showTelemetryLog(): void { const log = loadLocalTelemetryLog(); console.log('Last 30 days of telemetry events:'); console.log(JSON.stringify(log, null, 2)); } ``` ### 5. User Control **Users can opt-out, view data, and delete data at any time.** ```typescript // Telemetry management commands interface TelemetryCommands { // Enable/disable enable(): Promise<void>; disable(): Promise<void>; // View collected data (locally) show(): Promise<TelemetryLog[]>; // Delete local data deleteLocal(): Promise<void>; // Request server-side deletion deleteRemote(): Promise<void>; // Check status status(): Promise<TelemetryStatus>; } // Implementation dollhousemcp telemetry enable dollhousemcp telemetry disable dollhousemcp telemetry show dollhousemcp telemetry delete dollhousemcp telemetry status ``` --- ## Technical Implementation ### 1. Architecture ``` ┌─────────────────┐ │ User System │ │ (DollhouseMCP)│ └────────┬────────┘ │ │ 1. Event occurs (install, crash, etc.) │ ▼ ┌─────────────────┐ │ Telemetry Client│ │ (Local Buffer) │ ├─────────────────┤ │ - Validates │ │ - Sanitizes │ │ - Anonymizes │ │ - Batches │ └────────┬────────┘ │ │ 2. Batched, sanitized data │ (if user opted in) │ ▼ ┌─────────────────┐ │ Telemetry Server│ │ (Anonymous) │ ├─────────────────┤ │ - Aggregates │ │ - Analyzes │ │ - Stores │ └────────┬────────┘ │ │ 3. Aggregated insights │ ▼ ┌─────────────────┐ │ Dashboard │ │ (Developers) │ └─────────────────┘ ``` ### 2. Local Telemetry Client ```typescript // src/telemetry/TelemetryClient.ts export interface TelemetryConfig { enabled: boolean; endpoint: string; batchSize: number; // Send in batches to reduce network calls flushInterval: number; // Send every N seconds retryAttempts: number; timeout: number; } export class TelemetryClient { private config: TelemetryConfig; private buffer: TelemetryEvent[] = []; private installId: string; constructor(config: TelemetryConfig) { this.config = config; this.installId = this.loadOrGenerateInstallId(); } /** * Load existing install ID or generate new one */ private loadOrGenerateInstallId(): string { const configPath = path.join(os.homedir(), '.dollhouse', 'telemetry.json'); try { const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); return config.installId; } catch { const newId = crypto.randomUUID(); fs.mkdirSync(path.dirname(configPath), { recursive: true }); fs.writeFileSync(configPath, JSON.stringify({ installId: newId, createdAt: new Date().toISOString() })); return newId; } } /** * Record an event (sanitized before storage) */ public async trackEvent(event: TelemetryEvent): Promise<void> { if (!this.config.enabled) { return; // Telemetry disabled, do nothing } // Sanitize event before adding to buffer const sanitized = this.sanitizeEvent(event); // Add to local buffer this.buffer.push(sanitized); // Log locally for user transparency this.logEventLocally(sanitized); // Flush if batch size reached if (this.buffer.length >= this.config.batchSize) { await this.flush(); } } /** * Sanitize event to remove PII */ private sanitizeEvent(event: TelemetryEvent): TelemetryEvent { const sanitized = { ...event }; // Remove any paths with potential usernames if (sanitized.errorMessage) { sanitized.errorMessage = this.sanitizePath(sanitized.errorMessage); } // Validate no PII in fields this.validateNoPII(sanitized); return sanitized; } /** * Remove usernames from file paths */ private sanitizePath(message: string): string { // Replace /Users/username with /Users/<user> message = message.replace(/\/Users\/[^\/]+/g, '/Users/<user>'); // Replace C:\Users\username with C:\Users\<user> message = message.replace(/C:\\Users\\[^\\]+/g, 'C:\\Users\\<user>'); // Replace /home/username with /home/<user> message = message.replace(/\/home\/[^\/]+/g, '/home/<user>'); return message; } /** * Validate no PII in event */ private validateNoPII(event: TelemetryEvent): void { const str = JSON.stringify(event); // Check for email patterns if (/@.+\..+/.test(str)) { throw new Error('Telemetry event contains email address'); } // Check for potential usernames in paths if (/\/Users\/(?!<user>)[a-z]/.test(str) || /C:\\Users\\(?!<user>)[a-z]/i.test(str)) { throw new Error('Telemetry event contains unsanitized path'); } } /** * Log event locally for user transparency */ private logEventLocally(event: TelemetryEvent): void { const logPath = path.join(os.homedir(), '.dollhouse', 'telemetry.log'); const logEntry = { timestamp: new Date().toISOString(), event, sentToServer: false }; fs.appendFileSync(logPath, JSON.stringify(logEntry) + '\n'); } /** * Send buffered events to server */ private async flush(): Promise<void> { if (this.buffer.length === 0) { return; } const batch = [...this.buffer]; this.buffer = []; try { await this.sendBatch(batch); this.updateLocalLogAsSent(batch); } catch (error) { // Failed to send, add back to buffer for retry this.buffer.unshift(...batch); console.error('Failed to send telemetry (will retry):', error.message); } } /** * Send batch to telemetry server */ private async sendBatch(events: TelemetryEvent[]): Promise<void> { const response = await fetch(this.config.endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Telemetry-Version': '1.0' }, body: JSON.stringify({ installId: this.installId, events }), signal: AbortSignal.timeout(this.config.timeout) }); if (!response.ok) { throw new Error(`Telemetry server error: ${response.status}`); } } /** * Update local log to mark events as sent */ private updateLocalLogAsSent(events: TelemetryEvent[]): void { // Update local log to show these were sent successfully // (Implementation details omitted for brevity) } } ``` ### 3. Event Types ```typescript // src/telemetry/types.ts export type TelemetryEventType = | 'installation' | 'update' | 'crash' | 'error' | 'weekly_summary'; export interface BaseTelemetryEvent { eventType: TelemetryEventType; timestamp: string; // ISO 8601 installId: string; version: string; platform: PlatformMetrics; } export interface InstallationEvent extends BaseTelemetryEvent { eventType: 'installation'; installMethod: 'npm' | 'npx' | 'git-clone' | 'docker'; installType: 'new' | 'upgrade' | 'reinstall'; previousVersion?: string; } export interface UpdateEvent extends BaseTelemetryEvent { eventType: 'update'; fromVersion: string; toVersion: string; success: boolean; errorCategory?: string; durationMs: number; } export interface CrashEvent extends BaseTelemetryEvent { eventType: 'crash'; errorType: 'startup' | 'runtime' | 'shutdown'; errorCategory: string; component: string; recovered: boolean; // errorMessage is sanitized (no paths, no usernames) errorMessage: string; } export interface WeeklySummaryEvent extends BaseTelemetryEvent { eventType: 'weekly_summary'; weekStart: string; activeDays: number; sessionCount: number; features: { personasUsed: number; skillsUsed: number; templatesUsed: number; agentsUsed: number; memoriesUsed: number; }; performance: { avgStartupTime: number; avgResponseTime: number; }; health: { crashCount: number; errorCount: number; }; } ``` ### 4. Usage in Code ```typescript // Example: Track installation import { TelemetryClient } from './telemetry/TelemetryClient'; async function onInstallComplete(): Promise<void> { const telemetry = TelemetryClient.getInstance(); await telemetry.trackEvent({ eventType: 'installation', timestamp: new Date().toISOString(), installId: telemetry.getInstallId(), version: packageJson.version, platform: { os: process.platform === 'darwin' ? 'macos' : process.platform === 'win32' ? 'windows' : 'linux', osVersion: getOSVersion(), // Major version only nodeVersion: process.version.split('.').slice(0, 2).join('.'), arch: process.arch as 'x64' | 'arm64', mcpClient: detectMCPClient() }, installMethod: 'npm', installType: 'new' }); } // Example: Track crash process.on('uncaughtException', async (error) => { const telemetry = TelemetryClient.getInstance(); await telemetry.trackEvent({ eventType: 'crash', timestamp: new Date().toISOString(), installId: telemetry.getInstallId(), version: packageJson.version, platform: getPlatformMetrics(), errorType: 'runtime', errorCategory: error.code || 'UNKNOWN', component: extractComponentFromStack(error.stack), recovered: false, errorMessage: sanitizeErrorMessage(error.message) }); // Re-throw after telemetry sent throw error; }); ``` ### 5. Server-Side (Recommendations) ```typescript // Telemetry server should: // 1. Accept ONLY anonymized data // 2. Aggregate data before storage // 3. Delete installation-level data after aggregation // 4. Never log raw events interface TelemetryServer { // Endpoint for receiving events POST /api/v1/telemetry // Aggregated statistics (public dashboard) GET /api/v1/stats/installations GET /api/v1/stats/platforms GET /api/v1/stats/errors // Deletion endpoint (user-initiated) DELETE /api/v1/telemetry/:installId } // Server aggregation example async function aggregateInstallations(events: InstallationEvent[]): Promise<void> { // Group by platform const byPlatform = groupBy(events, e => e.platform.os); // Store only aggregates await db.insert('daily_installations', { date: today, windows: byPlatform.windows?.length || 0, macos: byPlatform.macos?.length || 0, linux: byPlatform.linux?.length || 0 }); // Delete individual events after aggregation await db.delete('raw_events', { eventType: 'installation', date: today }); } ``` ### 6. Telemetry Configuration File ```typescript // ~/.dollhouse/telemetry.json interface TelemetryLocalConfig { // Installation ID (generated once) installId: string; createdAt: string; // User preferences enabled: boolean; consentGiven: boolean; consentTimestamp: string; policyVersion: string; // Collection preferences collectCrashReports: boolean; collectUsageStats: boolean; collectPerformanceMetrics: boolean; // Privacy settings maxDataRetention: number; // days } // Example { "installId": "550e8400-e29b-41d4-a716-446655440000", "createdAt": "2025-10-15T10:30:00Z", "enabled": true, "consentGiven": true, "consentTimestamp": "2025-10-15T10:30:00Z", "policyVersion": "1.0", "collectCrashReports": true, "collectUsageStats": true, "collectPerformanceMetrics": false, "maxDataRetention": 90 } ``` --- ## AGPL and Dual-License Considerations ### AGPL-3.0 Requirements The AGPL-3.0 license has specific implications for telemetry: 1. **Network Use Disclosure** - AGPL requires source code availability for "network use" - Telemetry server code must be open source - Users must be able to self-host telemetry server 2. **Modifications Must Be Shared** - If you modify telemetry code, modifications must be shared - Applies to both client and server components 3. **User Freedom** - Users must be able to disable telemetry - Users must be able to run modified versions without telemetry - No "telemetry lock-in" - software must work fully without it ### Dual-License Considerations DollhouseMCP uses dual licensing (AGPL-3.0 + Commercial): 1. **AGPL Users** - Must have full control over telemetry - Can disable, modify, or remove telemetry code - Can self-host telemetry server 2. **Commercial License Users** - May have different telemetry terms - Could include mandatory telemetry for support purposes - Document differences clearly in commercial license ### Recommendations for AGPL Compliance ```typescript // 1. Make telemetry completely optional export const TELEMETRY_ENABLED = process.env.DOLLHOUSE_TELEMETRY !== 'false'; // 2. Document telemetry server source // README.md /** * Telemetry Server * * The telemetry server source code is available at: * https://github.com/DollhouseMCP/telemetry-server * * You can self-host the telemetry server by: * 1. Clone the repository * 2. Follow setup instructions * 3. Set DOLLHOUSE_TELEMETRY_ENDPOINT environment variable */ // 3. Allow endpoint override export const TELEMETRY_ENDPOINT = process.env.DOLLHOUSE_TELEMETRY_ENDPOINT || 'https://telemetry.dollhousemcp.com/api/v1/events'; // 4. Provide easy disable // Command: dollhousemcp telemetry disable --permanent // Environment: DOLLHOUSE_TELEMETRY=false // Config file: telemetry.enabled = false ``` ### License-Specific Telemetry Documentation ```markdown # Telemetry and Licensing ## AGPL-3.0 Users Under the AGPL-3.0 license, telemetry is: - **Opt-in by default** - You choose whether to enable it - **Completely optional** - All features work without telemetry - **Open source** - Telemetry server code is available - **Self-hostable** - You can run your own telemetry server - **Removable** - You can modify code to remove telemetry entirely ## Commercial License Users Commercial license users may have different telemetry terms: - See your commercial license agreement for details - Contact sales@dollhousemcp.com for questions ## Privacy Commitment Regardless of license: - We never collect personal information - All telemetry data is anonymous - You have full control over your data - Transparent disclosure of what is collected ``` --- ## User Communication ### 1. Installation Prompt Show during first installation or upgrade: ``` ┌─────────────────────────────────────────────────────────────┐ │ │ │ Welcome to DollhouseMCP v1.9.16! │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Help Improve DollhouseMCP │ │ │ ├─────────────────────────────────────────────────────┤ │ │ │ │ │ │ │ Would you like to share anonymous usage data to │ │ │ │ help us improve DollhouseMCP? │ │ │ │ │ │ │ │ We collect: │ │ │ │ ✓ Platform (OS, Node version, MCP client) │ │ │ │ ✓ Installation success/failure rates │ │ │ │ ✓ Crash reports (no personal info) │ │ │ │ ✓ Feature usage statistics (counts only) │ │ │ │ │ │ │ │ We NEVER collect: │ │ │ │ ✗ Your name, email, or GitHub username │ │ │ │ ✗ Your content (personas, skills, etc.) │ │ │ │ ✗ Detailed logs or commands │ │ │ │ ✗ IP addresses or location │ │ │ │ │ │ │ │ Learn more: https://dollhousemcp.com/telemetry │ │ │ │ │ │ │ │ [ Enable Telemetry ] [ No, Thanks ] │ │ │ │ │ │ │ │ (You can change this anytime with: │ │ │ │ dollhousemcp telemetry enable/disable) │ │ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 2. README Documentation Add to README.md: ```markdown ## Telemetry DollhouseMCP includes **optional, anonymous telemetry** to help us improve the project. ### What We Collect - **Platform information**: OS, Node version, MCP client - **Installation metrics**: Success/failure, installation method - **Crash reports**: Sanitized error categories (no personal info) - **Usage statistics**: Weekly feature counts (no detailed logs) ### What We DON'T Collect - Personal information (names, emails, usernames) - Your content (personas, skills, templates, memories) - Detailed usage logs or commands - IP addresses or geographic location - Any personally identifiable information ### Enabling/Disabling Telemetry **Opt-in during installation:** ```bash npm install @dollhousemcp/mcp-server # You'll be prompted to enable/disable telemetry ``` **Change anytime:** ```bash # Enable telemetry dollhousemcp telemetry enable # Disable telemetry dollhousemcp telemetry disable # Check status dollhousemcp telemetry status # View collected data dollhousemcp telemetry show # Delete local data dollhousemcp telemetry delete ``` **Environment variable:** ```bash # Disable telemetry completely export DOLLHOUSE_TELEMETRY=false ``` **Configuration file:** ```json { "telemetry": { "enabled": false } } ``` ### Privacy Policy For complete details, see our [Telemetry Privacy Policy](https://dollhousemcp.com/privacy/telemetry). ### Self-Hosting The telemetry server is open source. You can self-host it: ```bash git clone https://github.com/DollhouseMCP/telemetry-server cd telemetry-server # Follow setup instructions in README # Point DollhouseMCP to your server export DOLLHOUSE_TELEMETRY_ENDPOINT=https://your-server.com/api/v1/events ``` ``` ### 3. Dedicated Privacy Policy Page Create `docs/privacy/TELEMETRY_PRIVACY_POLICY.md`: ```markdown # Telemetry Privacy Policy **Last Updated**: October 15, 2025 **Version**: 1.0 ## Overview This privacy policy describes how DollhouseMCP collects, uses, and protects telemetry data. ## What We Collect ### Platform Information - Operating system type (Windows, macOS, Linux) - Operating system major version (e.g., "macOS 14", not specific builds) - Node.js major version (e.g., "20.x") - System architecture (x64, arm64) - MCP client being used (Claude Desktop, Claude Code, Gemini, Other) ### Installation Metrics - Installation timestamp - Package version installed - Installation method (npm, npx, git, docker) - Installation type (new install, upgrade, reinstall) - Previous version (for upgrades) - Update success/failure status ### Error and Crash Reports - Error category (e.g., "MODULE_NOT_FOUND", "PERMISSION_DENIED") - Component that encountered the error - Sanitized error message (no file paths, no usernames) - Whether recovery was successful - Timestamp of error ### Usage Statistics (Weekly Aggregates) - Number of active days per week - Number of sessions - Feature usage counts (e.g., "5 personas used this week") - Average startup time - Average response time - Crash and error counts ### Unique Installation ID - A randomly generated UUID (version 4) - Created locally on first installation - Cannot be linked back to any user identity - Used only to aggregate events from the same installation ## What We DON'T Collect We **never** collect: - Personal information (names, emails, addresses, phone numbers) - GitHub usernames or OAuth tokens - IP addresses (not even anonymized) - Geographic location (not even country-level) - User content (personas, skills, templates, memories) - File paths containing usernames - Detailed command logs - Keystroke or interaction logs - Computer or hostname - Network information (MAC addresses, etc.) - Any information that could identify you ## How We Use Telemetry Data ### Aggregate Analysis - Calculate installation success rates - Identify common error patterns - Understand platform distribution - Track feature adoption - Measure performance trends ### Product Improvements - Prioritize bug fixes based on crash frequency - Optimize for most common platforms - Improve installation experience - Enhance error messages - Guide feature development ### What We Don't Do - We never sell telemetry data - We never share data with third parties (except aggregate public statistics) - We never use data for advertising - We never link data to individual users ## Data Storage and Retention ### Local Storage - Telemetry events are logged locally in `~/.dollhouse/telemetry.log` - You can view this file anytime - Local logs are kept for 90 days by default - You can delete local logs anytime ### Server Storage - Events are sent in batches to our telemetry server - Events are aggregated within 24 hours - Individual events are deleted after aggregation - Aggregated statistics are kept indefinitely (no PII) - You can request deletion of your installation's data ## Your Rights and Controls ### Opt-In/Opt-Out - Telemetry is **opt-in by default** - You are prompted during installation - You can enable/disable anytime - Disabling stops all collection immediately ### View Your Data ```bash # View local telemetry log dollhousemcp telemetry show # View configuration cat ~/.dollhouse/telemetry.json ``` ### Delete Your Data ```bash # Delete local telemetry data dollhousemcp telemetry delete --local # Request server-side deletion dollhousemcp telemetry delete --remote # Or both dollhousemcp telemetry delete --all ``` ### Self-Host Telemetry Server - Telemetry server code is open source - You can run your own telemetry server - Point DollhouseMCP to your server via environment variable - Full control over all data ## Security ### Data Transmission - All telemetry data sent over HTTPS - No sensitive information transmitted - Failed transmissions are logged (for retry) ### Data Validation - All events validated before sending - Automatic PII detection and removal - Path sanitization (removes usernames) - Error message sanitization ### Server Security - Data encrypted at rest - Access logs monitored - Regular security audits - Minimal data retention ## Changes to This Policy We may update this privacy policy from time to time. Changes will be: - Announced on GitHub (release notes) - Documented in CHANGELOG - Shown in application on next launch - Posted at https://dollhousemcp.com/privacy/telemetry If we make significant changes: - You will be re-prompted for consent - You can review changes before agreeing - Previous consent becomes invalid ## Contact Questions about telemetry or privacy: - Email: privacy@dollhousemcp.com - GitHub Issues: https://github.com/DollhouseMCP/mcp-server/issues - GitHub Discussions: https://github.com/DollhouseMCP/mcp-server/discussions ## Open Source Commitment Under AGPL-3.0: - All telemetry code is open source - Telemetry server code is open source - You can audit all telemetry code - You can modify or remove telemetry - You can self-host telemetry infrastructure --- **Summary**: We collect minimal, anonymous telemetry to improve DollhouseMCP. You have full control. We never collect personal information. All data is transparent and deletable. ``` ### 4. In-App Notifications ```typescript // Show notification when telemetry helps fix a bug function showTelemetryImpactNotification(): void { console.log(` ╔══════════════════════════════════════════════════════════════╗ ║ Thank You for Your Help! ║ ╠══════════════════════════════════════════════════════════════╣ ║ ║ ║ Your anonymous telemetry data helped us fix a critical ║ ║ startup crash affecting macOS 14 users. ║ ║ ║ ║ This fix is in v1.9.17 (just released). ║ ║ ║ ║ Community-powered bug fixes like this are only possible ║ ║ with your help. Thank you! ║ ║ ║ ╚══════════════════════════════════════════════════════════════╝ `); } ``` --- ## Industry Examples ### 1. VS Code Telemetry **What they do right:** - Clear documentation of what is collected - Opt-out via setting: `"telemetry.telemetryLevel": "off"` - Detailed telemetry viewer in UI - Open source telemetry code - Regular transparency reports **What we can learn:** - Provide GUI for telemetry settings (not just CLI) - Show telemetry data in real-time - Publish regular transparency reports **VS Code telemetry settings:** ```json { "telemetry.telemetryLevel": "all" | "error" | "crash" | "off", "telemetry.enableCrashReporter": true | false, "telemetry.enableTelemetry": true | false } ``` ### 2. Homebrew Analytics **What they do right:** - Opt-out by default for CI environments - Anonymous by design (no user IDs at all) - Public analytics dashboard - Simple opt-out: `brew analytics off` - Clear documentation **What we can learn:** - Auto-disable in CI environments - Publish public dashboard with aggregated statistics - Keep opt-out extremely simple **Homebrew approach:** ```bash # Opt-out brew analytics off # Check status brew analytics # What they collect (from their docs) # - Command counts (e.g., "brew install" ran 1M times) # - Formula install counts # - macOS version distribution # - Homebrew version distribution ``` ### 3. Next.js Telemetry **What they do right:** - Zero personal data collection - Completely anonymous - Public disclosure of all events - Easy opt-out: `npx next telemetry disable` - Show example telemetry data in docs **What we can learn:** - Show real examples of telemetry events in documentation - Use simple, friendly command names - Focus on product improvement use cases **Next.js telemetry events:** ```typescript // They openly publish their telemetry events { "eventName": "NEXT_BUILD_COMPLETED", "payload": { "durationInSeconds": 34, "totalPageCount": 15, "hasDunderPages": false } } ``` ### 4. npm CLI **What they do right:** - Opt-out via config: `npm config set send-metrics false` - Minimal data collection - Focus on error reporting - Clear privacy policy **What we can learn:** - Use config system for persistence - Focus on actionable data (errors, crashes) - Keep data collection minimal ### 5. Sentry (Error Tracking) **What they do right:** - Specialized in crash/error reporting - Automatic PII scrubbing - User feedback collection (optional) - Source map support for debugging - Open source client libraries **What we can learn:** - Consider using Sentry for crash reports - Automatic PII detection is critical - Allow users to add context to crashes ### 6. Plausible Analytics (Privacy-First) **What they do right:** - No cookies, no tracking - Completely anonymous - EU/GDPR compliant - Open source - Public dashboards by default **What we can learn:** - Privacy-first analytics is possible - Open source builds trust - Public dashboards increase transparency --- ## Implementation Roadmap ### Phase 1: Foundation (Week 1-2) **Goals:** - Set up telemetry infrastructure - Implement basic event tracking - Create opt-in/opt-out mechanism **Tasks:** 1. Create `TelemetryClient` class with sanitization 2. Implement local telemetry log 3. Add opt-in prompt to installation 4. Create `dollhousemcp telemetry` CLI commands 5. Write privacy policy documentation **Deliverables:** - Working telemetry client (local only, no server yet) - CLI commands for enable/disable/show/delete - Documentation in README - Privacy policy document ### Phase 2: Server Infrastructure (Week 3-4) **Goals:** - Set up telemetry server - Implement event ingestion - Create aggregation pipeline **Tasks:** 1. Create telemetry server repository (open source) 2. Implement event ingestion API 3. Set up data aggregation (24-hour batches) 4. Implement deletion endpoint 5. Deploy server infrastructure **Deliverables:** - Open source telemetry server - Public API documentation - Self-hosting guide - Aggregation working ### Phase 3: Event Implementation (Week 5-6) **Goals:** - Track key events - Validate data collection - Test privacy measures **Tasks:** 1. Implement installation event tracking 2. Implement crash/error reporting 3. Implement update tracking 4. Implement weekly usage summaries 5. Add PII detection tests **Deliverables:** - All event types implemented - Comprehensive test coverage - PII detection working - Local testing complete ### Phase 4: Dashboard and Reporting (Week 7-8) **Goals:** - Create public dashboard - Generate insights - Document findings **Tasks:** 1. Create public analytics dashboard 2. Implement charts and graphs 3. Add export functionality 4. Create weekly/monthly reports 5. Document how data is used **Deliverables:** - Public dashboard at https://stats.dollhousemcp.com - Weekly transparency reports - Data usage documentation ### Phase 5: Iteration and Feedback (Ongoing) **Goals:** - Gather user feedback - Improve privacy measures - Add requested features **Tasks:** 1. Monitor opt-in rates 2. Collect user feedback 3. Iterate on privacy measures 4. Add transparency features 5. Regular privacy audits --- ## Legal and Compliance ### GDPR Compliance (EU Users) Even though telemetry is anonymous, GDPR still applies: 1. **Lawful Basis** - Consent (user opts in) - Legitimate interest (product improvement) 2. **User Rights** - Right to access (show command) - Right to deletion (delete command) - Right to data portability (export command) - Right to object (disable command) 3. **Requirements** - Clear consent mechanism ✓ - Easy opt-out ✓ - Privacy policy ✓ - Data minimization ✓ ### CCPA Compliance (California) California Consumer Privacy Act requirements: 1. **Disclosure** - What data is collected ✓ - Purpose of collection ✓ - Categories of data ✓ 2. **User Rights** - Right to know ✓ - Right to delete ✓ - Right to opt-out ✓ 3. **Do Not Sell** - We don't sell data ✓ - Clear disclosure ✓ ### Other Regulations **COPPA (Children's Privacy):** - Don't target children under 13 - No age collection - If children use product, need parental consent **PIPEDA (Canada):** - Similar to GDPR - Consent required - Reasonable security measures **LGPD (Brazil):** - Based on GDPR principles - User consent - Data minimization ### Recommendations 1. **Consult Legal Counsel** - Have lawyer review telemetry implementation - Ensure compliance with all applicable laws - Review privacy policy 2. **Document Everything** - What data is collected - Why it's collected - How it's used - How long it's retained 3. **Regular Audits** - Annual privacy audit - Update privacy policy as needed - Monitor regulatory changes 4. **Transparency** - Publish regular transparency reports - Disclose any data breaches immediately - Be proactive about privacy --- ## FAQ ### Q: Why collect telemetry at all? **A:** Telemetry helps us: - Understand what platforms to prioritize - Identify and fix bugs faster - Make data-driven decisions about features - Improve installation success rates Without telemetry, we're flying blind and making decisions based on assumptions. ### Q: Can you really not identify users? **A:** Correct. The installation ID is a random UUID generated locally. We never collect: - GitHub usernames - Email addresses - IP addresses - Computer names - Any other identifying information Even if we wanted to, we couldn't link an installation ID back to a specific person. ### Q: What if I don't trust you? **A:** You don't have to! - All telemetry code is open source - audit it yourself - Telemetry is opt-in - you choose whether to enable it - You can self-host the telemetry server - You can modify or remove telemetry code entirely (AGPL allows this) ### Q: Will features be locked behind telemetry? **A:** Absolutely not. All features work fully without telemetry. Telemetry is purely for product improvement. ### Q: How often is data sent? **A:** Events are batched and sent: - Every 1 hour (if batch size reached) - Every 24 hours (scheduled sync) - On shutdown (flush remaining events) Failed sends are retried with exponential backoff. ### Q: Can I see what data is being sent? **A:** Yes! Run `dollhousemcp telemetry show` to see all local telemetry events. The format is identical to what is sent to the server. ### Q: Can I partially opt-in? **A:** Yes! You can enable/disable specific telemetry types: ```bash # Enable crash reports only dollhousemcp telemetry enable --only-crashes # Enable installation metrics only dollhousemcp telemetry enable --only-installations # Enable everything except performance metrics dollhousemcp telemetry enable --no-performance ``` ### Q: What about enterprise/corporate users? **A:** Enterprise users often have strict data policies. We recommend: - Disable telemetry in corporate environments - Self-host telemetry server for internal metrics - Use environment variable `DOLLHOUSE_TELEMETRY=false` in CI/CD ### Q: How do you prevent data breaches? **A:** Multiple layers: - No PII means no sensitive data to breach - HTTPS for all transmission - Encryption at rest - Regular security audits - Minimal data retention (aggregate and delete) ### Q: Will you ever change what data is collected? **A:** If we add new telemetry events: - We'll announce it in release notes - We'll update the privacy policy - You'll be re-prompted for consent - Previous consent doesn't automatically apply to new data types ### Q: Can I export my telemetry data? **A:** Yes: ```bash # Export local telemetry log dollhousemcp telemetry export --output telemetry.json # Request server-side export dollhousemcp telemetry export --remote --output server-data.json ``` ### Q: What if I find a privacy issue? **A:** Please report it immediately: - Email: security@dollhousemcp.com - GitHub Security Advisory (private) - We'll fix it ASAP and notify all users ### Q: Do you use third-party analytics services? **A:** No. We run our own telemetry infrastructure. No data goes to Google Analytics, Mixpanel, or similar services. ### Q: How long do you keep data? **A:** - Individual events: 24 hours (then aggregated and deleted) - Aggregated statistics: Indefinitely (no PII in aggregates) - Local logs: 90 days by default (user configurable) ### Q: Can I contribute to the telemetry server? **A:** Yes! The telemetry server is open source at: https://github.com/DollhouseMCP/telemetry-server We welcome contributions to improve privacy, security, and functionality. --- ## Conclusion Implementing telemetry for DollhouseMCP requires careful balance between: - **Product Improvement**: Gathering data to make informed decisions - **User Privacy**: Protecting user information and building trust - **Transparency**: Being open about what is collected and why - **Compliance**: Following AGPL, GDPR, CCPA, and other regulations ### Key Principles to Remember 1. **Opt-in by default** - Never assume consent 2. **Minimal collection** - Only what's needed 3. **Anonymous by design** - No way to identify users 4. **Transparent disclosure** - Clear documentation 5. **User control** - Easy opt-out, view, and delete 6. **Open source** - Audit able telemetry code and server 7. **Regular audits** - Continuous privacy improvements ### Next Steps 1. Review this document with team 2. Get legal counsel review 3. Implement Phase 1 (foundation) 4. Test with small group of users 5. Gather feedback and iterate 6. Roll out to all users ### Success Metrics - High opt-in rate (target: >60%) - Low complaint rate (target: <1%) - Actionable insights from data - User trust maintained - AGPL compliance maintained --- **Document Version**: 1.0 **Last Updated**: October 15, 2025 **Next Review**: January 15, 2026 **Owner**: DollhouseMCP Core Team For questions or feedback on this document: - GitHub Issue: https://github.com/DollhouseMCP/mcp-server/issues - Email: privacy@dollhousemcp.com

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DollhouseMCP/DollhouseMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server