Overview
Different smart glasses models have different hardware configurations. Some have cameras, others don’t. Some have displays, others don’t. Some have speakers, others only have a microphone, or no audio support at all. The capabilities system lets you detect these differences and adapt your app accordingly.// Example: Check if the connected glasses have a camera
protected async onSession(session: AppSession, sessionId: string, userId: string): Promise<void> {
if (session.capabilities?.hasCamera) {
// Glasses have a camera - enable photo/video features
session.logger.info("Camera available!");
} else {
// No camera - show alternative features
session.logger.info("This device supports text and voice interactions.");
}
}
Accessing Capabilities
Device capabilities are available on theAppSession through the capabilities property:
import { AppSession, Capabilities } from '@mentraos/sdk';
protected async onSession(session: AppSession, sessionId: string, userId: string): Promise<void> {
// Capabilities may be null if not yet loaded
const caps: Capabilities | null = session.capabilities;
session.logger.info(`Connected to: ${caps?.modelName}`);
// Now you can check specific capabilities
if (caps.hasDisplay) {
session.logger.info(`Display resolution: ${caps?.display?.resolution?.width}x${caps?.display?.resolution?.height}`);
}
}
Common Use Cases
Checking for Display Capabilities
protected async onSession(session: AppSession, sessionId: string, userId: string): Promise<void> {
const caps = session.capabilities;
if (!caps) return;
if (caps.hasDisplay) {
const display = caps.display!;
// Adapt content based on display properties
if (display.isColor) {
// Use color-rich layouts and graphics
session.layouts.showReferenceCard("🌈 Color Display", "Enjoying rich visuals!");
} else {
// Use high-contrast, monochrome-friendly content
session.layouts.showTextWall("Monochrome display detected");
}
// Adapt text length based on display size
const maxLines = display.maxTextLines || 3;
if (maxLines < 5) {
// Use shorter messages for smaller displays
session.layouts.showTextWall("Short message");
} else {
// Can display longer content
session.layouts.showTextWall("This is a longer message that takes advantage of larger displays with more text lines available.");
}
} else {
// No display - use audio-only interactions
session.logger.info("No display available - using audio-only mode");
}
}
Checking for Camera Capabilities
protected async onSession(session: AppSession, sessionId: string, userId: string): Promise<void> {
const caps = session.capabilities;
if (!caps) return;
if (caps.hasCamera) {
const camera = caps.camera!;
// Check video capabilities
if (camera.video.canRecord) {
session.logger.info("📹 Video recording available");
}
if (camera.video.canStream) {
const streamTypes = camera.video.supportedStreamTypes || [];
if (streamTypes.includes('rtmp')) {
session.logger.info("📡 Live streaming available");
}
}
// Check photo capabilities
if (camera.resolution) {
const megapixels = (camera.resolution.width * camera.resolution.height) / 1000000;
session.logger.info(`📷 ${megapixels.toFixed(1)}MP camera available`);
}
} else {
// No camera - disable photo/video features
session.logger.info("Camera not available on this device");
}
}
Checking for LED Capabilities
protected async onSession(session: AppSession, sessionId: string, userId: string): Promise<void> {
const caps = session.capabilities;
if (!caps) return;
if (caps.hasLight) {
const light = caps.light!;
session.logger.info(`Device has ${light.count || 0} LEDs`);
// Check specific LED types
if (light.lights) {
light.lights.forEach((led, index) => {
const ledType = led.isFullColor ? 'RGB' : led.color || 'unknown';
const purpose = led.purpose || 'general';
session.logger.info(`LED ${index}: ${purpose} (${ledType})`);
});
}
// Adapt LED usage based on available types
const hasRGB = light.lights?.some(led => led.isFullColor);
const hasWhite = light.lights?.some(led => !led.isFullColor && led.color === 'white');
if (hasRGB) {
// Can use all colors
await session.led.turnOn({ color: 'blue', ontime: 1000 });
} else if (hasWhite) {
// Only white LED available
await session.led.turnOn({ color: 'white', ontime: 1000 });
}
} else {
// No LEDs - use alternative feedback methods
session.logger.info("No LED support - using display/audio feedback");
session.layouts.showTextWall("💡 Notification");
}
}
Adaptive Feature Selection
class AdaptiveApp extends AppServer {
protected async onSession(session: AppSession, sessionId: string, userId: string): Promise<void> {
const caps = session.capabilities
if (!caps) {
session.layouts.showTextWall("Loading device information...")
return
}
// Create a feature matrix based on available capabilities
const features = this.getAvailableFeatures(caps)
// Show welcome message with available features
const featureList = features.join("\n• ")
session.layouts.showReferenceCard(`Welcome to ${caps.modelName}`, `Available features:\n• ${featureList}`)
// Set up event subscriptions based on capabilities
this.setupEventSubscriptions(session, caps)
}
private getAvailableFeatures(caps: Capabilities): string[] {
const features: string[] = []
if (caps.hasCamera) {
features.push("📷 Photo capture")
if (caps.camera?.video.canStream) {
features.push("📡 Live streaming")
}
}
if (caps.hasMicrophone) {
features.push("🎤 Voice commands")
features.push("📝 Speech transcription")
}
if (caps.hasDisplay) {
features.push("📱 Visual interface")
if (caps.display?.canDisplayBitmap) {
features.push("🖼️ Image display")
}
}
if (caps.hasButton) {
features.push("🔘 Hardware controls")
}
if (caps.hasWifi) {
features.push("🌐 Internet connectivity")
}
if (caps.hasLight) {
features.push("💡 LED notifications")
const lights = caps.light?.lights || []
const hasRGB = lights.some(light => light.isFullColor)
if (hasRGB) {
features.push("🌈 RGB LED control")
}
}
return features
}
private setupEventSubscriptions(session: AppSession, caps: Capabilities): void {
// Only subscribe to events for available hardware
if (caps.hasMicrophone) {
session.events.onTranscription(data => {
// Handle voice input
})
}
if (caps.hasButton) {
session.events.onButtonPress(data => {
// Handle button input
})
}
if (caps.hasIMU) {
session.events.onHeadPosition(data => {
// Handle head movement
})
}
}
}
Device Examples
For reference, here are the capabilities of some common devices:| Device | Display | Camera | Microphone | Speaker | LEDs | Other Features |
|---|---|---|---|---|---|---|
| Even Realities G1 | Green monochrome | ❌ No | ✅ Yes | ❌ No | ❌ No | Button controls |
| Vuzix Z100 | Green monochrome | ❌ No | ❌ No | ❌ No | ❌ No | Basic display only |
| Mentra Live | ❌ No | ✅ 1080p streaming | ✅ Yes | ✅ Yes | ✅ RGB + White | IMU, WiFi, Button |

