MCLite
ForkA lightweight off-grid communicator firmware for the LilyGo T-Deck Plus and T-Watch Ultra. Purpose-built for emergency and outdoor communication — no internet, no cell towers needed. SD card configuration, web flasher, and room server support. Compatible with MeshCore apps.
Fork of MeshCore (Reference)
- Maintainer
- laserir ↗
- Status
- Active
- Maturity
- Beta
- Lifecycle
- Active
- Latest version
- 0.4.2
- Released
- 2026-07-23
- Runtime
- Arduino · C++
- Distribution
- Community
- Licensing
- Open source
- License
- MIT
Capabilities
Transports
- ✓ BLE
- ✓ USB serial
- ✕ Native TCP
- ✕ Wi-Fi AP
Operations
- ✓ Web flasher
- ✕ OTA updates
Networking
- ✕ Repeater
- ✕ Room server
- ✕ Observer
- ✕ KISS modem
Hardware
- ✓ GPS
- ✓ Display
- ✕ Sensors
- ✕ Low-power RX
Protocol
- ✓ MeshCore compatible
Node role
Features
- Web flasher (Chrome/Edge)
- SD card configuration (one person sets up, copies to everyone)
- Room server support (up to 8)
- On-screen keyboard
- GPS support
- No accounts, no pairing, no per-device setup
Project signals
- GitHub stars
- 23
- Forks
- 5
- Watchers
- 3
- Open issues
- 3
- Contributors
- 3
- Release downloads
- 569
- Latest downloads
- 81
- Source available
- Yes
- Releases available
- Yes
- CI builds
- Yes
Releases
from GitHub · updated 2026-07-23v0.4.2 # Latest 13 days ago · 2026-07-23 15:45 UTC
On-device scope-from-repeater picker, "heard by N repeaters" on channel messages, received hop-count display, and a memory-usage indicator, plus a scoped-flood fix. Update over WiFi (Admin → WiFi → Check for updates) or via the web flasher.
Added
- Pick a scope from a nearby repeater. When setting a region scope — global (Settings → Radio → Scope) or a per-channel/room override — a new From repeater button asks a heard repeater for the list of regions it actually serves, so you don't have to know the exact names. Pick a repeater, then pick one region from the reply; it fills the scope field for you to review and Save. The manual text entry is untouched — this just adds a shortcut. The picker lists direct-range (0-hop) repeaters the device has heard (tap the flood-advert button on the Heard Adverts screen to prompt discovery). Requires a repeater running firmware that answers the region query. Multi-hop repeaters are not supported — the query needs a route-direct path, and an overheard advert path isn't a reliable one; configure scopes from a repeater within direct range. (#45)
- "Heard by N repeaters" on sent channel messages. A channel message you send now shows
✓ ↻ Nonce nearby repeaters rebroadcast it — the✓means sent, and↻ Nis how many distinct repeaters were heard echoing it back (the count climbs as echoes arrive). It's deliberately different from a direct message's✓✓(which is a real delivery ACK) — a channel echo only confirms a repeater relayed it. Always on; only meaningful where repeaters are in range. Thanks @jason-s13r (#39). - Show received hop count. Optionally show how many hops a received message took (
xNnext to the time;x0= heard directly). Off by default — enable in Settings → Messaging → Show Hop Count. (#39) - Memory usage indicator (debug). Optionally show
P% R%(PSRAM / internal-RAM used) in the status bar, and log internal-DRAM free / low-water / largest-free-block plus PSRAM over serial — handy for diagnosing memory pressure. Off by default — enable in Settings → Display → Show Memory Usage. Thanks @jason-s13r (#38).
Changed
- LVGL now allocates from PSRAM instead of internal DRAM. This frees scarce internal RAM for the things that can only live there — notably BLE companion mode. Measured on the T-Deck with BLE companion and an app connected: ~124 KB internal DRAM free with a ~111 KB largest contiguous block (negligible fragmentation); the redirect is effectively what lets that combination fit. Validated on both T-Deck (octal PSRAM) and T-Watch Ultra (quad PSRAM) with no perceptible UI slowdown. Falls back to DRAM if PSRAM is unavailable. Thanks @jason-s13r (#38).
- Chat bubbles are freed when you leave a chat, so a previously-viewed conversation no longer keeps its rendered bubbles in memory while you're on other screens (they're rebuilt from history on reopen). (#38)
Fixed
- A scope/region field with spaces no longer silently kills scoped floods. A scope holds a single region
name; pasting a multi-region
region deflist (e.g.west pnw or wv eug) hashed the whole string into a transport key that matched no repeater, so hashtag/private-channel traffic was dropped while Public kept working. The config tool now rejects a scope containing a space, and the firmware keeps only the first token (with a serial note) across every input path —config.json, the companion set-scope command, and the on-device scope editor. (#36)
v0.4.1 # 1 month ago · 2026-06-25 11:41 UTC
MeshCore 1.16 upgrade, the full companion command set (status/trace, anon-req, explicit-unscoped), and companion message-sync fixes. Update over WiFi (Admin → WiFi → Check for updates) or via the web flasher.
Added
Manage rooms and channels from the companion app. The companion protocol gained the standard write/action commands the official MeshCore app uses, so things that previously failed against MCLite now work:
- Room login (
CMD_SEND_LOGIN): log into a configured room or repeater from the app. A blank password field uses the password already in the device config, and a wrong password instantly retries with the stored one. Thanks to the reporters (#32). - Add / remove channels (
CMD_SET_CHANNEL): join a Public, hashtag, or private channel — or remove one — from the app. Adding applies instantly with no reboot — the channel is usable right away and its share QR shows the real key, not zeros, with the session staying connected. Removing a channel still reboots to apply (a known limitation — MeshCore offers no way to remove a channel from the running radio, so the device rebuilds its channel table from config at boot; the app reconnects on its own). Gated by thepermissions.conversation_managementsetting, so a locked-down device still refuses it (#31). - Add / edit / remove contacts (
CMD_ADD_UPDATE_CONTACT,CMD_REMOVE_CONTACT): add a contact, rename one, or delete one (and its chat history) straight from the app. Adding and renaming apply instantly (the app stays connected); removing reboots to apply (the app reconnects) — see the consistent add/remove model below. Editing maps to the contact's display name; per-contact permission flags stay device-owner settings (the config tool / on-device Admin), and the app's own contact flags remain app-local. Gated bypermissions.conversation_management(#33). - Share a contact (
CMD_SHARE_CONTACT) re-broadcasts a contact's advert so a nearby device can add them, and reboot (CMD_REBOOT) is now honoured from the app's button. - The app's Local vs Flood advert buttons were already handled; confirmed during this work. With this, the companion can fully manage rooms, channels, and contacts (#31, #32, #33 all closed). A consistent rule across both contacts and channels: adding and editing apply instantly; removing reboots to apply (the app reconnects on its own). The reboot on removal is required for channels — MeshCore has no way to drop a channel from the running radio — and kept for contacts so the behaviour is uniform and predictable. Live changes are reflected on the device's own UI too — a contact/channel added or renamed from the app shows up in the on-device conversation list and Admin screens right away, no reboot. In-place editing of a contact's permission flags / a channel's settings still arrives alongside on-device editing.
- Room login (
Change device settings from the companion app. With
permissions.settingsset tofull, a connected app can now set the device name, radio parameters (frequency / spreading factor / bandwidth / coding rate), TX power, the BLE pairing PIN, and the path-hash mode (1/2/3 bytes per hop). Values are range-checked; the device name applies instantly to mesh adverts (the Bluetooth scan name refreshes on the next reboot), while radio / TX / PIN / path-hash save and apply on a quick reboot (the app reconnects). Path-hash mode is especially useful on large meshes — it lets app users match a 3-byte network without hand-editingconfig.json(see #36). A device left atrestrictedornonerefuses these. Identity keys, advert location (MCLite advertises GPS at the configured precision), and auto-add stay device-managed by design and are rejected.Set the region/scope from the companion app. The companion now honours
CMD_SET_DEFAULT_FLOOD_SCOPE(set the persi …
v0.4.0 # 1 month ago · 2026-06-22 14:47 UTC
What's Changed
- Chat screen header buttons: contact's map, requesting telemetry, and info dialog. by @jason-s13r in https://github.com/laserir/MCLite/pull/30
- Add more radio presets by @jason-s13r in https://github.com/laserir/MCLite/pull/29
Full Changelog: https://github.com/laserir/MCLite/compare/v0.3.9...v0.4.0
Device compatibility (2)
| Device | MCU | Radio | Status | Notes |
|---|---|---|---|---|
| LilyGo T-Deck | esp32-s3 | Semtech SX1262 | ✓ Supported | T-Deck Plus — primary target with QWERTY keyboard, trackball, GPS. |
| LilyGo T-Watch Ultra | esp32-s3 | Semtech SX1262 | ✓ Supported | T-Watch Ultra — wrist-worn with AMOLED touchscreen. |