Default port: Desktop App 19280, ESP32 WiFi 80
| Limit | Value | Description |
|---|---|---|
| Payload size | 10KB | Maximum request body size |
| Rate limit | 100 req/min | Per IP address |
| Request timeout | 30 sec | Prevents Slowloris attacks |
| CORS | localhost only | Only allows localhost origins |
| Field | Max Length | Format |
|---|---|---|
project |
100 chars | String |
tool |
50 chars | String |
model |
50 chars | String |
event |
50 chars | String |
memory |
- | N% where N is 0-100 |
state |
- | One of valid states |
character |
- | clawd or kiro |
| Endpoint | Desktop | ESP32 WiFi |
|---|---|---|
| POST/GET /status | ✓ | ✓ |
| GET /windows | ✓ | - |
| POST /close | ✓ | - |
| POST /show | ✓ | - |
| GET /health | ✓ | - |
| GET /debug | ✓ | - |
| POST /quit | ✓ | - |
| POST /lock, /unlock | ✓ | ✓ |
| GET/POST /lock-mode | ✓ | ✓ |
| GET/POST /window-mode | ✓ | - |
| POST /reboot | - | ✓ |
Update monitor status.
curl -X POST http://127.0.0.1:19280/status \
-H "Content-Type: application/json" \
-d '{"state":"working","tool":"Bash","project":"my-project"}'
Request Body:
| Field | Type | Description |
|---|---|---|
state |
string | start, idle, thinking, planning, working, notification, done, sleep |
event |
string | SessionStart, PreToolUse, Stop, etc. |
tool |
string | Tool name (e.g., Bash, Read, Edit) |
project |
string | Project name |
model |
string | Model name (e.g., opus, sonnet) |
memory |
string | Memory usage (e.g., 45%) |
character |
string | clawd or kiro |
terminalId |
string | Terminal ID for click-to-focus (iTerm2 session ID or Ghostty PID) |
Response:
{"success": true, "project": "my-project", "state": "working", "windowCount": 1}
Get all windows’ status.
curl http://127.0.0.1:19280/status
Response:
{
"windowCount": 2,
"projects": {
"my-project": {"state": "working", "tool": "Bash", "model": "opus", "memory": "45%"},
"other-project": {"state": "idle"}
}
}
List all active windows with their states and positions.
curl http://127.0.0.1:19280/windows
Response:
{
"windowCount": 2,
"windows": [
{"project": "my-project", "state": "working", "bounds": {"x": 1748, "y": 23, "width": 172, "height": 348}},
{"project": "other-project", "state": "idle", "bounds": {"x": 1566, "y": 23, "width": 172, "height": 348}}
]
}
Close a specific project window.
curl -X POST http://127.0.0.1:19280/close \
-H "Content-Type: application/json" \
-d '{"project":"my-project"}'
Show window and position to top-right corner.
# Show first window
curl -X POST http://127.0.0.1:19280/show
# Show specific project window
curl -X POST http://127.0.0.1:19280/show \
-H "Content-Type: application/json" \
-d '{"project":"my-project"}'
Request Body (optional):
| Field | Type | Description |
|---|---|---|
project |
string | Project name to show (defaults to first window) |
Response:
{"success": true, "project": "my-project"}
Get current window mode.
curl http://127.0.0.1:19280/window-mode
Response:
{"mode": "multi", "windowCount": 2, "lockedProject": null}
Set window mode (multi or single).
curl -X POST http://127.0.0.1:19280/window-mode \
-H "Content-Type: application/json" \
-d '{"mode":"single"}'
Lock to a specific project (single-window mode only).
curl -X POST http://127.0.0.1:19280/lock \
-H "Content-Type: application/json" \
-d '{"project":"my-project"}'
Response:
{"success": true, "lockedProject": "my-project"}
Unlock project.
curl -X POST http://127.0.0.1:19280/unlock
Get current lock mode.
curl http://127.0.0.1:19280/lock-mode
Response:
{
"mode": "on-thinking",
"modes": {"first-project": "First Project", "on-thinking": "On Thinking"},
"lockedProject": null,
"windowMode": "single"
}
Set lock mode (first-project or on-thinking).
curl -X POST http://127.0.0.1:19280/lock-mode \
-H "Content-Type: application/json" \
-d '{"mode":"first-project"}'
Health check endpoint.
curl http://127.0.0.1:19280/health
Response:
{"status": "ok"}
Get display and window debug information.
curl http://127.0.0.1:19280/debug
Quit the application.
curl -X POST http://127.0.0.1:19280/quit
Reboot the ESP32 device.
curl -X POST http://192.168.1.100/reboot