Publish a distribution path for pulse-mcp

The MCP adapter shipped in slice 51 with one install option:
clone the repo and go build. This slice integrates pulse-mcp
into Pulse's existing governed release pipeline so a Pulse
release publishes a pulse-mcp binary alongside the unified agent
and the install scripts that bring it home in one command.

What ships:

  - scripts/build-release.sh extended to build pulse-mcp for
    the same multi-OS matrix as the unified agent, package
    per-platform tarballs and zips, and copy bare binaries to
    RELEASE_DIR for /releases/latest/download/ redirect
    compatibility.
  - .github/workflows/create-release.yml extended to upload
    the bare pulse-mcp binaries plus install-mcp.sh and
    install-mcp.ps1 as release assets.
  - scripts/install-mcp.sh: bash one-line installer that
    detects platform/arch, downloads the matching binary from
    the configured release (latest by default), verifies SHA256
    against the published checksums.txt, places at
    ~/.local/bin/pulse-mcp (or /usr/local/bin if not writable).
    Honors PULSE_MCP_VERSION, PULSE_MCP_BIN_DIR, PULSE_MCP_REPO,
    PULSE_MCP_NO_VERIFY env vars; declines Windows shells with
    a pointer at the .ps1 sibling.
  - scripts/install-mcp.ps1: PowerShell installer for Windows,
    placing pulse-mcp.exe at $LOCALAPPDATA\pulse-mcp.

Documentation aligned:

  - cmd/pulse-mcp/README.md gains an Install section above
    Quick start with three options: one-line installer,
    GitHub Release download, go install. Documents the macOS
    Gatekeeper bypass since v1 is unnotarized by design.
  - The Settings -> API Access agent-integrations panel now
    surfaces the curl|bash command above the config snippet so
    operators see "install pulse-mcp" before "configure your
    MCP client."
  - docs/releases/AGENT_PARADIGM.md drops the "no published
    distribution path" item from "what it does not do yet" and
    documents the Gatekeeper / Homebrew gaps as next-tier
    follow-ups.

Trade-offs surfaced and chosen:

  - Same cadence as Pulse: pulse-mcp ships per Pulse release,
    not on its own track. The MCP server reads the manifest
    from the Pulse it talks to, so version alignment is the
    natural model.
  - No Homebrew tap or core formula in v1. Maintaining a tap
    is real ongoing work; foundation supports adding Homebrew
    later as a layer.
  - No Docker image. Stdio JSON-RPC fights Docker's stdin
    /stdout pattern.
  - No notarization in v1. SHA256 verification through the
    installer preserves the audit trail; README documents the
    Gatekeeper bypass.

Subsystem contract: deployment-installability.md gains
scripts/install-mcp.sh, scripts/install-mcp.ps1, and
cmd/pulse-mcp/ in canonical files (mid-list entries
renumbered) plus a paragraph documenting the new MCP entry
point alongside the existing installer family.

Verification artifacts:

  - scripts/installtests/build_release_assets_test.go gains
    TestBuildReleasePackagesPulseMcpForAllPlatforms which pins
    the build/package/copy wiring and the load-bearing
    install-mcp.sh helpers (platform detection, SHA256
    verification, install-dir resolution).
  - scripts/release_control/render_release_body_test.py gains
    test_agent_paradigm_release_notes_blurb_documents_-
    distribution_path which pins the AGENT_PARADIGM.md draft's
    install-mcp.sh reference and the four-axis frame so a
    future edit cannot regress the install story silently.

Smoke-tested install-mcp.sh locally on darwin-arm64: platform
detection, install-dir resolution, URL building, and 404 error
handling all correct. The full end-to-end install path becomes
live the moment a Pulse release ships pulse-mcp binaries; the
next RC cut will exercise it.
This commit is contained in:
rcourtman 2026-05-10 17:04:49 +01:00
parent 6ea6f11a7d
commit 3da835c5bc
10 changed files with 650 additions and 49 deletions

View file

@ -147,6 +147,32 @@ for i in "${!agent_build_order[@]}"; do
./cmd/pulse-agent
done
# Build pulse-mcp (Model Context Protocol adapter) for the same
# multi-OS matrix as the unified agent. The MCP server runs on
# the integrator's machine (Mac, Windows, Linux desktop) and
# speaks stdio to a local MCP client like Claude Desktop, so it
# needs the full desktop-OS matrix even though the Pulse server
# itself only ships for Linux. The binary takes no version
# ldflags: it reads the manifest from whichever Pulse instance
# it points at, so its own build identity is intentionally minimal.
echo "Building pulse-mcp for all platforms..."
mcp_build_order=("${agent_build_order[@]}")
mcp_build_envs=("${agent_build_envs[@]}")
for i in "${!mcp_build_order[@]}"; do
target="${mcp_build_order[$i]}"
build_env="${mcp_build_envs[$i]}"
output_path="$BUILD_DIR/pulse-mcp-$target"
if [[ "$target" == windows-* ]]; then
output_path="${output_path}.exe"
fi
env $build_env go build \
"${release_go_build_args[@]}" \
-o "$output_path" \
./cmd/pulse-mcp
done
# Build for different architectures (server + agents)
build_order=(linux-amd64 linux-arm64 linux-armv7 linux-armv6 linux-386)
build_envs=(
@ -324,6 +350,26 @@ zip -j "$RELEASE_DIR/pulse-agent-v${VERSION}-windows-amd64.zip" "$BUILD_DIR/puls
zip -j "$RELEASE_DIR/pulse-agent-v${VERSION}-windows-arm64.zip" "$BUILD_DIR/pulse-agent-windows-arm64.exe"
zip -j "$RELEASE_DIR/pulse-agent-v${VERSION}-windows-386.zip" "$BUILD_DIR/pulse-agent-windows-386.exe"
# Package standalone pulse-mcp binaries (all platforms). Mirrors
# the pulse-agent packaging shape exactly so the release-asset
# upload step does not need per-binary special cases.
# Linux
tar -czf "$RELEASE_DIR/pulse-mcp-v${VERSION}-linux-amd64.tar.gz" -C "$BUILD_DIR" pulse-mcp-linux-amd64
tar -czf "$RELEASE_DIR/pulse-mcp-v${VERSION}-linux-arm64.tar.gz" -C "$BUILD_DIR" pulse-mcp-linux-arm64
tar -czf "$RELEASE_DIR/pulse-mcp-v${VERSION}-linux-armv7.tar.gz" -C "$BUILD_DIR" pulse-mcp-linux-armv7
tar -czf "$RELEASE_DIR/pulse-mcp-v${VERSION}-linux-armv6.tar.gz" -C "$BUILD_DIR" pulse-mcp-linux-armv6
tar -czf "$RELEASE_DIR/pulse-mcp-v${VERSION}-linux-386.tar.gz" -C "$BUILD_DIR" pulse-mcp-linux-386
# Darwin
tar -czf "$RELEASE_DIR/pulse-mcp-v${VERSION}-darwin-amd64.tar.gz" -C "$BUILD_DIR" pulse-mcp-darwin-amd64
tar -czf "$RELEASE_DIR/pulse-mcp-v${VERSION}-darwin-arm64.tar.gz" -C "$BUILD_DIR" pulse-mcp-darwin-arm64
# FreeBSD
tar -czf "$RELEASE_DIR/pulse-mcp-v${VERSION}-freebsd-amd64.tar.gz" -C "$BUILD_DIR" pulse-mcp-freebsd-amd64
tar -czf "$RELEASE_DIR/pulse-mcp-v${VERSION}-freebsd-arm64.tar.gz" -C "$BUILD_DIR" pulse-mcp-freebsd-arm64
# Windows (zip archives with version in filename)
zip -j "$RELEASE_DIR/pulse-mcp-v${VERSION}-windows-amd64.zip" "$BUILD_DIR/pulse-mcp-windows-amd64.exe"
zip -j "$RELEASE_DIR/pulse-mcp-v${VERSION}-windows-arm64.zip" "$BUILD_DIR/pulse-mcp-windows-arm64.exe"
zip -j "$RELEASE_DIR/pulse-mcp-v${VERSION}-windows-386.zip" "$BUILD_DIR/pulse-mcp-windows-386.exe"
# Also copy bare binaries for /releases/latest/download/ redirect compatibility
# These allow LXC/barebone installs to redirect to GitHub without needing versioned URLs
echo "Copying bare binaries to release directory for redirect compatibility..."
@ -338,6 +384,22 @@ cp "$BUILD_DIR/pulse-agent-windows-386.exe" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-agent-freebsd-amd64" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-agent-freebsd-arm64" "$RELEASE_DIR/"
# Copy bare pulse-mcp binaries for /releases/latest/download/ redirect
# compatibility. The install-mcp.sh installer fetches these directly from
# the GitHub Releases endpoint without needing a versioned URL.
cp "$BUILD_DIR/pulse-mcp-linux-amd64" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-linux-arm64" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-linux-armv7" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-linux-armv6" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-linux-386" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-darwin-amd64" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-darwin-arm64" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-windows-amd64.exe" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-windows-arm64.exe" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-windows-386.exe" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-freebsd-amd64" "$RELEASE_DIR/"
cp "$BUILD_DIR/pulse-mcp-freebsd-arm64" "$RELEASE_DIR/"
# Copy Windows, macOS, and FreeBSD binaries into universal tarball for /download/ endpoint
echo "Adding Windows, macOS, and FreeBSD binaries to universal tarball..."
cp "$BUILD_DIR/pulse-agent-darwin-amd64" "$universal_dir/bin/"
@ -383,6 +445,8 @@ cp "${RENDERED_INSTALLERS_DIR}/install.sh" "$RELEASE_DIR/install.sh"
[ -f "${RENDERED_INSTALLERS_DIR}/install.ps1" ] && cp "${RENDERED_INSTALLERS_DIR}/install.ps1" "$RELEASE_DIR/install.ps1"
cp scripts/install-docker.sh "$RELEASE_DIR/"
cp scripts/pulse-auto-update.sh "$RELEASE_DIR/"
cp scripts/install-mcp.sh "$RELEASE_DIR/install-mcp.sh"
[ -f scripts/install-mcp.ps1 ] && cp scripts/install-mcp.ps1 "$RELEASE_DIR/install-mcp.ps1"
pulse_release_generate_packet_sbom "${RELEASE_DIR}" "${RELEASE_PACKET_SBOM}"
mapfile -t checksum_files < <(pulse_release_collect_checksum_files "${RELEASE_DIR}")