From 0c208611038d14cd316089d7a40b828999c4c7a8 Mon Sep 17 00:00:00 2001 From: Charles N Wyble Date: Tue, 17 Feb 2026 11:10:38 -0500 Subject: [PATCH] feat: integrate webserial-mcp for ESP32 MicroPython development - Add webserial-mcp service to docker-compose.yml - Create wrapper script and add to crush.json - Update STATUS.md with build status and requirements - Note: requires bridge server + browser + ESP32 hardware deps: generated with Crush Assisted-by: GLM-5 via Crush --- STATUS.md | 4 ++++ crush.json | 5 +++++ docker-compose.yml | 17 +++++++++++++++++ dockerfiles/webserial-mcp/Dockerfile | 26 ++++++++++++++++++++++++++ mcp-webserial-wrapper.sh | 4 ++++ 5 files changed, 56 insertions(+) create mode 100644 dockerfiles/webserial-mcp/Dockerfile create mode 100755 mcp-webserial-wrapper.sh diff --git a/STATUS.md b/STATUS.md index b3af19d..6128762 100644 --- a/STATUS.md +++ b/STATUS.md @@ -21,9 +21,11 @@ Last validated: 2026-02-17 - ✓ gimp-mcp: Working (GimpMCP v1.10.1) - requires GIMP with server running - ✓ kubernetes-mcp: Working (mcp-k8s Go binary) - requires kubeconfig mounted at /root/.kube/config - ✗ imap-mcp: Not working - requires working IMAP server (server crashes on startup if IMAP unreachable) +- ✗ webserial-mcp: Not working - requires bridge server running at ws://host.docker.internal:3000 + browser + ESP32 hardware **MCP Servers with Configuration Issues:** - ✗ imap-mcp: Not working - requires working IMAP server (server crashes on startup if IMAP unreachable) +- ✗ webserial-mcp: Not working - requires bridge server (esp32_bridge_server.py) running at ws://host.docker.internal:3000 + browser with WebSerial access + ESP32 hardware **Host-Only MCP Servers:** - ✗ kicad-mcp: Requires KiCAD installed on host (pcbnew Python module unavailable in container) @@ -47,6 +49,7 @@ Last validated: 2026-02-17 - bash-language-server: Built (v5.6.0) - configured in crush.json via wrapper script - docker-language-server: Built (v0.0.0) - configured in crush.json via wrapper script - ✓ kubernetes-mcp: Built (silenceper/mcp-k8s) - stdio-based, requires kubeconfig mount +- ✓ webserial-mcp: Built (Python/Flask) - stdio-based, requires bridge server + browser + ESP32 hardware **Builds in Progress:** - None @@ -96,6 +99,7 @@ All the following ahujasid repositories exist but contain no code (empty repos w | matomo-mcp | Blocked | Cannot build - vendor repository does not exist. CloneVendorRepos.sh references https://github.com/ahujasid/matomo-mcp-client.git which returns 404. | | discourse-mcp | Blocked | Cannot build - vendor repository exists but is empty. CloneVendorRepos.sh references https://github.com/ahujasid/discourse-mcp.git which has no commits. | | kubernetes-mcp | Built | Container built from Go source (67MB). Uses silenceper/mcp-k8s alternative repo. Multi-stage build with golang:1.24.1 and alpine:3.18.4. MCP stdio-based, requires kubeconfig mounted at /root/.kube/config. Supports K8s resources and Helm operations. | +| webserial-mcp | Built | Container built from Python source. Uses Flask-SocketIO for WebSocket bridge. MCP stdio-based, requires esp32_bridge_server.py running on host at ws://host.docker.internal:3000 + browser with WebSerial access + ESP32 hardware. Tools: upload_code, execute_command, read_console, reset_device, list_files. | | proxmox-mcp | Blocked | Cannot build - vendor repository https://github.com/ahujasid/ProxmoxMCP.git is empty (no code). | | terraform-mcp | Blocked | Cannot build - vendor repository https://github.com/ahujasid/terraform-mcp-server.git is empty (no code). | | nextcloud-mcp | Blocked | Cannot build - vendor repository https://github.com/ahujasid/nextcloud-mcp-server.git is empty (no code). | diff --git a/crush.json b/crush.json index 9f8c28a..9d85933 100644 --- a/crush.json +++ b/crush.json @@ -81,6 +81,11 @@ "type": "stdio", "command": "/home/charles/Projects/KNEL/KNEL-AIMiddleware/mcp-docspace-wrapper.sh", "timeout": 60 + }, + "webserial": { + "type": "stdio", + "command": "/home/charles/Projects/KNEL/KNEL-AIMiddleware/mcp-webserial-wrapper.sh", + "timeout": 60 } } } diff --git a/docker-compose.yml b/docker-compose.yml index e61a49e..97e28a9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -47,6 +47,23 @@ services: profiles: - dev + # ESP32 WebSerial MCP - MicroPython development via WebSerial + # NOTE: Requires bridge server running on host (esp32_bridge_server.py) + # and browser with WebSerial connected to ESP32 + webserial-mcp: + image: kneldevstack-aimiddleware-webserial-mcp + build: + context: ./vendor/webserial-mcp + dockerfile: ../../dockerfiles/webserial-mcp/Dockerfile + container_name: kneldevstack-aimiddleware-webserial-mcp + restart: unless-stopped + environment: + - PYTHONUNBUFFERED=1 + - WEBSOCKET_URL=ws://host.docker.internal:3000 + - MCP_TIMEOUT=30 + profiles: + - dev + # ========================================== # Hosting & Infrastructure (5 servers) # ========================================== diff --git a/dockerfiles/webserial-mcp/Dockerfile b/dockerfiles/webserial-mcp/Dockerfile new file mode 100644 index 0000000..47b81f7 --- /dev/null +++ b/dockerfiles/webserial-mcp/Dockerfile @@ -0,0 +1,26 @@ +# ESP32 WebSerial MCP Bridge +# This MCP requires the bridge server to be running and a browser+ESP32 connected + +FROM python:3.11-slim + +WORKDIR /app + +# Install dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt && \ + pip install --no-cache-dir nest-asyncio + +# Copy application files +COPY mcp_handler.py . +COPY mcp_client.py . +COPY esp32_bridge_server.py . +COPY templates/ templates/ + +# Environment variables +ENV PYTHONUNBUFFERED=1 +ENV WEBSOCKET_URL=ws://localhost:3000 +ENV MCP_TIMEOUT=30 + +# Default entrypoint is the MCP client (stdio-based) +ENTRYPOINT ["python", "mcp_client.py"] +CMD ["ws://host.docker.internal:3000"] diff --git a/mcp-webserial-wrapper.sh b/mcp-webserial-wrapper.sh new file mode 100755 index 0000000..205102a --- /dev/null +++ b/mcp-webserial-wrapper.sh @@ -0,0 +1,4 @@ +#!/bin/bash +docker run -i --rm \ + kneldevstack-aimiddleware-webserial-mcp \ + ws://host.docker.internal:3000