Summary
Add anonymous usage telemetry to Basic Memory using OpenPanel. Following the Homebrew analytics model: on by default with easy opt-out.
Motivation
We want to understand:
- What versions are in use
- What features are being used (MCP tools, CLI commands)
- What errors users encounter
- OS/Python version distribution
PyPI stats are unreliable, and we have no visibility into actual usage patterns.
Design Decisions
| Decision |
Choice |
Rationale |
| Backend |
OpenPanel Cloud |
Open source, privacy-first, Python SDK, $20/mo for 5K-100K events |
| Default |
ON (opt-out) |
Homebrew model - get meaningful data, easy to disable |
| Identification |
Random UUID |
Stored locally at ~/.basic-memory/.install_id, user can delete |
| First run |
One-time notice |
Not a prompt - just inform, then never show again |
What We'll Track
Events
| Event |
Properties |
Purpose |
app_started |
mode: "cli" | "mcp" |
Active usage |
mcp_tool_called |
tool: str |
Feature popularity |
cli_command |
command: str |
CLI usage patterns |
sync_completed |
entity_count, duration_ms |
Performance baseline |
error |
type, message (sanitized) |
Bug prioritization |
import_completed |
source: str |
Import feature usage |
Global Properties (every event)
app_version
python_version
os (darwin/linux/windows)
arch (arm64/x86_64)
install_id (random UUID)
What We NEVER Collect
- Note content
- File names or paths
- Personal information
- IP addresses (OpenPanel doesn't store these)
User Experience
First Run Notice (shown once)
Basic Memory collects anonymous usage statistics to help improve the software.
This includes: version, OS, feature usage, and errors. No personal data or note content.
To opt out: bm telemetry disable
Details: https://memory.basicmachines.co/telemetry
CLI Commands
bm telemetry disable # opt out
bm telemetry enable # opt back in
bm telemetry status # show current state + what's collected
Environment Variable
export BASIC_MEMORY_TELEMETRY_ENABLED=false # disable via env
Implementation
Files to Create
| File |
Description |
src/basic_memory/telemetry.py |
Core telemetry module (client, track function, notice) |
src/basic_memory/cli/commands/telemetry.py |
CLI commands (enable/disable/status) |
tests/test_telemetry.py |
Unit tests |
Files to Modify
| File |
Changes |
pyproject.toml |
Add openpanel dependency |
src/basic_memory/config.py |
Add telemetry_enabled (default True), telemetry_notice_shown fields |
src/basic_memory/cli/commands/__init__.py |
Register telemetry module |
src/basic_memory/cli/main.py |
Import telemetry commands |
src/basic_memory/mcp/server.py |
Add startup tracking + show notice |
src/basic_memory/cli/app.py |
Add startup tracking + show notice |
| MCP tool files |
Add track() calls |
| CLI command files |
Add track() calls |
Core Module (telemetry.py)
"""Anonymous telemetry for Basic Memory (Homebrew-style opt-out)."""
import platform
import uuid
from pathlib import Path
from openpanel import OpenPanel
from basic_memory import __version__
from basic_memory.config import ConfigManager
_client: OpenPanel | None = None
def get_install_id() -> str:
"""Get or create anonymous installation ID."""
id_file = Path.home() / ".basic-memory" / ".install_id"
if id_file.exists():
return id_file.read_text().strip()
install_id = str(uuid.uuid4())
id_file.parent.mkdir(parents=True, exist_ok=True)
id_file.write_text(install_id)
return install_id
def track(event: str, properties: dict | None = None) -> None:
"""Track an event. Fire-and-forget, never raises."""
try:
get_client().track(event, properties or {})
except Exception:
pass # Telemetry must never break the app
Documentation
Create a page at https://memory.basicmachines.co/telemetry documenting:
- Exactly what we collect
- What we never collect
- How to disable
- How to delete your data (delete
~/.basic-memory/.install_id)
Testing Strategy
- Unit tests for telemetry module (mock OpenPanel client)
- Verify opt-out disables tracking
- Verify notice only shows once
- Test env var override works
- Integration test for CLI commands
References
Summary
Add anonymous usage telemetry to Basic Memory using OpenPanel. Following the Homebrew analytics model: on by default with easy opt-out.
Motivation
We want to understand:
PyPI stats are unreliable, and we have no visibility into actual usage patterns.
Design Decisions
~/.basic-memory/.install_id, user can deleteWhat We'll Track
Events
app_startedmode: "cli" | "mcp"mcp_tool_calledtool: strcli_commandcommand: strsync_completedentity_count, duration_mserrortype, message(sanitized)import_completedsource: strGlobal Properties (every event)
app_versionpython_versionos(darwin/linux/windows)arch(arm64/x86_64)install_id(random UUID)What We NEVER Collect
User Experience
First Run Notice (shown once)
CLI Commands
Environment Variable
Implementation
Files to Create
src/basic_memory/telemetry.pysrc/basic_memory/cli/commands/telemetry.pytests/test_telemetry.pyFiles to Modify
pyproject.tomlopenpaneldependencysrc/basic_memory/config.pytelemetry_enabled(default True),telemetry_notice_shownfieldssrc/basic_memory/cli/commands/__init__.pysrc/basic_memory/cli/main.pysrc/basic_memory/mcp/server.pysrc/basic_memory/cli/app.pytrack()callstrack()callsCore Module (
telemetry.py)Documentation
Create a page at
https://memory.basicmachines.co/telemetrydocumenting:~/.basic-memory/.install_id)Testing Strategy
References