GlassCloud
GlassCloud
Cloud-Server für Rokid Bridge und GlassBridge — verwaltet Geräteverknüpfungen, MCP-Tool-Relay, Bildspeicherung mit Galerie und serverseitige LLM-Szenenbeschreibung.
Was er tut
GlassCloud ist das Backend für Rokid Smart-Glasses-Apps. Er bietet:
Geräteverknüpfung — QR-Code- oder Token-basiertes Pairing zwischen der Webkonsole und der Android-App
MCP-Tool-Relay — Leitet Gmail- und Kalender-Tool-Aufrufe von der Brille über WebSocket an Google-APIs weiter
Bildergalerie — Empfängt von der Brille hochgeladene Szenenbilder, speichert sie mit Metadaten und zeigt sie in einer Webgalerie an
Serverseitiges LLM — Wenn ein Bild ohne Beschreibung eintrifft, wird automatisch Gemini oder ChatGPT aufgerufen, um eine zu generieren, die dann zur Anzeige auf der Brille an die App zurückgegeben wird
Öffentliche Galerie-Links — Benutzerbezogene öffentliche Freigabe-Token, sodass Galerien ohne Anmeldung angesehen werden können
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Rokid Glasses │────▶│ GlassCloud │────▶│ Google APIs │
│ + Android App │ WS │ (This Server) │ │ Gmail/Calendar │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
REST API │ │ Server-side LLM
▼ ▼
┌─────────────────┐
│ Web Console │
│ Gallery · LLM │
│ Settings · QR │
└─────────────────┘Schnellstart
# Install dependencies
npm install
# Copy and fill in environment variables
cp .env.example .env
# Edit .env — see Configuration section below
# Development (auto-reload)
npm run dev
# Production build + run
npm run build
npm startÖffnen Sie http://localhost:3000/console, um auf die Webkonsole zuzugreifen.
Konfiguration
Alle Umgebungsvariablen werden beim Start mit Zod validiert. Der Server gibt die fehlenden Felder aus und beendet sich, falls erforderliche Variablen fehlen.
Geheimnisse generieren
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"Führen Sie dies zweimal aus — einmal für JWT_SECRET, einmal für ENCRYPTION_KEY.
Erforderliche Variablen
Variable | Beschreibung |
| Signiert Geräte-JWTs. Min. 32 Zeichen. Muss zufällig und geheim sein. |
| Verschlüsselt OAuth-Token und LLM-API-Schlüssel im Ruhezustand (AES-256-GCM). Min. 32 Zeichen. |
| Google OAuth 2.0 Client-ID |
| Google OAuth 2.0 Client-Geheimnis |
| OAuth-Redirect-URI — muss mit der in der Google Cloud Console registrierten übereinstimmen (z. B. |
Optionale Variablen
Variable | Standardwert | Beschreibung | |||||
|
| HTTP-Server-Port | |||||
|
|
|
|
| |||
|
|
|
|
|
|
|
|
|
| Pfad zur SQLite-Datenbankdatei | |||||
|
| Kommagetrennte Liste erlaubter CORS-Ursprünge | |||||
|
| Rate-Limit-Fenster in Millisekunden | |||||
|
| Maximale Anfragen pro Fenster pro IP (gilt für | |||||
|
| WebSocket-Keepalive-Ping-Intervall | |||||
|
| Wartezeit auf Pong vor Verbindungsabbruch |
Beispiel .env
PORT=3000
NODE_ENV=production
LOG_LEVEL=info
DATABASE_PATH=./data/glasscloud.db
JWT_SECRET=<generate with command above>
ENCRYPTION_KEY=<generate with command above>
CORS_ORIGINS=https://yourserver.com
GOOGLE_CLIENT_ID=123456789.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-xxxxx
GOOGLE_CALLBACK_URL=https://yourserver.com/auth/google/callbackGoogle OAuth-Einrichtung
Gehen Sie zu Google Cloud Console → APIs & Dienste
Erstellen Sie eine OAuth 2.0 Client-ID (Webanwendung)
Fügen Sie Ihre Callback-URL zu den Autorisierten Redirect-URIs hinzu:
https://yourserver.com/auth/google/callbackAktivieren Sie die Gmail API und Google Calendar API im Projekt
Fügen Sie Testnutzer unter OAuth-Zustimmungsbildschirm → Testnutzer hinzu (erforderlich, solange sich die App im Testmodus befindet)
Hinweis zu Google-Scopes: Diese App fordert
gmail.readonlyundcalendar.eventsan. Für eine öffentliche Bereitstellung mit mehr als 100 Nutzern erfordert Google eine CASA-Sicherheitsbewertung. Für private oder Testzwecke belassen Sie die App im Testmodus.
LLM-Einstellungen (Serverseitige Szenenbeschreibung)
GlassCloud kann automatisch Szenenbeschreibungen für Bilder generieren, die ohne eine solche hochgeladen wurden (z. B. wenn sich die Rokid-App im "Bypass LLM"-Modus befindet). Die generierte Beschreibung wird:
In der Datenbank gespeichert und in der Galerie angezeigt
In der Upload-API-Antwort zurückgegeben, damit die App sie sofort auf der Brille anzeigen kann
Konfiguration
Melden Sie sich unter
/consolean und klicken Sie im Header auf LLM Settings →Wählen Sie einen Anbieter (Gemini oder ChatGPT) und fügen Sie Ihren API-Schlüssel ein
Fügen Sie optional benutzerdefinierte Prompts hinzu und wählen Sie einen als aktiv aus
Der Standard-Prompt lautet: "Beschreibe die Szene in diesem Bild prägnant."
API-Schlüssel
Anbieter | Wo zu finden |
Gemini | |
ChatGPT |
API-Schlüssel werden im Ruhezustand mit ENCRYPTION_KEY (AES-256-GCM) verschlüsselt. Wenn kein API-Schlüssel konfiguriert ist, wird das serverseitige LLM stillschweigend übersprungen und Bilder mit leeren Beschreibungen werden unverändert gespeichert.
Webkonsolen-Seiten
URL | Beschreibung |
| Dashboard: Statistiken, Geräteverknüpfung, MCP-Dienstverwaltung |
| QR-Code / Link-Token zum Koppeln eines Geräts generieren |
| Bildergalerie (Tabellenansicht mit Vorschaubildern, Details, Löschen) |
| Bild in voller Größe mit Metadaten |
| LLM-Anbieter, API-Schlüssel und Prompt-Verwaltung |
| Öffentliche Galerie (keine Anmeldung erforderlich) |
| Details zu öffentlichen Fotos |
REST-API-Endpunkte
Gerät & Authentifizierung
Endpunkt | Methode | Auth | Beschreibung |
| GET | Keine | Gesundheitsprüfung mit Verbindungsstatistiken |
| GET | Keine | Google OAuth-Flow initiieren |
| GET | Keine | OAuth-Callback |
| POST | Keine | Link-Token gegen Geräte-JWT tauschen |
| GET | Geräte-JWT | Liste verknüpfter Geräte |
| DELETE | Sitzung | Gerät entkoppeln |
Bilder
Endpunkt | Methode | Auth | Beschreibung |
| POST | Geräte-JWT | Bild + Metadaten hochladen (multipart/form-data) |
| GET | Geräte-JWT | Bildmetadaten nach ID abrufen |
Upload-Felder
Feld | Typ | Erforderlich | Beschreibung |
| Datei | Ja | JPEG, PNG oder WebP — max. 20 MB |
| String | Ja | Szenenbeschreibung (kann leerer String sein) |
| String | Ja | Gerätemodellname |
| String | Ja | Eindeutige Gerätekennung |
| String | Nein | ISO 8601 Zeitstempel der Aufnahme |
| Zahl | Nein | Bildbreite in Pixeln |
| Zahl | Nein | Bildhöhe in Pixeln |
| String | Nein | Auf dem Gerät verwendetes LLM (z. B. |
Wenn scene_description leer ist und ein serverseitiges LLM konfiguriert ist, ruft der Server das LLM auf und fügt llmDescription in die Antwort ein:
{
"imageId": "uuid",
"originalFilename": "uuid.jpg",
"thumbnailFilename": "uuid_thumb.jpg",
"receivedAt": 1714000000000,
"capturedAt": 1714000000000,
"llmDescription": "A person walking through a crowded market..."
}MCP
Endpunkt | Methode | Auth | Beschreibung |
| GET | Geräte-JWT | Liste verfügbarer MCP-Dienste und Tools |
WebSocket-Protokoll
Verbindung unter: ws://localhost:3000/ws?deviceId=YOUR_DEVICE_ID
Client → Server
// Execute a tool
{ "type": "tool_execute", "requestId": "uuid", "serverId": "gmail",
"toolName": "gmail.get_unread", "arguments": { "maxResults": 10 } }
// Link device to user account
{ "type": "link_device", "requestId": "uuid",
"linkToken": "from-qr-code", "deviceId": "..." }
// Get user account info
{ "type": "get_user_account", "requestId": "uuid", "deviceId": "..." }Server → Client
// Immediate progress (for voice feedback while tool runs)
{ "type": "tool_progress", "requestId": "uuid",
"status": "executing", "message": "Checking your emails..." }
// Tool result
{ "type": "tool_result", "requestId": "uuid",
"result": { "success": true, "content": "You have 3 unread emails..." } }
// Error
{ "type": "error", "requestId": "uuid", "error": "Token expired" }Verfügbare MCP-Tools
Gmail
Tool | Beschreibung |
| Anzahl ungelesener E-Mails und Zusammenfassungen abrufen |
| E-Mails nach Suchanfrage durchsuchen |
| Vollständigen E-Mail-Inhalt nach ID abrufen |
Kalender
Tool | Beschreibung |
| Heutige Termine abrufen |
| Termine für N Tage abrufen |
| Neuen Termin erstellen |
Datenbankschema
Die Datenbank ist SQLite im WAL-Modus. Das Schema wird beim Start erstellt; neue Spalten werden über idempotente Migrationen hinzugefügt.
-- Users (from Google OAuth)
users (
id, google_id, email, display_name, profile_picture_url,
public_gallery_token, -- UUID for public gallery share link
llm_provider, -- 'Gemini' or 'ChatGPT' (default: 'Gemini')
openai_api_key_encrypted, -- AES-256-GCM encrypted
gemini_api_key_encrypted, -- AES-256-GCM encrypted
active_prompt_id, -- FK to llm_prompts.id
created_at, updated_at
)
-- Linked devices
devices (id, user_id, device_name, device_model, last_seen_at, last_heartbeat_at, linked_at, created_at)
-- QR code link tokens (single-use, 5 min expiry)
link_tokens (id, user_id, expires_at, used_at, used_by_device_id, created_at)
-- Encrypted Google OAuth tokens
oauth_tokens (id, user_id, provider, access_token_encrypted, refresh_token_encrypted, ...)
-- Scene images from glasses
glass_images (
id, device_model, device_instance_id,
scene_description, -- May be empty; server-side LLM fills it if blank
original_filename, thumbnail_filename,
captured_at, received_at, created_at,
image_width, image_height, -- Pixels (nullable)
user_id, -- FK to users.id (nullable for legacy rows)
llm_provider -- Which LLM generated the description
)
-- User-defined LLM prompts
llm_prompts (id, user_id, name, text, created_at)
-- Third-party MCP servers registered via console
third_party_mcp_services (id, name, description, owner_user_id, endpoint_url, auth_type, auth_config_encrypted, tools_json, ...)Verzeichnisstruktur
src/
├── index.ts # Entry point — starts HTTP + WebSocket servers
├── config/
│ ├── env.ts # Zod environment validation (exits on invalid config)
│ └── mcp-services.ts # Built-in MCP service definitions
├── server/
│ ├── express.ts # Express app — middleware, route mounting, error handling
│ ├── sessions.ts # In-memory session store for console auth
│ └── websocket.ts # WebSocket server with zombie connection cleanup
├── routes/
│ ├── auth.ts # Google OAuth flow
│ ├── console.ts # Web console dashboard
│ ├── devices.ts # Device management API
│ ├── gallery.ts # Image gallery (authenticated + public)
│ ├── health.ts # Health check
│ ├── images.ts # Image upload + retrieval API
│ ├── link.ts # QR code token generation
│ ├── mcp.ts # MCP services API
│ └── settings.ts # LLM settings page
├── services/
│ ├── auth.service.ts # OAuth + token refresh mutex
│ ├── device.service.ts # Device CRUD
│ ├── image.service.ts # Image save/list/delete + thumbnail generation
│ ├── link.service.ts # QR code token handling
│ ├── llm.service.ts # LLM settings CRUD + callLlm() (Gemini / ChatGPT)
│ ├── mcp-proxy.service.ts # MCP tool execution with input coercion
│ └── mcp-registry.service.ts # Third-party MCP server registry
├── websocket/
│ ├── handler.ts # Message routing with progress feedback
│ ├── protocol.ts # Message type definitions
│ └── connection.ts # Connection tracking
├── db/
│ ├── index.ts # SQLite connection + WAL mode
│ └── schema.ts # CREATE TABLE + ALTER TABLE migrations
├── utils/
│ ├── crypto.ts # AES-256-GCM encrypt/decrypt + token generation
│ ├── logger.ts # Pino structured logging
│ └── cache.ts # LRU cache for MCP tool results
└── types/
├── api.ts # REST API types
├── mcp.ts # MCP types
└── websocket.ts # WebSocket message typesDatendateien werden unter ./data/ geschrieben:
./data/glasscloud.db— SQLite-Datenbank./data/images/— Ursprünglich hochgeladene Bilder./data/thumbnails/— 400×400 JPEG-Vorschaubilder (generiert durch Sharp)
Sicherheit
OAuth-Token im Ruhezustand mit AES-256-GCM unter Verwendung von
ENCRYPTION_KEYverschlüsseltLLM-API-Schlüssel im Ruhezustand mit demselben Schlüssel verschlüsselt
Geräte-JWTs signiert mit
JWT_SECRET(HS256); bei jeder API-Anfrage verifiziertLink-Token nur als SHA-256-Hash gespeichert; einmalig verwendbar; 5 Minuten Gültigkeit
Rate-Limiting auf allen
/api/*-Routen (konfigurierbar über Env)Helmet-Sicherheitsheader auf allen Antworten
Öffentliche Galerie-Token sind zufällige UUIDs; das Regenerieren eines Tokens widerruft sofort den vorherigen Link
Lizenz
MIT
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
The Remote MCP server acts as a standardized bridge between LLM applications (like Claude, ChatGPT, and Cursor) and external services, enabling AI agents to access external tools and resources. Its primary capability is providing a centralized search tool to discover other MCP servers and their respective tools. Unlike local implementations, it runs remotely with OAuth authentication and permission controls for security.
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
Melaya is a remote MCP server. It gives an assistant hands on your own Android phone and browser: it reads the screen through the accessibility tree, then taps, types and navigates inside the apps and sites you allow-list, with no per-app API. It also builds, schedules and runs agent pipelines across 6k+ connected tools. OAuth 2.1, nothing to install.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jerryliu816/glasscloud'
If you have feedback or need assistance with the MCP directory API, please join our Discord server