Security and data handling
Extentos's data handling — what we collect (aggregate dev-time and library-runtime metadata that powers your own analytics dashboard plus ecosystem insights about vendor market share and capability popularity), what we never collect (speech transcripts, photo or video bytes, audio samples, handler-code input/output payloads, AI prompt and response text, end-user PII), how the boundary holds across the MCP server and the native iOS and Android libraries, and the three independent opt-out surfaces. Anonymous-first by design, GDPR-friendly because no end-user PII is ever stored, with a developer-facing analytics dashboard on the way.
Extentos collects aggregate metadata about how developers use the platform — which capabilities are popular, which vendors get adopted, how flows perform, where errors surface. This data powers three things: the developer-facing analytics dashboard (coming soon — you'll see your own app's usage in one view), the Extentos team's product roadmap (which vendors to add next, which capabilities to harden), and the ecosystem insights Extentos shares with glasses vendors as aggregate market data (10+ account minimum). What Extentos never collects is end-user content (speech transcripts, photo or video bytes, audio samples, AI prompts and responses), end-user PII (names, emails, phone numbers), spec JSON contents, toggle values, or stack traces. This page is the honest, complete picture of what crosses the network from your install and your shipped apps to Extentos's backend, anchored to the canonical telemetry contract at docs/mcp/TELEMETRY.md.
TL;DR
| What | |
|---|---|
| What we collect | Aggregate metadata — tool calls, install events, vendor adoption, capability usage, error rates, library/MCP versions, device models, country-from-IP, anonymous device identifiers. Tagged with anonymous IDs that can never be reversed back to a person. |
| What we never collect | Speech transcripts, photo bytes, video frames, audio samples, AI prompt and response text, handler-code input/output payloads, toggle values, IP addresses (dropped after country derivation), stack traces, end-user PII. |
| What end users see | Nothing about Extentos. End users have no relationship with us. Your shipped app on real Ray-Ban Meta hardware emits zero traffic to Extentos by default — RealMetaTransport doesn't talk to our backend at all. The developer chooses whether to enable runtime library telemetry on shipped apps. |
| Opt-out | Three independent surfaces — EXTENTOS_TELEMETRY=0 env var, extentos-mcp decline-privacy CLI, or ExtentosConfig.telemetryConsent = false in your shipped app. Any one disables telemetry upload; on-device debug logs still work. |
| Compliance | GDPR-friendly by construction — no end-user PII ever stored. Aggregate metadata retained indefinitely under Art. 6(1)(f) legitimate-interest basis to power both the developer dashboard and (multi-vendor-dependent) the vendor data product; right-to-erasure honored within 30 days regardless of retention policy. CCPA: planned cross-vendor data product qualifies as a "sale"; developer-level Do-Not-Sell opt-out is ExtentosConfig.dataSharingConsent = false (forthcoming SDK release). SOC 2 Type II on the post-launch roadmap. |
Why we collect telemetry — the honest answer
Extentos's business model includes monetizing aggregate ecosystem insights, and we're upfront about it.
Three concrete uses:
- Your own analytics dashboard. When the developer dashboard ships, you'll see your app's usage at
extentos.com/apps/<your-app>— which voice triggers your users fire, which AI calls are slowest, which device models your users have, error rates, session lengths, weekly active users. Same data Extentos collects centrally, scoped to youraccountId. This is genuinely valuable to developers and is why the underlying collection is broad rather than narrow. - Extentos's product roadmap. Aggregate signal across all developers tells us which vendors to add next (if 30% of new MCP installs ask about Mentra G1, we prioritize that transport), which capabilities are over-used relative to expectations, where the SDK has rough edges. Without this, every roadmap call is a guess.
- Cross-vendor ecosystem signals to glasses vendors (planned, multi-vendor only). Once Extentos supports ≥2 vendors with material installed bases, aggregate comparative market data — capability mix across the ecosystem, vendor market share, session-hour totals across vendors — becomes uniquely valuable to glasses vendors who only see their own SDK telemetry. We plan to sell this as market research, only as aggregates over at least 10 distinct accounts, never as individual-developer or individual-end-user data. This is a planned future revenue line that activates at multi-vendor scale; a single-vendor version isn't a meaningful product because each vendor already collects their own platform's usage data.
We chose a transparent collect-and-aggregate model rather than a "we collect nothing" claim that vendors quietly walk back. The discipline is in the firm content/PII boundary, not in collecting less data overall.
What we collect
All telemetry events conform to a single envelope (verbatim from docs/mcp/TELEMETRY.md):
{
"eventId": "tev_a1b2c3d4",
"timestamp": "2026-04-18T14:22:10.432Z",
"category": "runtime",
"name": "connection.opened",
"accountId": "acct_xyz",
"installId": "inst_abc123",
"appId": "com.example.app",
"anonymousDeviceId": "dev_789",
"libVersion": "1.2.0",
"mcpVersion": null,
"vendor": "meta_rayban",
"platform": "android",
"osVersion": "14",
"deviceModel": "pixel_8",
"country": "US",
"userSegment": null,
"properties": { "transportType": "RealMeta", "timeToConnectMs": 1820 }
}The events split into two categories:
Dev-time events (MCP server, category: "mcp")
Emitted from your machine while your AI agent operates Extentos — so they're tagged with your installId (anonymous) and, after linking, your accountId.
| Event | What it carries |
|---|---|
mcp.installed | First run on this machine. npm version, OS, detected agent host. |
mcp.consent_accepted / mcp.consent_declined | Privacy policy version. |
tool.called | Every MCP tool invocation. toolName, durationMs, outcome. |
session.created | createSimulatorSession invoked. Vendor, recording flag. |
account.login_initiated / _completed / linked / logged_out | Auth flow lifecycle. Trigger reason (cli_explicit, meter_exhausted), outcome, duration. |
Runtime events (your shipped app, category: "runtime")
Emitted by the Extentos library if the developer enables runtime telemetry (ExtentosConfig.telemetryConsent = true, default). Tagged with appId and anonymousDeviceId — never with end-user identity.
| Event | What it carries |
|---|---|
app.initialized | Library version, vendor, deviceModel, osVersion. |
connection.opened / closed | Transport type (RealMeta/BrowserSim/LocalSim), timeToConnectMs / durationMs, disconnect cause (typed enum). |
stream.started / stopped | streamType (video_frames, audio_chunks, transcription_incremental, etc.), durationMs. Safe subset of negotiated config (resolution, frame rate, codec, bitrate). No peer addresses, URIs, destination identifiers. |
toggle.changed | key (which of the 8 runtime toggles flipped), source (ui / voice / automation). No old/new values — the values can reveal product behavior. |
error.surfaced | errorClass, errorCode, layer (capability layer: audio / camera / speak / toggle / stream / transport / system). No stack traces. |
Notice the bold disclaimers — every event explicitly carries metadata only, never content.
Retired (deprecated) runtime events: pre-pivot the library also emitted trigger.fired, flow.completed, block.executed, callback.invoked, and spec.loaded to describe spec-DSL execution. Those events were retired with the pure-SDK pivot — the library no longer interprets a spec, so the events that described its execution no longer fire. Their schemas remain in the event registry marked deprecated: true for historical event-log validation; no new code emits them.
What we never collect
Verbatim list from the canonical telemetry doc (this list is published in the privacy policy):
- Speech transcripts (the words your user said)
- Photo bytes, video frames, audio samples
- Handler-code input/output payloads (the LLM prompts your handler builds, the responses it receives, anything your business logic passes around between SDK calls)
- AI provider responses, prompt text, tool-use traces
- Toggle values, variable values
- End-user PII of any kind (names, emails, phone numbers, account identifiers in your app)
- IP addresses (derived to country at ingest, then dropped — we never store the raw IP)
- Stack traces (may contain arbitrary values; stay local in your on-device event log)
- Anything tied to a specific end-user identity beyond the per-device anonymous
anonymousDeviceId
The library architecture enforces this — events are payload-stripped before they enter the upload queue, not in transit. There is no path from end-user content to Extentos's backend, even if the network were intercepted.
End-user privacy — your shipped apps
The clearest line: your shipped app on real Ray-Ban Meta glasses emits zero traffic to Extentos by default.
RealMetaTransport(the production transport) speaks to Meta DAT and the glasses over Bluetooth. It does not connect toapi.extentos.com. End users on real hardware have no network relationship with Extentos at all.BrowserSimTransport(the simulator transport) does talk to the Extentos backend over WebSocket — butBrowserSimTransportonly runs inconfig.debug == truebuilds during development. Shipped release builds default toRealMetaTransport, which doesn't connect.LocalSimTransport(Mock Device Kit simulation) is fully on-device. No network at all.
If the developer chooses to enable runtime library telemetry (ExtentosConfig.telemetryConsent = true, the default), the library emits the runtime events above to https://api.extentos.com/api/telemetry/events. This is the only Extentos network path from a shipped app — and it carries metadata, never content. The developer can disable it per-app via telemetryConsent = false.
End users never see Extentos branding, never get prompted by us, never need to consent to anything from us. Their privacy relationship is entirely with the developer's app — Extentos is invisible.
The 5 ID model
Five identifiers, each with a distinct scope. None of them is end-user PII, and Extentos cannot reverse any ID back to a person.
| ID | Scope | When created | Where stored |
|---|---|---|---|
installId | Per-machine MCP install | First npx @extentos/mcp-server run | ~/.extentos/install_id |
accountId | Per-Extentos-account | When developer signs up via device-code flow | Backend; cached in ~/.extentos/auth.json |
appId | Per-Extentos-app | Set by developer in ExtentosConfig.appId at library init | Compiled into the app |
anonymousDeviceId | Per-end-user-device | First library init on the user's device | App-private storage on the user's device |
userSegment | Developer-defined cohort label | Optional; glasses.telemetry.setUserSegment("...") | App memory; flushes with events |
The anonymousDeviceId lets Extentos count distinct devices and sessions without ever learning end-user identity. The userSegment is set by the developer — Extentos never sets or interprets it. It exists so the developer can cut their own dashboard by cohorts they define (beta tiers, geography, app version) without exposing any personal information.
BYOK — your AI provider keys
When your handler code calls an AI provider (Anthropic, OpenAI, Google, etc.), it does so directly against the provider using the developer's own credentials. Extentos never sees, stores, or proxies your AI provider keys — they live in your app and your provider's auth headers, end of story.
This is verified architecturally: Extentos has no callback or hook into your handler's runtime path. Your handler subscribes to SDK primitives (glasses.audio.transcriptions(), glasses.camera.capturePhoto(), glasses.audio.speak()), reads the values, and writes its own code — including the LLM call. The library never sees what's between the read and the next SDK call. There's no proxy layer, no logging of inputs, no inspection of outputs.
The getCredentialGuide MCP tool walks the developer through provider setup at production time — but it generates instructions for the developer to follow with their provider. Extentos never receives the credentials.
Three opt-out surfaces
Telemetry is opt-out at three independent levels, each disabling a different layer:
| Surface | Where | What it disables |
|---|---|---|
EXTENTOS_TELEMETRY=0 env var | Developer's shell | MCP-server-side telemetry for the current shell session. Doesn't persist across reboots. |
extentos-mcp decline-privacy CLI command | Writes ~/.extentos/consent | MCP-server-side telemetry permanently for this install. Survives reboots. Run accept-privacy to re-enable. |
ExtentosConfig.telemetryConsent = false | Developer's app code | Library-runtime telemetry from this app. Per-app — a developer with multiple apps can opt one out and leave others on. |
Any combination works. Telemetry never affects functionality — opting out doesn't disable any feature, just stops uploads.
The on-device event log (the 512-entry ring buffer your agent queries via getEventLog) keeps working regardless of telemetry consent — that data never crossed the network in the first place. See event log vs telemetry boundary.
Retention and deletion
| Data class | Retention |
|---|---|
| Raw telemetry events | Indefinite. Historical trend data is the asset behind both the developer dashboard and the (multi-vendor-dependent) vendor data product — cutting retention kills year-over-year comparisons. Lawful basis under GDPR is Art. 6(1)(f) legitimate interest, with a documented Legitimate Interest Assessment (aggregate metadata, no end-user PII, clearly disclosed purposes, full right-to-erasure preserved). |
| Aggregated rollups (daily / weekly / monthly per account, plus global) | Indefinite |
anonymousDeviceId records | Retained while the device sends events. No automatic expiration on inactivity — that destroys cohort retention analysis. |
Right-to-erasure (GDPR Art. 17 / CCPA right to delete). The indefinite-retention default does not block right-to-erasure. Developers can email support to delete their account's events; Extentos runs DELETE WHERE accountId = ... and acknowledges within 30 days (GDPR-compatible SLA). This deletes raw events tied to the account; aggregated rollups derived before the deletion request stay (those have no accountId attribution by construction). Anonymous events without an accountId (emitted before account linking and never retroactively re-tagged) cannot be associated to a person and are kept as aggregate-only data.
CCPA "sale" classification. The planned cross-vendor data product qualifies as a "sale" under CCPA when it ships. The developer-level Do-Not-Sell mechanism is ExtentosConfig.dataSharingConsent = false (forthcoming SDK release) — disables aggregate inclusion only, while the developer's own analytics dashboard keeps working. The current telemetryConsent = false is all-or-nothing.
Transport and auth security
- TLS everywhere. All Extentos backend connections (
api.extentos.comfor telemetry and simulator-session WebSockets) use TLS 1.2+. No plaintext channels. - Auth tokens at file mode
0600. When you link an account,~/.extentos/auth.jsonis written with owner read/write only. Other users on the machine can't read your token. - Anonymous bearer for telemetry. Telemetry uploads authenticate via the
installId(MCP-side) orappId + anonymousDeviceId(library-side). No account credentials are sent on telemetry calls. - Local bridge bound to
127.0.0.1only. The MCP server's auto-bind listener (port31337) refuses non-loopback connections. TheinstallIdit serves is not a secret — it's the same value sent toapi.extentos.comon every tool call — so loopback exposure is intentional. - Pre-GA hardening note. The current telemetry ingest scheme trusts self-reported IDs (per
TELEMETRY.mdline 129). For MVP this is acceptable — spoofed events skew aggregate fleet data, not security-sensitive. Before external GA, this hardens to one of: ingest-signed install tokens, per-request HMAC keyed on a secret baked at library init, or rate-limit-based outlier detection.
The library is open-source
Both android-library/glasses-core/ (Kotlin) and ios-library/Sources/GlassesCore/ (Swift) are MIT-licensed and source-available in the Extentos repository. Anything we claim about telemetry payloads is verifiable in code. The mcp-server/ package is also MIT and source-available — mcp-server/src/telemetry/ carries the entire ingest pipeline.
If our payload-stripping ever drifts from what's documented, the diff shows up in a public commit. This is part of the trust model: documentation can lie, source code can't.
Compliance posture
| Standard | Status |
|---|---|
| GDPR | Compatible. Lawful basis for analytics is Art. 6(1)(f) legitimate interest, documented in our LIA. No end-user PII stored. Right-to-erasure honored within 30 days regardless of retention policy. |
| CCPA | Compatible with explicit "sale" disclosure. The planned cross-vendor data product qualifies as a "sale" under CCPA when it ships. Developer-level Do-Not-Sell mechanism is ExtentosConfig.dataSharingConsent = false (forthcoming SDK release) — separate from telemetry collection. Right to know honored at request. |
| HIPAA | Not certified at MVP. Production runtime emits no Extentos traffic from RealMetaTransport, so a HIPAA-bound app shipping with telemetry-off is technically usable; a formal BAA isn't available pre-GA |
| SOC 2 | Type II on the post-launch roadmap. The architecture is designed SOC 2-compatible (audit logging, access controls, vendor management, retention policies). Once the 12-month observation period kicks off, the report becomes available under NDA to vendor data-product customers. |
| ISO 27001 | Not pursued at MVP |
For compliance-sensitive apps today: ship with ExtentosConfig.telemetryConsent = false to disable all library telemetry. Combined with the fact that RealMetaTransport doesn't talk to Extentos's backend, your shipped app emits zero traffic to us at runtime — the privacy boundary is enforced architecturally, not just by policy.
For developers who want telemetry on (for the developer dashboard) but want to opt their app's data out of vendor aggregates: set ExtentosConfig.dataSharingConsent = false. Your own dashboard analytics keep working; your data is excluded from cross-account aggregates we may sell to glasses vendors once the multi-vendor product ships. (Forthcoming SDK release; until then, full telemetry opt-out via telemetryConsent = false is the only granularity.)
Frequently asked questions
Wait — Extentos collects telemetry from my shipped app?
By default, yes — runtime metadata events (no content, no PII) flow to api.extentos.com/api/telemetry/events from your shipped app if ExtentosConfig.telemetryConsent = true (the default). Set it to false and your app emits zero Extentos network traffic. Many apps will leave it on because the developer dashboard is built on this data — you're trading runtime metadata for an analytics surface for your own app.
Will my users' voice transcripts ever leave their device?
Through Extentos? Never. Voice transcripts are app_callback inputs your code processes; Extentos's library doesn't read them, log them, or transmit them. If your AI handler sends them to your provider (Anthropic, OpenAI, etc.), that's between your app and your provider — Extentos is not in the path.
Can Extentos see what my user captured in a photo?
No. Photo bytes are app_callback inputs to your handler. Extentos transports them between the glasses and your handler but does not inspect, store, or upload them. Your handler is the only place those bytes can reach an external service, and that's a choice your code makes.
Will Extentos sell data about my app to my competitors?
When Extentos supports multiple vendors, we plan to sell aggregate cross-vendor ecosystem signals (vendor market share, capability popularity across platforms, session-hour totals across the ecosystem) to glasses vendors as market research, only as aggregates over at least 10 distinct accounts. We additionally suppress vendor-level data when fewer than 25 developers ship to that vendor — small-vendor ecosystems are protected from inadvertent disclosure. Individual-account data, your specific app's usage patterns, and anything that could identify your app or your users is never shared with third parties. These two floors are the structural guarantees against competitive leakage. This product is multi-vendor-dependent — at single-vendor scale today, no such sale takes place because each vendor already has their own platform's data via their SDK.
Developers can also opt their app out of inclusion in future vendor aggregates via ExtentosConfig.dataSharingConsent = false (forthcoming SDK release) — separate from disabling telemetry collection. Your own developer-dashboard analytics keep working; your data is excluded from cross-account aggregates.
Can my users opt out of Extentos telemetry?
End users have no direct relationship with Extentos and don't see our branding. Their opt-out is via the developer's app — if you want to give your users a toggle, gate ExtentosConfig.telemetryConsent behind a setting in your app. Or simply ship with telemetry off if your privacy posture requires it.
Is my Extentos auth token shared across machines?
No. ~/.extentos/auth.json is per-machine. To use the same account on another machine, run extentos-mcp login there. The token is stored at file mode 0600 (owner read/write only).
Does Extentos work in air-gapped or no-network environments?
The MCP-driven dev loop (code generation, validation, on-device LocalSimTransport simulation) works fully offline. The browser simulator (BrowserSimTransport) and the simulator-session features need network access to api.extentos.com. Your shipped app on real glasses (RealMetaTransport) doesn't need network access to Extentos — only between the phone and the glasses, plus whatever AI providers your app calls.
When does the developer dashboard ship?
It's on the roadmap; the data pipeline is already collecting events from MVP day-one so the dashboard is purely a backend query layer over data that already exists. Watch the changelog for actual ship dates.
What about developer source code?
Your generated code, your spec, your handler implementations, your test fixtures — none of it ever leaves your machine. The MCP server reads your project to inspect state (inspectIntegration, validateIntegration) and writes generated files, but it does not upload your code, contents, or git history anywhere.
How do I request deletion of my data under GDPR?
Email Extentos support from the email associated with your account. We run DELETE WHERE accountId = ... and acknowledge within 30 days. The indefinite-retention default does not block right-to-erasure — deletion requests are honored independent of retention policy. Aggregated rollups derived before the deletion request stay (those have no accountId attribution by construction); raw events tied to your account are removed. Anonymous events without an accountId (emitted before account linking) cannot be associated to you and are retained as aggregate-only data.
Related
- Pricing — what the free tier covers, the account-required browser simulator
- Auth — anonymous-first identity model, device-code flow, account linking
- Architecture — how telemetry fits into the broader system, what the on-device event log captures
- Changelog — track when the developer dashboard and other features ship
Pricing
Extentos is free. All 18 MCP tools, on-device simulation through Meta's Mock Device Kit, code generation, validation, and real-hardware testing on Meta Ray-Ban work with no account, no email, no payment. The only thing that requires sign-in is the browser simulator at extentos.com/s — sign in once with Google or email and minting simulator sessions becomes unlimited. Sign-in is free, no payment, no card.
Support
How to get help with Extentos — bug reports and feature requests via GitHub issues at github.com/Asgermolgaard/vibe-hardware, what to include in a bug report so it's actionable across the four components (MCP server, native libraries, backend, simulator UI), self-service diagnostics through the extentos-mcp CLI (whoami, status, getEventLog), security disclosure path, pre-1.0 response expectations, and where to read source code yourself before filing. No paid support tiers exist at launch.