#!/bin/sh # Entrypoint for the OpenPencil Vue container: runs the static SPA server on # :3100 and the @open-pencil/mcp Streamable-HTTP server on :7600 in the same # container. Forwards SIGTERM/SIGINT to both so docker stop is clean. # POSIX sh only (no `wait -n`) — the runtime image is Alpine/dash. set -eu WEB_PORT="${OPENPENCIL_WEB_PORT:-3100}" MCP_PORT="${OPENPENCIL_MCP_PORT:-7600}" # The MCP server creates a Unix socket + discovery file by default. In the # container we direct them under /data (writable volume) so the socket never # collides with /run/user/... and documents land on the persisted volume. export OPENPENCIL_MCP_ROOT="${OPENPENCIL_MCP_ROOT:-/data}" export OPENPENCIL_MCP_SOCKET="${OPENPENCIL_MCP_SOCKET:-/data/mcp.sock}" export OPENPENCIL_MCP_DISCOVERY_PATH="${OPENPENCIL_MCP_DISCOVERY_PATH:-/data/mcp.json}" export OPENPENCIL_MCP_CORS_ORIGIN="${OPENPENCIL_MCP_CORS_ORIGIN:-}" # Bind MCP on all interfaces so sibling containers (chatapi) can reach it by # service name (openpencil:7600), not just via localhost port-forwarding. export OPENPENCIL_MCP_HOST="${OPENPENCIL_MCP_HOST:-0.0.0.0}" mkdir -p "$OPENPENCIL_MCP_ROOT" "$(dirname "$OPENPENCIL_MCP_SOCKET")" "$(dirname "$OPENPENCIL_MCP_DISCOVERY_PATH")" echo "[openpencil] starting static SPA on :${WEB_PORT} and MCP on :${MCP_PORT}" # Static SPA. OPENPENCIL_WEB_PORT="$WEB_PORT" bun static-server.mjs & WEB_PID=$! # MCP server (Streamable HTTP at /mcp). Bun runs the node-targeted bin. PORT="$MCP_PORT" bun packages/mcp/bin/openpencil-mcp-http.js & MCP_PID=$! shutdown() { echo "[openpencil] shutting down (MCP=$MCP_PID, web=$WEB_PID) ..." kill -TERM "$MCP_PID" "$WEB_PID" 2>/dev/null || true exit 0 } trap shutdown TERM INT # Wait for both processes; stop the container when either exits. STATUS=0 while :; do WEB_ALIVE=0; MCP_ALIVE=0 kill -0 "$WEB_PID" 2>/dev/null && WEB_ALIVE=1 kill -0 "$MCP_PID" 2>/dev/null && MCP_ALIVE=1 if [ "$WEB_ALIVE" = "0" ] || [ "$MCP_ALIVE" = "0" ]; then STATUS=1 break fi # Poll every second; a SIGTERM/SIGINT wakes the loop via the trap's exit. sleep 1 done echo "[openpencil] a child process exited; stopping the container" kill -TERM "$MCP_PID" "$WEB_PID" 2>/dev/null || true wait "$MCP_PID" 2>/dev/null || true wait "$WEB_PID" 2>/dev/null || true exit "$STATUS"