Merge branch 'session-combined'

This commit is contained in:
Martin Vogel committed 2026-06-09 11:57:03 +02:00
commit 8d6dfc5758
14 files changed
+207 -40

No files matched your search

+26
View File
@@ -189,8 +189,34 @@ jobs:
chmod +x codebase-memory-mcp
scripts/smoke-test.sh ./codebase-memory-mcp
# The -portable binary is what all linux install/update paths now deliver;
# it MUST start on old glibc (Debian 11 / RHEL 8 / Ubuntu 20.04). Runs it
# in debian:bullseye (glibc 2.31) — the standard dynamic binary would fail
# here with `GLIBC_2.38 not found`.
- name: Old-glibc compatibility
run: scripts/ci/check-glibc-compat.sh ./codebase-memory-mcp
- name: Security audits
run: |
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
+38
View File
@@ -308,6 +308,44 @@ jobs:
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
run: twine upload --non-interactive dist/*
# ── 8b. Publish server.json to the official MCP Registry ──────
# Runs after npm + PyPI so the registry can verify package ownership
# (npm: `mcpName` field in package.json; PyPI: `mcp-name:` marker in
# the package README). Authenticates with GitHub Actions OIDC — no
# token, no interactive device flow. server.json's version is synced
# from the just-published npm package so it always matches the release.
#
# Intentionally does NOT gate publish-final: the binary release is the
# product, the registry entry is metadata. A registry-preview outage
# must never block shipping. Re-run this job alone to retry — it does
# not touch npm/PyPI, so retries are safe.
publish-mcp-registry:
needs: [publish-registries]
runs-on: ubuntu-latest
permissions:
id-token: write # GitHub OIDC auth to the MCP Registry
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Sync server.json version to the released package
run: |
VERSION=$(jq -r '.version' pkg/npm/package.json)
jq --arg v "$VERSION" '.version = $v | (.packages[].version) = $v' \
server.json > server.tmp && mv server.tmp server.json
echo "server.json pinned to $VERSION"
cat server.json
- name: Install mcp-publisher
run: |
curl -fsSL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
- name: Authenticate to MCP Registry (GitHub OIDC)
run: ./mcp-publisher login github-oidc
- name: Publish server.json to MCP Registry
run: ./mcp-publisher publish
# ── 9. Atomic un-draft (only after npm + PyPI succeed) ────────
# The GitHub release stays in DRAFT until both registries publish.
# If anything upstream fails, the draft can be deleted and the run
+4
View File
@@ -0,0 +1,4 @@
{
"$schema": "https://glama.ai/mcp/schemas/server.json",
"maintainers": ["DeusData"]
}
+8 -2
View File
@@ -97,10 +97,16 @@ else
EXT="tar.gz"
fi
# Linux ships a fully-static "-portable" build; the standard linux binary
# dynamically links glibc 2.38+ and fails on older distros (Debian 11, RHEL 8,
# Ubuntu 20.04). macOS/Windows have no such variant.
PORTABLE=""
[ "$OS" = "linux" ] && PORTABLE="-portable"
if [ "$VARIANT" = "ui" ]; then
ARCHIVE="codebase-memory-mcp-ui-${OS}-${ARCH}.${EXT}"
ARCHIVE="codebase-memory-mcp-ui-${OS}-${ARCH}${PORTABLE}.${EXT}"
else
ARCHIVE="codebase-memory-mcp-${OS}-${ARCH}.${EXT}"
ARCHIVE="codebase-memory-mcp-${OS}-${ARCH}${PORTABLE}.${EXT}"
fi
URL="${CBM_DOWNLOAD_URL}/${ARCHIVE}"
+25
View File
@@ -0,0 +1,25 @@
# Glama MCP directory (glama.ai) check image — NOT required to run the tool.
#
# codebase-memory-mcp 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.
#
# We pull the "-portable" release asset, which is fully statically linked
# (gcc -static) — unlike the standard asset, which dynamically links glibc/
# libstdc++ and would fail on an older base. Because it's static, the runtime
# base image is arbitrary. TARGETARCH is amd64 / arm64, matching the 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}-portable.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"]
+38
View File
@@ -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)"
+5 -1
View File
@@ -105,7 +105,11 @@ async function main() {
fs.mkdirSync(BIN_DIR, { recursive: true });
const archive = `codebase-memory-mcp-${platform}-${arch}.${ext}`;
// Linux ships a fully-static "-portable" build; the standard linux binary
// dynamically links glibc 2.38+ and fails on older distros. macOS/Windows
// have no such variant. Keep in sync with install.sh / pypi _cli.py / cli.c.
const variant = platform === 'linux' ? '-portable' : '';
const archive = `codebase-memory-mcp-${platform}-${arch}${variant}.${ext}`;
const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${archive}`;
process.stdout.write(`codebase-memory-mcp: downloading v${VERSION} for ${platform}/${arch}...\n`);
+1
View File
@@ -2,6 +2,7 @@
"name": "codebase-memory-mcp",
"version": "0.7.0",
"description": "Fast code intelligence engine for AI coding agents — single static binary MCP server",
"mcpName": "io.github.DeusData/codebase-memory-mcp",
"license": "MIT",
"repository": {
"type": "git",
+2
View File
@@ -1,5 +1,7 @@
# codebase-memory-mcp
mcp-name: io.github.DeusData/codebase-memory-mcp
**Fast code intelligence engine for AI coding agents.** Indexes an average repository in milliseconds, the Linux kernel (28M LOC) in 3 minutes. Answers structural queries in under 1ms.
This package installs the `codebase-memory-mcp` binary from [GitHub Releases](https://github.com/DeusData/codebase-memory-mcp/releases). The binary is downloaded on first run and cached in your OS cache directory.
+5 -1
View File
@@ -153,7 +153,11 @@ def _download(version: str) -> Path:
os_name = _os_name()
arch = _arch()
ext = "zip" if os_name == "windows" else "tar.gz"
archive = f"codebase-memory-mcp-{os_name}-{arch}.{ext}"
# Linux ships a fully-static "-portable" build; the standard linux binary
# dynamically links glibc 2.38+ and fails on older distros. macOS/Windows
# have no such variant. Keep in sync with install.sh / install.js / cli.c.
variant = "-portable" if os_name == "linux" else ""
archive = f"codebase-memory-mcp-{os_name}-{arch}{variant}.{ext}"
url = f"https://github.com/{REPO}/releases/download/v{version}/{archive}"
_validate_url_scheme(url)
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Regression guard: the linux binary we ship must START on OLD glibc.
#
# The standard linux release binary dynamically links glibc 2.38+ / GLIBCXX
# 3.4.32 and fails to start on Debian 11, RHEL/Rocky 8, Ubuntu 20.04, Amazon
# Linux 2, etc. The fix points all linux install + self-update paths at the
# fully-static "-portable" asset. This runs a given linux binary inside an
# old-glibc container (debian:bullseye, glibc 2.31) and asserts it starts:
# - RED for the dynamic standard binary (GLIBC_2.38 not found)
# - GREEN for the static -portable binary (runs anywhere)
#
# Usage: check-glibc-compat.sh <path-to-linux-binary>
# Env: GLIBC_TEST_IMAGE (default: debian:bullseye-slim, glibc 2.31)
set -euo pipefail
BIN="${1:?usage: check-glibc-compat.sh <path-to-linux-binary>}"
IMAGE="${GLIBC_TEST_IMAGE:-debian:bullseye-slim}"
BIN_ABS="$(cd "$(dirname "$BIN")" && pwd)/$(basename "$BIN")"
echo "==> running $(basename "$BIN") --version inside ${IMAGE} (glibc 2.31)"
docker run --rm -v "${BIN_ABS}:/cbm:ro" "${IMAGE}" /cbm --version
echo "PASS: binary starts on old glibc (${IMAGE})"
+11
View File
@@ -597,6 +597,17 @@ if ! echo "$UPDATE_OUT" | grep -qi 'standard'; then
echo "FAIL: update --dry-run did not respect --standard flag"
exit 1
fi
# On Linux the binary must self-update from the static "-portable" asset: the
# standard linux asset dynamically links glibc 2.38+ and breaks on older distros
# (Debian 11, RHEL 8, Ubuntu 20.04). Guards build_update_url in src/cli/cli.c.
if [ "$(uname -s)" = "Linux" ]; then
if ! echo "$UPDATE_OUT" | grep -q -- '-portable'; then
echo "FAIL: linux update --dry-run does not target the -portable asset"
echo "$UPDATE_OUT"
exit 1
fi
echo "OK: linux update targets the -portable (static) asset"
fi
echo "OK: update --dry-run --standard completed"
# 6d: config set/get/reset round-trip
+11 -32
View File
@@ -2,49 +2,28 @@
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "io.github.DeusData/codebase-memory-mcp",
"title": "Codebase Memory",
"description": "Persistent codebase knowledge graph — 159 languages, sub-ms queries, 99% fewer tokens than grep. Survives session restarts and context compaction.",
"description": "Codebase knowledge graph for AI agents — 159 languages, sub-ms queries, 99% fewer tokens.",
"repository": {
"url": "https://github.com/DeusData/codebase-memory-mcp",
"source": "github"
},
"version": "0.6.1",
"websiteUrl": "https://deusdata.github.io/codebase-memory-mcp/",
"version": "0.7.0",
"packages": [
{
"registryType": "mcpb",
"identifier": "https://github.com/DeusData/codebase-memory-mcp/releases/download/v0.6.1/codebase-memory-mcp-darwin-arm64.tar.gz",
"fileSha256": "3468e5df340e53dba2d23cc30bf44210c412dfb2538d7da992465934bf4980e0",
"registryType": "npm",
"identifier": "codebase-memory-mcp",
"version": "0.7.0",
"runtimeHint": "npx",
"transport": {
"type": "stdio"
}
},
{
"registryType": "mcpb",
"identifier": "https://github.com/DeusData/codebase-memory-mcp/releases/download/v0.6.1/codebase-memory-mcp-darwin-amd64.tar.gz",
"fileSha256": "a85f8313181c7ffd3a0ac494c0e2bf1b5647f15de06686f8a0728162bf4326ac",
"transport": {
"type": "stdio"
}
},
{
"registryType": "mcpb",
"identifier": "https://github.com/DeusData/codebase-memory-mcp/releases/download/v0.6.1/codebase-memory-mcp-linux-amd64.tar.gz",
"fileSha256": "a24c04fd1fd61b08158e011685cf08d860e3594e4ce057ffda57d1cc2f4afdd1",
"transport": {
"type": "stdio"
}
},
{
"registryType": "mcpb",
"identifier": "https://github.com/DeusData/codebase-memory-mcp/releases/download/v0.6.1/codebase-memory-mcp-linux-arm64.tar.gz",
"fileSha256": "29811aadc2aa99fb9612683af30a06d03fcb2bfefb95c12ea672671827bd111c",
"transport": {
"type": "stdio"
}
},
{
"registryType": "mcpb",
"identifier": "https://github.com/DeusData/codebase-memory-mcp/releases/download/v0.6.1/codebase-memory-mcp-windows-amd64.zip",
"fileSha256": "e331f84f2ec760d179025b16b440b0f14282e83f2432318969dc69dde8ffffd0",
"registryType": "pypi",
"identifier": "codebase-memory-mcp",
"version": "0.7.0",
"runtimeHint": "uvx",
"transport": {
"type": "stdio"
}
+11 -4
View File
@@ -3761,8 +3761,13 @@ static void build_update_url(char *url, int url_sz, const char *os, const char *
if (!base_url || !base_url[0]) {
base_url = "https://github.com/DeusData/codebase-memory-mcp/releases/latest/download";
}
snprintf(url, url_sz, "%s/codebase-memory-mcp-%s%s-%s.%s", base_url, want_ui ? "ui-" : "", os,
arch, ext);
/* Linux ships a fully-static "-portable" build; the standard linux binary
* dynamically links glibc 2.38+ and fails on older distros. macOS/Windows
* have no such variant. Keep in sync with install.sh / install.js / pypi
* _cli.py. */
const char *portable = (strcmp(os, "linux") == 0) ? "-portable" : "";
snprintf(url, url_sz, "%s/codebase-memory-mcp-%s%s-%s%s.%s", base_url, want_ui ? "ui-" : "", os,
arch, portable, ext);
}
/* Prompt to delete existing indexes. Returns 0 to continue, 1 to abort. */
@@ -3801,8 +3806,10 @@ static int download_verify_install(const char *url, const char *ext, const char
}
char archive_name[CLI_BUF_256];
snprintf(archive_name, sizeof(archive_name), "codebase-memory-mcp-%s%s-%s.%s",
want_ui ? "ui-" : "", os, arch, ext);
/* Must match build_update_url: linux uses the static "-portable" asset. */
const char *portable = (strcmp(os, "linux") == 0) ? "-portable" : "";
snprintf(archive_name, sizeof(archive_name), "codebase-memory-mcp-%s%s-%s%s.%s",
want_ui ? "ui-" : "", os, arch, portable, ext);
int crc = verify_download_checksum(tmp_archive, archive_name);
if (crc == CLI_TRUE) {
cbm_unlink(tmp_archive);