feat: add Tactility MCP Screen foundation

This commit is contained in:
Adolfo Reyna
2026-06-24 23:48:21 -04:00
parent fb800bb5bd
commit ac9d6dc0d3
9 changed files with 1057 additions and 1 deletions
+41 -1
View File
@@ -27,6 +27,47 @@ The original reference documents and implementations are:
- Initial Tactility SDK: `0.7.0-dev`
- Language: C/C++ with ESP-IDF, FreeRTOS, Tactility SDK, and LVGL
## Current implementation status
Phase 1 is implemented, builds successfully for ESP32-S3, and has been tested
on a 320x240 Tactility device at runtime.
Completed:
- Tactility app lifecycle and app-owned drawing area
- HTTP JSON-RPC endpoint on port 80
- `tools/list`
- `get_capabilities`
- `clear_screen`
- `draw_text`
- request-size limits and JSON-RPC error responses
- live `tools/list` and `get_capabilities` calls
- live `clear_screen` and `draw_text` calls
- live malformed-JSON error handling
- crash-safe HTTP worker shutdown during app destruction
- three forced stop/start cycles with the management and MCP endpoints still
responsive afterward
Blocked by the current external-app ABI:
- UDP discovery requires `lwip_recvfrom` and `lwip_sendto`, which the running
Tactility 0.7.0-dev firmware does not export to ELF apps. The existing bridge
falls back to HTTP subnet scanning, so MCP connectivity remains available.
Pending verification:
- verify service behavior while the app is genuinely hidden behind another
running application. A remote HelloWorld launch did not trigger `onHide`, so
this needs a manual launcher/device interaction test.
### Shutdown implementation note
Tactility unloads external-app ELF memory immediately after `onDestroy`
returns. An app task blocked in `accept()` therefore cannot be allowed to
survive destruction. The HTTP listener is non-blocking, client reads have
short timeouts, and `onDestroy` closes sockets, waits for the worker to signal
exit, then deletes the suspended worker task before returning.
## Design principles
1. Preserve the existing MCP tool names and JSON-RPC contract wherever the
@@ -382,4 +423,3 @@ Implement Phase 1 as a minimal vertical slice:
6. Add `get_capabilities`, `clear_screen`, and `draw_text`.
7. Build.
8. Run a host smoke test through the existing bridge.