GlassCloud
GlassCloud
Rokid BridgeおよびGlassBridge用のクラウドサーバー — デバイスのリンク、MCPツールの中継、ギャラリー付きの画像ストレージ、サーバーサイドLLMによるシーン記述を処理します。
機能
GlassCloudはRokidスマートグラスアプリのバックエンドです。以下の機能を提供します:
デバイスリンク — WebコンソールとAndroidアプリ間でのQRコードまたはトークンベースのペアリング
MCPツール中継 — グラスからGoogle APIへのGmailおよびカレンダーのツール呼び出しをWebSocket経由でプロキシ
画像ギャラリー — グラスからアップロードされたシーン画像を受信し、メタデータと共に保存してWebギャラリーに表示
サーバーサイドLLM — 説明のない画像が到着した際、自動的にGeminiまたはChatGPTを呼び出して説明を生成し、グラスに表示するためにアプリへ返信
公開ギャラリーリンク — ユーザーごとの公開共有トークンにより、ログインなしでギャラリーを閲覧可能
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Rokid Glasses │────▶│ GlassCloud │────▶│ Google APIs │
│ + Android App │ WS │ (This Server) │ │ Gmail/Calendar │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
REST API │ │ Server-side LLM
▼ ▼
┌─────────────────┐
│ Web Console │
│ Gallery · LLM │
│ Settings · QR │
└─────────────────┘クイックスタート
# 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 starthttp://localhost:3000/console を開き、Webコンソールにアクセスします。
設定
すべての環境変数は起動時にZodで検証されます。必要な変数が不足している場合、サーバーは不足しているフィールドを表示して終了します。
シークレットの生成
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"これを2回実行してください。1回は JWT_SECRET 用、もう1回は ENCRYPTION_KEY 用です。
必須変数
変数 | 説明 |
| デバイスJWTの署名用。32文字以上。ランダムかつ秘密である必要があります。 |
| OAuthトークンおよびLLM APIキーの保存時の暗号化用(AES-256-GCM)。32文字以上。 |
| Google OAuth 2.0 クライアントID |
| Google OAuth 2.0 クライアントシークレット |
| OAuthリダイレクトURI — Google Cloud Consoleに登録されているものと一致する必要があります(例: |
オプション変数
変数 | デフォルト | 説明 | |||||
|
| HTTPサーバーポート | |||||
|
|
|
|
| |||
|
|
|
|
|
|
|
|
|
| SQLiteデータベースファイルのパス | |||||
|
| 許可されたCORSオリジンのカンマ区切りリスト | |||||
|
| レート制限ウィンドウ(ミリ秒) | |||||
|
| IPごとのウィンドウあたりの最大リクエスト数( | |||||
|
| WebSocketキープアライブping間隔 | |||||
|
| 接続を閉じる前にpongを待機する時間 |
.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の設定
OAuth 2.0 クライアントID(ウェブアプリケーション)を作成します
承認済みのリダイレクトURI にコールバックURLを追加します:
https://yourserver.com/auth/google/callbackプロジェクトで Gmail API および Google Calendar API を有効にします
OAuth同意画面 → テストユーザー にテストユーザーを追加します(アプリがテストモードの間は必須です)
Googleスコープに関する注意: このアプリは
gmail.readonlyおよびcalendar.eventsを要求します。100人以上のユーザーを抱える公開デプロイには、GoogleによるCASAセキュリティ評価が必要です。個人利用やテスト目的の場合は、アプリをテストモードのままにしてください。
LLM設定(サーバーサイドのシーン記述)
GlassCloudは、説明なしでアップロードされた画像(Rokidアプリが「LLMバイパス」モードの場合など)に対して、自動的にシーン記述を生成できます。生成された説明は以下の通りです:
データベースに保存され、ギャラリーに表示されます
アップロードAPIのレスポンスとして返され、アプリがグラス上に即座に表示できるようにします
設定
/consoleにサインインし、ヘッダーの LLM Settings → をクリックしますプロバイダー(Gemini または ChatGPT)を選択し、APIキーを貼り付けます
必要に応じてカスタムプロンプトを追加し、1つをアクティブとして選択します
デフォルトのプロンプトは: "Describe the scene in this image concisely." です。
APIキー
プロバイダー | 取得先 |
Gemini | |
ChatGPT |
APIキーは ENCRYPTION_KEY (AES-256-GCM) を使用して保存時に暗号化されます。APIキーが設定されていない場合、サーバーサイドLLMは静かにスキップされ、説明が空の画像はそのまま保存されます。
Webコンソールページ
URL | 説明 |
| ダッシュボード: 統計、デバイスリンク、MCPサービス管理 |
| デバイスペアリング用のQRコード/リンクトークンの生成 |
| 画像ギャラリー(サムネイル、詳細、削除を含むテーブルビュー) |
| メタデータ付きのフルサイズ画像 |
| LLMプロバイダー、APIキー、プロンプト管理 |
| 公開ギャラリー(ログイン不要) |
| 公開写真の詳細 |
REST APIエンドポイント
デバイスと認証
エンドポイント | メソッド | 認証 | 説明 |
| GET | なし | 接続統計を含むヘルスチェック |
| GET | なし | Google OAuthフローの開始 |
| GET | なし | OAuthコールバック |
| POST | なし | リンクトークンとデバイスJWTの交換 |
| GET | デバイスJWT | リンクされたデバイスのリスト |
| DELETE | セッション | デバイスのリンク解除 |
画像
エンドポイント | メソッド | 認証 | 説明 |
| POST | デバイスJWT | 画像とメタデータのアップロード (multipart/form-data) |
| GET | デバイスJWT | IDによる画像メタデータの取得 |
アップロードフィールド
フィールド | 型 | 必須 | 説明 |
| file | はい | JPEG, PNG, または WebP — 最大20 MB |
| string | はい | シーンの説明(空文字でも可) |
| string | はい | デバイスモデル名 |
| string | はい | 一意のデバイス識別子 |
| string | いいえ | 画像がキャプチャされたISO 8601タイムスタンプ |
| number | いいえ | 画像の幅(ピクセル) |
| number | いいえ | 画像の高さ(ピクセル) |
| string | いいえ | デバイス上で使用されたLLM (例: |
scene_description が空で、サーバーサイドLLMが設定されている場合、サーバーはLLMを呼び出し、レスポンスに llmDescription を含めます:
{
"imageId": "uuid",
"originalFilename": "uuid.jpg",
"thumbnailFilename": "uuid_thumb.jpg",
"receivedAt": 1714000000000,
"capturedAt": 1714000000000,
"llmDescription": "A person walking through a crowded market..."
}MCP
エンドポイント | メソッド | 認証 | 説明 |
| GET | デバイスJWT | 利用可能なMCPサービスとツールのリスト |
WebSocketプロトコル
接続先: ws://localhost:3000/ws?deviceId=YOUR_DEVICE_ID
クライアント → サーバー
// 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": "..." }サーバー → クライアント
// 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" }利用可能なMCPツール
Gmail
ツール | 説明 |
| 未読メール数と概要の取得 |
| クエリによるメール検索 |
| IDによるメール本文の取得 |
カレンダー
ツール | 説明 |
| 今日の予定を取得 |
| N日分の予定を取得 |
| 新しい予定の作成 |
データベーススキーマ
データベースはWALモードのSQLiteです。スキーマは起動時に作成され、新しいカラムはべき等なマイグレーションによって追加されます。
-- 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, ...)ディレクトリ構造
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 typesデータファイルは ./data/ に書き込まれます:
./data/glasscloud.db— SQLiteデータベース./data/images/— アップロードされた元の画像./data/thumbnails/— 400×400 JPEGサムネイル(Sharpによって生成)
セキュリティ
OAuthトークン は
ENCRYPTION_KEYを使用してAES-256-GCMで保存時に暗号化されますLLM APIキー は同じキーで保存時に暗号化されます
デバイスJWT は
JWT_SECRET(HS256) で署名され、すべてのAPIリクエストで検証されますリンクトークン はSHA-256ハッシュとしてのみ保存され、使い捨てで5分で期限切れになります
すべての
/api/*ルートで レート制限 を実施(環境変数で設定可能)すべてのレスポンスに Helmet セキュリティヘッダーを適用
公開ギャラリートークン はランダムなUUIDであり、再生成すると以前のリンクは即座に無効化されます
ライセンス
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