Every MentraOS app starts with a MiniAppServer. It handles webhooks from the MentraOS Cloud, manages WebSocket connections, and gives you a MentraSession for each user who opens your app.

Basic Setup

import { MiniAppServer, type MentraSession } from "@mentra/sdk";

const app = new MiniAppServer({
  packageName: "com.example.myapp",
  apiKey: process.env.API_KEY!,
  port: 3000,
});

app.onSession((session: MentraSession) => {
  // Your app logic goes here - this runs once per user
});

await app.start();
No class inheritance needed. Create an instance, register callbacks, start the server.

What MiniAppServer Does

ResponsibilityDetails
HTTP ServerListens for webhooks from MentraOS Cloud (Hono-based)
WebSocket ClientMaintains a connection to MentraOS Cloud per user session
Session ManagerCreates a MentraSession for each user who starts your app
Lifecycle HandlerCalls your onSession and onStop callbacks at the right times

Configuration

const app = new MiniAppServer({
  packageName: "com.example.myapp",     // From developer console
  apiKey: process.env.API_KEY!,          // From developer console
  port: 3000,                            // Your server port
});

Required Settings

Unique identifier for your app.
  • Format: Reverse domain notation (e.g., com.company.appname)
  • Set in the Developer Console
  • Used to route sessions to your app
Your app’s API key.
  • Found in the Developer Console under your app’s settings
  • Keep this secret - use environment variables, not hardcoded strings
The port your server listens on.
  • Defaults to 80 if not set
  • Must match the port in your deployment configuration and ngrok tunnel

Optional Settings

Secret for signing authentication cookies in webviews.
  • Required if your app uses webviews with authentication
  • Must be at least 8 characters
  • Use a strong random string from an environment variable

Lifecycle Callbacks

onSession

Called when a user starts your app on their glasses. This is where your app logic lives.
app.onSession((session: MentraSession) => {
  const userId = session.userId;

  session.transcription.on((data) => {
    session.display.showTextWall(data.text);
  });

  session.onReconnected(() => {
    // The user's connection was briefly lost and restored.
    // All subscriptions are preserved - no action needed.
  });

  session.onStopped((reason) => {
    // This specific session ended. Clean up any per-user state.
  });
});
The MentraSession object is your connection to that user. Everything you do with their glasses goes through it. See MentraSession for the full API.

onStop

Called when a user session ends. Receives the session (if available) and a reason string.
app.onStop((session, reason) => {
  console.log("Session ended:", reason);
});

onToolCall

Called when the MentraOS AI system invokes one of your app’s registered tools.
app.onToolCall(async (session, toolName, args) => {
  if (toolName === "summarize") {
    return { result: "Summary of the conversation..." };
  }
  return { error: "Unknown tool" };
});

Custom Routes

MiniAppServer is built on Hono, so you can add your own HTTP routes directly:
app.get("/api/health", (c) => {
  return c.json({ ok: true });
});

app.post("/api/data", async (c) => {
  const body = await c.req.json();
  return c.json({ received: true });
});

Authenticated Routes

If your app has a webview that needs to make authenticated API calls:
import { createAuthMiddleware, getMentraAuth } from "@mentra/sdk";

const authMiddleware = createAuthMiddleware({
  apiKey: process.env.API_KEY!,
  packageName: "com.example.myapp",
  cookieSecret: process.env.COOKIE_SECRET!,
});

app.get("/api/me", authMiddleware, (c) => {
  const auth = getMentraAuth(c);
  return c.json({ userId: auth.userId });
});

Migrating from AppServer

If you’re updating from v2, see the Migration Guide. The key change is moving from class inheritance to callbacks:
// v2 - class inheritance
class MyApp extends AppServer {
  protected async onSession(session: AppSession, sessionId: string, userId: string) {
    // ...
  }
}
const app = new MyApp({ ... });

// v3 - callbacks
const app = new MiniAppServer({ ... });
app.onSession((session: MentraSession) => {
  // ...
});
The AppServer class still works in v3.0 for backward compatibility. It will be removed in v3.1.