Skip to main content
Glama
verify-mcp-clients.sh3.4 kB
#!/usr/bin/env bash set -euo pipefail # Validate CLI presence/version and basic handshake per model. # Optional: set EXERCISE_CLI=1 to also invoke the model CLI via executeTask. # # Usage: scripts/verify-mcp-clients.sh [claude codex gemini] ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" MODELS=("$@") if [ ${#MODELS[@]} -eq 0 ]; then MODELS=(claude codex gemini) fi EXERCISE_CLI="${EXERCISE_CLI:-0}" MAIN="src/main.js" min_version() { case "$1" in claude) echo "1.0.128" ;; codex) echo "0.73.0" ;; gemini) echo "0.21.0" ;; *) echo "0.0.0" ;; esac } version_ge() { # returns 0 if $1 >= $2 [ "$(printf '%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ] } for model in "${MODELS[@]}"; do echo "=== [$model] ===" CLEANUP_FILES=() if ! command -v "$model" >/dev/null 2>&1; then echo "[skip] $model not installed" continue fi version="$($model --version 2>&1 | head -n1 || true)" minver="$(min_version "$model")" echo "[info] version: ${version:-unknown} (min $minver)" if [ -n "$version" ] && ! version_ge "$version" "$minver"; then echo "[fail] $model version below minimum; skipping further checks" continue fi # Create a temp config per model CFG="$(mktemp -t mcp-${model}-config.XXXX.json)" OUT="$(mktemp -t mcp-${model}-out.XXXX)" ERR="$(mktemp -t mcp-${model}-err.XXXX)" CLEANUP_FILES+=("$CFG" "$OUT" "$ERR") trap 'rm -f "${CLEANUP_FILES[@]}"' EXIT cat >"$CFG" <<EOF { "name": "test-${model}-server", "model": "${model}", "tools": [ { "name": "echo-${model}", "description": "echo tool for ${model}", "prompt": "echo hello-${model}", "inputs": [] } ] } EOF if ! node "$MAIN" --config "$CFG" --handshake-and-exit >"$OUT" 2>"$ERR"; then echo "[fail] handshake exited non-zero (see $OUT / $ERR)" continue fi if grep -qi 'error' "$OUT" "$ERR"; then echo "[fail] handshake output contains 'error' (see $OUT / $ERR)" continue fi if ! node -e "JSON.parse(require('fs').readFileSync('$OUT','utf8'))" >/dev/null 2>&1; then echo "[fail] handshake stdout not JSON (see $OUT)" continue fi echo "[pass] handshake ok" if [ "$EXERCISE_CLI" = "1" ]; then if [ "$model" = "gemini" ] && [ "${SKIP_GEMINI_EXERCISE:-1}" = "1" ]; then echo "[info] skipping gemini CLI exercise (set SKIP_GEMINI_EXERCISE=0 to force)" continue fi CLI_OUT="$(mktemp -t mcp-${model}-cli-out.XXXX)" CLI_ERR="$(mktemp -t mcp-${model}-cli-err.XXXX)" CLEANUP_FILES+=("$CLI_OUT" "$CLI_ERR") if ! NODE_ENV=test node -e "const { executeTask } = require('./src/main'); (async () => { const res = await executeTask('${model}', undefined, 'Reply with hello-${model} and nothing else.', process.cwd()); console.log(JSON.stringify(res)); process.exit(res.exitCode === 0 ? 0 : 1); })();" >"$CLI_OUT" 2>"$CLI_ERR"; then echo "[fail] CLI task failed to execute (see $CLI_OUT / $CLI_ERR)" continue fi if grep -qi 'error' "$CLI_OUT" "$CLI_ERR"; then echo "[fail] CLI task output contains 'error' (see $CLI_OUT / $CLI_ERR)" continue fi if ! grep -qi "hello-${model}" "$CLI_OUT"; then echo "[fail] CLI task output missing expected text (see $CLI_OUT)" continue fi echo "[pass] CLI task ok" else echo "[info] CLI task skipped (set EXERCISE_CLI=1 to run)" fi done

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PortlandKyGuy/dynamic-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server