Skip to main content
When developing your MentraOS app, you’ll want to test it locally before deploying to production. This guide explains how local development works and how to set it up.

How MentraOS Apps Work

Understanding the architecture helps explain why we need tunneling for local development:
User's Glasses ←→ MentraOS Relay Server←→ Your App Server
The flow:
  1. User interacts with glasses (voice, buttons, camera)
  2. MentraOS Relay Server processes the interaction
  3. Relay Server sends events to your app server via webhook
  4. Your app responds (display text, play audio, etc.)
  5. Response flows back through the Relay Server to the user’s phone, and then to the user’s glasses
The key requirement: MentraOS Relay Server must be able to reach your app server over the internet.

The Local Development Problem

When you run your app locally, it’s only accessible on your machine:
Your App: http://localhost:3000 ✅ (you can access it)
         http://localhost:3000 ❌ (MentraOS Relay Server cannot access it)
Why this doesn’t work:
  • localhost is not a public address
  • MentraOS Relay Server runs on the internet
  • Relay Server can’t reach your local machine directly
  • Firewalls and routers block incoming connections

The Solution: Tunneling with ngrok

ngrok creates a secure tunnel from a public URL to your local server:
MentraOS Relay Server → https://abc123.ngrok.io → localhost:3000 → Your App
                        (public internet)         (your machine)
Now MentraOS Relay Server can send events to https://abc123.ngrok.io, and they’ll be forwarded to your local app.

Quick Start

1. Install ngrok

macOS:
brew install ngrok
Linux:
curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | \
  sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && \
  echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | \
  sudo tee /etc/apt/sources.list.d/ngrok.list && \
  sudo apt update && sudo apt install ngrok
Windows / Other: Download from ngrok.com/download

2. Start Your App

# In your app directory
bun install
bun run dev

# Your app is now running on http://localhost:3000

3. Start ngrok Tunnel

In a new terminal:
ngrok http 3000
You’ll see output like:
ngrok

Session Status                online
Account                       [email protected] (Plan: Free)
Version                       3.x.x
Region                        United States (us)
Latency                       -
Web Interface                 http://127.0.0.1:4040
Forwarding                    https://abc123.ngrok.io -> http://localhost:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00
Copy the Forwarding URL: https://abc123.ngrok.io

4. Update Developer Console

  1. Go to console.mentra.glass/apps
  2. Select your app
  3. Set App Server URL to: https://abc123.ngrok.io
  4. Save changes

5. Test on Glasses

  1. Open your app on MentraOS glasses
  2. Interact with it (speak, press buttons, etc.)
  3. Watch your terminal - you should see events coming in
  4. Check ngrok’s web interface at http://localhost:4040 to see requests

Development Workflow

Typical workflow:
# Terminal 1: Start your app
cd my-mentra-app
bun run dev

# Terminal 2: Start ngrok
ngrok http 3000

# Copy ngrok URL and update Developer Console
# → Test on glasses
# → Make code changes
# → App auto-restarts (if using nodemon)
# → Test again
When you restart ngrok:
  • Free ngrok URLs change each time
  • You must update the Developer Console with the new URL
  • Paid ngrok plans provide persistent URLs

ngrok Web Interface

ngrok provides a web interface at http://localhost:4040 showing:
  • Request Inspector - See all incoming requests
  • Request/Response Details - Headers, body, timing
  • Replay Requests - Resend requests for debugging
This is incredibly useful for debugging webhook issues.

Common Issues

Issue: “Connection Refused”

Problem: ngrok can’t connect to your local server Solution:
# Make sure your app is running first
bun run dev

# Then start ngrok in another terminal
ngrok http 3000

Issue: “No Events Coming Through”

Problem: You don’t see any requests in your terminal Solution:
  1. Check packageName - Must match exactly in both your code and Developer Console
  2. Check API key - Must be correct and match your app in Developer Console
  3. Check ngrok URL - Must be correct in Developer Console (no trailing slash)
  4. Check ngrok is still running (free URLs expire after 2 hours)
  5. Check your app is still running
  6. Look at ngrok web interface (localhost:4040) to see if requests are arriving
  7. Check your app logs for errors
Common mistakes:
// ❌ Wrong - packageName doesn't match Developer Console
packageName: 'com.example.myapp'  // Console has: 'com.mycompany.myapp'

// ❌ Wrong - incorrect API key
apiKey: 'old-api-key-here'

// ✅ Correct - matches Developer Console exactly
packageName: 'com.mycompany.myapp',
apiKey: process.env.MENTRA_API_KEY,

Issue: “ngrok URL Changed”

Problem: You restarted ngrok and URL changed Solution:
  • Free plan: Update Developer Console with new URL each time
  • Paid plan: Use reserved domains for persistent URLs
  • Alternative: Deploy to Railway/Ubuntu for persistent URLs

ngrok Free vs Paid

Free Plan

  • ✅ Unlimited tunnels
  • ✅ Web interface
  • ❌ URL changes each restart
  • ❌ 40 connections/minute limit
  • ❌ Random subdomain
  • ✅ Everything in Free
  • Reserved domains - URL never changes
  • ✅ Custom domains
  • ✅ Higher limits
  • ✅ More regions
For serious development, paid ngrok or deployment to Railway/Ubuntu is recommended.

Alternatives to ngrok

CloudFlare Tunnel

cloudflared tunnel --url http://localhost:3000
  • Free persistent URLs
  • More complex setup
  • Good for long-term development

localtunnel

npx localtunnel --port 3000
  • Simpler than ngrok
  • Less reliable
  • Good for quick tests

VS Code Port Forwarding

If using GitHub Codespaces or VS Code Remote:
  • Built-in port forwarding
  • No extra tools needed
  • Limited to VS Code environment

Next Steps