{"name":"com.extentos/mcp-server","slug":"extentos-mcp-server","title":null,"description":"Build smart-glasses apps with AI agents: scaffold, validate, and simulate before real hardware.","url":"https://mcp.market/server/extentos-mcp-server","rating":null,"grade":"A","score":94,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":33,"stars":2,"forks":0,"downloads_week":139,"last_push_at":"2026-09-05T09:10:40.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"npm","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/extentos/mcp-server","website":"https://extentos.com/docs/mcp-server","version":"0.11.63","remotes":[],"packages":[{"registryType":"npm","identifier":"@extentos/mcp-server","version":"0.11.63","transport":{"type":"stdio"}}],"tools":[{"name":"adoptConnectionPageFile","description":"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 ","write_action":false,"price_micros":0,"input_schema":null},{"name":"assertToolCalled","description":"**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.**","write_action":false,"price_micros":0,"input_schema":null},{"name":"completeAuthLink","description":"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","write_action":false,"price_micros":0,"input_schema":null},{"name":"createSimulatorSession","description":"**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","write_action":true,"price_micros":0,"input_schema":null},{"name":"deleteSimulatorSession","description":"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 som","write_action":true,"price_micros":0,"input_schema":null},{"name":"ensureSimulatorBrowser","description":"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** — i","write_action":false,"price_micros":0,"input_schema":null},{"name":"generateConnectionModule","description":"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 f","write_action":false,"price_micros":0,"input_schema":null},{"name":"getAssistantConfig","description":"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 ","write_action":false,"price_micros":0,"input_schema":null},{"name":"getCapabilityGuide","description":"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 / connectio","write_action":false,"price_micros":0,"input_schema":null},{"name":"getCodeExample","description":"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 a","write_action":false,"price_micros":0,"input_schema":null},{"name":"getConnectionPageConfig","description":"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 → c","write_action":false,"price_micros":0,"input_schema":null},{"name":"getCredentialGuide","description":"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 b","write_action":false,"price_micros":0,"input_schema":null},{"name":"getCredentialStatus","description":"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 enc","write_action":false,"price_micros":0,"input_schema":null},{"name":"getDisplayState","description":"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 nod","write_action":false,"price_micros":0,"input_schema":null},{"name":"getEventLog","description":"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 `er","write_action":false,"price_micros":0,"input_schema":null},{"name":"getGatewayUsage","description":"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-g","write_action":false,"price_micros":0,"input_schema":null},{"name":"getMigrationGuide","description":"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`, `Dis","write_action":false,"price_micros":0,"input_schema":null},{"name":"getPermissions","description":"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 ","write_action":false,"price_micros":0,"input_schema":null},{"name":"getPlatformInfo","description":"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 complet","write_action":false,"price_micros":0,"input_schema":null},{"name":"getProductionChecklist","description":"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?: { ","write_action":false,"price_micros":0,"input_schema":null},{"name":"getProjectAnalytics","description":"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 Analyt","write_action":false,"price_micros":0,"input_schema":null},{"name":"getSimulatorStatus","description":"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 ","write_action":false,"price_micros":0,"input_schema":null},{"name":"getVoiceCommandGuidance","description":"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`","write_action":false,"price_micros":0,"input_schema":null},{"name":"injectAssistantUtterance","description":"**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 `co","write_action":false,"price_micros":0,"input_schema":null},{"name":"injectHardwareButton","description":"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 t","write_action":false,"price_micros":0,"input_schema":null},{"name":"injectInput","description":"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 ","write_action":false,"price_micros":0,"input_schema":null},{"name":"injectTranscript","description":"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 ","write_action":false,"price_micros":0,"input_schema":null},{"name":"inspectIntegration","description":"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 `foun","write_action":false,"price_micros":0,"input_schema":null},{"name":"regenerateConnectionPageFile","description":"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 serve","write_action":false,"price_micros":0,"input_schema":null},{"name":"searchDocs","description":"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 capabil","write_action":false,"price_micros":0,"input_schema":null},{"name":"setAssistantConfig","description":"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 ","write_action":false,"price_micros":0,"input_schema":null},{"name":"setConnectionPageConfig","description":"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","write_action":false,"price_micros":0,"input_schema":null},{"name":"setCredential","description":"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 rea","write_action":false,"price_micros":0,"input_schema":null},{"name":"setSimDevice","description":"Switch the simulated glasses DEVICE MODEL. Meta: rayban_meta, oakley_meta_hstn, oakley_meta_vanguard, rayban_meta_optics, meta_glasses (camera + audio, NO display) and rayban_display (display + Neural Band). 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","write_action":false,"price_micros":0,"input_schema":null},{"name":"setSimVideo","description":"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 ta","write_action":false,"price_micros":0,"input_schema":null},{"name":"validateIntegration","description":"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 (`proj","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":94,"grade":"A","scanned_at":"2026-09-20T11:38:39.999Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-20T11:38:39.939Z","components":{"code":{"score":25,"max":25,"notes":["145 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":15,"max":15,"notes":["last push 15 days ago"]},"identity":{"score":9,"max":10,"notes":["registry namespace matches repository owner","website matches verified namespace"]}},"findings":[],"inputs":{"packages":[{"registryType":"npm","identifier":"@extentos/mcp-server","version":"0.11.63","found":true,"license":"MIT","hasInstallScripts":false,"dependencyCount":4,"publishedAt":"2026-09-05T09:07:43.893Z","repositoryUrl":"git+https://github.com/extentos/mcp-server.git","weeklyDownloads":139}],"repo":{"found":true,"owner":"extentos","repo":"mcp-server","archived":false,"pushedAt":"2026-09-05T09:10:40Z","stars":2,"forks":0,"openIssues":1,"ownerType":"Organization","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/287534144?v=4","ownerCreatedAt":"2026-05-24T21:50:25Z","license":"MIT"},"icon":{"url":"https://extentos.com/apple-icon.png?d39017c4038416e8","source":"site","width":331,"height":331},"presence":{"stars":2,"forks":0,"downloadsWeek":139,"license":"MIT","lastPushAt":"2026-09-05T09:10:40.000Z","score":33}}}},"grade_history":[],"reviews":[]}