Files
wehub-resource-sync 5a558eb09e
Backend Tests / discover-tests (push) Waiting to run
Backend Tests / ${{ matrix.name }} (push) Blocked by required conditions
Build and Publish SDK / build-and-publish (push) Waiting to run
Build Opik Docker Images / set-version (push) Waiting to run
Build Opik Docker Images / build-backend (push) Blocked by required conditions
Build Opik Docker Images / build-sandbox-executor-python (push) Blocked by required conditions
Build Opik Docker Images / build-python-backend (push) Blocked by required conditions
Build Opik Docker Images / build-frontend (push) Blocked by required conditions
Build Opik Docker Images / create-git-tag (push) Blocked by required conditions
ClickHouse Migration Cluster Check / validate-clickhouse-migrations (push) Waiting to run
Docs - Publish / run (push) Waiting to run
E2E Tests - Post Merge (v2) / 🧪 E2E v2 Tests (${{ github.event.inputs.tier || 't1' }}) (push) Waiting to run
E2E Tests - Post Merge (v2) / 📢 Slack Notification (push) Blocked by required conditions
Frontend Unit Tests / Test on Node 20 (push) Waiting to run
Guardrails E2E Tests / Select Python version matrix (push) Waiting to run
Guardrails E2E Tests / Guardrails E2E Tests ${{matrix.python_version}} (push) Blocked by required conditions
Guardrails E2E Tests / 📢 Slack Notification (push) Blocked by required conditions
Guardrails Backend Unit Tests / Guardrails Backend Unit Tests (push) Waiting to run
Guardrails Backend Unit Tests / 📢 Slack Notification (push) Blocked by required conditions
SDK Library Integration Tests Runner / Check Secrets (push) Waiting to run
SDK Library Integration Tests Runner / Missed OpenAI API Key Warning (push) Blocked by required conditions
SDK Library Integration Tests Runner / Build (push) Blocked by required conditions
SDK Library Integration Tests Runner / openai_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / langchain_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / langchain_legacy_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / llama_index_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / anthropic_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / mistral_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / groq_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / aisuite_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / haystack_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / dspy_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / crewai_v0_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / crewai_v1_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / genai_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / adk_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / adk_legacy_1_3_0_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / evaluation_metrics_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / bedrock_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / litellm_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / harbor_tests (push) Blocked by required conditions
SDK Library Integration Tests Runner / Slack Notification (push) Blocked by required conditions
Lint Opik Helm Chart / lint-helm-chart (Helm v3.21.0) (push) Waiting to run
Lint Opik Helm Chart / lint-helm-chart (Helm v4.2.0) (push) Waiting to run
Lint Opik Helm Chart / unittest-helm-chart (push) Waiting to run
Lint Opik Helm Chart / render-equality (push) Waiting to run
Opik Optimizer - Unit Tests / Opik Optimizer Unit Tests Python ${{matrix.python_version}} (push) Waiting to run
Python BE E2E Tests / Python BE E2E (push) Waiting to run
Python Backend Tests / run-python-backend-tests (push) Waiting to run
Python SDK Unit Tests / Python SDK Unit Tests ${{matrix.python_version}} (push) Waiting to run
Release Drafter / update_release_draft (push) Waiting to run
SDK E2E Libraries Integration Tests / Check Secrets (push) Waiting to run
SDK E2E Libraries Integration Tests / Missed OpenAI API Key Warning (push) Blocked by required conditions
SDK E2E Libraries Integration Tests / build-opik (push) Blocked by required conditions
SDK E2E Libraries Integration Tests / E2E Lib Integration Python ${{matrix.python_version}} (push) Blocked by required conditions
TypeScript SDK Integration Build & Publish / build-and-publish (opik-gemini) (push) Waiting to run
TypeScript SDK Integration Build & Publish / build-and-publish (opik-langchain) (push) Waiting to run
TypeScript SDK Integration Build & Publish / build-and-publish (opik-openai) (push) Waiting to run
TypeScript SDK Integration Build & Publish / build-and-publish (opik-otel) (push) Waiting to run
TypeScript SDK Integration Build & Publish / build-and-publish (opik-vercel) (push) Waiting to run
TypeScript SDK Library Integration Tests / Check Secrets (push) Waiting to run
TypeScript SDK Library Integration Tests / opik-vercel (Vercel AI SDK / eve) (push) Blocked by required conditions
TypeScript SDK Build & Publish / build-and-publish (push) Waiting to run
TypeScript SDK Unit Tests / Test on Node ${{ matrix.node-version }} (push) Waiting to run
TypeScript SDK Compatibility V1.x E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / TypeScript SDK Compatibility V1.x E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
TypeScript SDK E2E Tests / TypeScript SDK E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
Python SDK E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK E2E Tests / Python SDK E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK E2E Tests / build-opik (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Python SDK Compatibility V1.x E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK E2E Tests / build-opik (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer E2E Tests Python ${{matrix.python_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer Integration Smoke Tests (push) Has been cancelled
🐙 Code Quality / detect (push) Has been cancelled
🐙 Code Quality / lint (${{ matrix.leg.name }}) (push) Has been cancelled
🐙 Code Quality / summary (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:25:44 +08:00

189 lines
5.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Convert .agents/mcp.json (Cursor format) to .mcp.json (Claude CLI format)
# Usage: convert-mcp.sh <input-file> <output-file>
#
# Transformations:
# 1. Replace ${workspaceFolder}/ with empty string in all paths
# 2. For docker commands with envFile:
# - Add --env-file <path> to args (after --rm if present, otherwise prepend)
# - Remove -e VARNAME pairs (where VARNAME has no =)
# - Remove the envFile property
# 3. For non-docker commands with envFile:
# - Parse the env file and merge into .env map
# - Remove the envFile property
set -euo pipefail
input="${1:-}"
output="${2:-}"
if [[ -z "$input" || -z "$output" ]]; then
echo "Usage: convert-mcp.sh <input-file> <output-file>" >&2
exit 1
fi
if [[ ! -f "$input" ]]; then
echo "Error: Input file '$input' does not exist" >&2
exit 1
fi
if ! command -v jq &> /dev/null; then
echo "Error: jq is required but not installed" >&2
exit 1
fi
# Validate input is valid JSON
if ! jq empty "$input" 2>/dev/null; then
echo "Error: Input file '$input' is not valid JSON" >&2
exit 1
fi
# Helper function to parse env file into JSON object
# Handles: missing files, empty files, comment-only files, special characters
parse_env_file() {
local file="$1"
if [[ ! -f "$file" ]]; then
echo "{}"
return
fi
# Use jq to properly escape values for JSON safety
local pairs=()
while IFS= read -r line || [[ -n "$line" ]]; do
# Skip empty lines and comments
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
# Must contain =
[[ "$line" != *"="* ]] && continue
# Split on first = only
key="${line%%=*}"
value="${line#*=}"
# Trim whitespace from key
key="${key#"${key%%[![:space:]]*}"}"
key="${key%"${key##*[![:space:]]}"}"
# Skip if key is empty
[[ -z "$key" ]] && continue
# Clean ${workspaceFolder}/ from value
value="${value//\$\{workspaceFolder\}\//}"
# Use jq to safely escape both key and value
pairs+=("$(jq -n --arg k "$key" --arg v "$value" '{($k): $v}')")
done < "$file"
# Merge all pairs into single object
if [[ ${#pairs[@]} -eq 0 ]]; then
echo "{}"
else
printf '%s\n' "${pairs[@]}" | jq -s 'add // {}'
fi
}
# Pre-parse env files for non-docker commands
# Build a JSON object mapping cleaned envFile path -> parsed env vars
env_data="{}"
# Check if mcpServers exists and has entries
if jq -e '.mcpServers // empty | keys | length > 0' "$input" >/dev/null 2>&1; then
while IFS= read -r env_path; do
[[ -z "$env_path" ]] && continue
parsed=$(parse_env_file "$env_path")
[[ "$parsed" == "{}" ]] && continue
env_data=$(echo "$env_data" | jq --arg path "$env_path" --argjson vars "$parsed" '. + {($path): $vars}')
done < <(jq -r '
.mcpServers // {} | to_entries[] |
select(.value.envFile and .value.command != "docker") |
.value.envFile |
gsub("\\$\\{workspaceFolder\\}/"; "")
' "$input" 2>/dev/null | sort -u)
fi
jq --argjson envData "$env_data" '
# Helper: clean ${workspaceFolder}/ from paths
def clean_path:
if type == "string" then gsub("\\$\\{workspaceFolder\\}/"; "") else . end;
# Helper: safely get array, defaulting null/non-array to []
def safe_array:
if type == "array" then . else [] end;
# Helper: safely get object, defaulting null/non-object to {}
def safe_object:
if type == "object" then . else {} end;
# Helper: remove -e VARNAME pairs where VARNAME has no = (env vars provided by env-file)
def remove_standalone_env_vars:
safe_array |
. as $arr |
reduce range(0; $arr | length) as $i (
{result: [], skip: false};
if .skip then
.skip = false
elif ($arr[$i] == "-e") and ($i + 1 < ($arr | length)) and (($arr[$i + 1] // "") | tostring | contains("=") | not) then
.skip = true
else
.result += [$arr[$i]]
end
) | .result;
# Helper: insert --env-file into args
# Tries to insert after --rm; if --rm not found, prepends to args
def insert_env_file($path):
safe_array |
if any(. == "--rm") then
# Insert after --rm
reduce .[] as $item (
[];
. + [$item] + (if $item == "--rm" then ["--env-file", $path] else [] end)
)
else
# Prepend --env-file to args
["--env-file", $path] + .
end;
# Main transformation - handle missing/null mcpServers gracefully
if .mcpServers | type == "object" then
.mcpServers |= with_entries(
# Skip null server entries
if .value | type != "object" then .
else
.value |= (
# Get cleaned envFile path if present and non-empty
(if (.envFile // "") | length > 0 then (.envFile | clean_path) else null end) as $envPath |
# Transform based on command type
if .command == "docker" and $envPath then
# Docker: move envFile to --env-file arg, remove standalone -e vars
.args = (.args | remove_standalone_env_vars | insert_env_file($envPath)) |
del(.envFile)
elif $envPath then
# Non-docker: parse envFile and merge into .env map
# (Claude CLI only expands envFile for docker commands)
($envData[$envPath] // {}) as $parsedEnv |
.env = ((.env | safe_object) + $parsedEnv) |
del(.envFile)
else
.
end |
# Clean ${workspaceFolder}/ from cwd if present
if .cwd then .cwd |= clean_path else . end |
# Clean ${workspaceFolder}/ from env values if present
if .env | type == "object" then
.env |= with_entries(
if .value | type == "string" then .value |= clean_path else . end
)
else . end
)
end
)
else
.
end
' "$input" > "$output"
echo " Converted MCP config: $input -> $output"