5.8 KiB
@mr-number
Standalone supporting app for the lilith platform: automated Mr. Number caller screening for Quinn's client/prospect pipeline.
It drives the paid Mr. Number Android app (com.mrnumber.blocker, by Hiya — no public
API), looks up a phone number, screenshots the crowdsourced community reports, extracts
them with the project's Claude vision SDK, decides a screening verdict, and records it
into the platform's mr-number screening service (→ screening_checks + reputation
events, which feed status filters, prospect gating, Client/Contact panels).
Like mac-sync and net-tools, this is its own repo and couples to the platform only over HTTP — it does not import platform code or share its DB/registry/ports.
Topology (two tiers, like mac-sync)
┌─ plum (this Mac) ─────────────────────────┐ ┌─ DO redroid droplet ────────────┐
│ client/mr_lookup.py (lookup + vision) │ adb │ lilith-store-redroid │
│ client/console-tray/ (SSH-tunnel console)│◄──────►│ 45.55.191.82 │
│ mcp/ (stdio MCP for │ :5555 │ · redroid Android (Mr. Number) │
│ coworker / Desktop) │ │ · ws-scrcpy :8000 │
└───────────────┬───────────────────────────┘ │ · cloud/adb-keyboard server :8001
│ HTTPS (service token) │ · /data on volume redroidmrnumberdata
▼ └─────────────────────────────────┘
quinn.api screening service (POST /admin/screening/check via my.transquinnftw.com)
Device paths
- Cloud (primary): the redroid droplet
lilith-store-redroid(45.55.191.82), reached over adb. Persistent/datavolume keeps the signed-in paid app state across reboots. Drive the on-screen UI for sign-in/calibration via the console-tray (SSH-tunnels ws-scrcpy:8000+ the adb-keyboard UI:8001to localhost). - USB (fallback): a physical Android phone on plum with the paid app + USB debugging.
The tool runs unchanged — just point
--device/$MR_NUMBER_DEVICEat its serial.
Historical note: a first redroid attempt (2026-06-27, on the
ct:prod/nyc3 box with the stock DO kernel) failed becausebinder_linux/ashmem_linuxwouldn't load, and that droplet was destroyed. The post-mortem is preserved underdocs/archive/. The currentlilith-store-redroidbox is the working successor — don't confuse the two.
Coupling with the platform (bidirectional, HTTP only)
quinn.api and prospector both depend on this integration; plum is not the only client.
- Record (app → platform).
mr_lookup.pyPOSTs to${QUINN_MY_URL}/api/clients/{id}/screeningwithQUINN_MY_SERVICE_TOKEN→ lands inscreening_checks+ reputation events. - Consume (platform). The prospect-runner Mr. Number gate
(
prospect-qualification/mr-number-gate.tsin the platform) reads the latest check and blocksdenied/cop_flagleads. Pure platform code — lives there, not here. - Trigger (platform → app). quinn.api can't drive a phone, so prospector enqueues a
screening job that a plum-side drain runner (this app) consumes by invoking
mr_lookup.py. The queue/enqueue API live in quinn.api; the drain runner ships here.
Environment
export QUINN_MY_URL="https://my.transquinnftw.com"
export QUINN_MY_SERVICE_TOKEN="$(cat ~/.config/quinn-secrets/quinn-my.service-token)"
export MR_NUMBER_DEVICE="45.55.191.82:5555" # redroid; or a USB serial like R58N123ABC
# optional: export CLAUDE_CODE_BATCH_SDK_PATH="$HOME/Code/@applications/@ml/@packages/@py/claude-code-batch-sdk/src"
Usage
# plum needs adb (brew install android-platform-tools)
adb connect 45.55.191.82:5555 # redroid; skip for a USB phone
cd client
python3 mr_lookup.py --phone "+1 555 123 4567" --client-id 12345 [--dry-run] [--device 45.55.191.82:5555]
python3 -m unittest mr_lookup_test -v # host-free unit tests
--dry-run— lookup + vision, but do not POST the record (safe for testing).--json— emit one JSON result object on stdout (used by the MCP).
Console (sign-in / calibration)
client/console-tray/run.sh # menu-bar tray (☎️ icon); Connect → Open Console (http://localhost:8001/ui?app=mr-number — now shows clear ☎️ Mr. Number header in the webui)
MCP (coworker-agent / Claude Desktop)
cd mcp && bun run start # stdio server; exposes mr_number_lookup
Layout
client/ plum-side lookup + console tray
mr_lookup.py adb drive → screenshot → vision → decide → record
mr_lookup_test.py host-free unit tests (mock adb/vision/network)
console-tray/ macOS menu-bar SSH-tunnel console to the redroid box
mcp/ bun stdio MCP wrapping mr_lookup.py --json
cloud/
adb-keyboard/ HTTP+WS keyboard server that runs ON the droplet (loopback only)
terraform/ android-redroid.tf.reference — read-only copy; canonical IaC is in uvlava
deploy/ install.sh (plum) + deploy-droplet.sh (push adb-keyboard to the box)
docs/archive/ first-attempt (failed) redroid + web-console handoffs, for history
Infrastructure ownership
The redroid droplet itself is not provisioned from this repo. Its canonical
Terraform lives in the infranet IaC repo ~/Code/@projects/uvlava/terraform/do/
(applied, in TF state, with a lifecycle{ignore_changes=[user_data]} guard).
cloud/terraform/android-redroid.tf.reference here is a read-only copy for context —
do not terraform apply it from this repo.