TL;DR
Our official devtools (CLI, Terraform provider, MCP server, JavaScript SDK, Python SDK) attach a few metadata headers to every authenticated API call. We use those headers to count how many organizations adopt each devtool and which versions are in active use. We never see your commands, monitor names, or any payload contents — only the fact that some call happened, plus the version of the client that made it.
If you'd rather we didn't collect even that, every devtool honors a single opt-out toggle (see Opting out below).
Why we collect this
DevHelm offers five distinct ways to interact with the platform: a web dashboard, a CLI, a Terraform provider, an MCP server (for Cursor / Claude Desktop / etc.), and SDKs in two languages. Without basic adoption signals from those clients, we can't answer questions like:
- Is anybody using the Terraform provider? (decides whether we keep investing in it)
- Can we deprecate CLI v0.5 yet? (decides our backward-compat burden)
- Which MCP clients should we test against? (Cursor, Claude Desktop, others?)
The alternative — flying blind and either over- or under-investing in each surface — is worse for both us and you.
Exactly what we collect
Every authenticated request from an official DevHelm devtool carries these HTTP headers:
| Header | Example | Notes |
|---|---|---|
X-DevHelm-Surface | cli | One of: cli, tf, mcp, sdk-js, sdk-py |
X-DevHelm-Surface-Version | 0.7.2 | Semver of the client binary / package |
Surface-specific extras:
| Header | Sent by | Example |
|---|---|---|
X-DevHelm-Cli-Os | CLI | darwin-arm64, linux-x86_64 |
X-DevHelm-Cli-Install-Source | CLI | npm, brew, other |
X-DevHelm-Mcp-Client | MCP server | cursor, claude-desktop, claude-code, zed, vscode, windsurf |
X-DevHelm-Sdk-Name | SDKs | sdk-js, sdk-py |
That's the complete list. Nothing about which command you ran, which monitor you queried, which keys you used, what hostnames you target, or the contents of any request body or response.
What we don't collect
For absolute clarity:
- No command names or arguments.
devhelm monitors create --url https://acme.examplearrives at our API as the same anonymous metadata asdevhelm --version. - No request or response payloads. Our standard API audit log captures what changed in your account (because that's table stakes for any B2B platform), but the telemetry layer described here adds no extra payload visibility.
- No source IPs in the telemetry rollup. (Source IP exists in our standard request logs for security and rate-limiting, governed by our Privacy Policy.)
- No environment variables, file contents, or working directory from your machine.
- No identifiers from your dev environment (no MAC addresses, no machine fingerprints).
What we do with it
The data lives in two places:
- A single Postgres row per (organization × devtool) that holds: when we first saw the org on that surface, when we last saw it, a running count of calls, and the latest version observed. That's it. No per-call history.
- Two PostHog events per (organization × devtool), ever: one when we first see the org on a given surface (
cli_first_run,tf_provider_first_apply,mcp_server_first_call,sdk_first_authenticated_request) and — if we ever ship it — one if the org makes a call after a long dormancy. Sparse by design; not one event per API request.
Aggregate numbers from these signals show up in our internal GTM dashboards. They are never sold, never shared with marketing networks, and never used to build per-user profiles. They exist solely to inform DevHelm's own product investment and deprecation decisions.
Opting out
Set the DEVHELM_TELEMETRY=0 environment variable. Every official devtool reads this and, when set, simply does not send the surface headers. The API has no way to record what it doesn't receive.
The CLI also accepts a per-invocation --no-telemetry flag for one-off opt-outs.
There is no separate "opt out via web settings" toggle — the headers are emitted by your local devtool, so the opt-out lives there. We deliberately built it this way so you don't have to trust a server-side setting.
Third-party / unofficial clients
If you call the DevHelm API directly with curl, your own scripts, or an unofficial client, you naturally do not send these headers and we collect nothing surface-related. That path is fully supported and not penalized.
Changes
This page is the source of truth. We will update it before changing what the official devtools collect, never after. The history is visible in the devhelmhq/mono repo.
Last updated: May 2026.