Resources

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, AI prompt and response payloads, 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 collectAggregate 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 collectSpeech transcripts, photo bytes, video frames, audio samples, AI prompt and response text, app_callback payloads, spec JSON contents, toggle values, IP addresses (dropped after country derivation), stack traces, end-user PII.
What end users seeNothing 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-outThree 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.
ComplianceGDPR-friendly by construction — no end-user PII ever stored. 90-day raw retention, GDPR deletion requests honored within 30 days. SOC2 work is 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:

  1. 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 your accountId. This is genuinely valuable to developers and is why the underlying collection is broad rather than narrow.
  2. 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.
  3. Saleable ecosystem signals to glasses vendors. Aggregate market data — Ray-Ban Meta vs Oakley Meta installation share, capability mix across the developer base, session-hour totals. Sold to glasses vendors as market research, only as aggregates over at least 10 distinct accounts, never as individual-developer or individual-end-user data. This is one of Extentos's revenue lines.

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": "flow.completed",
  "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": { "triggerId": "describe_scene", "durationMs": 3125, "outcome": "normal" }
}

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.

EventWhat it carries
mcp.installedFirst run on this machine. npm version, OS, detected agent host.
mcp.consent_accepted / mcp.consent_declinedPrivacy policy version.
tool.calledEvery MCP tool invocation. toolName, durationMs, outcome.
session.createdcreateSimulatorSession invoked. Vendor, recording flag.
account.login_initiated / _completed / linked / logged_outAuth 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.

EventWhat it carries
app.initializedLibrary version, vendor, deviceModel, osVersion.
connection.opened / closedTransport type (RealMeta/BrowserSim/LocalSim), durationMs, cause (typed).
trigger.firedtriggerId, triggerType. No transcript.
flow.completedtriggerId, durationMs, outcome.
block.executedblockId, blockType, durationMs, outcome. No result payload.
callback.invokedhandlerName, durationMs, outcome. No request/response payloads.
stream.started / stoppedstreamType, durationMs. Safe subset of negotiated config (resolution, frame rate, codec, bitrate). No peer addresses, URIs, destination identifiers.
error.surfacederrorClass, errorCode, layer. No stack traces.
spec.loadedspecFingerprint (sha256 hash, no contents), triggerCount, blockCount.
toggle.changedkey, source. No values.
meter.warning_reached / exhausted_reachedAnonymous-meter lifecycle.

Notice the bold disclaimers — every event explicitly carries metadata only, never content.

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
  • app_callback input or output payloads (these may contain end-user data your AI processes)
  • AI provider responses, prompt text, tool-use traces
  • Spec JSON contents (block names, trigger phrases may be business-sensitive — only hashes and counts)
  • Toggle values, variable values, template substitution data
  • 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 to api.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 — but BrowserSimTransport only runs in config.debug == true builds during development. Shipped release builds default to RealMetaTransport, 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.

IDScopeWhen createdWhere stored
installIdPer-machine MCP installFirst npx @extentos/mcp-server run~/.extentos/install_id
accountIdPer-Extentos-accountWhen developer signs up via device-code flowBackend; cached in ~/.extentos/auth.json
appIdPer-Extentos-appSet by developer in ExtentosConfig.appId at library initCompiled into the app
anonymousDeviceIdPer-end-user-deviceFirst library init on the user's deviceApp-private storage on the user's device
userSegmentDeveloper-defined cohort labelOptional; 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 spec includes ai_call actions, the developer's app_callback handlers run the AI calls against the developer's chosen provider (Anthropic, OpenAI, Google, etc.) 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: the app_callback mechanism is a function pointer your code provides. The library invokes it; the function returns; the library moves on. There's no inspection of inputs, no logging of outputs, no proxy layer. Even if Extentos wanted to ingest the call content, the architecture doesn't expose it.

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:

SurfaceWhereWhat it disables
EXTENTOS_TELEMETRY=0 env varDeveloper's shellMCP-server-side telemetry for the current shell session. Doesn't persist across reboots.
extentos-mcp decline-privacy CLI commandWrites ~/.extentos/consentMCP-server-side telemetry permanently for this install. Survives reboots. Run accept-privacy to re-enable.
ExtentosConfig.telemetryConsent = falseDeveloper's app codeLibrary-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 classRetention
Raw telemetry events90 days
Aggregated rollups (daily / weekly / monthly per account, plus global)Indefinite
anonymousDeviceId records180 days of inactivity, then purged

GDPR deletion requests: 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; aggregated rollups derived before deletion are retained but no longer attribute to the account. Anonymous events without an accountId (i.e., from before account linking) are retained until natural expiration.

Transport and auth security

  • TLS everywhere. All Extentos backend connections (api.extentos.com for 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.json is 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) or appId + anonymousDeviceId (library-side). No account credentials are sent on telemetry calls.
  • Local bridge bound to 127.0.0.1 only. The MCP server's auto-bind listener (port 31337) refuses non-loopback connections. The installId it serves is not a secret — it's the same value sent to api.extentos.com on every tool call — so loopback exposure is intentional.
  • Pre-GA hardening note. The current telemetry ingest scheme trusts self-reported IDs (per TELEMETRY.md line 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

StandardStatus
GDPRCompatible by construction — no end-user PII stored, deletion requests honored within 30 days
CCPACompatible — same reasons
HIPAANot 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 2On the post-launch roadmap. The architecture is designed to be SOC2-compatible (audit logging, access controls, vendor management) but the formal Type II report comes after GA
ISO 27001Not 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.

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?

We sell aggregate ecosystem signals (vendor market share, capability popularity, session-hour totals) to glasses vendors as market research, only as aggregates over at least 10 distinct accounts. 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. The 10-account aggregation floor is the structural guarantee against competitive leakage.

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. Aggregated rollups derived before the deletion request stay (those have no accountId attribution); raw events tied to your account are removed.

  • Pricing — what the free tier covers, the 1000-event meter context
  • 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