extentos
Extentos MCP Server gives AI coding agents deterministic tools to build, validate, and test smart-glasses apps (Meta Ray-Ban, Android XR preview, Brilliant preview) across Android/iOS without needing hardware.
Platform & capability discovery –
getPlatformInfo,getCapabilityGuide, andgetCodeExampleexpose SDK capabilities, per-feature Kotlin/Swift call shapes, and canonical patterns (assistant loop, voice Q&A, display navigation, live transcription).Scaffolding –
generateConnectionModulegenerates the app bootstrap, connection UI placement, permissions, manifest, and platform config;getPermissionsderives exact Android/iOS/Meta-DAT permission requirements.Migration –
getMigrationGuidemaps existing Meta DAT code to Extentos primitives with an ordered cutover plan.Managed configuration – read/update connection-page theming, assistant model/voice/memory settings, project sounds, credentials status, gateway usage, and production analytics.
Integration inspection & validation –
inspectIntegrationreads the current repo state;validateIntegrationruns ~16 severity-tiered readiness checks (manifest, generated files, dependencies, permissions, bootstrap wiring, project key).Browser simulator sessions –
createSimulatorSession,getSimulatorStatus,ensureSimulatorBrowser,getEventLog,setSimVideo,setSimDevice, and session deletion enable persistent, end-to-end testing with the same SDK code on a WebSocket transport.Agent-driven E2E testing – inject voice transcripts (
injectTranscript), drive assistant turns (injectAssistantUtterance), assert tool calls (assertToolCalled), simulate camera shutter pauses (injectHardwareButton), and drive display UI viagetDisplayState/injectInput.Voice & assistant guidance –
getVoiceCommandGuidanceanalyzes wake phrases for UX/collision issues;searchDocsprovides bundled versioned documentation on assistant runtime, custom handlers, permissions, simulator lifecycle, and more.Production readiness –
getProductionChecklistandgetCredentialGuidewalk the path from simulator to real hardware, including Meta DAT credential setup and BYOK provider key storage.Credential-safe operations –
setCredentialuses a browser handoff so secrets never pass through the agent;getCredentialStatusonly reports presence/masked hints.
Supports scaffolding, validating, and simulating smart-glasses integrations in Android apps, including connection modules, permissions, manifest configuration, and simulator sessions.
Supports scaffolding, validating, and simulating smart-glasses integrations in iOS apps, including connection modules, permissions, Info.plist configuration, and simulator sessions.
Provides tools for building, validating, and testing smart-glasses apps for Meta smart glasses (Ray-Ban Meta, Oakley Meta, Meta Ray-Ban Display), including camera capture, voice triggers, live transcription, audio playback, display interaction, and browser-based simulation.
Extentos MCP Server
Give your AI coding agent the tools to build smart-glasses apps.
Extentos is an MCP (Model Context Protocol) server that lets agents like Claude Code, Cursor, and Cline add smart-glasses capabilities — camera capture, voice triggers, live transcription, audio playback — to any Android or iOS app. The tools are deterministic: discovery, scaffolding, validation, and a browser-based simulator for end-to-end testing without hardware.
Works with Meta smart glasses today (Ray-Ban Meta, Oakley Meta, Meta Ray-Ban Display), with a multi-vendor architecture by design.
This repository is the public home of @extentos/mcp-server — releases, changelog, and issue tracking. The package ships on npm.
Install
Claude Code
claude mcp add extentos -- npx -y @extentos/mcp-server@latestCursor — one click:
Cline / any MCP client
{
"mcpServers": {
"extentos": {
"command": "npx",
"args": ["-y", "@extentos/mcp-server@latest"]
}
}
}Requires Node 20+.
Related MCP server: IndieStack
What your agent can do with it
Tool group | What it does |
Discovery |
|
Scaffolding |
|
Guidance |
|
Validation |
|
Simulation |
|
Production |
|
Docs |
|
The workflow an agent typically runs: discover capabilities → scaffold the connection module → write handler code against the SDK → validate → simulate end-to-end → production checklist.
Tools
getPlatformInfo — SDK capability catalog, version/artifact info, and platform constraints
getCapabilityGuide — per-feature call shapes in Kotlin + Swift with gotchas
getCodeExample — canonical end-to-end patterns (voice Q&A, photo-describe, live transcription UI, …)
getMigrationGuide — mapping table and cutover plan from Meta DAT direct usage to Extentos
generateConnectionModule — scaffold the connection UI, manifest, and platform config into your app
getConnectionPageConfig — read the managed connection-page configuration
setConnectionPageConfig — update the managed connection-page configuration
regenerateConnectionPageFile — regenerate a managed connection-page file after config changes
adoptConnectionPageFile — bring an existing connection-page file under managed configuration
getAssistantConfig — read the managed voice-assistant configuration (model, voice, memory, wake sound)
setAssistantConfig — update the managed voice-assistant configuration
listProjectSounds — list custom sounds uploaded for the project
addProjectSound — upload a custom sound (earcons, wake sounds) to the project
shutter — trigger a camera shutter in the active simulator session
getGatewayUsage — AI-gateway usage and metering for the project
getCredentialStatus — which credentials (Meta DAT, AI provider) are configured
setCredential — store a credential for the project
getProjectAnalytics — usage analytics for the project's glasses integration
getVoiceCommandGuidance — implementation guidance for voice triggers and wake phrases
getPermissions — the exact permission set the integration needs per platform
inspectIntegration — read the current state of the integration in your repo
validateIntegration — deterministic checks of the integration (manifest, config, wiring)
createSimulatorSession — mint a browser-simulator session for end-to-end testing
ensureSimulatorBrowser — open/attach the simulator browser tab for the session
completeAuthLink — finish the device-code sign-in flow
getEventLog — read the session event log (transport, audio, camera, speak, toggle, stream, system)
injectTranscript — inject a voice transcript into the running app, as if the wearer spoke
injectAssistantUtterance — drive the voice assistant with an utterance end-to-end (real provider session)
assertToolCalled — wait for an assistant tool-call event matching name/args (agent E2E loop)
getSimulatorStatus — live session state: phase, roles, open streams, freshness, test videos
setSimVideo — pipe a test video into the simulated camera
setSimDevice — switch the simulated glasses model
getDisplayState — read the rendered display tree and interactive element ids (Ray-Ban Display)
injectInput — drive display input: select/navigate/back, like Neural Band gestures
injectHardwareButton — simulate the hardware capture button
getProductionChecklist — the path from simulator to real glasses
getCredentialGuide — how to obtain and configure Meta DAT credentials
searchDocs — search the bundled, versioned documentation topics
How it fits together
Your app depends on the native SDK:
com.extentos:glasses(Android, Maven Central) or the Swift package (iOS)Your code subscribes to capability primitives from its own handler classes —
glasses.audio.transcriptions(),glasses.camera.capturePhoto(),glasses.audio.speak()The simulator is the same app on a different substrate: WebSocket transport instead of Bluetooth, so agent-verified behavior carries to hardware
Discovery, validation, and guidance tools work anonymously. Creating browser-simulator sessions and scaffolding require a free account — the server walks the agent (and you) through a device-code sign-in when needed.
Community integrations
Independent projects that have built with and evaluated Extentos:
EgoFlow — an egocentric-video capture platform. Its
extentosbranch drives the glasses connection and live video through the Extentos Android SDK into EgoFlow's existing RTMP transport and backend, and was taken end-to-end on real Ray-Ban Meta glasses.Voice-triggered capture POC — an independent, MIT-licensed iOS proof of concept. A registered wake phrase triggers
glasses.camera.capturePhoto, driven headlessly through the browser simulator by the MCP tools; the repo has the implementation and a recording of the run.
Links
Issues & feedback
Bug reports and feedback are welcome — open an issue. The package is pre-1.0; tool surfaces may evolve between minor versions.
For security reports, see SECURITY.md — please don't open public issues for vulnerabilities.
License
Available Tools
38 toolsaddProjectSoundA
Upload a local audio file into a project's named-sound library. Pass the name app code will play it with and a path to an MP3/M4A/AAC/WAV file under 1 MB. After the next assistant start (app relaunch), every device running the app can glasses.audio.playSound(name) — and the sound appears in the dashboard's Agent section, where a human can re-point that name at a different clip with no app change. The SDK plays none of them on its own. Code registrations (audio.registerSound) win over library sounds on name collisions. GATED by the project's MCP access grant (assistant_config.sounds — default Read+Write; a permission_denied 403 means the owner restricted it). Requires a linked Extentos account (a 401 returns account_required, run extentos-mcp login). USE to provision an app's UI sounds while building it — e.g. a camera app's shutter click ({ name: "shutter", filePath: "./sounds/shutter.mp3" }). DON'T USE for the assistant's VOICE (that's setAssistantConfig) or for sounds the app should bundle locally (registerSound in app code needs no upload).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The play-by-name key, e.g. "shutter" — app code calls glasses.audio.playSound(name). | |
| filePath | Yes | Path to a local MP3/M4A/AAC/WAV file under 1 MB (relative to the working directory, or absolute). | |
| appPackage | Yes | The app's package / bundle id (project_install_id), e.g. com.example.myapp. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations exist, the description bears full responsibility. It discloses file size limit (<1 MB), allowed formats (MP3/M4A/AAC/WAV), activation timing (after next assistant start), cross-device availability, dashboard appearance, collision rules (registerSound wins), and error cases (403, 401). Missing explicit success return, but overall very transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and informative. It starts with purpose, then constraints, then usage guidelines. Every sentence adds value without being overly verbose. Could be slightly trimmed, but it earns its length. Score 4 for good efficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema and three parameters, the description covers the tool's purpose, constraints, behavioral nuances, error scenarios, and usage boundaries comprehensively. It even explains SDK behavior and dashboard appearance. Nothing essential is missing for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents each parameter. The description reinforces the meaning by giving examples and context (e.g., name is 'play-by-name key', filePath relative/absolute, appPackage is 'project_install_id'). It adds marginal extra value beyond the schema, so a score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a clear verb and resource: 'Upload a local audio file into a project's named-sound library.' It distinguishes itself from sibling tools by explicitly stating what it is for (provisioning UI sounds) and what it is not for (assistant voice, local bundle sounds), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use and when-not-to-use guidance: 'USE to provision an app's UI sounds while building it' and 'DON'T USE for the assistant's VOICE (that's setAssistantConfig) or for sounds the app should bundle locally (registerSound in app code needs no upload).' It also states prerequisites (linked Extentos account, MCP access grant).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adoptConnectionPageFileA
Adopt the committed extentos.connection-page.json UP to the dashboard/server (file → server) — the deliberate one-time seed of an existing code/file theme into the managed config. Reads the file at projectPath, validates it, and persists it (requires a linked account — run extentos-mcp login). DRIFT-PROTECTED: if the app already has a managed server config that DIFFERS from the file, it returns status: needs_confirmation with both versions and does NOT clobber — re-call with confirm: true to let the file win (or run regenerateConnectionPageFile to let the server win). Android-only for now (iOS is Phase 4). USE to seed an existing committed theme into the dashboard. DON'T USE for routine edits (author via setConnectionPageConfig / dashboard, then regenerateConnectionPageFile).
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Set true to overwrite an existing, DIFFERING server config with the committed file. Omit on the first call to get the drift check (status: needs_confirmation). | |
| platform | No | Defaults to android. iOS file-sync is Phase 4. | |
| appPackage | Yes | The app's package / bundle id (project_install_id). | |
| projectPath | Yes | Absolute path to the project root (required — reads app/src/main/assets/extentos.connection-page.json). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully covers key behaviors: drift protection (needs_confirmation flow), required login, Android-only limitation, and that it reads a specific file. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Thorough but efficient; each sentence adds value. Slightly long but front-loaded with core action. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema or annotations, the description provides complete context: prerequisites, drift flow, platform limitations, and parameter roles. Sufficient for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of parameters. Description adds value by explaining confirm's role in overwriting, platform default, and that projectPath reads a specific file. Justifies 4 due to added context beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool seeds a committed file to the server, distinguishing it from siblings like setConnectionPageConfig and regenerateConnectionPageFile by specifying use cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'USE to seed an existing committed theme' and 'DON'T USE for routine edits', providing clear when-to-use and when-not-to-use guidance, plus mentions drift protection and login requirement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assertToolCalledA
Phase 4 — wait for an assistant.tool_called event matching name (and optionally argsMatch partial-match). Re-scans the backend event log every ~200ms from a FIXED anchor until match or timeout, then returns the matched event payload directly (or errors with tool_not_called on timeout). Pass sinceCursor — the watchCursor from the injectAssistantUtterance that triggered the tool. That anchors the wait BEFORE the inject, so the triggered tool call (which the model fires 0.5-2s later) is always caught even if this call starts after the tool already fired. Without sinceCursor the call anchors at its own start ("now") and will MISS a tool that fired in the gap between your inject and this call — the dominant false-negative cause before the 2026-05-29 fix. The fixed-anchor re-scan (vs an advancing cursor) also means a late-committing event is never skipped, and the match is pure seq-comparison so it has zero clock-skew dependency. USE in the agent E2E loop right after injectAssistantUtterance. DON'T USE to inspect the full event trace (use getEventLog) or to check static tool registration (use inspectIntegration).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Exact tool name to wait for. Must match the `name` argument passed to `tool(name, description) { ... }` in the customer's glasses.assistant.start { } block. | |
| argsMatch | No | Optional top-level partial match against the tool's parsed args. All keys in argsMatch must be present in the call's args with equal scalar values; nested objects compared structurally. v1 ships top-level partial-match only — nested glob patterns deferred. Omit for any-args match. | |
| sessionId | Yes | ||
| timeoutMs | No | Max time to wait, in ms. Default 5000. Clamped to [250, 60000]. The Mock provider dispatches in <50ms so 5000 is generous; OpenAi provider dispatches in 500-2000ms post-utterance (budget 10000+ for camera/vision tools). | |
| sinceCursor | No | **Strongly recommended.** The `watchCursor` value returned by the `injectAssistantUtterance` that should trigger this tool. Anchors the wait at the point BEFORE the inject, guaranteeing the triggered tool call is caught regardless of model latency or how quickly you call assertToolCalled. Omit only when watching for a tool with no preceding inject in this same agent turn (e.g. a tool fired by a real sim-browser voice turn) — then the call anchors at "now" and only catches tools that fire after this call starts. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It describes polling every 200ms from a fixed anchor, matching logic, timeout behavior, and the fixed-anchor re-scan guarantee. It does not explicitly state read-only nature but that is inferred.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat lengthy but every sentence is informative and earned. It is front-loaded with the core purpose and structured logically. Could be slightly more concise, but no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and no output schema, the description fully covers return values (matched event payload or error), internal behavior (polling, fixed anchor), and rationale for design choices. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 80%, and description adds critical context for all parameters: name's matching semantics, argsMatch's partial top-level matching, timeoutMs defaults and provider-specific advice, and sinceCursor's role in preventing race conditions. This goes beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool waits for an 'assistant.tool_called' event matching a given name with optional argsMatch. It uses specific verbs and resources, and distinguishes itself from siblings like getEventLog and inspectIntegration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (right after injectAssistantUtterance in E2E loop) and when not to use (for full event trace or static registration). Also explains the critical sinceCursor parameter and provides guidance on timeoutMs based on providers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
completeAuthLinkA
Poll the backend until the user finishes signup at the verificationUrl, then persist the bearer token to ~/.extentos/auth.json. USE after createSimulatorSession returns status:'auth_required' AND you set autoLink:false (or the inline poll timed out). DON'T USE preemptively. Note (Bundle 10+): createSimulatorSession's autoLink arg (default true) handles this inline for you in the typical case; you only need to call completeAuthLink directly if you opted out of autoLink or the user took longer to approve than autoLinkSeconds.
| Name | Required | Description | Default |
|---|---|---|---|
| deviceCode | Yes | The `deviceCode` from createSimulatorSession's auth_required (HTTP 402) response — the opaque handle the backend correlates the developer's signup with. A stale/unknown code returns unknown_device_code (call createSimulatorSession again for a fresh one). | |
| maxWaitSeconds | No | Max seconds to keep polling for the developer to finish signup. Default 600 (also the cap). On timeout returns auth_timeout (retryable) — call again with the SAME deviceCode while it's still valid. | |
| pollIntervalSeconds | No | Seconds between backend polls. Default 5; clamped to [1, 30]. The backend may push a longer interval, which then overrides this value. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description bears full burden. It discloses persistent side effects (writing to ~/.extentos/auth.json), error conditions (unknown_device_code, auth_timeout), and the polling mechanism. Minor gap: doesn't detail behavior if called multiple times with same deviceCode after success.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is a single, well-structured paragraph. It front-loads the primary action, uses bold for important notes, and every sentence adds value. No redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, the description adequately explains the flow, expected outcomes (token persisted), and error handling. It references the relevant sibling tool createSimulatorSession, providing complete operational context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of parameters with descriptions. Description adds context on the source of deviceCode and default/clamping behaviors for maxWaitSeconds and pollIntervalSeconds, but largely reiterates schema info. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: polling the backend to complete user signup and persist a bearer token. It distinguishes itself from the sibling tool createSimulatorSession, which handles auth inline, by specifying when this tool is needed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: after createSimulatorSession returns 'auth_required' with autoLink:false or after a timeout. Also warns against preemptive use and highlights that autoLink handles it by default in bundle 10+.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
createSimulatorSessionA
Get-or-create: provision a browser-based simulator session for this project, OR return the existing saved one. The simulator hosts your customer-built app running against a Meta-DAT-shaped transport stub — glasses.audio.transcriptions(), glasses.camera.capturePhoto(), glasses.audio.speak() and every other capability primitive flow through it exactly as they would on real hardware, so the agent can dogfood a handler in a browser before a Meta DAT is paired. Persistent-simulations model: each project + platform has at most one saved sim tied to the user's account. Calling this returns that sim's existing URL if it exists (status:'resumed') instead of creating a new one. Rotating to a new sim identity is a deliberate two-step act: deleteSimulatorSession({ sessionId }) first, THEN mint again. There is no force-fresh flag, on purpose — a discarded sim leaves device registrations behind that outlive it, so a silent replace can auto-bind the next mint to an app that is already gone. First-time per project: creates the sim (status:'active'); subsequent calls in any future session return the same sim. Auto-bind (response carries autoBind:'attached'): when the dev's running app is reachable via the MCP local bridge, attaches it to the session — no rebuild needed. Otherwise URL-bake fallback (Android: buildConfigField patch; iOS: plist write). For 'resumed' responses, the URL is unchanged from last time so no rebuild/patch is needed regardless. Iteration model — DO NOT call this per change: app-code edits rebuild + reinstall and reattach automatically; the simulator URL is stable. Calling this again on the same project just returns the same sim — cheap, idempotent. First-link auto-poll: when account-linking is required, by default polls completeAuthLink internally for autoLinkSeconds (default 30) and re-mints on success. autoLink: false for CI / non-interactive contexts.
| Name | Required | Description | Default |
|---|---|---|---|
| glasses | Yes | Target glasses vendor. Canonical: 'meta'. 'meta_rayban' is a legacy alias (same vendor) kept for compatibility. 'android_xr' is EXPERIMENTAL/PREVIEW (Android XR projected glasses — no shipping hardware) and 'brilliant' is PREVIEW (Brilliant Labs Halo and Frame — the Extentos BLE transport is built on BOTH platforms and Halo is orderable, but the vendor says first units ship early August 2026, so nothing has run on a device and there is no emulator either). For both, simulator sessions CAN be minted, so an app's behaviour under that device identity is testable today; code scaffolding remains Meta-only. ⚠️ PLATFORM CONSTRAINT: 'android_xr' is Android-ONLY and minting it with platform:'ios' is REFUSED — Google's model is a projected activity, which is an Android activity, so no iOS transport can exist and simulating one would teach your app a combination no device can be. 'meta' and 'brilliant' mint on either platform. | |
| autoLink | No | When true (default), if the backend returns auth_required, this handler polls completeAuthLink internally for `autoLinkSeconds` and re-mints on success. Set false in CI / non-interactive contexts. | |
| platform | No | ||
| projectPath | No | Absolute path to the app project — the SAME value you pass to generateConnectionModule and validateIntegration. This is how a sim gets BOUND to a project: the manifest there supplies the key that makes this call get-or-create rather than mint. **Omitting it silently falls back to the process working directory**, so a call made from a directory with no extentos.manifest.json returns an UNBOUND sim that is shared across every unscaffolded directory for this account — which is how a workspace ends up with a row of unnamed, indistinguishable simulators. Pass it explicitly once the project exists. | |
| recordBinary | No | ||
| autoLinkSeconds | No | Max seconds to wait for the user to approve the verification URL when autoLink is true. Default 30. Clamped to [10, 300]. | |
| autoOpenBrowser | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly. It discloses get-or-create semantics, the one-sim-per-project model, autoBind attached vs URL-bake fallback, auto-polling of completeAuthLink with re-mint on success, and the platform constraint that android_xr is Android-only. It even warns about the unbound-sim pitfall when projectPath is omitted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with bolded section headers and each paragraph addresses a distinct concern. It is front-loaded with the core get-or-create purpose, then dives into lifecycle, identity, auto-bind, and auth. While lengthy, every sentence contributes meaningful information for a complex tool with no annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description comprehensively covers purpose, lifecycle, idempotency, auth flow, platform constraints, and pitfalls like the projectPath omission. It omits semantics for three parameters (platform, recordBinary, autoOpenBrowser) and does not describe the full return shape beyond status and autoBind, but overall it is unusually complete for an un-annotated tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 57%, and the description adds significant meaning for four of seven parameters: glasses (vendor/experimental status, platform constraint), autoLink (internal polling behavior, default), projectPath (binding semantics, fallback to cwd), and autoLinkSeconds (clamping). However, platform, recordBinary, and autoOpenBrowser are left undocumented in both schema and description, preventing a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Get-or-create' and clearly states it provisions a browser-based simulator session or returns the existing saved one. It also distinguishes itself from sibling tools like deleteSimulatorSession by explicitly explaining the two-step rotation process, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'DO NOT call this per change' and explains that app-code edits rebuild automatically, so repeated calls are unnecessary. It also instructs users to call deleteSimulatorSession before re-minting and recommends autoLink:false for CI contexts, providing clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
deleteSimulatorSessionA
Retire a simulator session on purpose. USE only when you genuinely need a NEW session identity — a different session id and URL. You almost never do. createSimulatorSession already RESUMES the saved sim for a project: same session, same URL, your app reattaches with no rebuild. That is the persistent-sim model and it is the intended way to work. DON'T USE to 'clean up' or 'start over' when something looks wrong — deleting disconnects any attached app and browser, and an app carrying a baked EXTENTOS_SESSION_URL needs a rebuild against the new one. Deleting is the FIRST HALF of a deliberate rotation: delete, THEN mint. There is no one-call force-fresh, precisely so a rotation is two explicit steps rather than a silent replace. Sim churn is what that costs you: discarded sessions leave device registrations behind that outlive them, and a later mint can auto-bind to an app that is already gone. Idempotent — deleting a session that is already gone returns alreadyGone: true rather than an error, so a retry is safe and you can still tell the two apart.
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries behavioral transparency. It discloses that deletion disconnects attached apps/browsers, that apps with baked EXTENTOS_SESSION_URL need rebuilding, that session churn leaves stale device registrations, and that the tool is idempotent returning alreadyGone: true. These are critical behavioral traits beyond the simple 'delete' semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than typical, but every sentence earns its place for a destructive tool. It front-loads the core purpose and then systematically covers usage, warnings, workflow, costs, and idempotency. The structure is logical and dense without redundancy, making the length appropriate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive tool with no annotations and no output schema, the description covers all necessary context: preconditions, consequences, workflow position, side effects, and return behavior on already-gone sessions. It explains the persistent-sim model and why one-call force-fresh doesn't exist, giving the agent a complete mental model.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one required sessionId with no description, and the description does not explicitly explain the parameter. However, the single parameter's meaning is self-evident from the tool name and context; the description reinforces that sessionId identifies the session to retire. Since it is a simple string with minLength, the lack of explicit parameter detail is not a significant gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Retire a simulator session on purpose,' providing a specific verb and resource. It clearly distinguishes this tool from createSimulatorSession by stating that delete is only for rotating to a new session identity, and explicitly contrasts the delete-and-mint flow with the resume model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use and when-not-to-use instructions: 'USE only when you genuinely need a NEW session identity' and 'DON'T USE to clean up or start over.' It names the alternative (createSimulatorSession) and explains the intended two-step rotation process, providing unambiguous decision criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ensureSimulatorBrowserA
Ensure a connected simulator browser tab for the session — opens one if needed and confirms the browser's WebSocket actually attached before returning. The browser tab is the hardware surrogate's viewport: camera + inject tools require it (setSimVideo returns browser_not_attached without it; the capture_photo / describe_scene flows the assistant runtime drives fail). Idempotent — if a browser is already connected it's a no-op (returns alreadyOpen: true); it never opens a redundant tab (the hub would reject a second live browser with role_conflict). When to call: right after createSimulatorSession before any camera-driven flow; after a backend deploy (which severs every sim WebSocket — the tab does NOT auto-reconnect); whenever the tab was closed; or any time getSimulatorStatus / a camera tool reports the browser isn't attached. How it works: checks the AUTHORITATIVE in-memory hub liveness (the same signal setSimVideo/inject enforce, so this can't disagree with them — unlike getSimulatorStatus.connectedRoles.browser, which is persisted state that can lag a dead socket ~25-50s after an unclean drop); if no browser is attached, the MCP server opens the session URL in the developer's default browser ITSELF (cross-platform — no shell command for you to run), then polls until the tab's WebSocket attaches or timeoutMs elapses. Headless / remote agents: pass autoOpen: false to get an immediate presence snapshot + the sessionUrl with NO spawn and NO wait — surface the URL to the developer to open on a machine with a display, then re-run with autoOpen:true to confirm. Returns { alreadyOpen, opened, browserConnected, browserClientId, appConnected, sessionUrl, waitedMs }; errors with browser_not_connected (carrying sessionUrl) when an auto-open didn't attach in time. DON'T USE to check whether the device APP is attached or hardware is ready — this ensures the BROWSER viewer only; use getSimulatorStatus for app/hardware state.
| Name | Required | Description | Default |
|---|---|---|---|
| autoOpen | No | When true (default): if no browser is connected the MCP server opens the session URL in the developer's default browser and polls until it attaches. When false: returns an immediate presence snapshot + sessionUrl with no spawn and no wait — for headless/remote agents that surface the URL to the developer themselves. | |
| sessionId | Yes | ||
| timeoutMs | No | Max ms to wait for the browser tab's WebSocket to attach after auto-opening. Default 20000. Clamped to [5000, 60000]. Bump it for a cold-started browser or a slow machine. Ignored when autoOpen:false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: idempotent, no redundant tab, checks authoritative hub liveness, opens browser directly, polls, handles errors, and explains autoOpen:false case for headless. It even notes that hub rejects second live browser. Comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured and front-loaded. Every sentence adds value, explaining behavior, usage, and edge cases. It could be slightly more concise but given the complexity, it earns a 4.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers return object shape, error conditions, when to call, and behavioral differences from siblings. It explains the lag in getSimulatorStatus and the authoritative hub check. For a tool with 3 params and no output schema, this is outstandingly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67% (autoOpen and timeoutMs described), and the description adds meaningful context: autoOpen:false gives immediate snapshot without spawn, timeoutMs has default and clamp range. SessionId lacks description but is required and minimal. Overall enhances understanding beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool ensures a connected simulator browser tab, opening one if needed and confirming WebSocket attachment. It specifies the resource (simulator browser tab) and action (ensure connection), and distinguishes from siblings like getSimulatorStatus which check app/hardware state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: after createSimulatorSession, after backend deploy, after tab close, or when reported not attached. It also explicitly says when NOT to use: for app/hardware state, directing to getSimulatorStatus. This is exemplary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generateConnectionModuleA
One-shot project scaffold — emits the bootstrap module that wires Extentos.create(...) into the host app, build-script changes, dependencies, permissions, and the integration manifest. Run once per project; after this lands, the agent writes its own Handler classes against the SDK primitives surfaced by getCapabilityGuide / getCodeExample. PATH IS DERIVED FROM capabilities. An audio-only footprint emits the VOICE scaffold — SDK dependency, mic permission, bootstrap; NO connection page, NO Meta account, NO App ID or Client Token, NO credentialed repository, and NO placement round trip (single call). PLATFORM NUANCE on the vendor SDK itself: on Android the voice path genuinely does not pull it (com.extentos:glasses is vendorless; only com.extentos:glasses-meta carries the DAT artifacts, which is why the split exists — Meta's Android artifacts sit behind a credentialed repo that returns 401 without a PAT). On iOS the swift-glasses package is a single umbrella and GlassesCore links MWDATCore/MWDATCamera, so the DAT SDK IS in the graph for a voice app — but Meta's iOS repo is PUBLIC, so it resolves with no account, no token and no auth. The developer-facing promise holds on both; the dependency graph differs. Splitting iOS to mirror Android is a 3.0 item (breaking for existing consumers). A footprint including camera / video / display emits the DEVICE scaffold: adds com.extentos:glasses-meta plus the Meta DAT repository, and requires the vendor credential setup. Omitting capabilities defaults to VOICE. The two-call flow below applies to the DEVICE scaffold only. Two-call flow: call once WITHOUT placement to receive status: "needs_placement" plus the question to ask the dev (where should ExtentosConnectionPage live in the app?); after the dev answers, call again WITH placement set to one of the 5 ids to receive the full scaffold (files, suggestedRendering, etc.). Existing-app detection (Android): pass projectPath so the handler reads AndroidManifest.xml and detects whether you already have an Application subclass. If yes, the emitted ExtentosBootstrap is an object (init helper) plus a manual_patch for your existing class — no clobber. If no (greenfield) OR projectPath omitted, the bootstrap is emitted as a full Application subclass and the agent sets <application android:name> accordingly. Returns files[] with action values 'create' and 'manual_patch' — see searchDocs('file_actions') for how to apply each. Pass capabilities (the SDK feature names your app uses, incl. display) so the scaffold records them in the manifest AND emits ExtentosConfig.usedCapabilities — the connection page then shows one tile per capability, lit per the connected glasses. USE as the first generation tool when scaffolding a fresh project. DON'T USE when Extentos is already installed (use inspectIntegration to read current state).
| Name | Required | Description | Default |
|---|---|---|---|
| glasses | Yes | Target glasses vendor. Canonical: 'meta'. 'meta_rayban' is a legacy alias (same vendor) kept for compatibility. 'android_xr' is EXPERIMENTAL/PREVIEW (Android XR projected glasses — no shipping hardware) and 'brilliant' is PREVIEW (Brilliant Labs Halo and Frame — the Extentos BLE transport is built on BOTH platforms and Halo is orderable, but the vendor says first units ship early August 2026, so nothing has run on a device and there is no emulator either). For both, simulator sessions CAN be minted, so an app's behaviour under that device identity is testable today; code scaffolding remains Meta-only. ⚠️ PLATFORM CONSTRAINT: 'android_xr' is Android-ONLY and minting it with platform:'ios' is REFUSED — Google's model is a projected activity, which is an Android activity, so no iOS transport can exist and simulating one would teach your app a combination no device can be. 'meta' and 'brilliant' mint on either platform. | |
| platform | Yes | ||
| placement | No | Where ExtentosConnectionPage should live in the app. Omit on the first call to receive the placement question; pass on the second call after the dev has chosen. | |
| appPackage | Yes | The Extentos project identity (reverse-DNS). This is what the SDK reports as the app id for telemetry, agent config, and sounds — it is NOT required to equal the store bundle id / applicationId (the scaffold bakes it as config.appId, decoupled). For a NEW app, use your bundle id. For an EXISTING app already shipped to both stores with DIFFERENT locked bundle ids, pass the SAME appPackage on BOTH platforms — both then share ONE Extentos project (one agent config, one sound set, per-platform analytics) regardless of the store ids. | |
| projectPath | No | Absolute path to the project root. Android-only: when provided, the handler reads `app/src/main/AndroidManifest.xml` to detect an existing Application subclass and emit an init-helper bootstrap (object) + a manual_patch for that class — avoiding the Application clobber. Optional; absent → assume greenfield and emit the Application-subclass form. | |
| capabilities | No | The SDK capabilities your app uses (feature names from getPlatformInfo — e.g. ["capture_photo", "transcription_incremental", "speak", "display"]). The scaffold records them in the integration manifest AND emits ExtentosConfig.usedCapabilities (Android) so the connection page shows one tile per capability — lit when the connected glasses provide it, dimmed when they don't (e.g. Display on a non-display Ray-Ban). Omit → no capability tiles and no derived camera/mic/speaker permissions (declare nothing, show nothing). Re-run with an updated set to change it (the bootstrap regenerates). Both platforms emit ExtentosConfig.usedCapabilities — Kotlin setOf(CapabilityKind.X, …) / Swift [.camera, …]. | |
| libraryVersion | No | ||
| responseFormat | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility for behavioral disclosure. It thoroughly describes the two-call flow, the existing-app detection logic (object + manual_patch vs full Application subclass), the return format (files[] with action values 'create' and 'manual_patch'), and platform-specific dependency differences (Android vs iOS). It also discloses that re-running with updated capabilities regenerates the bootstrap and mentions the 'no clobber' promise.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-organized with bold section headers and clear separation of concerns. It front-loads the core purpose, then covers usage, platform nuances, and edge cases. While every section earns its place, there is some redundancy (e.g., the emphasis on capabilities-derived path appears twice) and the platform nuance section is quite dense, so a slight tightening could improve conciseness without losing value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (8 parameters, multiple platforms, two-call flow, existing-app detection) and the absence of an output schema, the description leaves little uncovered. It explains the return value, references searchDocs('file_actions') for handling actions, covers platform-specific behaviors, and handles edge cases like greenfield vs existing app. It is exceptionally complete for a tool of this scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds substantial meaning beyond the input schema. It explains how `capabilities` drives the scaffold type (VOICE vs DEVICE) and the derived path, how `placement` is used across calls, and how `projectPath` triggers existing-app detection. It also clarifies that `appPackage` is decoupled from store bundle ids, which is not apparent in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'One-shot project scaffold — emits the bootstrap module that wires `Extentos.create(...)` into the host app', which clearly states the verb, resource, and output. It goes on to detail what is emitted (build-script changes, dependencies, permissions, integration manifest), and distinguishes itself from siblings by explicitly positioning it as the first generation tool and contrasting with inspectIntegration for already-installed projects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('USE as the first generation tool when scaffolding a fresh project') and when not to ('DON'T USE when Extentos is already installed'), even naming the alternative tool (inspectIntegration). It also provides detailed instructions on the two-call flow (without and with placement) and gives concrete guidance on how to handle existing apps via projectPath.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getAssistantConfigA
Read the per-project "Agent" (assistant) settings the dashboard holds for an app — the OpenAI Realtime model, the voice, the memory (compaction) model, and the within-session memory mode — plus the catalog of valid options for each, the dashboard defaults, and the SDK hard defaults. Returns { managed, config, options, dashboardDefaults, sdkHardDefaults }: managed=true means a dashboard row exists and drives these at session start; managed=false means none is set, so the SDK uses its hard defaults unless the app code sets values. Runtime precedence is code-set > dashboard config > SDK hard defaults; this tool sees the dashboard layer only. Account-scoped + read-only — requires a linked Extentos account (run extentos-mcp login; a 401 returns account_required). Consumed by BOTH SDKs at assistant start (iOS re-fetches on app relaunch — no rebuild needed). USE to see what models/voice a project is configured with, or to discover the valid option ids before recommending a change. DON'T USE to change them (use setAssistantConfig; the dashboard's Agent section is the human-facing editor) or for usage/cost (use getGatewayUsage).
| Name | Required | Description | Default |
|---|---|---|---|
| appPackage | Yes | The app's package / bundle id (project_install_id), e.g. com.example.myapp. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses that the tool is account-scoped and read-only, requires login (401 returns account_required), and explains the managed flag and runtime precedence. Also mentions SDK consumption behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is comprehensive but not overly verbose. It is structured logically with clear sections. A minor deduction for length, but every sentence contributes value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description thoroughly explains the return structure (managed, config, options, etc.), auth requirements, runtime precedence, and consumption by SDKs. Covers all essential context for a read-only tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (appPackage) with full schema coverage (100%). The description reiterates the parameter but adds minimal new semantic meaning beyond the schema description. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads per-project assistant settings (models, voice, memory) and returns a structured response. It distinguishes from sibling tools like setAssistantConfig (change) and getGatewayUsage (usage/cost).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: to view current config or discover valid option ids before recommending a change. Also explicitly states when not to use: for changing config (use setAssistantConfig) or for usage/cost (use getGatewayUsage). Includes auth prerequisite.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getCapabilityGuideA
Per-feature SDK usage guide — minimal Kotlin + Swift snippet + gotchas + which getCodeExample patterns exercise the feature. Pairs with getPlatformInfo (which lists feature names and categories) by adding the actual idiom for using each feature. Covers: lower-level primitives (capture_photo / capture_video / record_audio / transcription_incremental / speak / video_frames / audio_chunks / connection_state / toggles / voice_command); and the assistant runtime (assistant_runtime as the umbrella, assistant_start, assistant_tool, assistant_provider_openai) — the canonical voice-AI surface. For voice-assistant work on new apps, start with assistant_runtime for the overview then drill into the individual primitives. USE when you know which feature you need but don't know the canonical call shape, or when you're hitting a confusing failure (the gotchas typically cover it). DON'T USE for a complete compositional pattern (use getCodeExample) or for capability discovery (use getPlatformInfo).
| Name | Required | Description | Default |
|---|---|---|---|
| feature | Yes | Feature name from getPlatformInfo.features[].name. Includes the cross-cutting SDK surfaces (connection_state, toggles) and the wake-phrase + media capabilities. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so description carries full burden. It discloses return content (minimal Kotlin + Swift snippet, gotchas, related getCodeExample patterns) and limitations ('minimal', 'typically cover it'). It doesn't explicitly state read-only behavior, but the guide nature implies non-mutation, and no hidden side effects are indicated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a clear purpose, followed by relationship to siblings, coverage list, and usage guidance. The 'Covers' feature list partially duplicates the schema enum, but adds semantic grouping that aids understanding. The USE/DON'T USE sections are succinct and effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description fully explains return content and boundaries. It covers what the tool does, when to use it, when not to, and how it relates to siblings. For a lookup guide with one parameter, the description is comprehensive and complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (enum + description referencing getPlatformInfo.features[].name). Description adds value by semantically grouping feature types (lower-level primitives vs assistant runtime) and advising to start with 'assistant_runtime' for voice-assistant apps, which helps parameter selection beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly defines the tool as a 'Per-feature SDK usage guide' with Kotlin/Swift snippets, gotchas, and related code patterns. It distinguishes from siblings by stating it adds 'the actual idiom' for feature usage, while getPlatformInfo only lists names/categories and getCodeExample provides full patterns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear USE conditions ('when you know which feature you need but don't know the canonical call shape, or when you're hitting a confusing failure') and explicitly names alternatives for DON'T USE cases (getCodeExample for compositional patterns, getPlatformInfo for capability discovery).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getCodeExampleA
Reference library — retrieve a complete SDK code example (Kotlin + Swift) for a use case. For voice-assistant work on any new app, start with assistant_agent_loop — the Phase 4 glasses.assistant.start { tool(name, description) { body -> ToolResult } } API where the model owns wake detection + turn taking + intent parsing + confirmation speech and the customer only writes tool bodies that act on app state. The provider abstraction covers OpenAI Realtime, xAI Grok, and Google Gemini Live (Gemini from SDK 1.8.0+) — the model id picks the vendor. The example pairs the customer code with the agent-driven E2E loop (injectAssistantUtterance → assertToolCalled) that verifies it without humans. For the dedicated agent-side test workflow (explicit two-step wake, multi-tool sweep, four-channel verification: event log + adb logcat + screencap + library state; real-OpenAi capable since iter5.2): agent_driven_e2e_full_loop. For the glasses-display two-view navigation pattern (browse ⇄ detail on the Ray-Ban Display, Neural-Band select + assistant tools driving one state machine): display_browse_detail. Other patterns still ship for apps that need fine-grained control: voice_qa_assistant (manual glasses.voice.onPhrase wake + glasses.audio.recordDiscrete + customer-side AnthropicClient — the pre-Phase-3 composition), barge_in_speak (manual TTS cancel on user interrupt), photo_describe_voice (wake → photo → vision LLM → speak), live_transcription_ui (transcripts into Compose/SwiftUI state), voice_notes (wake → record → persist), connection_page_setup (the minimum bootstrap wiring), byok_anthropic (an Anthropic HTTP client the CUSTOMER'S OWN handler code calls with the customer's own key — used by voice_qa_assistant / photo_describe_voice. It has nothing to do with the assistant runtime, which always runs on the Extentos managed gateway with no key of any kind), agent_test_loop (the legacy three-surface verification recipe — for Phase 4 use agent_driven_e2e_full_loop). USE when you're about to write handler code and want the canonical shape to peel from, OR when you want the agent test driver that asserts the handler works end-to-end. DON'T USE for capability discovery (use getPlatformInfo) or per-feature minimal usage (use getCapabilityGuide).
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | Which compositional pattern to fetch. Each returns full Kotlin + Swift code, an explanation, gotchas, and the SDK features it exercises. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. It clearly states what the tool returns ('full Kotlin + Swift code, an explanation, gotchas, and the SDK features it exercises') and clarifies a key potential misperception about byok_anthropic (not related to the assistant runtime). It does not cover rate limits or auth, but this is a reference retrieval tool with no mutation, so the transparency level is strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but the tool exposes 13 distinct patterns that each require explanation. The opening sentence is clear and purposeful, and the bulk organizes usage recommendations by bolded alternatives. While it could benefit from a bullet list, the density is justified and front-loaded with the most important direction ('start with assistant_agent_loop').
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description discloses return contents and maps every pattern to its intended use context. It even explains that the pattern affects the example's code shape and verification approach, and covers when not to use the tool. The description is effectively a complete usage guide for the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema covers the single `pattern` parameter with an enum, the description provides deep semantics for nearly every enum value, explaining what each pattern is for, when to use it, and how it relates to others. This goes far beyond the schema's tiny one-line description, making the parameter choices much more meaningful.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Reference library — retrieve a complete SDK code example (Kotlin + Swift) for a use case', providing a specific verb and resource. It immediately names recommended sibling patterns (assistant_agent_loop, agent_driven_e2e_full_loop) and distinguishes them from fine-grained alternatives, clearly differentiating this tool from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is given: 'USE when you're about to write handler code...' and 'DON'T USE for capability discovery (use getPlatformInfo) or per-feature minimal usage (use getCapabilityGuide)'. It also explains when to choose each pattern relative to alternatives (e.g., 'For the dedicated agent-side test workflow... agent_driven_e2e_full_loop').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getConnectionPageConfigA
Read the per-project ExtentosConnectionPage config (theming tokens + section visibility) the dashboard/server holds for an app. Returns { managed, config }: managed=true means the dashboard/server is the SINGLE source of truth (the SDK applies server.overlay(defaults) at render time) and the committed extentos.connection-page.json should mirror it; managed=false means UNMANAGED (committed file → code ExtentosTheme → built-in defaults). Read-only. USE to inspect what the dashboard currently drives, or before regenerateConnectionPageFile. DON'T USE to change it (use setConnectionPageConfig).
| Name | Required | Description | Default |
|---|---|---|---|
| appPackage | Yes | The app's package / bundle id (project_install_id), e.g. com.example.myapp. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses the tool is read-only, explains the managed/unmanaged behavior and its implications for source of truth, and describes the relationship with regenerateConnectionPageFile. No annotations provided, so the description carries the burden and does well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections and uses bold for emphasis. It is slightly verbose but each sentence adds value. Could be slightly more concise, but still effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given one parameter and no output schema, the description fully covers the tool's purpose, return shape, and behavioral implications. It also relates to sibling tools, making it complete for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter appPackage has a clear schema description (minLength, example). The tool description does not add extra semantics beyond what the schema provides. Schema coverage is 100%, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads the per-project ExtentosConnectionPage config, specifies the return structure ({ managed, config }), and explains the managed flag. It distinguishes from sibling tools like setConnectionPageConfig and regenerateConnectionPageFile.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use (inspect dashboard-driven config or before regenerateConnectionPageFile) and when not to use (to change, use setConnectionPageConfig). Provides clear usage context and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getCredentialGuideA
Return step-by-step credential setup for the Meta DAT build identity plus each BYOK AI provider the app integrates. Returns { metaCredentials, serviceCredentials, keyStorage, summary }: metaCredentials = { required, requiredScope: 'real_hardware_only', scopeNote, steps[], configChange: { file, keys[], example, note? } } — the requiredScope / scopeNote say Meta DAT creds are needed ONLY for builds on real Ray-Ban Meta hardware; sim/emulator dev works without them, so DON'T lead the developer through Meta's developer-portal registration until the hardware milestone. serviceCredentials = one entry per BYOK service { service, forHandlers[], steps[], codeExample }. keyStorage = platform-specific { preferredPath, fallbackPath, doNotDo[], notes[] } secure-storage guidance. Cross-links: getProductionChecklist for where these steps sit in the ship sequence, getCredentialStatus / setCredential for the account-vaulted path (secrets pasted in the dashboard, never through the agent). USE when wiring a new BYOK provider or graduating from simulator to real hardware. DON'T USE during the simulator-only dev loop (Meta DAT creds aren't needed there).
| Name | Required | Description | Default |
|---|---|---|---|
| handlers | No | Optional list of handler names. When provided, each provider guide labels which handlers it's for by matching name patterns (vision/translate/gemini/etc.). | |
| platform | Yes | ||
| services | No | BYOK providers the app integrates — one per integration. OPTIONAL: omit (or pass []) for the Meta-DAT-only guide (a no-BYOK app needn't invent a provider). Order doesn't matter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite no annotations, the description fully discloses behavior: it is a read-only guide that returns structured credential setup info. It reveals that Meta DAT credentials are only needed for real hardware, not simulator. The return structure is detailed (metaCredentials, serviceCredentials, etc.) with no hidden side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the main purpose. It is somewhat lengthy but every sentence adds value. Could be slightly more concise, but overall efficient for the amount of detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a guide tool: no output schema exists, but the return structure is fully detailed. It also provides usage context, cross-links, and platform-specific guidance. All relevant aspects are covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, and the description adds meaning beyond the schema: it explains that omitting services returns a Meta-DAT-only guide, and clarifies handler matching by name patterns. The platform parameter is not described in schema or description beyond being required, but context is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns step-by-step credential setup for Meta DAT build identity and BYOK providers. It specifies the verb 'return' and the resource 'credential setup', distinguishing it from sibling tools like getCredentialStatus/setCredential by noting they are for the account-vaulted path.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'when wiring a new BYOK provider or graduating from simulator to real hardware.' Also states when not to use: 'DON'T USE during the simulator-only dev loop.' Provides cross-links to related tools for context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getCredentialStatusA
Read whether a project's Meta DAT build identity is set — plus a MASKED hint and when it was updated. Returns { credentials: { metaDat: { set, appId, clientTokenHint, teamId, urlScheme, updatedAt } } }. There is NO provider-key entry — the assistant always runs on the Extentos managed gateway and there is no key to supply or check. SECRETS ARE NEVER EXPOSED — only presence + a masked hint; the encrypted value is never read or decrypted. Account-scoped — requires a linked Extentos account (a 401 returns account_required, run extentos-mcp login). GATED by the project's Credentials access grant (default Read+Write; a permission_denied (403) means it was set to Off). USE to check whether a project still needs an API key before recommending setup, or to confirm a key landed after setCredential. DON'T USE to read a secret value (impossible by design) — to ADD one, use setCredential.
| Name | Required | Description | Default |
|---|---|---|---|
| appPackage | Yes | The app's package / bundle id (project_install_id). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses read-only nature, that secrets are never exposed, account-scoping requiring linked Extentos account, and permission gating (Credentials access grant). Details error responses (401, 403) for authentication and authorization failures. No contradictions with annotations (none provided).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is front-loaded with core functionality and return shape, then adds important caveats and usage guidance. While slightly verbose, every sentence provides value. Could be marginally tighter but still well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, the description covers return shape, error conditions, authentication requirements, permission model, and usage context. It is fully self-contained and provides all necessary information for an agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already describes the single required parameter 'appPackage' as 'The app\'s package / bundle id (project_install_id).' The description does not add additional parameter-level information beyond what the schema provides, but schema coverage is 100% so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool reads whether a project's Meta DAT build identity is set, plus a masked hint and update time. Specifies the return structure. Distinguishes from siblings by explicitly stating not to use for reading secret values and directs to setCredential for adding.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use (check before recommending setup, confirm after setCredential) and when not to use (never to read a secret value). Provides alternative tool (setCredential) for adding credentials.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getDisplayStateA
Read what's currently rendered on the simulated glasses DISPLAY (track 5 — the native glasses.display.* capability). Returns the DisplayNode tree the app most recently rendered via glasses.display.show { column { text(); button(...) } } (or shown: false after glasses.display.clear() / before any show), the flat list of selectable node ids (button ids + clickable container ids), the node count, and the root kind. This is how the agent verifies what's on the glasses screen without pixels, and discovers which ids it can drive with injectInput. Source is the live in-memory hub snapshot (the latest show frame), so it's exact + immediate — no event-log redaction. Pairs with injectInput to close the agent-driven E2E loop for display flows: createSimulatorSession → (app calls display.show) → getDisplayState (read the tree + ids) → injectInput({ action: 'select', targetId }) → the dev's onClick runs → getDisplayState again to see the re-render. USE to confirm a display rendered, read its structure, or find selectable ids before injectInput. DON'T USE for the display event history (use getEventLog(filter: 'display')) or non-display session state (use getSimulatorStatus).
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries full burden. It discloses that it returns DisplayNode tree, selectable node ids, node count, root kind, and explains the source is live in-memory hub snapshot, exact and immediate. This is thorough for a read-only operation, though it could mention what happens if session does not exist or if display has never been shown.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed and well-structured, with clear sections covering purpose, output, source, and usage flow. It is somewhat long but every sentence adds value. Could be slightly more concise, but overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (no output schema, one parameter), the description covers output (DisplayNode tree, selectable ids, etc.), usage context, and pairing with injectInput. It lacks parameter description but is otherwise complete for the agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has one required parameter (sessionId) with 0% schema description coverage. The description does not explain what sessionId is or how to obtain it. Given the lack of coverage, the description should at least describe the parameter's purpose, but it does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it reads the currently rendered display on simulated glasses, specifying the track (track 5) and native capability. It distinguishes from siblings by mentioning pairs with injectInput and not for event history (getEventLog) or non-display state (getSimulatorStatus).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance on when to use: to confirm a display rendered, read structure, or find selectable ids before injectInput. Also clearly states what not to use for: display event history (use getEventLog) or non-display session state (use getSimulatorStatus). Provides a usage flow with createSimulatorSession, getDisplayState, injectInput, getDisplayState again.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getEventLogA
Fetch structured event trace inside a simulator session. Primary debugging tool for why is my handler not seeing what I expect — transcripts not arriving, photo capture failing, toggle changes not propagating, speak getting cut off, connection dropping, display not rendering. Events are grouped into six chips (errors / voice / camera / display / lifecycle / custom) — one chip per event, with errors absorbing every severity≥warn row regardless of modality. To see e.g. voice activity plus voice errors, fetch the chips separately and union them. USE to diagnose which capability primitive is misbehaving. DON'T USE for static configuration checking (use validateIntegration) or for live session phase (use getSimulatorStatus). Scope: captures the simulator's WebSocket relay — transport + SDK primitives (audio, camera, speak, toggles, voice triggers, runtime events). Customer-side direct-HTTP calls (BYOK Anthropic / OpenAI / Gemini / etc.) traverse api..com from the customer's app, NOT the simulator relay — invisible by default. Surface BYOK calls in the event log by wrapping them in glasses.observability.aiCall(label) { ... } — the wrapper emits ai_call_start and ai_call_end frames with timing + success/error metadata. These land under the 'custom' chip — the dedicated 'ai' chip was retired 2026-07-25 after never carrying an event in production. Without the wrapper, BYOK failures show as silent gaps (e.g. capture_photo + photo_result + speak with 3 unexplained seconds between) — those failures still need logcat / OSLog. Use the wrapper for any AI call that's part of your debug story; leave it off for true fire-and-forget background calls. Live watch: pass follow: true to block until new events land instead of returning an empty snapshot, and carry the returned cursor between calls — loop the pair to tail the log in real time (e.g. to follow a multi-turn AI conversation the developer built into the app, reacting to each speak as it happens). See getCodeExample('agent_test_loop').
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| cursor | No | Opaque keyset cursor from a prior getEventLog response. Pass it back to fetch ONLY events newer than the last batch — no duplicates, no gaps, even for events that share a millisecond timestamp. Omit it to read from the start of the log. The cursor is the agent's bookmark: capture one BEFORE injectTranscript, then watch forward from it so nothing that lands between inject and read is missed. | |
| filter | No | Chip to filter the event stream by. 'all' (default) returns every event. 'errors' returns severity≥warn events across all modalities. 'voice' / 'camera' / 'display' cover hardware/integration capabilities (severity=info only — failures land under 'errors'). 'display' covers the native glasses display capability — `display_show` (a tree was rendered, with node count + root kind), `display_navigate` (focus moved), `display_select` (a node's onClick fired — driven by injectInput or the sim gesture panel), `display_back`, `display_error`; pair it with getDisplayState to verify display flows. 'voice' includes mic/STT (`stt_transcript`, `stt_partial`), TTS (`speak`, `speak_completed`, `tts_audio_chunk`), AND **Phase 4 assistant runtime events** (`Assistant` lifecycle — session started/ended, user/assistant spoke, tool called/result, reconnected — emitted by `glasses.assistant.start(provider) { tool(...) { ... } }`; in the sim, `injectAssistantUtterance` drives a turn). Assistant errors are promoted to 'errors' severity automatically. (The earlier Phase 3 `glasses.conversation.*` runtime was REMOVED — it does not exist on current Android; do not look for `conversation.*` events.) `ai_*` events from `glasses.observability.aiCall(label) { ... }` land under 'custom' (the dedicated 'ai' chip was retired 2026-07-25 — it never carried an event in production). Wrap BYOK calls to see start/end + duration in the timeline; without the wrapper those calls are invisible to the relay entirely. 'lifecycle' covers connection / session / pairing / hardware / runtime state. 'custom' is the open-world catch-all for app-emitted event types the platform did not anticipate. | |
| follow | No | When true, turns this call into a live watch: if no events are newer than `cursor`, the call BLOCKS until something happens (or `timeoutMs` elapses) instead of returning an empty snapshot. Returns the moment activity lands. Run it in a loop — capture the returned `cursor`, react to `events`, call again — to tail the log in real time. This is the optimal way to follow an unfolding flow (e.g. a multi-turn AI conversation in the app): the agent sees whatever happened next without having to guess the event type in advance. The response adds `followed: true`, `timedOut`, and `waitedMs`. A `timedOut: true` result is normal (no activity yet) — not an error; re-call with the same cursor to keep watching. | |
| sessionId | Yes | ||
| timeoutMs | No | Max time (ms) a `follow` call blocks waiting for new events. Clamped to [1000, 60000]; default 15000. Ignored unless `follow` is true. | |
| redactBinary | No | ||
| responseFormat | No | ||
| collapseRepeats | No | When true (default), consecutive payload-identical events (same layer/severity/type/message/details — timestamps excluded) collapse into ONE entry carrying `repeat: N` and `lastTimestamp`, so a runaway emitter can't fill the response with one line repeated hundreds of times. `totalEvents` and the summary count RAW events. Pass false for the uncollapsed rows. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden—and it delivers. It discloses the WebSocket relay scope, BYOK invisibility and the observability wrapper, the chip grouping behavior including errors absorbing severity≥warn events, the follow blocking behavior, cursor bookmark semantics, and retired event types (ai chip, Phase 3 conversation runtime). No contradictions with annotations (none present).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured and front-loaded with the core purpose. It stays scannable via USE/DON'T USE callouts, bolded scope, and short paragraphs. Some duplication exists between the description and the filter schema's description (e.g., ai chip retirement), but overall each sentence adds substantive guidance; it could be tightened, yet complexity justifies the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description covers the full context an agent needs: event grouping and meanings, severity rules, BYOK visibility and wrapper, follow/cursor tailing with timing details, and a reference to getCodeExample('agent_test_loop'). It also addresses edge cases like combined voice and voice errors requiring separate fetches, making it complete for its complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 56%, and the description adds meaningful semantics beyond the schema for the most important parameters: filter, follow, cursor, and collapseRepeats. It explains chip meanings, event types, and the live-watch loop. However, some parameters like redactBinary and responseFormat are not explained in the description or schema, leaving a small gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Fetch structured event trace inside a simulator session' and immediately states its primary diagnostic purpose. It also distinguishes this tool from siblings by explicitly naming validateIntegration and getSimulatorStatus as alternative tools for other use cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use and when-not-to-use guidance: 'USE to diagnose which capability primitive is misbehaving. DON'T USE for static configuration checking (use validateIntegration) or for live session phase (use getSimulatorStatus).' It also covers the subtle BYOK wrapper case and live-follow pattern, giving clear context for selecting this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getGatewayUsageA
Read account-scoped managed-AI-gateway usage + exact cost for a project over a recent window. Returns { window, totals, byModel, creditBalanceUsd }: totals carry token counts, response count, and the exact list-price USD cost from the billing ledger; byModel breaks the same down per model (biggest first). METADATA ONLY — token counts and cost, never transcripts/audio/prompt content. Only managed-gateway + dashboard-vault-BYOK sessions are metered; a code-direct setOpenaiApiKey() bypass goes straight to OpenAI and is invisible here. Account-scoped + read-only — requires a linked Extentos account (a 401 returns account_required, run extentos-mcp login). USE to report spend, spot the dominant model, or ground a model-choice recommendation in real cost (pair with getAssistantConfig). DON'T USE for live per-event traces (use getEventLog) or to change config (use setAssistantConfig).
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days. Default 30. Clamped to [1, 365]. Bucketing auto-scales (hour ≤2d, day ≤92d, week ≤183d, else month). | |
| appPackage | Yes | The app's package / bundle id (project_install_id). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses read-only nature, required linked account (401 error), metadata-only (no transcripts/audio), and what is/isn't metered. Since no annotations exist, description fully covers behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with main purpose, returns format explained, then constraints and usage guidelines. Slightly long but every sentence adds new information; no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Explains return object shape (window, totals, byModel, creditBalanceUsd), error case (401), and pairing suggestion. No output schema needed; missing only minor details like rate limits or pagination (likely not needed).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% but description adds value: default value for 'days' (30), bucketing auto-scaling rules, clarifies 'appPackage' as project_install_id. Exceeds baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states verb 'Read' and resource 'account-scoped managed-AI-gateway usage + exact cost'. Distinguishes from siblings by specifying managed-gateway scope and contrasting with direct OpenAI calls.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides USE cases (report spend, dominant model, cost-driven recommendation) and DON'T USE cases (live traces → getEventLog, config changes → setAssistantConfig), with sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getMigrationGuideA
The entry point for a developer who ALREADY built their app against raw Meta DAT (the Device Access Toolkit / Wearables SDK) and wants to move onto the Extentos SDK. Extentos's production transport calls the SAME DAT underneath, so migration is a call-site swap, not a rewrite. Returns a map KEYED BY THE DAT SYMBOL you already have (Wearables.createSession, photoDataPublisher, addStream, Display, raw CaptureError, …) → the Extentos primitive that replaces it (glasses.connection, glasses.camera.capturePhoto, glasses.camera.videoFrames, glasses.display.show, ExtentosResult, …), plus a one-line 'what changes' per area and an ordered cutover plan. It re-embeds NO code — each mapping names the Extentos feature, so you drill into getCapabilityGuide(feature) for the Kotlin/Swift idiom and getCodeExample(pattern) for a full composition. The plan orchestrates the tools that already exist: generateConnectionModule (replaces Wearables.initialize/configure + your registration UI) → getPermissions (replaces hand-mapped manifest/plist + Meta scopes) → per-call-site swaps → validateIntegration → createSimulatorSession. Scope: FULL CUTOVER, not coexistence — running raw DAT and Extentos side-by-side in one process is not supported today (the DeviceSession is a single-owner handle), and the response says so. USE when a project already imports com.meta.wearable.dat.* (Android) / MWDATCore/MWDATCamera (iOS) and you're adopting Extentos. DON'T USE for a greenfield project with no existing DAT code (start at getPlatformInfo → generateConnectionModule).
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | Which SDK the app is migrating FROM. Optional — defaults to `meta_dat` (the only wrapper we map from today; the enum is forward-compatible for other vendors/wrappers as they land). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that migration is a call-site swap, not a rewrite; returns a map keyed by DAT symbol; re-embeds no code; provides an ordered cutover plan orchestrating other tools; clearly states that coexistence is not supported. No annotations exist, so the description carries full burden and meets it thoroughly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence adds value; it is front-loaded with purpose and structured with clear sections. Slightly verbose but justified by the complexity of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema or annotations, the description fully covers the return value structure, the migration plan, links to other tools, and scope limitations. It is complete for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (single parameter with enum and description). The description adds value by explaining the default behavior (defaults to meta_dat) and forward-compatibility of the enum, going beyond the schema's documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is the entry point for developers migrating from Meta DAT to Extentos SDK, specifying the output (mapping from DAT symbol to Extentos primitive) and scope (full cutover, not coexistence). It distinguishes from sibling tools like getCapabilityGuide and getCodeExample by positioning itself as the starting point.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use (project with existing DAT imports) and when not to use (greenfield project with no DAT code), and provides an alternative starting point (getPlatformInfo → generateConnectionModule) for the latter case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getPermissionsA
Derive the Android permissions, iOS Info.plist keys, Meta DAT scopes, AND the runtime grants a list of SDK capabilities requires. Returns { android, ios, metaDat, runtimeGrants, summary }. runtimeGrants is the half that is not a manifest entry — the OS grants nothing until the app ASKS at runtime, and applying every returned plist key still ships a mute app if you skip it. Each entry says who asks (requestedBy: app | sdk), the exact call when it is yours, and what silence looks like when nobody does. On iOS the microphone is the app's job and its absence is invisible: no prompt, no error, no transcripts, every voice command dead on hardware while working perfectly in the simulator — ALWAYS all three platform blocks regardless of the platform argument (which only frames the one-line summary; it does NOT filter the response). android = { permissions[], manifestEntries[] (ready-to-paste lines), foregroundService: { required, types[], declaration, devInstructions }, notificationListener: { required, declaration, devInstructions }, minimumSdk, compileSdk, targetSdk }. ios = { plistKeys: [{ key, value, reason }] }. metaDat = { scopes[], registrationRequired, registrationSteps[] }. Capabilities that need no platform permission (e.g. speak, connection_state, earcon) contribute nothing and are accepted silently — they never error. USE after deciding which features (capture_photo, transcription_incremental, voice_command, …) the app integrates. DON'T USE for capability discovery (use getPlatformInfo).
| Name | Required | Description | Default |
|---|---|---|---|
| platform | Yes | Selects how the one-line `summary` is phrased (Android vs iOS framing). Required — but does NOT filter the response: the android, ios, and metaDat blocks are all returned either way. | |
| capabilities | Yes | Capability names from getPlatformInfo.features[].name. e.g. ['capture_photo', 'transcription_incremental', 'voice_command']. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden and delivers richly. It discloses critical behavioral traits: runtimeGrants is 'the half that is not a manifest entry,' the platform argument 'does NOT filter the response,' and capabilities needing no permission 'are accepted silently — they never error.' It even explains the consequence of skipping runtime grants (mute app).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with backticked field names and explicit blocks. Every sentence earns its place given the complexity of the tool. It is front-loaded with the core purpose before diving into details. Slightly dense, but appropriate for the information density required.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description fully enumerates the return structure: '{ android, ios, metaDat, runtimeGrants, summary }' with subfields. It also covers edge cases (silent acceptance, platform non-filtering, runtime grant implications). For a tool with this complexity, the description leaves no critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value beyond the schema by giving concrete capability examples and explaining that the platform argument only shapes the summary line, not the response. However, the schema already covers the core semantics of both parameters, so the extra information is enhancement rather than necessity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Derive the Android permissions, iOS Info.plist keys, Meta DAT scopes, AND the runtime grants a list of SDK capabilities requires,' which is a specific verb+resource statement. It explicitly distinguishes from sibling tools by ending with 'DON'T USE for capability discovery (use getPlatformInfo).'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'USE after deciding which features (capture_photo, transcription_incremental, voice_command, …) the app integrates.' It also provides a clear exclusion: 'DON'T USE for capability discovery (use getPlatformInfo).' This is a model of usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getPlatformInfoA
Return static platform metadata: library version + the list of SDK capabilities the glasses expose. TWO INTEGRATION PATHS — decide which one BEFORE scaffolding. Voice apps (assistant, transcriptions, recordDiscrete, speak, audio streams) reach the glasses through the phone's own Bluetooth audio routing: NO vendor SDK, NO vendor credentials, NO connection page, NO pairing flow — and the complete agent runtime (turn-taking, barge-in, tool calling, local + cloud models) works there. Only CAMERA and DISPLAY require a vendor integration. If the developer hasn't said they need camera or display, they are on the voice path — do NOT send them through Meta account setup, a Developer Center registration, or a GitHub PAT they don't need. Phase 4 assistant runtime (glasses.assistant.start(provider) { tool(name, description) { body -> ToolResult } }) is the canonical voice-assistant API — the model owns wake/turn-taking/intent/confirmation, the customer writes tool bodies that act on app state. Lower-level primitives are still surfaced for fine-grained control (audio.transcriptions, audio.recordDiscrete, audio.speak, audio.audioChunks, camera.capturePhoto, camera.videoFrames, toggles, connection.state, …). The right first call for any new task — primes the agent on what primitives are available before writing handler code. Default response is COMPACT — capability names and categories only — keeping the typical first-call cost ~2KB. Per-feature call shape + idiom + gotchas comes from getCapabilityGuide(feature); full compositional patterns (assistant_agent_loop for the canonical glasses.assistant.start loop; voice_qa_assistant for the manual composition) from getCodeExample(pattern); conceptual docs from searchDocs(topic: 'assistant_runtime') for the assistant surface, or searchDocs(topic: 'voice_integration') for the lower-level primitives. Pass expand: ['capabilities.full'] for the machine-readable catalog with params/payload/requires/constraints. glasses is optional — defaults to meta; android_xr is also supported (preview) and meta_rayban is accepted as a legacy alias. Note the vendorless baseline needs no value here at all — voice apps run without a vendor; pass it explicitly for forward compatibility once additional vendors land. Already built on raw Meta DAT? Call getMigrationGuide — it maps your existing DAT symbols to Extentos primitives and gives an ordered cutover plan, rather than starting from scratch. USE at session start before scaffolding or writing handler code. DON'T USE for what's installed in the project (use inspectIntegration).
| Name | Required | Description | Default |
|---|---|---|---|
| expand | No | Optional opt-in expansions on top of the compact default. 'schema' = full JSON Schema document. 'capabilities.full' = per-primitive params/payload/requires/constraints. 'capabilities.advanced' = droppedPrimitives + futurePrimitives (informational only). | |
| glasses | No | Target glasses vendor. Canonical: 'meta'. 'meta_rayban' is a legacy alias (same vendor) kept for compatibility. 'android_xr' is EXPERIMENTAL/PREVIEW (Android XR projected glasses — no shipping hardware) and 'brilliant' is PREVIEW (Brilliant Labs Halo and Frame — the Extentos BLE transport is built on BOTH platforms and Halo is orderable, but the vendor says first units ship early August 2026, so nothing has run on a device and there is no emulator either). For both, simulator sessions CAN be minted, so an app's behaviour under that device identity is testable today; code scaffolding remains Meta-only. ⚠️ PLATFORM CONSTRAINT: 'android_xr' is Android-ONLY and minting it with platform:'ios' is REFUSED — Google's model is a projected activity, which is an Android activity, so no iOS transport can exist and simulating one would teach your app a combination no device can be. 'meta' and 'brilliant' mint on either platform. | |
| sections | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses that the default response is 'COMPACT' (~2KB), that expand can opt into 'capabilities.full', that glasses is optional defaulting to meta, and that android_xr is preview. It doesn't explicitly say 'read-only' but 'return static metadata' implies no side effects. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with bold key phrases, bullets, and clear USE/DON'T USE markers. It front-loads the core purpose and then packs decision-relevant context. While it could be trimmed, each sentence earns its place by steering the agent toward correct tool selection and parameter choices.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description provides a complete picture: default response shape, expansion options, vendor defaults, integration path guidance, and pointers to related tools for feature guides, code examples, and docs. It leaves little ambiguity about what to expect and how to proceed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67% (2/3 params described). The description adds significant nuance beyond the schema for glasses ('defaults to meta', 'android_xr preview', 'meta_rayban legacy', 'vendorless baseline needs no value') and for expand (references capabilities.full and compact default). The sections parameter is not explicitly described, but its values ('version', 'capabilities') are implied by the opening line about library version and capability list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear, specific statement: 'Return static platform metadata: library version + the list of SDK capabilities the glasses expose.' This uses a specific verb and resource, and immediately distinguishes itself from sibling tools by positioning itself as the 'right first call for any new task' while pointing to getCapabilityGuide, getCodeExample, and searchDocs for deeper detail.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Extremely explicit usage guidance is provided: 'USE at session start before scaffolding or writing handler code' and 'DON'T USE for what's installed in the project (use inspectIntegration).' It also describes the two integration paths (voice vs camera/display), tells the developer which path to choose based on requirements, and names alternatives like getMigrationGuide for existing Meta DAT users.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getProductionChecklistA
Return a personalized production-readiness checklist based on the SDK capabilities the app uses, the handlers it declares, and the BYOK services it integrates. Returns { ready, steps, summary }: ready is true when no step has status 'needed'; each steps[] entry is { category, description, status: 'done' | 'needed' | 'optional', details, fix?, requiredScopes?, affectedHandlers?, codeChange?: { file, hint } }. Steps are conditional — streams add a foreground-service step, voice/camera/audio add a real-hardware-verification step, and declared BYOK services (or the Phase 3 conversation runtime) add an API-keys step. Pass projectPath so the Meta-account and credential-swap steps read the project's real build state and report 'done' instead of 'needed'. status is guidance, not a measurement: ONLY the vendor-setup and credential steps are derived from your project, and only with projectPath — every other step stays 'needed' however much of the work you have actually completed, so identical output before and after doing the work is expected rather than a bug. ready accordingly means 'nothing left on this list', NOT 'Extentos verified your app'; for checks that genuinely inspect the project use validateIntegration. Cross-links: getPermissions for the exact permission set the Permissions-Audit step describes, getCredentialGuide for the per-provider key setup the API-Keys step needs, validateIntegration for the structural pre-test gate. USE when going to production. DON'T USE during development.
| Name | Required | Description | Default |
|---|---|---|---|
| handlers | No | Names of the handlers the app declares (labels the API Keys step's affectedHandlers). Does NOT by itself trigger the API Keys step — declare `services` for that. | |
| platform | Yes | ||
| services | No | BYOK provider names the app actually integrates (e.g. ["anthropic", "openai"]). The trigger for the API Keys step — a DAT-native app (capture_photo + speak) or a Phase 4 managed-gateway app declares none and skips it. | |
| projectPath | No | Absolute (or cwd-relative) path to the project root. Optional — when given, the Meta-Developer-Account and Credential-Swap steps read the real build state (Android extentos_meta_credentials.xml / iOS Info.plist MWDAT dict) to mark themselves 'done' vs 'needed'. Omit → every step is assumed not-yet-done. | |
| capabilities | Yes | Capability names from getPlatformInfo.features[].name. Drives the streams / hardware-verify / permissions-audit steps. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full transparency burden. It fully discloses that 'status is guidance, not a measurement', that 'ready means nothing left on this list, NOT Extentos verified your app', and explains which steps are project-derived. It also clarifies that identical output before and after doing work is expected. However, it does not mention rate limits or potential performance implications of calling the tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is comprehensive but somewhat lengthy. It is front-loaded with the return structure and purpose, then dives into conditional behavior. Every sentence adds value, but the extensive detail could be streamlined slightly without losing clarity. The use of bold and cross-references is helpful for structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 5 parameters (2 required), no output schema, and no annotations, the description covers behavioral expectations, return format, conditional logic, and limitations well. It could be improved by noting output size or performance considerations, but overall it is sufficiently complete for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 80%, meaning most parameters are already described in the schema. The description adds value by explaining the behavioral interactions between parameters (e.g., 'handlers' labels the API Keys step but does not trigger it alone; 'services' is the trigger). It also gives context on how 'projectPath' affects step status. The description does not detail the enum values for 'platform' beyond what the schema provides, but the added semantic ties between parameters are significant.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description specifies the tool returns a personalized production-readiness checklist based on SDK capabilities, handlers, and BYOK services. It clearly distinguishes the verb 'return' and resource 'checklist', and the cross-links to siblings like 'getPermissions' and 'validateIntegration' help differentiate its purpose from those tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states 'USE when going to production. DON'T USE during development.' It also provides cross-links and conditions (e.g., 'for checks that genuinely inspect the project use validateIntegration'), offering clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getProjectAnalyticsA
Read a project's PRODUCTION analytics — aggregate telemetry from the app's shipped (App Store / Play Store) installs over a recent window. Returns { window, totals: { events, activeInstalls }, byEvent, byDay, byVendor, byPlatform, hasData }. METADATA ONLY — event counts + active installs, NEVER transcripts/content/PII. Reads the prod-attested telemetry warehouse (the same data the dashboard Analytics page shows), so it is EMPTY until the app ships to a store and sends prod-attested events — dev/sideload telemetry is a separate tier and not included (use getEventLog for the live sim/dev event stream). Account-scoped + OWNERSHIP-CHECKED (you can only read your own projects; a 403 not_owner means your account has no data for that package) and GATED by the project's Analytics access grant (default Read; a permission_denied (403) means it was set to Off). A 401 returns account_required (run extentos-mcp login). USE to report a shipped app's real-world usage/adoption. DON'T USE for gateway spend (use getGatewayUsage) or live dev events (use getEventLog).
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Look-back window in days. Default 30. Clamped to [1, 365]. | |
| appPackage | Yes | The app's package / bundle id (project_install_id). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavioral traits: it's read-only ('METADATA ONLY'), never returns transcripts or PII, reads from prod-attested telemetry warehouse, and explains auth/ownership checks (403 errors) and setup (401 -> run login). No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single solid paragraph, dense but not overly long. Key information is front-loaded (what it does, what it returns). Could benefit from bullet points for readability, but still efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but the description enumerates the return fields (window, totals, byEvent, etc.), explains data source and emptiness condition, covers error responses (403, 401) and prerequisites, and guides against misuse. Very complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline 3. The description adds meaning beyond schema by explaining the default and range for 'days' (clamped [1,365]), calling 'appPackage' a 'bundle id', and describing the return shape which the schema doesn't cover.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it reads production analytics for a project, specifying the verb 'Read', the resource 'project's PRODUCTION analytics', and the scope 'aggregate telemetry from ... shipped installs'. It distinguishes itself from sibling tools like getEventLog and getGatewayUsage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use ('report a shipped app's real-world usage/adoption') and when NOT to use ('DON'T USE for gateway spend (use getGatewayUsage) or live dev events (use getEventLog)'), providing clear alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getSimulatorStatusA
Read a live simulator session's current state — phase (active/paused/closed), hardware-ready, attached roles (app + browser), and the testVideos list available to drive setSimVideo (defaults bundled with the platform plus any MP4s uploaded for this project on the simulator page). Also returns a freshness advisory — each role's connectedAt plus the staleness rule — so you can catch the #1 silent failure in the test loop: driving a connection that went STALE after a code change (rebuilt/reinstalled the app → relaunch it so it's the fresh build; pushed a deploy → it severed the sim WebSockets, so re-ensure the browser). Session-level snapshot only. Does NOT report which capability streams are open — it never did: activeStreams/lastEventTimestamp existed but were never populated by anything (zero of 251 production sessions), so they were removed in 0.11.55 rather than left reporting 0 while streams ran. To see whether a subscription is live, read the event log (getEventLog) or your own app's state. USE during testing to confirm the session is healthy, the app role has attached, that a connection isn't stale after a change, or to discover which test videos you can pipe into capture_photo/capture_video. DON'T USE for event traces (use getEventLog).
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden. It discloses that the tool does NOT report active streams, explains why fields were removed, and describes the freshness advisory. This is thorough and honest about limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is informative but verbose (around 150 words). It front-loads the main purpose, but contains detailed explanations that could be shortened or moved to separate documentation. It earns its sentences but lacks conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description thoroughly explains the return value (phase, hardware-ready, roles, testVideos, freshness advisory) and what it does not return. It is complete for an agent to understand what information the tool provides.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, and the tool description does not explicitly describe the sessionId parameter beyond context. While the parameter is simple and inferable from the tool purpose, the description misses an opportunity to add explicit meaning, such as format or source.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a clear verb-resource structure ('Read a live simulator session's current state') and lists specific return fields. It explicitly distinguishes from siblings like getEventLog, helping the agent select the right tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: 'USE during testing to confirm...' and 'DON'T USE for event traces (use getEventLog)'. It also explains when to check for stale connections, giving clear context for appropriate use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getVoiceCommandGuidanceA
Analyze proposed voice phrases for UX issues (length, homophones, digit-usage, Meta wake-word collision, ambiguity with existing phrases) before wiring them into a wake trigger. Returns { results, generalGuidance, summary }: results is one entry per input phrase — { phrase, issues: [{ severity: 'error' | 'warning' | 'info', rule, message }], suggestions: [], collisions: [] } — where collisions lists exact-duplicate matches and issues carries per-rule findings (rules: too_short, homophone_risk, digit_usage, punctuation, collision, disambiguation, meta_wake_word_overlap, match_mode_hint). Only collision and meta_wake_word_overlap are error-severity (fix before wiring); everything else is advisory. generalGuidance is cross-phrase advice; summary is a one-line rollup. Applies equally to glasses.voice.onPhrase(phrase) { ... } registrations and direct glasses.audio.transcriptions() consumers — the issues this catches are the same regardless of which API surface dispatches the handler. USE before adding new phrase-match conditions to ANY voice-driven handler. DON'T USE for general voice docs (use searchDocs topic 'voice_integration').
| Name | Required | Description | Default |
|---|---|---|---|
| phrases | Yes | The proposed wake / trigger phrases to analyze (at least one). Each is scored against every rule — e.g. ['take a photo', 'start recording']. | |
| existingPhrases | No | Phrases already wired into the app. Optional — when given, the analyzer also flags exact-duplicate collisions and shared-prefix ambiguity between the new `phrases` and these already-registered ones. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so exceptionally. It details the return structure (`{ results, generalGuidance, summary }`), the shape of `results` entries, the list of rules, severity levels (`error` vs `warning`/`info`), and which specific issues are error-level. It also discloses that behavior is identical regardless of the API surface used, adding meaningful context beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence is dense with essential information. It is front-loaded with the primary purpose, then systematically covers return type, rule details, API applicability, and usage guidance. There is no filler or redundancy; the structure makes it easy to parse despite the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool returns a complex nested result with no output schema, but the description fully compensates by detailing the entire return structure, including per-phrase issue objects, rule names, and severity semantics. It also covers usage context, exclusions, and alternatives, making the description self-sufficient for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers 100% of parameters with descriptions, so the baseline is 3. The description adds extra semantic value by explaining how `existingPhrases` influences behavior (flagging exact-duplicate collisions and shared-prefix ambiguity) and by describing the output structure that depends on those parameters. This goes beyond simple schema repetition, justifying a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Analyze') and resource ('proposed voice phrases'), with a defined goal ('for UX issues') and a list of concrete rules. It distinguishes itself from siblings by explicitly naming `searchDocs` as the alternative for general voice docs, making it clear what this tool is for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use ('USE before adding new phrase-match conditions to ANY voice-driven handler'), when-not-to-use ('DON'T USE for general voice docs'), and points to the alternative tool (`use searchDocs topic 'voice_integration'`). It also clarifies applicability across two API surfaces, leaving no ambiguity about the intended invocation context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
injectAssistantUtteranceA
Phase 4 — drive an assistant turn from outside the live session for agent-driven E2E tests of glasses.assistant.start { tool(...) { ... } }. As of iter5.2 (2026-05-27) the text: path works for BOTH the Mock provider and the real OpenAi Realtime provider — same MCP call, provider-appropriate routing: (a) OpenAi (default in production apps) — injected as a synthetic user turn via conversation.item.create + response.create on the live Realtime WebSocket. Drives REAL model behavior with full conversation context + tool routing decisions; costs real tokens (~$0.005/turn); takes 500-2000ms for the model to respond + dispatch tool. (b) Mock — word-overlap-matches against registered tool descriptions + dispatches synchronously. Sub-ms, deterministic, $0. The library filters inject frames to source: "assistant_inject" only, so browser-mic STT transcripts (already flowing via the PCM audio path) are NOT double-injected. Wake first if Dormant. This handler does NOT auto-wake — if the session is Dormant (silence-timeout, fresh session, post-end_conversation), the library's injectUserTurn silently no-ops because connectionRef is null + the inject is dropped. Drive the wake faithfully via injectTranscript({ text: "<your wake phrase>" }), wait for assistant.session_started in getEventLog, THEN inject. This mirrors what a real user does on real hardware: phrase, wait, command. (The iter5.3 autoWake convenience was shipped + reverted in 0.1.4 — it collapsed the explicit two-step into one call, hiding the wake step and racing with onWake greeting hooks.) audioWavBase64 path is DEFERRED to v1.1 (needs Rust core changes) — handler returns not_implemented if passed. Returns watchCursor — a seq cursor captured immediately before the inject; pass it straight into assertToolCalled({ sinceCursor }) so the assertion anchors BEFORE this inject and never misses the tool call it triggers (the model fires the tool 0.5-2s later, often after your assertToolCalled call has already started). USE in the agent E2E loop: createSimulatorSession → injectTranscript("") → (wait for session_started) → const r = injectAssistantUtterance({ text: "..." }) → assertToolCalled({ name: "...", sinceCursor: r.watchCursor }) → getEventLog(types:['assistant.*']) → cross-verify via adb logcat + screencap. DON'T USE for Phase 3 glasses.conversation.onWake { listen / speak } flows — that's still injectTranscript's domain.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Utterance text the agent wants the assistant to react to. Routed differently per provider, but always via the same `stt_transcript`/`source: "assistant_inject"` frame: (a) **OpenAi provider (iter5.2)** — injected as a synthetic user turn via `conversation.item.create` + `response.create` on the live Realtime WebSocket. The model decides which tool to call based on its full instructions + the user message. ~$0.005/turn, 500-2000ms latency. Use for real-provider verification without needing real audio or human-in-loop. (b) **Mock provider** — word-overlap-matches against each registered tool's description (case-insensitive, tokens ≥ 3 chars, first match wins). Sub-ms, $0. Write tool descriptions so the keywords your test utterance contains overlap, e.g. "Take a photo with the glasses camera" matches text "take a photo". **Mock tool args are an empty object (F-75):** the Mock matches the tool by DESCRIPTION but does not extract arguments from the utterance — it dispatches with `{}`, so a tool whose args type has REQUIRED fields throws MissingFieldException under Mock injection. Make Mock-testable tools' args optional (nullable / defaulted) or parse them from the utterance text in the tool body; validate required-typed-arg tools against the real OpenAi provider, which fills args from the model. | |
| sessionId | Yes | ||
| audioWavBase64 | No | DEFERRED to v1.1 — passing this field returns `not_implemented`. The intended path: base64-encoded WAV (mono i16 LE PCM; rate matched to the live audio path at implementation time); library decodes and feeds through audio_chunks Flow to the active real provider. Needs a Rust core extension that Sprint 1's machine-split deliberately avoids. For end-to-end real-provider validation in the meantime, run the OpenAi provider session with a real mic source (sim browser tab mic, or real glasses). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full burden. It thoroughly discloses provider routing (OpenAi vs Mock), costs, latency, mock argument behavior (empty object), deferred audioWavBase64, wake requirement (no auto-wake), and return value (watchCursor). This is comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very long and detailed, which impacts conciseness. However, it is well-structured with bold headers, bullet points, and code-like steps. It front-loads the purpose and usage, but the length may hinder quick scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the absence of output schema, and moderate schema coverage, the description is exceptionally complete. It covers purpose, usage, behavioral nuances, parameter details, return value, dependencies, and exclusions. The example usage pattern ties it all together.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67%, so baseline is 3. The description adds significant meaning: for `text`, it explains provider-specific routing and mock matching; for `audioWavBase64`, it clarifies deferred status and intended path; for `sessionId`, it implies use from `createSimulatorSession`. The description compensates well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'drive an assistant turn from outside the live session for agent-driven E2E tests'. It specifies the verb (inject) and resource (assistant utterance), and distinguishes it from sibling `injectTranscript` by mentioning Phase 4 vs Phase 3.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage instructions: 'USE in the agent E2E loop: createSimulatorSession → injectTranscript → ... → injectAssistantUtterance → assertToolCalled' and 'DON'T USE for Phase 3 glasses.conversation.onWake flows — that's still injectTranscript's domain'. It also explains the wake requirement and how to use with `assertToolCalled`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
injectHardwareButtonA
Press the simulated glasses' hardware CAPTURE BUTTON (the right-temple controls) — the agent's way to exercise the wearer's hardware privacy gestures with no human and no hardware. Tap on a LIVE camera stream pauses it; a second tap resumes. While paused, every stream-needing capture (capturePhoto — both mechanisms —, captureVideo, videoFrames) fails with CaptureError.StreamPaused carrying the actionable "tap the right temple to resume" message, and a capture_denied row lands in getEventLog(filter: 'errors') — the same behavior a wearer's temple tap produces on real glasses, because it IS the same shared gate. Hold STOPS the stream (camera_stream_closed): on real glasses the hold stops the whole device session — the connection drops and the SDK auto-recovers over ~3-5s; the sim closes the stream and deliberately skips the connection blip (a surfaced substrate delta) — the next frame-grab photo / video / videoFrames use re-arms it. The stream-state transitions land as camera_stream_opened / camera_stream_paused / camera_stream_resumed / camera_stream_closed under filter 'camera', and the sim page's capture LED tracks them (lit = streaming, dark = paused/closed); videoFrames delivery halts while paused and dies on close. A gesture with NO live stream is invisible to the app (hardware-faithful — it falls through to Meta's first-party capture, which DAT apps never see): arm the stream first. Mirrors the sim page's Hardware-buttons panel — same hub path, identical downstream. Typical loop: createSimulatorSession → ensureSimulatorBrowser → setSimVideo → (app takes a photo — stream arms) → injectHardwareButton (pause) → drive a capture → getEventLog(filter: 'errors') shows capture_denied → injectHardwareButton (resume) → capture succeeds. USE to test paused/stopped-camera handling end-to-end. DON'T USE for display input (injectInput), voice (injectTranscript), or hardware alerts like thermal/hinges (those inject via the sim page).
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | The press gesture. 'tap' = pause/resume toggle (StreamState PAUSED; no app-callable resume). 'hold' = stop the stream (on hardware the whole device session stops and the SDK auto-recovers; in the sim the stream closes and the next camera use re-arms it). This is the complete gesture set the glasses' capture button produces for third-party streams. Defaults to 'tap'. | |
| button | No | Which hardware button to press. 'capture' (the right-temple capture button) only — the one button whose effect DAT surfaces to third-party apps. Defaults to 'capture'. | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description fully covers behavioral traits. It details the effects of tap vs hold, stream state transitions, error handling, differences from real hardware, and visual cues (LED). This is comprehensive transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured and front-loaded. Every sentence adds value, though some redundancy could be trimmed. However, the detail is justified given the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a tool with 3 parameters and no output schema. It covers input, behavior, side effects, error handling, and typical usage. No missing context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds significant meaning beyond the schema. It explains default values for action and button, the complete gesture set, and provides a typical usage loop. Schema coverage is 67%, but the description compensates fully with rich context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: pressing the simulated glasses' hardware capture button. It distinguishes this from sibling tools like injectInput and injectTranscript by specifying it's for hardware gestures, not display input or voice.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidelines are provided: 'USE to test paused/stopped-camera handling end-to-end. DON'T USE for display input (injectInput), voice (injectTranscript), or hardware alerts.' Also includes a typical loop example, making it very clear when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
injectInputA
Drive the simulated glasses' DISPLAY input — the agent's way to "click" the display with no human and no hardware (track 5). Three actions: select (+ targetId) fires that node's onClick, running the developer's handler exactly as a Neural-Band index-pinch would on real glasses — THE action that closes the display E2E loop; navigate (+ optional targetId) moves the focus highlight (to a specific id, or the next selectable node when omitted); back emits a back gesture. The frame is delivered to the simulator browser tab (the display surrogate that owns the rendered tree + focus), which routes the selection back to the app — so an agent-injected select and a human clicking the sim's gesture panel are identical downstream (selection flows browser → backend → app, mirroring real hardware). Requires the simulator browser tab connected — the display only exists while the browser renders it; call ensureSimulatorBrowser({ sessionId }) first or this returns browser_not_connected. Discover targetId values from getDisplayState.interactiveIds. Typical loop: createSimulatorSession → ensureSimulatorBrowser → (app shows a display) → getDisplayState → injectInput({ action: 'select', targetId: 'end-run' }) → getEventLog(filter: 'display') shows display_select then the re-render (display_show). Mirrors injectTranscript (voice) / setSimVideo (camera) for the display capability. USE to exercise display button handlers + navigation end-to-end. DON'T USE for voice flows (injectTranscript / injectAssistantUtterance) or to read display state (getDisplayState).
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | 'select' fires the target (or focused) node's onClick — pass targetId (from getDisplayState.interactiveIds) for a deterministic click. 'navigate' moves the focus highlight to targetId, or to the next selectable node when targetId is omitted. 'back' emits a back gesture (an event; the dev owns 'views' via successive show() calls). | |
| targetId | No | The node id to target. For 'select', the button/container id whose onClick should fire (strongly recommended — get it from getDisplayState.interactiveIds; omit to select the currently-focused node). For 'navigate', the id to focus (omit to advance to the next focusable). Ignored for 'back'. | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully bears the burden. It details each action's effect (select fires onClick, navigate moves focus, back emits back gesture) and the downstream flow mirroring real hardware. Error conditions (browser_not_connected) and relationships to other capabilities are also disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is lengthy but well-structured with bolded action names and a bullet-like layout. It front-loads the core purpose and packs necessary details. Minor redundancy exists, but every sentence serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers prerequisites, typical loop, error conditions, and relationships to other tools. It provides enough context for an agent to use this complex tool correctly without an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 67%, and the description adds significant value beyond the schema: it explains where to get targetId values, the effect of omitting it for navigate, and the role of sessionId in the typical loop. However, sessionId itself is not elaborately described.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: driving simulated glasses display input as an agent's way to 'click' the display. It names three specific actions (select, navigate, back) and distinguishes itself from sibling tools like injectTranscript and setSimVideo.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is provided: 'USE to exercise display button handlers + navigation end-to-end. DON'T USE for voice flows... or to read display state.' It also gives a prerequisite (call ensureSimulatorBrowser first) and a typical loop, making when-to-use and when-not-to-use very clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
injectTranscriptA
Inject a synthetic STT transcript into a live simulator session, the same way the simulator browser tab's click-to-fire chips do. Closes the agent-driven end-to-end test loop: after createSimulatorSession returns and your app attaches, call this with the wake phrase text to drive your voice handler — no human in the loop. Frame travels through the same hub path as a real browser click, so handler dispatch + event-log entries (visible via getEventLog) are identical. Drives the glasses.voice.onPhrase matcher: a wake-phrase match dispatches the handler exactly as a real utterance would. USE for automated voice-flow validation (createSimulatorSession → injectTranscript → getEventLog). DON'T USE for static validation (use validateIntegration) or capability discovery (use getPlatformInfo). See getCodeExample(pattern: 'agent_driven_e2e_full_loop') for the full agent-driven recipe.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The transcript text to inject. For wake-phrase tests, pass the exact phrase your onPhrase / transcriptions matcher expects (case-insensitive substring match — "start recording" matches "please start recording now"). | |
| isFinal | No | When true (default for type=stt_transcript), the frame is a final transcript that fires onPhrase matchers. When false, it's a partial — most matchers wait for finals, but the simulator UI + live-captions consumers see both. | |
| partial | No | Convenience: when true, send as stt_partial (a not-yet-final transcript). Sets isFinal=false by default. Use for testing live-captions UI that consumes partials. | |
| sessionId | Yes | ||
| confidence | No | STT confidence value (0-1). Defaults to 0.99 to match the manual_trigger semantics the simulator's click-to-fire uses. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: it follows the same hub path as real browser clicks, produces identical handler dispatch and event-log entries, triggers the glasses.voice.onPhrase matcher, and clarifies final vs. partial transcript semantics, giving agents a complete mental model.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized: starts with the core purpose, then explains the mechanism, usage pattern, exclusions, and adds a pointer to an example—every sentence contributes value without redundancy, making it dense but efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 5 parameters, no annotations, and no output schema, the description is comprehensive: it covers when and how to use, what happens during execution (handler dispatch and event-log entries), and how to verify via getEventLog, leaving no critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 80%, but the description adds significant semantic context: it explains the wake-phrase matching behavior, case-insensitive substring matching, the purpose of isFinal/partial for testing live-captions, and the confidence default matching manual_trigger, all of which enrich the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action: injecting a synthetic STT transcript into a live simulator session, and explicitly distinguishes from siblings by contrasting with validateIntegration and getPlatformInfo, as well as referencing related tools like createSimulatorSession and getEventLog.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit USE/DON'T USE guidance, specifying when to use injectTranscript (automated voice-flow validation) and when not to (static validation via validateIntegration, capability discovery via getPlatformInfo), plus a reference to getCodeExample for a full recipe.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspectIntegrationA
Read-only snapshot of the current Extentos integration at a project path. Returns { found, manifest, generatedFilesStatus, dependency, drift, connectionPageConfig, gaps, summary }. found: false is NOT an error — when no extentos.manifest.json exists the call still succeeds, returning empty sub-objects plus a gaps remediation string that tells you to run generateConnectionModule. When found: true: manifest is the parsed extentos.manifest.json; generatedFilesStatus is per-file { path, exists, hasMarker, hashMatch }; dependency is { found, coordinate, file } for the Gradle/SPM dependency; drift is { fileDrift: [{ path, reason: 'missing' | 'marker_absent' | 'hash_mismatch' }], dependencyDrift: boolean }; connectionPageConfig is the committed connection-page snapshot (or null); gaps is an array of human-readable remediation strings; summary is a one-line rollup. USE before validateIntegration or for a 'what's wired so far?' read. DON'T USE for correctness checking / a pre-test gate (use validateIntegration — it severity-tiers the same surface and adds ~15 checks).
| Name | Required | Description | Default |
|---|---|---|---|
| projectPath | No | Absolute (or cwd-relative) path to the project root holding extentos.manifest.json. Optional — defaults to the MCP server's current working directory (process.cwd()); pass it explicitly whenever the project isn't the cwd. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that `found: false` is not an error, explains the behavior in that case (returns empty sub-objects and a `gaps` remediation string), and details all return fields. It also states read-only nature, leaving no hidden behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a concise opening sentence followed by a detailed breakdown using backticks and bold. It is slightly long but every sentence adds value. Could be slightly tightened, but very effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description compensates fully by enumerating all return fields and their sub-fields with behavior. It covers all relevant scenarios (found vs not found), making the tool's complete behavior transparent. No detail is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (projectPath). The description adds meaningful context beyond the schema: explains it's optional, defaults to cwd, and advises when to pass it explicitly. This covers syntax and usage intent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb-resource phrase: 'Read-only snapshot of the current Extentos integration at a project path.' It names the return structure, distinguishes from sibling validateIntegration by providing explicit usage guidance, and leaves no ambiguity about the tool's purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('USE before validateIntegration or for a 'what's wired so far?' read') and when NOT to use ('DON'T USE for correctness checking / a pre-test gate'), and names the alternative (validateIntegration) with a brief rationale. This provides clear decision criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listProjectSoundsA
List a project's named-sound library — the sounds uploaded in the dashboard's Agent section or via addProjectSound. Returns { sounds: [{ id, name, url, createdAt }] }. Devices download + register the library at assistant start; app code plays any of them with glasses.audio.playSound(name). The SDK plays none of them on its own — every sound fires because app code asked for it. GATED by the project's MCP access grant (assistant_config.sounds — default Read+Write; a permission_denied 403 means the owner restricted it). Requires a linked Extentos account (a 401 returns account_required, run extentos-mcp login). USE to see which sound names app code can play, or before adding a sound to avoid a duplicate name. DON'T USE to add sounds (use addProjectSound).
| Name | Required | Description | Default |
|---|---|---|---|
| appPackage | Yes | The app's package / bundle id (project_install_id), e.g. com.example.myapp. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the return format, the fact that the SDK does not automatically play sounds, the gating and permission errors (403, 401), and the auth requirement. It could be more explicit about being a read-only operation with no side effects, but it is largely transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is relatively long but every sentence provides value. It is structured: purpose, return format, behavioral context, gating/auth, usage guidance. It is front-loaded with purpose. Could be slightly more concise, but still well-organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no output schema, the description fully explains the return structure, behavioral details, prerequisites, error conditions, and usage context. It also distinguishes from relevant sibling tools. Completely sufficient for an agent to decide when and how to use this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (one parameter). The description does not add new meaning beyond the schema's description of `appPackage`. Baseline is 3, and the description meets that without adding further parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List a project's named-sound library' with a specific verb and resource. It explicitly distinguishes from the sibling tool addProjectSound by stating 'DON'T USE to add sounds (use addProjectSound).'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: 'USE to see which sound names app code can play, or before adding a sound to avoid a duplicate name. DON'T USE to add sounds (use addProjectSound).' It also mentions prerequisites like a linked Extentos account and access grant permissions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
regenerateConnectionPageFileA
Regenerate the committed extentos.connection-page.json FROM the dashboard/server config (file ← server) — the generated mirror that makes the dashboard's tokens real in the repo and lets the app theme correctly offline. Returns file: { path, content } for you to write (it carries a generated _comment marker — do not hand-edit; edits belong in the dashboard). If the project is UNMANAGED (no server config) there is nothing to mirror. Pass projectPath to get a drift note when an existing committed file would be overwritten. Android-only for now (iOS file-sync is Phase 4). USE after setConnectionPageConfig / dashboard edits to sync the repo. DON'T USE to push local edits up (use adoptConnectionPageFile).
| Name | Required | Description | Default |
|---|---|---|---|
| platform | No | Defaults to android. iOS file-sync is Phase 4 — returns a not_supported message for now. | |
| appPackage | Yes | The app's package / bundle id (project_install_id). | |
| projectPath | No | Absolute path to the project root. Optional — when given, enables an overwrite/drift note if a committed file already exists. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It explains the generation direction, the returned file structure with a _comment marker and warning against hand-editing, the drift note behavior when projectPath is given, and the platform limitation. It does not explicitly mention idempotency or required permissions, but overall it is fairly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is about 6 sentences, each providing necessary context. It is front-loaded with the main action and distinguishes from siblings. While slightly verbose, it is efficient and well-structured, earning a 4.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description adequately explains the return value (file object with path, content, _comment marker) and the offline theming purpose. It covers the key scenarios and platform limitations. However, it could mention error cases (e.g., unknown appPackage), but overall it is fairly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by clarifying the platform default and iOS constraint, and by explaining the optional projectPath enables a drift note. This goes beyond the schema descriptions, justifying a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Regenerate' and the resource 'committed extentos.connection-page.json', and explains the direction (from server config to file). It distinguishes from the sibling tool adoptConnectionPageFile, which does the reverse direction. The purpose is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is provided: 'USE after setConnectionPageConfig / dashboard edits to sync the repo. DON'T USE to push local edits up (use adoptConnectionPageFile).' It also notes that the tool is Android-only and that unmanaged projects have nothing to mirror. This gives clear when-to-use and when-not-to-use advice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchDocsA
Search Extentos documentation by topic or keyword. The conceptual / narrative layer that complements the action-oriented tools — read these to understand how the SDK is meant to be used, not just what calls exist. Canonical post-pivot topics: getting_started (full topic index — read first), custom_handlers (the central composition doc — how to write a Handler class that subscribes to capability primitives), assistant_runtime (the canonical voice-assistant surface; read first if you're building a voice assistant), voice_integration (lower-level primitives — glasses.voice.onPhrase + audio.recordDiscrete + customer-side LLM; for fine-grained control), connection_ui_placement, host_app_scaffold, auto_bind_session_lifecycle, local_bridge_discovery, device_code_flow, connection_state_model, permissions, production_checklist, concurrency_modes, multi_platform_projects, library_api, toggles, audio_video_coexistence, simulator_browser_mode, simulator_session_lifecycle (mint once, reuse, delete deliberately — read before minting a second sim for a project), event_log_schema, file_actions, agent_e2e_testing (how an AI coding agent verifies its own generated handler end-to-end — sim event log + adb-mediated emulator DB read + screencap, the dual-layer pattern that closes the agent loop without a human). Topic IDs are stable. At least one of topic or query is required (enforced by the handler — calling with neither returns an invalid_arguments error). Pass topic alone to fetch the full topic content (most common); pass query alone for keyword search across all topics; pass both to narrow keyword search inside a topic. mode: "snippets" returns only the matching paragraphs instead of full topic bodies — pair with a query when keyword-searching across topics so a single search doesn't dump ~20KB of unrelated content into context. USE to learn how primitives compose into a real flow, or to read up on a specific feature (permissions, toggles, connection lifecycle). DON'T USE for the platform capability list (use getPlatformInfo), call-shape per feature (use getCapabilityGuide), or project-installed state (use inspectIntegration).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Response shape. 'full' (default) returns each matching topic's full body — the original behavior, best for reading a single named topic. 'snippets' returns only the paragraphs containing the query terms (up to 3 per topic, ~600 chars each) — best when querying across topics so you don't pay for unrelated content in the agent's context window. Snippets mode requires a query; pure topic fetches always return full content. | |
| query | No | Optional keyword(s). When omitted, the response is the full content of the topic named in `topic`. When both supplied, query narrows within the topic. At least one of `query` or `topic` must be supplied. | |
| topic | No | Optional topic id. Omit and pass `query` for cross-topic keyword search; pass topic alone to fetch the topic's full content (most common usage). At least one of `query` or `topic` must be supplied. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden and meets it: it discloses the enforcement rule ('At least one of `topic` or `query` is required... returns an invalid_arguments error'), stable topic IDs, snippets-mode paragraph limits, and the differing behavior when both parameters are supplied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but densely packed, with each section earning its place: purpose, topic list, usage conditions, mode semantics, and off-path disambiguation. It is front-loaded with the core function, and the extensive topic enumeration prevents invalid calls by providing valid string constants.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and three mostly optional params, the description covers everything an agent needs: it explains error behavior, mode output shapes, canonical topic IDs, and explicitly contrasts with sibling tools. No critical behavioral aspect is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already describes each parameter (100% coverage), the description adds essential semantics: the canonical topic list, the three parameter combination patterns (topic alone, query alone, both), and the snippet mode constraint (requires query). This goes far beyond the schema's field-level descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear, specific verb+resource: 'Search Extentos documentation by topic or keyword.' It further distinguishes itself from siblings by explicitly naming what it is NOT for ('DON'T USE for the platform capability list (use getPlatformInfo)...'), making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit USE/DON'T USE guidance with named alternates (getPlatformInfo, getCapabilityGuide, inspectIntegration). It also details when to use full vs snippets mode based on query scope, offering context for both common and edge use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
setAssistantConfigA
Change a project's dashboard-managed "Agent" (assistant) settings via MCP — any of the OpenAI Realtime model, voice, memory (compaction) model, or within-session memory mode (PARTIAL update; pass only what you're changing). Validates each value against the catalog (call getAssistantConfig first to see valid ids) and echoes the COST IMPACT of a model change (per-1M rates, old → new) so a switch is never blind. GATED by the project's MCP access grant — the default is Read+Write so it works out of the box; the owner can restrict it per-project in the dashboard, and a permission_denied (403) means Assistant-config access was set to Read or Off. Requires a linked Extentos account (a 401 returns account_required, run extentos-mcp login). Applies to the next assistant session on BOTH platforms (a value set in app code still wins; Android picks it up in a fresh process, iOS on app relaunch). USE to configure a project's voice agent from the agent loop. DON'T USE to read current settings (use getAssistantConfig) or to set secrets (credentials are never written through the agent).
| Name | Required | Description | Default |
|---|---|---|---|
| voice | No | Voice id. Optional — pass only to change it. | |
| appPackage | Yes | The app's package / bundle id (project_install_id). | |
| realtimeModel | No | OpenAI Realtime model id. Optional — pass only to change it. | |
| compactionModel | No | Memory (compaction) model id. Optional — pass only to change it. | |
| withinSessionMemory | No | Within-session memory mode. Optional — pass only to change it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden and excels. It discloses partial update, validation against catalog, cost impact echo, access gating with default Read+Write, error codes meaning, linked account requirement, and cross-platform session application. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is fairly long but well-structured. First sentence gives purpose and scope, then details validation, cost, gating, errors, platform effects, and usage guidance. Every sentence adds value; could be slightly tighter but efficiently conveys critical information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 5 parameters (4 enums), partial update, validation, cost impact, gated access, error conditions, and cross-platform behavior, the description covers all necessary context for correct invocation. No output schema, but return behavior is sufficiently described (errors, cost echo). Complete for a configuration mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (baseline 3). The description adds value by clarifying that parameters are optional for partial updates, advising to call getAssistantConfig first to see valid ids, and noting cost impact for model change. This goes beyond schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it changes dashboard-managed agent settings (voice, realtime model, compaction model, within-session memory) via MCP. It distinguishes from getAssistantConfig (reading) and setCredential (secrets), and specifies partial update behavior. The verb 'Change' and resource 'dashboard-managed Agent settings' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells when to use ('USE to configure a project's voice agent from the agent loop') and when not to use ('DON'T USE to read current settings (use getAssistantConfig) or to set secrets'). It also advises calling getAssistantConfig first to see valid ids, and mentions the gated access and error responses (401, 403) with instructions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
setConnectionPageConfigA
Persist the per-project ExtentosConnectionPage config (theming tokens + section visibility) to the dashboard/server, making the app MANAGED — the dashboard/server becomes the single source of truth and the SDK fetches it at render time (server.overlay(defaults)). Requires a linked Extentos account (run extentos-mcp login once; a 401 returns account_required with that hint). Validated against the connection-page schema — unknown keys are surfaced as a warning (the SDK ignores them), not blocked. After writing, run regenerateConnectionPageFile to mirror it into the committed extentos.connection-page.json. USE to author/update connection-page theming from the agent; the web dashboard's Connection section is the human-facing equivalent. DON'T USE just to read (use getConnectionPageConfig).
| Name | Required | Description | Default |
|---|---|---|---|
| config | Yes | The config to persist: { schemaVersion?, sections?, appearance? }. sections = { capabilities?, toggles?, voiceCommands? } booleans (section visibility); appearance = { colors?, typography?, shapes? } token maps per the connection-page schema. Omitted top-level fields are stored null and the SDK fills them from defaults. | |
| appPackage | Yes | The app's package / bundle id (project_install_id). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses making the app MANAGED, validation behavior (warnings for unknown keys not blocked), post-write action ('run regenerateConnectionPageFile'), and error handling (401 with account_required hint). No annotations present so description carries full burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Somewhat long but every sentence adds essential information; front-loaded with key purpose. Could be slightly more structured but remains efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers prerequisites, behavior, post-write action, and error cases. Lacks explicit return value description, but for a mutation tool without output schema, this is acceptable. Complete enough given complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds context: explains config structure, that omitted fields become null and SDK fills defaults, and identifies appPackage as bundle id. Adds meaningful value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool persists ExtentosConnectionPage config (theming and section visibility) and distinguishes it from siblings like getConnectionPageConfig (read) and regenerateConnectionPageFile (post-write mirror).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use ('to author/update connection-page theming'), when not to (just to read, use getConnectionPageConfig), and prerequisites (linked Extentos account, login hint).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
setCredentialA
Start WRITE-WITHOUT-KNOWING entry of the project's Meta DAT build identity. Takes NO secret argument BY DESIGN: the value must never pass through you. Returns a browser handoff { mode: "browser", url, credentialType, currentlySet } — a link to the project's dashboard credentials page where the signed-in owner pastes the secret; it goes straight from them into the encrypted vault (you can never read it back). GATED by the project's Credentials access grant at Read+Write (default Read+Write; a permission_denied (403) means it was set to Read or Off). Account-scoped (a 401 returns account_required, run extentos-mcp login). USE to wire up a project's API key from the agent loop without ever handling the secret: show the developer the returned URL, ask them to paste + save, then confirm with getCredentialStatus. DON'T pass a key value (there is no field for it) and DON'T ask the developer to paste a secret into the chat.
| Name | Required | Description | Default |
|---|---|---|---|
| appPackage | Yes | The app's package / bundle id (project_install_id). | |
| credentialType | Yes | Which credential to set. Only `meta_dat` (the Meta DAT build identity) exists — the assistant runs on the Extentos managed gateway and there is no provider key to supply. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully bears the burden. It discloses that the tool is a write operation that never accepts the secret, returns a browser handoff for secure entry, and is gated by credentials access grant. It explains the security design and error responses. No contradictions with missing annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence is necessary and contributes value. The description is front-loaded with the core purpose, then systematically covers security design, return value, access control, error handling, and usage guidance. No redundancy or wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is fully complete for the tool's complexity: it explains what the tool does, how to use it, the return format, access gating, error codes, and the recommended post-step. Despite no output schema, the return shape is explicitly given. No gaps remain for an agent to misuse it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds significant context: appPackage is described as "The app's package / bundle id (project_install_id)", and credentialType explains why only meta_dat exists ("the assistant runs on the Extentos managed gateway and there is no provider key to supply"). This enriches the schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb "Start WRITE-WITHOUT-KNOWING entry" and the resource "Meta DAT build identity", distinguishing it from siblings like getCredentialStatus which confirms the credential. It emphasizes the unique design of not passing the secret.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly guides when to use: "USE to wire up a project's API key from the agent loop without ever handling the secret." Provides clear exclusions: "DON'T pass a key value (there is no field for it) and DON'T ask the developer to paste a secret into the chat." Suggests follow-up with getCredentialStatus. Also explains error scenarios (403, 401).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
setSimDeviceA
Switch the simulated glasses DEVICE MODEL — one of the eight simulatable models: rayban_meta, oakley_meta_hstn, oakley_meta_vanguard, rayban_meta_optics, meta_glasses (camera + audio, NO display), rayban_display (display + Neural Band), and the EXPERIMENTAL Android XR pair — android_xr_audio_glasses (camera + audio, no display) and android_xr_display_glasses (adds a display, driven by the temple touchpad, panel 450x394 rather than Meta's 600x600 square). The selected device's capability profile drives glasses.display.isAvailable on the connected app, so this is how an agent tests BOTH branches of a capability-gated feature headless: set rayban_display to exercise the display path (glasses.display.show renders), set any no-display model to verify the graceful degradation (the app's isAvailable guard declines; show() no-ops). The model identity ALSO surfaces to the app as glasses.device.type (and in the assistant's glasses-state context), so per-model polish — e.g. an Oakley-specific default voice — is testable by switching between models that share the same capability profile. Mirrors the sim's device dropdown — the change persists on the session AND is pushed live to a connected app (the gate flips without a reconnect), and a device_changed event lands in getEventLog(filter:'lifecycle'). USE before driving a display flow to pin which device you're testing; pair with getDisplayState / injectInput. DON'T USE for the camera scene (setSimVideo) or voice (injectTranscript).
| Name | Required | Description | Default |
|---|---|---|---|
| device | Yes | The device model to simulate. Display-capable: 'rayban_display' (Meta, Neural Band, 600x600 panel) and 'android_xr_display_glasses' (Android XR, temple touchpad, 450x394 panel) — on both, glasses.display.isAvailable → true and display trees render. The Meta no-display models — 'rayban_meta' (Gen 1/2), 'oakley_meta_hstn', 'oakley_meta_vanguard', 'rayban_meta_optics' (prescription-first Gen 2), 'meta_glasses' (the 2026 Meta-branded line) — share the camera+audio profile but carry distinct identities (glasses.device.type). The two android_xr models switch the session's VENDOR, which is how you check the same code path under a second vendor — but ONLY on an Android session: switching an iOS session onto an android_xr device is REFUSED (vendor_platform_unsupported), because a projected activity is an Android activity and no iOS transport can exist. The brilliant models switch vendor on either platform. A new session defaults to its vendor's default model (rayban_meta for meta). | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and succeeds. It discloses persistence ('change persists on the session'), live propagation ('pushed live to a connected app without a reconnect'), event generation ('device_changed event lands in getEventLog'), and capability effects ('drives glasses.display.isAvailable'). It also explains the no-display degradation behavior, making the tool's side effects highly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and information-rich, with every sentence providing actionable detail. It is quite long and runs as a single unbroken block, and there is some repetition (e.g., display/no-display classification). It is appropriately sized for the tool's complexity but not maximally scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is highly complete: purpose, usage, behavior, persistence, eventing, and alternatives are all covered, which is impressive for a tool with no annotations or output schema. The omission of the brilliant models and the platform-switching refusal behavior (noted only in the schema) is a minor gap, and there is no mention of the return value, but overall the context is robust.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds meaningful context for the 'device' parameter (display panel differences, testing implications, identity surface), going beyond the schema. However, it omits two valid enum values (brilliant_halo, brilliant_frame) and incorrectly states only 'eight' simulatable models, creating an inconsistency with the schema. sessionId gets no explanatory value, but it is a standard identifier.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Switch the simulated glasses DEVICE MODEL') and the resource ('simulated glasses'), making the tool's purpose immediately obvious. It also distinguishes the tool from siblings by explicitly saying DON'T USE for camera scene (setSimVideo) or voice (injectTranscript), which is strong differentiation. The minor miscount of 'eight' models versus the ten in the schema does not obscure the core purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance ('USE before driving a display flow', 'test BOTH branches of a capability-gated feature headless') and when-not-to-use ('DON'T USE for the camera scene or voice'), even naming alternative tools. This is the gold standard for usage direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
setSimVideoA
Pipe a Test Video into the simulator's camera input so capture_photo / capture_video / videoFrames run against a known scene instead of a blank viewport — closes the agent-driven test loop for camera-driven flows the same way injectTranscript closes it for voice flows. Discover available IDs via getSimulatorStatus.testVideos (bundled defaults + project uploads). Requires the simulator browser tab to be connected (browser role attached) — call ensureSimulatorBrowser({ sessionId }) first to guarantee it (idempotent: opens the tab cross-platform + polls until it attaches). Same precondition as the simulator's photo/video capture itself. The browser loads the video as its cameraSource (same code path as a human drag-dropping a file), and a camera_source_set lifecycle event lands in getEventLog so the source change is visible to your verification step. USE before triggering a capture_photo / capture_video flow that needs a scene. DON'T USE to upload new videos — that's the project simulator page's job (extentos.com/projects//simulator).
| Name | Required | Description | Default |
|---|---|---|---|
| videoId | Yes | ID of the test video to load. Get the available list from getSimulatorStatus.testVideos — each entry has an id, name, description, durationSec, and source ('default' = bundled, 'project' = uploaded via the simulator page). | |
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but description fully discloses behavior: loads video as cameraSource, same code path as drag-drop, emits lifecycle event, requires browser role attached, and is idempotent with ensureSimulatorBrowser.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, all sentences add value, but could be slightly more concise; still well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations and no output schema, the description provides complete context: purpose, prerequisites, discovery method, when/not to use, and relation to other tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Adds meaning for videoId (where to get it, fields) beyond schema, but sessionId parameter lacks description in both schema and description, despite being required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it pipes a test video into the simulator's camera input so capture_photo/capture_video/videoFrames use a known scene, distinguishing it from siblings like injectTranscript.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'USE before triggering a capture_photo/capture_video flow that needs a scene' and 'DON'T USE to upload new videos', plus describes prerequisite of browser tab connection and suggests ensureSimulatorBrowser.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validateIntegrationA
Pre-test gate that runs ~16 severity-tiered checks over the whole project — manifest present + parses, generated-file markers + hashes, dependency declared, library-version freshness, Android Meta-DAT repo declaration, bootstrap wiring (ExtentosGlasses.create / Extentos.create), connection-page config, toolchain (AGP/Gradle) floors, foreground-service hints, permissions, and the PROJECT KEY (project_key_present) — the account-bound gateway credential, checked for correct SHAPE and not merely presence, because an unresolved build-setting placeholder passes a build and then fails at runtime in every environment. Only generateConnectionModule mints one, including for voice-only apps that generate no connection page. The permissions check DERIVES the permissions your declared capabilities imply and verifies they're present in the REAL app/src/main/AndroidManifest.xml elements (Android) or the app target's Info.plist keys (iOS) — the runtime source of truth, not the manifest JSON's permissions array. Returns { valid, checks, summary }: each checks[] entry is { name, passed, severity?: 'error' | 'warn' | 'info', details?, fix? }. valid is true when zero ERROR-severity checks fail; warn/info are advisories that don't block. summary reads 'Safe to test' ONLY at zero warnings — any warning demotes it to 'review before testing'. So treat this as a graded readiness report, not a binary pass/fail. USE after making changes, before testing. DON'T USE for reading state without judging it (use inspectIntegration).
| Name | Required | Description | Default |
|---|---|---|---|
| projectPath | No | Absolute (or cwd-relative) path to the project root. Optional — defaults to the MCP server's current working directory (process.cwd()); pass it explicitly whenever the project isn't the cwd. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers richly. It discloses the severity model, return object shape, the meaning of 'valid' and 'summary', the warning-to-review demotion, the runtime source of truth for permissions, and that the project key is checked for shape not just presence. This goes far beyond a simple mutability hint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence contributes substantive detail—no filler. It is front-loaded with the core purpose ('Pre-test gate') and then methodically enumerates checks and behaviors. The length is justified by the tool's complexity, though it could arguably be trimmed into bullet points without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description fully explains the return structure, severity semantics, and interpretation of results. It also covers edge cases (voice-only apps, derived permissions, runtime source of truth) and integrates with sibling tools, making it complete for an AI agent to invoke and interpret correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description already covers the single parameter (projectPath) at 100%, so the baseline is 3. The description adds a small nuance about passing it explicitly when the project isn't the cwd, but this largely restates the schema. No extra parameter meaning is needed beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies validateIntegration as a 'Pre-test gate' running severity-tiered checks across the project, enumerating the major check categories and explicitly distinguishing it from sibling tools like inspectIntegration. The specific verb 'validate' plus the detailed list of checks leaves no ambiguity about the tool's purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage guidance is explicit: 'USE after making changes, before testing' and 'DON'T USE for reading state without judging it (use inspectIntegration).' It also clarifies that only generateConnectionModule mints the project key, preventing misuse. This is the gold standard for when-to-use and when-not-to-use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
8 tool updates
v0.11.34- Changed
createSimulatorSession3 fields changed- changed
Input schema / properties / glasses / descriptionPrevious value: -"Target glasses vendor. Canonical: 'meta'. 'meta_rayban' is a legacy alias (same vendor) kept for compatibility. 'android_xr' is EXPERIMENTAL/PREVIEW (Android XR projected glasses — no shipping hardware) and 'brilliant' is EVALUATION (Brilliant Labs Halo and Frame — hardware ships, but the Extentos BLE transport is not built yet). For both, simulator sessions CAN be minted, so an app's behaviour under that device identity is testable today; code scaffolding remains Meta-only."New value: +"Target glasses vendor. Canonical: 'meta'. 'meta_rayban' is a legacy alias (same vendor) kept for compatibility. 'android_xr' is EXPERIMENTAL/PREVIEW (Android XR projected glasses — no shipping hardware) and 'brilliant' is PREVIEW (Brilliant Labs Halo and Frame — the Extentos BLE transport is built on BOTH platforms and Halo is orderable, but the vendor says first units ship early August 2026, so nothing has run on a device and there is no emulator either). For both, simulator sessions CAN be minted, so an app's behaviour under that device identity is testable today; code scaffolding remains Meta-only. ⚠️ PLATFORM CONSTRAINT: 'android_xr' is Android-ONLY and minting it with platform:'ios' is REFUSED — Google's model is a projected activity, which is an Android activity, so no iOS transport can exist and simulating one would teach your app a combination no device can be. 'meta' and 'brilliant' mint on either platform." - added
Input schema / properties / projectPath / descriptionAdded value: +"Absolute path to the app project — the SAME value you pass to generateConnectionModule and validateIntegration. This is how a sim gets BOUND to a project: the manifest there supplies the key that makes this call get-or-create rather than mint. **Omitting it silently falls back to the process working directory**, so a call made from a directory with no extentos.manifest.json returns an UNBOUND sim that is shared across every unscaffolded directory for this account — which is how a workspace ends up with a row of unnamed, indistinguishable simulators. Pass it explicitly once the project exists." - removed
Input schema / properties / resetFreshRemoved value: -{ - "description": "When true, archive any existing saved sim for this project + platform and create a fresh one with a new sessionId. Default false — get-or-create returns the existing saved sim. Use for ID rotation (URL got hijacked, dev wants a clean slate). Dashboard's 'Reset' button hits the same backend path.", - "type": "boolean" -}
- Added
deleteSimulatorSession - Changed
generateConnectionModule1 field changed- changed
Input schema / properties / glasses / descriptionPrevious value: -"Target glasses vendor. Canonical: 'meta'. 'meta_rayban' is a legacy alias (same vendor) kept for compatibility. 'android_xr' is EXPERIMENTAL/PREVIEW (Android XR projected glasses — no shipping hardware) and 'brilliant' is EVALUATION (Brilliant Labs Halo and Frame — hardware ships, but the Extentos BLE transport is not built yet). For both, simulator sessions CAN be minted, so an app's behaviour under that device identity is testable today; code scaffolding remains Meta-only."New value: +"Target glasses vendor. Canonical: 'meta'. 'meta_rayban' is a legacy alias (same vendor) kept for compatibility. 'android_xr' is EXPERIMENTAL/PREVIEW (Android XR projected glasses — no shipping hardware) and 'brilliant' is PREVIEW (Brilliant Labs Halo and Frame — the Extentos BLE transport is built on BOTH platforms and Halo is orderable, but the vendor says first units ship early August 2026, so nothing has run on a device and there is no emulator either). For both, simulator sessions CAN be minted, so an app's behaviour under that device identity is testable today; code scaffolding remains Meta-only. ⚠️ PLATFORM CONSTRAINT: 'android_xr' is Android-ONLY and minting it with platform:'ios' is REFUSED — Google's model is a projected activity, which is an Android activity, so no iOS transport can exist and simulating one would teach your app a combination no device can be. 'meta' and 'brilliant' mint on either platform."
- Changed
getCapabilityGuide1 field changed- changed
Input schema / properties / feature / enumPrevious value: -[ - "assistant_provider_openai", - "assistant_runtime", - "assistant_session_runtime", - "assistant_start", - "assistant_tool", - "assistant_vision", - "audio_chunks", - "cancel_speak", - "capture_photo", - "capture_video", - "connection_state", - "conversation_ai_complete", - "conversation_listen", - "conversation_on_wake", - "conversation_runtime", - "conversation_speak", - "display", - "earcon", - "record_audio", - "speak", - "toggles", - "transcription_incremental", - "video_frames", - "voice_command" -]New value: +[ + "assistant_provider_openai", + "assistant_runtime", + "assistant_session_runtime", + "assistant_start", + "assistant_tool", + "assistant_vision", + "audio_chunks", + "camera_stream_state", + "cancel_speak", + "capture_photo", + "capture_video", + "connection_state", + "display", + "earcon", + "record_audio", + "speak", + "toggles", + "transcription_incremental", + "video_frames", + "voice_command" +]
- Changed
getCodeExample1 field changed- changed
Input schema / properties / pattern / enumPrevious value: -[ - "agent_driven_e2e_full_loop", - "agent_test_loop", - "assistant_agent_loop", - "barge_in_speak", - "byok_anthropic", - "connection_page_setup", - "conversation_agent_loop", - "display_browse_detail", - "display_media_gallery", - "live_transcription_ui", - "photo_describe_voice", - "video_frames_ml", - "voice_notes", - "voice_qa_assistant" -]New value: +[ + "agent_driven_e2e_full_loop", + "agent_test_loop", + "assistant_agent_loop", + "barge_in_speak", + "byok_anthropic", + "connection_page_setup", + "display_browse_detail", + "display_media_gallery", + "live_transcription_ui", + "photo_describe_voice", + "video_frames_ml", + "voice_notes", + "voice_qa_assistant" +]
- Changed
getPlatformInfo2 fields changed- changed
Input schema / properties / glasses / descriptionPrevious value: -"Target glasses vendor. Canonical: 'meta'. 'meta_rayban' is a legacy alias (same vendor) kept for compatibility. 'android_xr' is EXPERIMENTAL/PREVIEW (Android XR projected glasses — no shipping hardware) and 'brilliant' is EVALUATION (Brilliant Labs Halo and Frame — hardware ships, but the Extentos BLE transport is not built yet). For both, simulator sessions CAN be minted, so an app's behaviour under that device identity is testable today; code scaffolding remains Meta-only."New value: +"Target glasses vendor. Canonical: 'meta'. 'meta_rayban' is a legacy alias (same vendor) kept for compatibility. 'android_xr' is EXPERIMENTAL/PREVIEW (Android XR projected glasses — no shipping hardware) and 'brilliant' is PREVIEW (Brilliant Labs Halo and Frame — the Extentos BLE transport is built on BOTH platforms and Halo is orderable, but the vendor says first units ship early August 2026, so nothing has run on a device and there is no emulator either). For both, simulator sessions CAN be minted, so an app's behaviour under that device identity is testable today; code scaffolding remains Meta-only. ⚠️ PLATFORM CONSTRAINT: 'android_xr' is Android-ONLY and minting it with platform:'ios' is REFUSED — Google's model is a projected activity, which is an Android activity, so no iOS transport can exist and simulating one would teach your app a combination no device can be. 'meta' and 'brilliant' mint on either platform." - removed
Input schema / requiredRemoved value: -[ - "sections" -]
- Changed
searchDocs1 field changed- changed
Input schema / properties / mode / descriptionPrevious value: -"Response shape (F-R4-10). 'full' (default) returns each matching topic's full body — the original behavior, best for reading a single named topic. 'snippets' returns only the paragraphs containing the query terms (up to 3 per topic, ~600 chars each) — best when querying across topics so you don't pay for unrelated content in the agent's context window. Snippets mode requires a query; pure topic fetches always return full content."New value: +"Response shape. 'full' (default) returns each matching topic's full body — the original behavior, best for reading a single named topic. 'snippets' returns only the paragraphs containing the query terms (up to 3 per topic, ~600 chars each) — best when querying across topics so you don't pay for unrelated content in the agent's context window. Snippets mode requires a query; pure topic fetches always return full content."
- Changed
setSimDevice2 fields changed- changed
Input schema / properties / device / descriptionPrevious value: -"The device model to simulate. Display-capable: 'rayban_display' (Meta, Neural Band, 600x600 panel) and 'android_xr_display_glasses' (Android XR, temple touchpad, 450x394 panel) — on both, glasses.display.isAvailable → true and display trees render. The Meta no-display models — 'rayban_meta' (Gen 1/2), 'oakley_meta_hstn', 'oakley_meta_vanguard', 'rayban_meta_optics' (prescription-first Gen 2), 'meta_glasses' (the 2026 Meta-branded line) — share the camera+audio profile but carry distinct identities (glasses.device.type). The two android_xr models switch the session's VENDOR, which is how you check the same code path under a second vendor. A new session defaults to its vendor's default model (rayban_meta for meta)."New value: +"The device model to simulate. Display-capable: 'rayban_display' (Meta, Neural Band, 600x600 panel) and 'android_xr_display_glasses' (Android XR, temple touchpad, 450x394 panel) — on both, glasses.display.isAvailable → true and display trees render. The Meta no-display models — 'rayban_meta' (Gen 1/2), 'oakley_meta_hstn', 'oakley_meta_vanguard', 'rayban_meta_optics' (prescription-first Gen 2), 'meta_glasses' (the 2026 Meta-branded line) — share the camera+audio profile but carry distinct identities (glasses.device.type). The two android_xr models switch the session's VENDOR, which is how you check the same code path under a second vendor — but ONLY on an Android session: switching an iOS session onto an android_xr device is REFUSED (vendor_platform_unsupported), because a projected activity is an Android activity and no iOS transport can exist. The brilliant models switch vendor on either platform. A new session defaults to its vendor's default model (rayban_meta for meta)." - changed
Input schema / properties / device / enumPrevious value: -[ - "rayban_meta", - "oakley_meta_hstn", - "oakley_meta_vanguard", - "rayban_meta_optics", - "meta_glasses", - "rayban_display", - "android_xr_audio_glasses", - "android_xr_display_glasses", - "brilliant_frame", - "brilliant_halo" -]New value: +[ + "rayban_meta", + "oakley_meta_hstn", + "oakley_meta_vanguard", + "rayban_meta_optics", + "meta_glasses", + "rayban_display", + "android_xr_audio_glasses", + "android_xr_display_glasses", + "brilliant_halo", + "brilliant_frame" +]
37 tool updates
v0.1.1- First observed
addProjectSound - First observed
adoptConnectionPageFile - First observed
assertToolCalled - First observed
completeAuthLink - First observed
createSimulatorSession - First observed
ensureSimulatorBrowser - First observed
generateConnectionModule - First observed
getAssistantConfig - First observed
getCapabilityGuide - First observed
getCodeExample - First observed
getConnectionPageConfig - First observed
getCredentialGuide - First observed
getCredentialStatus - First observed
getDisplayState - First observed
getEventLog - First observed
getGatewayUsage - First observed
getMigrationGuide - First observed
getPermissions - First observed
getPlatformInfo - First observed
getProductionChecklist - First observed
getProjectAnalytics - First observed
getSimulatorStatus - First observed
getVoiceCommandGuidance - First observed
injectAssistantUtterance - First observed
injectHardwareButton - First observed
injectInput - First observed
injectTranscript - First observed
inspectIntegration - First observed
listProjectSounds - First observed
regenerateConnectionPageFile - First observed
searchDocs - First observed
setAssistantConfig - First observed
setConnectionPageConfig - First observed
setCredential - First observed
setSimDevice - First observed
setSimVideo - First observed
validateIntegration
TDQS
Each tool has a clearly distinct purpose, supported by detailed descriptions that specify when to use and not use them. Even closely related tools like injectTranscript, injectAssistantUtterance, and assertToolCalled are well-differentiated by their target phase and behavior.
Most tool names follow a consistent verb_noun pattern (e.g., getPlatformInfo, createSimulatorSession, setSimVideo). A few compound names like regenerateConnectionPageFile deviate slightly, but overall the pattern is predictable and readable.
With 37 tools, the count is high but appropriate for the broad scope of the server, which spans project scaffolding, configuration, simulator management, testing, analytics, and production readiness. Each tool serves a specific need, though some consolidation could be possible.
The tool surface is comprehensive, covering the entire development lifecycle from project initialization and capability discovery to integration validation, simulator testing, credential management, and production checklist. There are no obvious gaps in core workflows.
Maintenance
Related MCP Connectors
Stripe-native marketplace where AI agents discover and pay per call for API services.
Multi-tenant MCP gateway for AI commerce. One connection, every store.
Multi-tenant MCP gateway for AI commerce. One connection, every store.
Multi-tenant MCP gateway for AI commerce. One connection, every store.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceUniversal AI API Orchestrator. 850 tools across 53 services under a single MCP interface. Connect Claude, GPT, or Gemini to Stripe, Slack, GitHub, LinkedIn, Cloudflare, Shopify, Twilio, and 46 more via natural language. $0.10/execution, no subscription. Patent Pending.2935-
- AlicenseAqualityFmaintenanceDiscovery layer between AI coding agents and 3,100+ developer tools. Search, compare, and get integration code for auth, payments, analytics, email, databases, and 25 other categories — so agents recommend existing tools instead of generating boilerplate.243MIT
- FlicenseNot gradedqualityCmaintenanceInstant Backend for SMBs — AI-callable MCP tools for generating business pages, Stripe payments, notifications, and invoice processing. No signup, no dashboard, just results.-
- AlicenseNot gradedqualityCmaintenanceStripe-native marketplace where AI agents autonomously discover and purchase API services via MCP. Pay-per-call, no accounts needed. 6 live services including Phone Validator, Web Scraper, PDF Generator and Screenshot API.1MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/extentos/mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server