Step-by-step instructions to get both the MCP Server (backend) and the Mobile App (frontend) running locally.
| Tool | Minimum Version | Check |
|---|---|---|
| Node.js | >= 20.19.4 |
node --version |
| npm | >= 10 |
npm --version |
| Expo Go (on your phone) | Latest from App Store / Play Store | — |
| OpenAI API key | — | platform.openai.com/api-keys |
Note: React Native 0.81 and Metro 0.83 require Node ≥ 20.19.4. If you're on an older patch, upgrade via
nvm install 20(or whichever version manager you use).
git clone <your-repo-url> cxc2026
cd cxc2026cd mcp-server
npm installcp .env.example .envOpen mcp-server/.env and review the defaults:
# Server configuration
NODE_ENV=development
PORT=3001
LOG_LEVEL=infoThe defaults work as-is for local development. Change PORT if 3001 is already in use (and update EXPO_PUBLIC_MCP_SERVER_URL in the mobile app accordingly).
npm run buildThis compiles TypeScript from src/ into dist/. Not needed for development — npm run dev runs TypeScript directly.
Development mode (runs TypeScript directly with hot-reload via tsx):
npm run devOn startup a predev script automatically detects your Mac's LAN IP and writes it into mobile-app/.env so physical devices can reach the server:
[sync-env] Detected LAN IP: 10.31.62.242
[sync-env] ✔ Updated mobile-app/.env → EXPO_PUBLIC_MCP_SERVER_URL=http://10.31.62.242:3001
[...] INFO: MCP server listening on port 3001 (development)
Production mode (uses compiled JS — does not run sync-env automatically):
npm run build
npm startcurl http://localhost:3001/healthExpected response:
{ "status": "ok", "nodes": 0, "edges": 0 }Leave this terminal running and open a new terminal for the mobile app.
cd mobile-app
npm installcp .env.example .envOpen mobile-app/.env and fill in your OpenAI key:
# Your OpenAI API key (required)
EXPO_PUBLIC_OPENAI_API_KEY=sk-proj-...
# MCP Server URL — auto-configured by `npm run dev` in mcp-server/
EXPO_PUBLIC_MCP_SERVER_URL=http://localhost:3001Why
EXPO_PUBLIC_prefix? Expo SDK 49+ only exposes env vars prefixed withEXPO_PUBLIC_to client code. Without the prefix,process.env.*will beundefinedat runtime.
Note: You don't need to manually set
EXPO_PUBLIC_MCP_SERVER_URL— the MCP server'spredevscript (scripts/sync-env.ts) automatically detects your LAN IP and patches this value every time you runnpm run devinmcp-server/. Just make sure you start the backend before the Expo dev server.
npm startThis launches the Expo CLI. You'll see a QR code in your terminal.
| Target | Action |
|---|---|
| iOS Simulator | Press i in the Expo CLI terminal |
| Android Emulator | Press a in the Expo CLI terminal |
| Physical device (Expo Go) | Scan the QR code with your phone's camera (iOS) or the Expo Go app (Android) |
- Start the MCP server first (
npm run devinmcp-server/) — this auto-syncs the LAN IP. - Then start the Expo dev server in a second terminal (
npm startinmobile-app/). - Open the app on your device/simulator.
- Grant camera and microphone permissions when prompted.
- Tap the green Start button — the camera feed should appear and the mic indicator should turn red.
Note: Full end-to-end functionality (vision analysis, transcription, LLM responses) requires a valid
EXPO_PUBLIC_OPENAI_API_KEYwith access togpt-5-nano(vision),gpt-5-mini(LLM), andwhisper-1.
| Command | Description |
|---|---|
npm run dev |
Auto-sync LAN IP to mobile .env, then start in dev mode |
npm run build |
Compile TypeScript → dist/ |
npm start |
Start compiled server (no auto-sync) |
npm run typecheck |
Type-check without emitting |
| Command | Description |
|---|---|
npm start |
Start Expo dev server |
npm run ios |
Start and open iOS simulator |
npm run android |
Start and open Android emulator |
Your Node.js version is too old. Upgrade to the latest Node 20 patch:
nvm install 20
nvm use 20- Make sure the MCP server is running (
npm run devinmcp-server/). - The
predevsync-env script should have auto-configuredmobile-app/.envwith your LAN IP. Verify by checking the startup output for[sync-env] ✔ Updated ...or[sync-env] ✔ ... already up-to-date. - If the IP looks wrong (e.g. you switched Wi-Fi), restart the MCP server —
predevre-detects the IP each time. - After the IP changes, restart the Expo dev server (
Ctrl+Cthennpx expo start --clear) so the new env var is picked up. - Check that your phone and computer are on the same Wi-Fi network.
⚠️ EDUROAM / enterprise Wi-Fi warning: Networks like eduroam may assign different IP subnets to different devices even though they share the same SSID. Your laptop and phone could end up on isolated subnets that can't reach each other. If you see connection failures on eduroam, try a personal hotspot or a simple WPA2 home/office network instead.
The predev script picks the first non-internal, non-link-local IPv4 address. If your machine has multiple network interfaces (VPN, Docker, etc.), it may pick the wrong one. You can manually override it in mobile-app/.env:
EXPO_PUBLIC_MCP_SERVER_URL=http://<your-actual-lan-ip>:3001Find your LAN IP with ifconfig | grep "inet " (macOS), hostname -I (Linux), or ipconfig | findstr IPv4 (Windows). The sync-env script won't overwrite a correct value — it only updates when the IP changes.
- Expo Go supports
expo-cameraandexpo-audioon physical devices only — simulators have limited camera support. - Make sure you granted permissions. On iOS you can reset them in Settings → Privacy.
Either kill the existing process:
lsof -ti:3001 | xargs kill -9Or change the port in mcp-server/.env and update EXPO_PUBLIC_MCP_SERVER_URL in mobile-app/.env to match.