Live table monitoring
Real-time occupancy per table with camera snapshots. Managers see which tables are occupied, vacant, or in transition across all branches.
Enter the access code to view platform documentation, MCP guides, and app screenshots.
Incorrect code.
← Back to homeKnowledge
Reference for what Ryrah does, how the stack fits together, and how to connect Claude via the Model Context Protocol (MCP).
Ryrah is restaurant service intelligence: computer vision at each branch watches dining tables, tracks occupancy and food service, and reconciles every session against your POS — surfacing gaps as actionable flags.
Real-time occupancy per table with camera snapshots. Managers see which tables are occupied, vacant, or in transition across all branches.
AI detects when food arrives and is cleared, measuring service timing against operational standards.
Cross-checks vision sessions with Rista POS — KOT opened, bill closed, voids, and sessions without billing.
Color-coded alerts (yellow, orange, red) for missing sales, late KOTs, long vacant periods, and other operational issues.
Managers receive instant notifications with links to review flagged sessions and video evidence.
Monitor Jetson heartbeats, camera online status, and table zone polygons. Draw zones in the dashboard; edge devices pull updates on startup.
Daily PDF reports, sales dashboards, reconciliation KPIs, and on-demand video clip playback for flagged events.
mcp.ryrah.cloud — OAuth via Authentik
| Service | URL | Purpose |
|---|---|---|
| Marketing | www.ryrah.cloud | This site |
| Dashboard | app.ryrah.cloud | Web UI for ops teams |
| API | api.ryrah.cloud | REST + WebSocket backend |
| Auth | auth.ryrah.cloud | Authentik OAuth / SSO |
| MCP | mcp.ryrah.cloud | Claude connector endpoint |
See MongoDB schema for the full data model and App tour for screenshots of each screen.
The Ryrah dashboard at app.ryrah.cloud gives ops teams a single place to monitor tables, reconcile POS gaps, and review reports. Screenshots below were captured from a live walkthrough of every main page.
Database: occupancy (MongoDB 7, replica set rs0).
Mongoose pluralizes collection names — e.g. model Session → collection sessions.
sessions (live reconciliation) and as standalone records in flags
(historical analytics). Reconcile operations update both.
sessionsCore table occupancy sessions — one document per sit-down from occupied to vacant.
| Field | Type | Description |
|---|---|---|
sessionId | String | Unique session identifier (indexed) |
branchCode | String | Outlet code, e.g. S122 (indexed) |
tableName | String | Table label from vision system |
occupiedAt | Date | When guests sat down |
vacantAt | Date? | When table cleared (null = active) |
kotOpenedAt | Date? | POS KOT opened timestamp |
billClosedAt | Date? | POS bill paid/closed timestamp |
orderCancelled | Boolean | Whether the order was voided |
foodDetectedAt | Date? | First food arrival detected |
foodRemovedAt | Date? | Food cleared from table |
flags[] | Array | Embedded reconciliation flags (see below) |
lastKnownOrderItems[] | Array | itemId, name, quantity, kotId, invoiceNumber |
durationMinutes | Number? | Session length |
linkedInvoiceNumber | String? | Matched POS invoice |
shiftedFrom / shiftedTo | String? | Table transfer tracking |
sessionEndReason | String? | Why session ended (manual, timeout, etc.) |
joinedTables[] | String[] | Combined tables for large parties |
createdAt / updatedAt | Date | Auto timestamps |
Embedded flags[] sub-document fields:
| Field | Type | Description |
|---|---|---|
flagType | String | Issue type, e.g. no_kot, late_kot, no_sale |
status | enum | red · orange · yellow |
message | String | Human-readable alert text |
timestamp | Date | When flag was raised |
reconciled | Boolean | Whether ops team resolved it |
reconciledReason / reconciledBy / reconciledAt | — | Resolution audit trail |
playbackUrl | String? | Bunny CDN video embed URL |
flagsStandalone flag history for analytics and reporting (mirrors embedded session flags).
| Field | Type | Description |
|---|---|---|
branchCode | String | Outlet code (indexed) |
tableName | String | Table label |
sessionId | String | Parent session (indexed) |
flagType | String | Issue type |
status | enum | orange · red |
message | String | Alert text |
timestamp | Date | When raised (indexed) |
occupiedAt / vacantAt | Date? | Session window context |
reconciled | Boolean | Resolution status (indexed) |
reconciliationReason / reconciledBy / reconciledAt | — | Resolution audit trail |
createdAt / updatedAt | Date | Auto timestamps |
foodeventsRaw food arrival/removal events from edge vision (snake_case field names).
| Field | Type | Description |
|---|---|---|
table_name | String | Table label (indexed) |
branch_code | String | Outlet code (indexed) |
event_type | enum | food_arrived · food_removed |
timestamp | Date | Event time |
person_count | Number | People detected at table |
food_count | Number | Food items detected |
has_food | Boolean | Whether food is present |
camera_id | String? | Source camera |
branchesOutlet configuration and metadata (manager contacts, notification settings).
| Field | Type | Description |
|---|---|---|
branchCode | String | Unique outlet code (indexed) |
name | String | Display name |
location | String? | Physical address or area |
isActive | Boolean | Whether monitoring is enabled |
metaData | Map | Flexible key/value — e.g. managerName, notificationRecipients |
usersDashboard login accounts.
| Field | Type | Description |
|---|---|---|
username | String | Unique login name |
passwordHash | String | bcrypt hash (never exposed via MCP) |
role | enum | landlord · admin · owner |
branchCode | String? | Scoped outlet (required for owner role) |
createdAt | Date | Account creation time |
monitoredtablesTables registered for vision monitoring per branch.
| Field | Type | Description |
|---|---|---|
tableName | String | Table label |
branchCode | String | Outlet code |
cameraId | String? | Assigned camera |
lastSeenAt | Date | Last vision heartbeat |
isActive | Boolean | Whether table is monitored |
camerazonesTable zone polygons per camera — Jetson-compatible JSON stored centrally and synced to edge on startup.
| Field | Type | Description |
|---|---|---|
cameraId | String | Camera identifier (e.g. cam3) |
branchCode | String | Outlet code |
snapshotResolution | Object | { width, height } reference frame for polygon coordinates |
polygons | Map | Table name → array of [x, y] points |
updatedBy | String? | Dashboard user or MCP actor |
source | enum | ui · mcp · import · edge |
edgedevicesJetson heartbeat registry — one document per branch edge device.
| Field | Type | Description |
|---|---|---|
branchCode | String | Unique outlet code |
lastHeartbeatAt | Date | Most recent POST /api/heartbeat |
cameraMapping | Map | Camera ID → table names array |
tableCount | Number | Active tables in last heartbeat |
isOnline | Boolean | Derived from 90s offline threshold |
videoclipjobsAsync jobs to extract and upload video clips for flagged sessions.
| Field | Type | Description |
|---|---|---|
jobId | String | Unique job ID |
sessionId | String | Linked session |
tableName / branchCode | String | Location context |
flagType / flagTimestamp | — | Which flag triggered the clip |
status | enum | pending · processing · completed · failed |
playbackUrl | String? | Resulting Bunny embed URL |
error | String? | Failure message if status = failed |
completedAt | Date? | When job finished |
playbackjobsLive HLS stream replay jobs requested from the Jetson edge device.
| Field | Type | Description |
|---|---|---|
streamId | String | Unique stream identifier |
camera_id | String | Source camera |
start_time / end_time | Date | Replay window |
status | enum | PENDING · STREAMING · COMPLETED · FAILED |
created_at / last_active | Date | Job creation and Jetson heartbeat |
Ryrah exposes an MCP server so Claude can query live occupancy, flags, sales summaries, and maintain MongoDB data on your behalf — authenticated through Authentik.
https://mcp.ryrah.cloud (no /mcp path required).ryrah-mcp-claude (public client, no secret).Tools available after connecting Claude to Ryrah MCP:
| Tool | Description |
|---|---|
list_branches | Monitored outlets from POS configuration |
get_live_occupancy | Current table states and snapshots |
list_flags | Active reconciliation flags |
get_session_timeline | Timeline for a specific table session |
list_occupancy_sessions | Historical occupancy sessions |
list_food_events | Food arrival/removal events |
get_sales_summary | POS sales for a branch and date |
get_reconciliation_stats | Flag counts and reconciliation KPIs |
get_health | API health check |
| Tool | Description |
|---|---|
get_edge_health | Edge heartbeats, online cameras, zone summary |
list_edge_cameras | Per-camera status, tables, snapshot and zone availability |
list_camera_zones | All polygon configs in MongoDB |
get_camera_polygons | Zone JSON for one camera (Jetson format) |
update_camera_polygons | Create or replace table zones for a camera |
| Tool | Description |
|---|---|
get_database_stats | Collection counts and storage stats |
list_db_branches | Branch records in MongoDB |
update_branch | Update branch name, location, metadata |
list_monitored_tables | Tables registered for monitoring |
reconcile_flag | Mark a flag resolved with reason |
end_table_session | Manually end an active table session |
cleanup_old_data | Preview or delete old flags, sessions, or food events (dry-run by default) |
| Tool | Description |
|---|---|
list_dashboard_users | List all dashboard login accounts |
get_dashboard_user | Get one user by username |
create_dashboard_user | Create login (username, password, role, branchCode for owners) |
update_dashboard_user | Update role, location, or password |
delete_dashboard_user | Remove a dashboard account |
cleanup_old_data defaults to dryRun: true — review counts before deleting.reconciledOnly: true (default) so unresolved issues are kept.sessionId|flagType|timestamp — use values from list_flags or the dashboard.metaData via update_branch.get_sales_summary may return 403 until the server IP is whitelisted in Rista. Other tools are unaffected.