Files
ely-eye/ely-eye-mcp/install.sh
T
ZacharyZhang-NY 4cd29f91e5 Add Ely-Eye MCP server
Local read-only Model Context Protocol server (Go) exposing the .ely_eye memory
store to coding agents such as Codex and Claude Code: nine tools over status,
cartridges, Evidence Atoms, compiled evidence packs, proof suites, and HashHop
proofs. One-line cross-platform install (no Docker), with a prebuilt-binary
release workflow.
2026-05-30 23:51:45 -04:00

144 lines
4.5 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
# Ely-Eye MCP installer for Linux and macOS.
#
# curl -fsSL https://raw.githubusercontent.com/ZacharyZhang-NY/ely-eye/main/ely-eye-mcp/install.sh | bash
#
# By default it downloads a prebuilt, checksum-verified binary for this platform
# and needs no toolchain. Run with --method source from a repository checkout to
# build with Go instead. The binary is installed into <ely-eye-home>/bin and
# registered with Codex and Claude Code.
REPO="ZacharyZhang-NY/ely-eye"
CLIENT="both"
SCOPE="project"
SERVER_NAME="ely-eye"
METHOD="auto"
VERSION=""
PROJECT_ROOT=""
ELY_EYE_HOME=""
while [[ $# -gt 0 ]]; do
case "$1" in
--client) CLIENT="$2"; shift 2 ;;
--scope) SCOPE="$2"; shift 2 ;;
--server-name) SERVER_NAME="$2"; shift 2 ;;
--method) METHOD="$2"; shift 2 ;;
--version) VERSION="$2"; shift 2 ;;
--project-root) PROJECT_ROOT="$2"; shift 2 ;;
--ely-eye-home) ELY_EYE_HOME="$2"; shift 2 ;;
--repo) REPO="$2"; shift 2 ;;
*) echo "unknown argument: $1" >&2; exit 1 ;;
esac
done
case "$METHOD" in auto | download | source) ;; *) echo "method must be auto, download, or source" >&2; exit 1 ;; esac
SOURCE="${BASH_SOURCE[0]:-}"
SCRIPT_DIR=""
if [[ -n "$SOURCE" && -f "$SOURCE" ]]; then
SCRIPT_DIR="$(cd -- "$(dirname -- "$SOURCE")" && pwd)"
fi
if [[ -z "$PROJECT_ROOT" ]]; then
if [[ -n "$SCRIPT_DIR" && -f "$SCRIPT_DIR/go.mod" ]]; then
PROJECT_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
else
PROJECT_ROOT="$PWD"
fi
fi
PROJECT_ROOT="$(cd -- "$PROJECT_ROOT" && pwd)"
[[ -z "$ELY_EYE_HOME" ]] && ELY_EYE_HOME="$PROJECT_ROOT/.ely_eye"
mkdir -p "$ELY_EYE_HOME/bin"
BINARY="$ELY_EYE_HOME/bin/ely-eye-mcp"
detect_platform() {
local os arch
case "$(uname -s)" in
Linux) os="linux" ;;
Darwin) os="darwin" ;;
*) echo "unsupported operating system: $(uname -s)" >&2; exit 1 ;;
esac
case "$(uname -m)" in
x86_64 | amd64) arch="amd64" ;;
arm64 | aarch64) arch="arm64" ;;
*) echo "unsupported architecture: $(uname -m)" >&2; exit 1 ;;
esac
echo "${os}_${arch}"
}
sha256() {
if command -v sha256sum >/dev/null 2>&1; then
sha256sum "$1" | awk '{print $1}'
else
shasum -a 256 "$1" | awk '{print $1}'
fi
}
resolve_version() {
if [[ -n "$VERSION" ]]; then echo "$VERSION"; return 0; fi
local body
body="$(curl -fsSL "https://api.github.com/repos/${REPO}/releases" 2>/dev/null)" || return 0
printf '%s\n' "$body" \
| grep -oE '"tag_name": *"mcp-[^"]*"' \
| head -n 1 \
| sed -E 's/.*"(mcp-[^"]*)".*/\1/' || true
}
build_from_source() {
command -v go >/dev/null 2>&1 || { echo "Go 1.25 or newer is required to build from source." >&2; exit 1; }
[[ -n "$SCRIPT_DIR" && -f "$SCRIPT_DIR/go.mod" ]] || { echo "source builds must run from a repository checkout." >&2; exit 1; }
echo "Building ely-eye-mcp from source with Go."
( cd "$SCRIPT_DIR" && CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o "$BINARY" ./cmd/ely-eye-mcp )
}
download_binary() {
local tag="$1" platform asset url sums tmp
platform="$(detect_platform)"
asset="ely-eye-mcp_${platform}.tar.gz"
url="https://github.com/${REPO}/releases/download/${tag}/${asset}"
sums="https://github.com/${REPO}/releases/download/${tag}/ely-eye-mcp_SHA256SUMS.txt"
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' RETURN
echo "Downloading $asset from release $tag."
curl -fsSL "$url" -o "$tmp/$asset"
curl -fsSL "$sums" -o "$tmp/SHA256SUMS"
local expected actual
expected="$(grep -E " \*?${asset}\$" "$tmp/SHA256SUMS" | awk '{print $1}' || true)"
[[ -n "$expected" ]] || { echo "checksum for $asset not found in release." >&2; exit 1; }
actual="$(sha256 "$tmp/$asset")"
[[ "$expected" == "$actual" ]] || { echo "checksum mismatch for $asset." >&2; exit 1; }
tar -xzf "$tmp/$asset" -C "$tmp"
mv "$tmp/ely-eye-mcp" "$BINARY"
chmod +x "$BINARY"
}
acquire() {
case "$METHOD" in
source) build_from_source; return ;;
download)
local tag; tag="$(resolve_version)"
[[ -n "$tag" ]] || { echo "no prebuilt release found for ${REPO}." >&2; exit 1; }
download_binary "$tag"; return ;;
auto)
local tag; tag="$(resolve_version)"
if [[ -n "$tag" ]]; then
download_binary "$tag"
else
echo "No prebuilt release available; building from source."
build_from_source
fi ;;
esac
}
acquire
"$BINARY" setup \
--client "$CLIENT" \
--scope "$SCOPE" \
--server-name "$SERVER_NAME" \
--project-root "$PROJECT_ROOT" \
--ely-eye-home "$ELY_EYE_HOME" \
--binary "$BINARY"