142 lines
5.7 KiB
Bash
Executable File
142 lines
5.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# MCPletA2A — start.sh
|
|
# Starts: Mock Service (port 5100) + Platform Host (Dashboard :4000, A2A :4001)
|
|
# MCPlet servers are spawned automatically by the Host via stdio.
|
|
# =============================================================================
|
|
set -euo pipefail
|
|
|
|
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PLATFORM_DIR="$BASE_DIR/platform_impl"
|
|
REF_DIR="$BASE_DIR/reference_impl"
|
|
PID_DIR="$BASE_DIR/.pids"
|
|
LOG_DIR="$BASE_DIR/.logs"
|
|
|
|
export REF_IMPL_DIST="$REF_DIR/dist"
|
|
|
|
# ---- Colour helpers ----------------------------------------------------------
|
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
|
|
info() { echo -e "${CYAN}[start]${RESET} $*"; }
|
|
ok() { echo -e "${GREEN}[start]${RESET} $*"; }
|
|
warn() { echo -e "${YELLOW}[start]${RESET} $*"; }
|
|
die() { echo -e "${RED}[start] ERROR:${RESET} $*" >&2; exit 1; }
|
|
|
|
# ---- Pre-flight checks -------------------------------------------------------
|
|
command -v node >/dev/null 2>&1 || die "node is not in PATH"
|
|
|
|
[[ -f "$PLATFORM_DIR/dist/index.js" ]] || \
|
|
die "platform_impl not built. Run: cd platform_impl && npm run build"
|
|
|
|
[[ -f "$REF_DIR/dist/mock-services/server.js" ]] || \
|
|
die "reference_impl not built. Run: cd reference_impl && npm run build"
|
|
|
|
# ---- LLM API key check -------------------------------------------------------
|
|
# Read the provider from reference.yaml (line starting with " provider:")
|
|
_llm_provider="$(grep -E '^\s+provider:' "$REF_DIR/config/reference.yaml" | head -1 | awk '{print $2}')"
|
|
|
|
case "$_llm_provider" in
|
|
openrouter)
|
|
if [[ -z "${OPENROUTER_API_KEY:-}" ]]; then
|
|
warn "LLM provider is 'openrouter' but OPENROUTER_API_KEY is not set."
|
|
warn " → Get a key at https://openrouter.ai/keys"
|
|
warn " → Then run: export OPENROUTER_API_KEY=sk-or-..."
|
|
warn " LLM calls will fail until the key is set."
|
|
fi
|
|
;;
|
|
claude|"")
|
|
if [[ -z "${ANTHROPIC_API_KEY:-}" ]]; then
|
|
warn "LLM provider is 'claude' but ANTHROPIC_API_KEY is not set."
|
|
warn " → Get a key at https://console.anthropic.com/settings/keys"
|
|
warn " → Then run: export ANTHROPIC_API_KEY=sk-ant-..."
|
|
warn " To switch to OpenRouter instead, edit:"
|
|
warn " $REF_DIR/config/reference.yaml"
|
|
warn " Uncomment the 'provider: openrouter' block and set OPENROUTER_API_KEY."
|
|
warn " LLM calls will fail until the key is set."
|
|
fi
|
|
;;
|
|
*)
|
|
warn "Unknown LLM provider '$_llm_provider' in reference.yaml."
|
|
warn " Supported values: claude, openrouter"
|
|
;;
|
|
esac
|
|
|
|
mkdir -p "$PID_DIR" "$LOG_DIR"
|
|
|
|
# ---- Check already running ---------------------------------------------------
|
|
is_running() {
|
|
local pidfile="$PID_DIR/$1.pid"
|
|
[[ -f "$pidfile" ]] && kill -0 "$(cat "$pidfile")" 2>/dev/null
|
|
}
|
|
|
|
if is_running mock-services || is_running platform-host; then
|
|
warn "Some services are already running. Run ./stop.sh first."
|
|
exit 1
|
|
fi
|
|
|
|
# ---- Start Mock Service (port 5100) -----------------------------------------
|
|
info "Starting Mock Service on port 5100 ..."
|
|
node "$REF_DIR/dist/mock-services/server.js" \
|
|
>"$LOG_DIR/mock-services.log" 2>&1 &
|
|
echo $! > "$PID_DIR/mock-services.pid"
|
|
|
|
# Wait until port 5100 is accepting connections (max 10 s)
|
|
for i in $(seq 1 20); do
|
|
if node -e "
|
|
const net = require('net');
|
|
const s = net.createConnection(5100, '127.0.0.1');
|
|
s.on('connect', () => { s.destroy(); process.exit(0); });
|
|
s.on('error', () => { s.destroy(); process.exit(1); });
|
|
" 2>/dev/null; then
|
|
ok "Mock Service ready (pid $(cat "$PID_DIR/mock-services.pid"))"
|
|
break
|
|
fi
|
|
sleep 0.5
|
|
if [[ $i -eq 20 ]]; then
|
|
die "Mock Service did not start in time. Check $LOG_DIR/mock-services.log"
|
|
fi
|
|
done
|
|
|
|
# ---- Start Platform Host (spawns MCPlet servers internally) ------------------
|
|
info "Starting Platform Host ..."
|
|
info " Config : $REF_DIR/config/reference.yaml"
|
|
info " Dashboard → http://localhost:4000"
|
|
info " A2A ext → http://localhost:4001"
|
|
|
|
MCPLET_CONFIG="$REF_DIR/config/reference.yaml" \
|
|
MCPLET_AGENT_MODULE="file://$REF_DIR/dist/agents/register.js" \
|
|
node "$PLATFORM_DIR/dist/index.js" \
|
|
>"$LOG_DIR/platform-host.log" 2>&1 &
|
|
echo $! > "$PID_DIR/platform-host.pid"
|
|
|
|
# Wait until Dashboard is reachable (max 15 s)
|
|
for i in $(seq 1 30); do
|
|
if node -e "
|
|
const net = require('net');
|
|
const s = net.createConnection(4000, '127.0.0.1');
|
|
s.on('connect', () => { s.destroy(); process.exit(0); });
|
|
s.on('error', () => { s.destroy(); process.exit(1); });
|
|
" 2>/dev/null; then
|
|
ok "Platform Host ready (pid $(cat "$PID_DIR/platform-host.pid"))"
|
|
break
|
|
fi
|
|
sleep 0.5
|
|
if [[ $i -eq 30 ]]; then
|
|
warn "Platform Host did not expose Dashboard in time."
|
|
warn "Check $LOG_DIR/platform-host.log for errors."
|
|
fi
|
|
done
|
|
|
|
# ---- Summary -----------------------------------------------------------------
|
|
echo ""
|
|
echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|
|
echo -e "${GREEN}${BOLD} MCPletA2A started successfully${RESET}"
|
|
echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|
|
echo -e " Mock Service → ${CYAN}http://localhost:5100${RESET}"
|
|
echo -e " Dashboard → ${CYAN}http://localhost:4000${RESET}"
|
|
echo -e " A2A Endpoint → ${CYAN}http://localhost:4001/a2a/task${RESET}"
|
|
echo ""
|
|
echo -e " Logs : ${LOG_DIR}/"
|
|
echo -e " Stop : ${BOLD}./stop.sh${RESET}"
|
|
echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|