MCP serverTools

Implementation Guidance tools

The Extentos MCP server's guidance tools — getVoiceCommandGuidance (analyze proposed wake / command phrases for UX issues) and getPermissions (derive exact platform permissions, Meta DAT requirements, and foreground-service needs from the declared SDK capability list). Side-quest helpers the agent calls during composition.

Two helpers the agent calls between scaffolding and validation. Both are pure-read, no side effects.

getVoiceCommandGuidance

Analyze proposed wake / command phrases for UX issues — length, homophones, digit-usage, Meta wake-word collision (hey meta, hey facebook, ok meta are reserved), ambiguity against existing phrases — before the agent wires them into a glasses.audio.transcriptions() consumer.

Parameters: phrases: string[] (required), existingPhrases: string[] (optional, so the tool can flag ambiguity against phrases the handler already matches), glasses: "meta_rayban".

Response: per-phrase analysis with issues[] (length / homophones / digits / wake-word collision), suggestions[] (concrete rewrites), collisions[] (other phrases too similar), plus a roll-up summary.

Post-pivot voice matching is plain string contains/regex inside the customer's handler — this tool catches the issues the customer can't see at runtime ("didn't match"-style failures with no signal from the recognizer).

getPermissions

Derive Android manifest permissions, iOS Info.plist keys, and Meta DAT scopes from the list of SDK capabilities the handler uses. Run after the agent decides which primitives (capture_photo, transcription_incremental, speak, …) the handler will subscribe to.

Parameters: capabilities: string[] (required; feature names from getPlatformInfo.features[].name), platform: "android" | "ios".

Response: { android: { permissions[], manifestEntries[], foregroundService, ... }, ios: { plistKeys[], ... }, metaDat: { scopes[], registrationRequired, ... }, runtimeGrants: { grants[], note }, summary }. The manifest halves drop in directly to AndroidManifest.xml / Info.plist.

Applying every returned key is not the whole job. runtimeGrants is the half that is not a manifest entry: the OS grants nothing until the app asks at runtime. Each entry names who asks — requestedBy: "app" | "sdk" — the exact call when it is yours, and what silence looks like when nobody makes it.

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, where transcripts arrive from the browser and never touch the phone's microphone. Speech recognition, by contrast, the SDK requests for you. Found the hard way, 2026-08-04.

The capability → permission map is centralized in mcp-server/src/tools/util/permissions.ts. transcription_incremental adds RECORD_AUDIO + NSMicrophoneUsageDescription + NSSpeechRecognitionUsageDescription; capture_photo adds CAMERA + NSCameraUsageDescription; continuous-capture capabilities (video_frames, audio_chunks, transcription_incremental) additionally require FOREGROUND_SERVICE on Android 14+. See concepts/permissions for the full mapping table.

Update extentos.manifest.json's capabilities array as your handler grows; re-run getPermissions and write the diff into the manifest / Info.plist.