Files
tactility_apps/Apps/McpScreen/README.md
T
Adolfo Reyna 0fb3c22f79
Main / Build (Brainfuck) (push) Has been cancelled
Main / Build (Breakout) (push) Has been cancelled
Main / Build (Calculator) (push) Has been cancelled
Main / Build (Diceware) (push) Has been cancelled
Main / Build (EpubReader) (push) Has been cancelled
Main / Build (GPIO) (push) Has been cancelled
Main / Build (GraphicsDemo) (push) Has been cancelled
Main / Build (HelloWorld) (push) Has been cancelled
Main / Build (M5UnitTest) (push) Has been cancelled
Main / Build (Magic8Ball) (push) Has been cancelled
Main / Build (MediaKeys) (push) Has been cancelled
Main / Build (MystifyDemo) (push) Has been cancelled
Main / Build (SerialConsole) (push) Has been cancelled
Main / Build (Snake) (push) Has been cancelled
Main / Build (TamaTac) (push) Has been cancelled
Main / Build (TodoList) (push) Has been cancelled
Main / Build (TwoEleven) (push) Has been cancelled
Main / Bundle (push) Has been cancelled
feat: add McpScreen phase 2 display tools
2026-06-25 12:43:08 -04:00

2.2 KiB

MCP Screen

Native Tactility port of the MicroPython MCP Screen firmware.

Phase 1 provides:

  • JSON-RPC 2.0 over POST /api/mcp on port 80
  • tools/list
  • get_capabilities
  • clear_screen
  • draw_text

Phase 2 adds:

  • draw_raw_rgb565
  • POST /api/screen/raw
  • draw_color_bmp
  • bridge-assisted PBM draw_image
  • PBM get_screenshot

Backlight and screen-power controls are intentionally excluded.

See IMPLEMENTATION_PLAN.md for the full roadmap.

UDP discovery is temporarily unavailable to an external app because the Tactility 0.7.0-dev firmware does not export lwip_recvfrom and lwip_sendto. The existing MicroPython bridge remains compatible through its HTTP subnet-scan fallback.

The HTTP worker uses a non-blocking listener and short client timeouts. onHide signals it and returns immediately; the worker owns the socket shutdown and then suspends itself outside the GUI lifecycle. It is reaped by the next onShow, or by onDestroy before Tactility unloads the external ELF.

The MCP server is foreground-only: it starts in onShow, and port 80 closes within one short worker poll after onHide. It is intentionally unavailable whenever McpScreen is not the active screen.

Build

. /Users/adolforeyna/esp/esp-idf/export.sh
export TACTILITY_SDK_PATH=/Users/adolforeyna/.gemini/antigravity/scratch/tactility/release/TactilitySDK
python3 tactility.py Apps/McpScreen build esp32s3 --local-sdk

Direct smoke test

Replace the IP address with the device address:

curl -s http://DEVICE_IP/api/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
curl -s http://DEVICE_IP/api/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"draw_text","arguments":{"text":"Hello from MCP","x":20,"y":30,"size":2}}}'

The existing MicroPython host bridge can also be used unchanged:

python3 /Users/adolforeyna/Projects/MicroPython/test1/Screen/mcp_bridge.py

Or run the included Phase 2 smoke test:

python3 Apps/McpScreen/tools/smoke_test.py --ip DEVICE_IP --draw

The --ip argument is required until UDP discovery is available to external apps.