diff --git a/.github/workflows/_smoke.yml b/.github/workflows/_smoke.yml index d2429db4e..75e4506fb 100644 --- a/.github/workflows/_smoke.yml +++ b/.github/workflows/_smoke.yml @@ -194,3 +194,22 @@ jobs: scripts/security-strings.sh ./codebase-memory-mcp scripts/security-install.sh ./codebase-memory-mcp scripts/security-network.sh ./codebase-memory-mcp + + # ── Glama directory check image (non-gating) ────────────────────── + # Builds packaging/glama/Dockerfile — the image Glama builds to score the + # server — and runs an MCP initialize + tools/list handshake to confirm the + # containerized stdio server still starts and introspects. Guards the Glama + # listing integration against drift (Dockerfile breakage, release-asset + # renames, introspection regressions). + # + # continue-on-error: a broken *directory* image must never block a release — + # the shipped product binaries are unaffected. The red X is the signal to fix + # the Glama integration, not a release gate. + smoke-glama-image: + runs-on: ubuntu-latest + timeout-minutes: 10 + continue-on-error: true + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Build Glama image and verify MCP introspection + run: bash packaging/glama/verify.sh diff --git a/glama.json b/glama.json new file mode 100644 index 000000000..a8304bca0 --- /dev/null +++ b/glama.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://glama.ai/mcp/schemas/server.json", + "maintainers": ["DeusData"] +} diff --git a/packaging/glama/Dockerfile b/packaging/glama/Dockerfile new file mode 100644 index 000000000..52d364a72 --- /dev/null +++ b/packaging/glama/Dockerfile @@ -0,0 +1,25 @@ +# Glama MCP directory (glama.ai) check image — NOT required to run the tool. +# +# codebase-memory-mcp ships as a single, fully-static Linux binary (gcc -static) +# and needs NO Docker to run. This image exists only so Glama can build a +# sandbox, launch the stdio MCP server, and run its introspection checks, which +# power the directory's score badge. The same image is exercised locally and in +# CI by packaging/glama/verify.sh to guard against drift. +# +# The binary is static, so the runtime base is arbitrary. We fetch the latest +# released binary for the build platform's architecture (TARGETARCH is amd64 / +# arm64, matching the release asset names). + +FROM debian:bookworm-slim AS fetch +ARG TARGETARCH +RUN apt-get update \ + && apt-get install -y --no-install-recommends curl ca-certificates \ + && curl -fsSL "https://github.com/DeusData/codebase-memory-mcp/releases/latest/download/codebase-memory-mcp-linux-${TARGETARCH}.tar.gz" \ + | tar -xz -C /tmp codebase-memory-mcp \ + && chmod +x /tmp/codebase-memory-mcp \ + && rm -rf /var/lib/apt/lists/* + +FROM debian:bookworm-slim +COPY --from=fetch /tmp/codebase-memory-mcp /usr/local/bin/codebase-memory-mcp +ENV CBM_CACHE_DIR=/tmp/cbm +ENTRYPOINT ["codebase-memory-mcp"] diff --git a/packaging/glama/verify.sh b/packaging/glama/verify.sh new file mode 100755 index 000000000..0a7950a32 --- /dev/null +++ b/packaging/glama/verify.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Build the Glama check image and confirm the MCP stdio server starts and +# answers initialize + tools/list with no project indexed — exactly what +# Glama's directory check does. Used locally and by the CI smoke suite. +# +# Env: +# IMAGE image tag to build (default: cbm-glama-check) +# DOCKER_BUILD_ARGS extra args for `docker build` (e.g. --platform linux/amd64) +set -euo pipefail + +IMAGE="${IMAGE:-cbm-glama-check}" +DIR="$(cd "$(dirname "$0")" && pwd)" + +run_with_timeout() { + local t="$1"; shift + if command -v timeout >/dev/null 2>&1; then timeout "$t" "$@" + elif command -v gtimeout >/dev/null 2>&1; then gtimeout "$t" "$@" + else "$@"; fi +} + +echo "==> building ${IMAGE} (${DIR}/Dockerfile)" +# shellcheck disable=SC2086 +docker build ${DOCKER_BUILD_ARGS:-} -f "${DIR}/Dockerfile" -t "${IMAGE}" "${DIR}" + +echo "==> MCP introspection handshake (initialize -> initialized -> tools/list)" +REQ="$(printf '%s\n%s\n%s\n' \ + '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"glama-verify","version":"1"}}}' \ + '{"jsonrpc":"2.0","method":"notifications/initialized"}' \ + '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}')" +OUT="$(printf '%s' "${REQ}" | run_with_timeout 60 docker run -i --rm "${IMAGE}" || true)" + +printf '%s\n' "${OUT}" + +echo "==> assertions" +printf '%s' "${OUT}" | grep -q '"result"' || { echo "FAIL: no JSON-RPC result (server did not respond)"; exit 1; } +printf '%s' "${OUT}" | grep -q 'search_graph' || { echo "FAIL: tools/list missing expected tool 'search_graph'"; exit 1; } +COUNT="$(printf '%s' "${OUT}" | grep -o '"name"' | wc -l | tr -d ' ')" +echo "PASS: server started and introspected; ~${COUNT} name entries (>=14 tools expected)"