From 7e4108fb3242a447bd45ed48d2498242efae6f7b Mon Sep 17 00:00:00 2001 From: RNL Date: Sat, 5 Sep 2026 00:12:23 +1000 Subject: [PATCH] fix(mcp): repair sse->http transport mismatch, auto-provision API key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bambu_mcp_server was refactored from FastMCP/sse to mcp-gate's http|stdio transport, but native/bambu-run-mcp.service, setup.sh, and bambu-run.sh enable-mcp were never updated — the systemd unit crash-looped on an invalid --transport sse flag on any Pi deployed after that change. Also closes the follow-on gap: MCP over http requires BAMBU_RUN_MCP_API_KEY, which nothing ever generated, so a fixed service would just crash-loop on a different error instead. Both setup.sh and enable-mcp now auto-generate and persist a key (same pattern as DJANGO_SECRET_KEY), print it in the ready-to-use Claude Desktop config, and respect a real environment variable over .env if one is already set. setup.sh's MCP step also gained an idempotency guard so re-running it doesn't re-prompt/reinstall MCP that's already enabled. Claude-Session: https://claude.ai/code/session_017Yxt4rdkuSowToxEKGMG9x --- native/bambu-run-mcp.service | 2 +- native/bambu-run.sh | 17 ++++++++++++- setup.sh | 48 +++++++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/native/bambu-run-mcp.service b/native/bambu-run-mcp.service index 1cd0219..10a530f 100644 --- a/native/bambu-run-mcp.service +++ b/native/bambu-run-mcp.service @@ -7,7 +7,7 @@ Type=exec WorkingDirectory={{REPO_DIR}} EnvironmentFile={{REPO_DIR}}/.env Environment=DJANGO_SETTINGS_MODULE=standalone.settings -ExecStart={{VENV_DIR}}/bin/python standalone/manage.py bambu_mcp_server --transport sse --host 0.0.0.0 --port 8808 +ExecStart={{VENV_DIR}}/bin/python standalone/manage.py bambu_mcp_server --transport http --host 0.0.0.0 --port 8808 Restart=on-failure RestartSec=10 diff --git a/native/bambu-run.sh b/native/bambu-run.sh index 1477fb6..eb10a39 100755 --- a/native/bambu-run.sh +++ b/native/bambu-run.sh @@ -5,6 +5,7 @@ set -euo pipefail REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)" VENV_DIR="$REPO_DIR/.venv" +ENV_FILE="$REPO_DIR/.env" MANAGE="$VENV_DIR/bin/python $REPO_DIR/standalone/manage.py" SERVICES="bambu-run-web.service bambu-run-collector.service" @@ -44,6 +45,19 @@ case "${1:-help}" in echo "Installing MCP dependencies..." "$VENV_DIR/bin/pip" install --quiet ".[mcp]" + # Resolution order: a real process/systemd env var always wins and is + # never written to .env; otherwise reuse whatever's already in .env; + # otherwise generate one (same pattern setup.sh uses for DJANGO_SECRET_KEY). + if [ -n "${BAMBU_RUN_MCP_API_KEY:-}" ]; then + echo "Using BAMBU_RUN_MCP_API_KEY from the environment (not written to .env)." + elif grep -q '^BAMBU_RUN_MCP_API_KEY=' "$ENV_FILE" 2>/dev/null; then + echo "BAMBU_RUN_MCP_API_KEY already in .env, reusing it." + else + MCP_API_KEY=$("$VENV_DIR/bin/python" -c "import secrets; print(secrets.token_urlsafe(32))") + echo "BAMBU_RUN_MCP_API_KEY=$MCP_API_KEY" >> "$ENV_FILE" + echo "Generated BAMBU_RUN_MCP_API_KEY and saved it to .env." + fi + sed "s|{{REPO_DIR}}|$REPO_DIR|g; s|{{VENV_DIR}}|$VENV_DIR|g" \ "$REPO_DIR/native/bambu-run-mcp.service" > "$SERVICE_DIR/bambu-run-mcp.service" @@ -52,10 +66,11 @@ case "${1:-help}" in systemctl --user start bambu-run-mcp.service PI_IP=$(hostname -I 2>/dev/null | awk '{print $1}') + MCP_KEY_FOR_DISPLAY="${BAMBU_RUN_MCP_API_KEY:-$(grep '^BAMBU_RUN_MCP_API_KEY=' "$ENV_FILE" 2>/dev/null | cut -d= -f2-)}" echo "MCP server enabled on port 8808." echo echo " Claude Desktop config:" - echo " {\"mcpServers\":{\"bambu-run\":{\"url\":\"http://${PI_IP:-localhost}:8808/sse\"}}}" + echo " {\"mcpServers\":{\"bambu-run\":{\"url\":\"http://${PI_IP:-localhost}:8808/mcp\",\"headers\":{\"Authorization\":\"Bearer ${MCP_KEY_FOR_DISPLAY}\"}}}}" fi ;; disable-mcp) diff --git a/setup.sh b/setup.sh index acfa393..bec997b 100755 --- a/setup.sh +++ b/setup.sh @@ -218,19 +218,38 @@ systemctl --user enable bambu-run-web.service bambu-run-collector.service echo MCP_ENABLED=false -read -rp "Enable MCP server for AI agent access (Claude Desktop, Claude Code, etc.)? [y/N] " ENABLE_MCP -if [[ "$ENABLE_MCP" =~ ^[Yy] ]]; then - green "Installing MCP dependencies..." - "$VENV_DIR/bin/pip" install $PIP_QUIET_FLAG ".[mcp]" - - sed "s|{{REPO_DIR}}|$REPO_DIR|g; s|{{VENV_DIR}}|$VENV_DIR|g" \ - "$REPO_DIR/native/bambu-run-mcp.service" > "$SERVICE_DIR/bambu-run-mcp.service" - - systemctl --user daemon-reload - systemctl --user enable bambu-run-mcp.service - systemctl --user start bambu-run-mcp.service +if [ -f "$SERVICE_DIR/bambu-run-mcp.service" ]; then + yellow "MCP server already enabled, skipping (use ./native/bambu-run.sh disable-mcp first to reconfigure)." MCP_ENABLED=true - green "MCP server enabled on port 8808." +else + read -rp "Enable MCP server for AI agent access (Claude Desktop, Claude Code, etc.)? [y/N] " ENABLE_MCP + if [[ "$ENABLE_MCP" =~ ^[Yy] ]]; then + green "Installing MCP dependencies..." + "$VENV_DIR/bin/pip" install $PIP_QUIET_FLAG ".[mcp]" + + # Resolution order: a real process/systemd env var always wins and is + # never written to .env (lets deployments override without touching + # the file); otherwise reuse whatever's already in .env; otherwise + # generate one, same pattern as DJANGO_SECRET_KEY above. + if [ -n "${BAMBU_RUN_MCP_API_KEY:-}" ]; then + yellow "Using BAMBU_RUN_MCP_API_KEY from the environment (not written to .env)." + elif grep -q '^BAMBU_RUN_MCP_API_KEY=' "$ENV_FILE" 2>/dev/null; then + yellow "BAMBU_RUN_MCP_API_KEY already in .env, reusing it." + else + MCP_API_KEY=$("$VENV_DIR/bin/python" -c "import secrets; print(secrets.token_urlsafe(32))") + echo "BAMBU_RUN_MCP_API_KEY=$MCP_API_KEY" >> "$ENV_FILE" + green "Generated BAMBU_RUN_MCP_API_KEY and saved it to .env." + fi + + sed "s|{{REPO_DIR}}|$REPO_DIR|g; s|{{VENV_DIR}}|$VENV_DIR|g" \ + "$REPO_DIR/native/bambu-run-mcp.service" > "$SERVICE_DIR/bambu-run-mcp.service" + + systemctl --user daemon-reload + systemctl --user enable bambu-run-mcp.service + systemctl --user start bambu-run-mcp.service + MCP_ENABLED=true + green "MCP server enabled on port 8808." + fi fi # Enable linger so services survive SSH logout @@ -288,15 +307,16 @@ green "============================================" echo echo " Dashboard: $DASHBOARD_URL" if [ "$MCP_ENABLED" = true ]; then - echo " MCP Server: http://${PI_IP:-localhost}:8808/sse" + echo " MCP Server: http://${PI_IP:-localhost}:8808/mcp" fi echo " Status: systemctl --user status bambu-run-web bambu-run-collector" echo " Logs: journalctl --user -u bambu-run-web -u bambu-run-collector -f" echo " Helper: ./native/bambu-run.sh {start|stop|restart|status|logs|update}" echo if [ "$MCP_ENABLED" = true ]; then + MCP_KEY_FOR_DISPLAY="${BAMBU_RUN_MCP_API_KEY:-$(grep '^BAMBU_RUN_MCP_API_KEY=' "$ENV_FILE" 2>/dev/null | cut -d= -f2-)}" echo " Claude Desktop config:" - echo " {\"mcpServers\":{\"bambu-run\":{\"url\":\"http://${PI_IP:-localhost}:8808/sse\"}}}" + echo " {\"mcpServers\":{\"bambu-run\":{\"url\":\"http://${PI_IP:-localhost}:8808/mcp\",\"headers\":{\"Authorization\":\"Bearer ${MCP_KEY_FOR_DISPLAY}\"}}}}" echo fi echo " Services auto-start on boot. Safe to close SSH."