From 3547db27d747bb89c211a95bbc7dc5b7ea18b7e6 Mon Sep 17 00:00:00 2001 From: John Qiu Date: Sun, 15 Mar 2026 00:26:24 +1030 Subject: [PATCH] fix(init): use claude mcp add for new Claude Code, install skills to ~/.claude/skills/ - Detect claude CLI availability; if present, use `claude mcp add` with --transport http (Streamable HTTP) instead of writing .mcp.json - Fall back to .mcp.json for environments without claude CLI - Install skills directly to ~/.claude/skills/ (where Claude Code reads them) - Remove marketplace/plugin registration (not used by Claude Code) Co-Authored-By: Claude Opus 4.6 --- init.sh | 100 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 33 deletions(-) diff --git a/init.sh b/init.sh index f2375b1..fc2f9d0 100755 --- a/init.sh +++ b/init.sh @@ -1,6 +1,6 @@ #!/bin/bash -# ai-proj-helper MCP 初始化脚本 -# 为用户配置 ai-proj MCP 连接 +# ai-proj-helper 初始化脚本 +# 配置 MCP 连接 + 安装技能到 ~/.claude/skills/ set -e @@ -51,6 +51,12 @@ read_config_value() { CONFIG_MODE=$(read_config_value "mode" "sse") +# ── Detect claude CLI ──────────────────────────────────────────────── +HAS_CLAUDE=false +if command -v claude &>/dev/null; then + HAS_CLAUDE=true +fi + # ── Interactive mode selection ──────────────────────────────────────── if [ -z "$MODE" ]; then echo "┌─────────────────────────────────────┐" @@ -58,7 +64,7 @@ if [ -z "$MODE" ]; then echo "└─────────────────────────────────────┘" echo "" echo "MCP 连接模式:" - echo " 1) sse - 远程 SSE 连接 (推荐,零依赖)" + echo " 1) sse - 远程连接 (推荐,零依赖)" echo " 2) stdio - 本地进程 (需要 Node.js + mcp-task-bridge)" echo "" read -p "选择模式 [1/2] (default: $([ "$CONFIG_MODE" = "stdio" ] && echo "2" || echo "1")): " mode_choice @@ -87,17 +93,26 @@ fi echo "" echo "配置信息:" echo " 模式: $MODE" +echo " Claude CLI: $($HAS_CLAUDE && echo '检测到' || echo '未检测到 (回退写 .mcp.json)')" if [ "$MODE" = "sse" ]; then - echo " SSE: $SSE_URL" + echo " URL: $SSE_URL" else echo " API: $API_BASE" fi echo "" -# ── SSE mode ───────────────────────────────────────────────────────── +# ── Configure MCP ──────────────────────────────────────────────────── if [ "$MODE" = "sse" ]; then - mkdir -p "$(dirname "$MCP_CONFIG")" - cat > "$MCP_CONFIG" << EOF + if $HAS_CLAUDE; then + # 新版 Claude Code: 用 claude mcp add 注册(transport=http,即 Streamable HTTP) + # 先移除旧配置(忽略错误) + claude mcp remove -s user ai-proj 2>/dev/null || true + claude mcp add ai-proj "$SSE_URL" -t http -s user -H "X-API-Key: $TOKEN" 2>&1 + echo "✅ 已通过 claude mcp add 注册 (Streamable HTTP)" + else + # 旧版或无 CLI: 回退写 .mcp.json + mkdir -p "$(dirname "$MCP_CONFIG")" + cat > "$MCP_CONFIG" << EOF { "mcpServers": { "ai-proj": { @@ -110,9 +125,9 @@ if [ "$MODE" = "sse" ]; then } } EOF - echo "✅ 已生成 $MCP_CONFIG (SSE 模式)" + echo "✅ 已生成 $MCP_CONFIG (SSE 模式)" + fi -# ── stdio mode: ensure mcp-task-bridge ──────────────────────────────── elif [ "$MODE" = "stdio" ]; then if [ ! -d "$MCP_BRIDGE_DIR" ]; then echo "📦 mcp-task-bridge 未找到,正在克隆..." @@ -129,8 +144,13 @@ elif [ "$MODE" = "stdio" ]; then BRIDGE_ENTRY="$MCP_BRIDGE_DIR/dist/index.js" - mkdir -p "$(dirname "$MCP_CONFIG")" - cat > "$MCP_CONFIG" << EOF + if $HAS_CLAUDE; then + claude mcp remove -s user ai-proj 2>/dev/null || true + claude mcp add ai-proj -s user -e "NODE_ENV=production" -e "TASK_API_BASE=$API_BASE" -e "TASK_API_TOKEN=$TOKEN" -e "MCP_SERVER_NAME=ai-proj" -- node "$BRIDGE_ENTRY" 2>&1 + echo "✅ 已通过 claude mcp add 注册 (stdio)" + else + mkdir -p "$(dirname "$MCP_CONFIG")" + cat > "$MCP_CONFIG" << EOF { "mcpServers": { "ai-proj": { @@ -146,26 +166,36 @@ elif [ "$MODE" = "stdio" ]; then } } EOF - echo "✅ 已生成 $MCP_CONFIG (stdio 模式)" + echo "✅ 已生成 $MCP_CONFIG (stdio 模式)" + fi fi -# ── Register skill marketplace ─────────────────────────────────────── -echo "📦 注册技能市场..." -SCRIPT_DIR="$SCRIPT_DIR" python3 << 'PYEOF' -import json, os, datetime -path = os.path.expanduser("~/.claude/plugins/known_marketplaces.json") -os.makedirs(os.path.dirname(path), exist_ok=True) -data = json.load(open(path)) if os.path.exists(path) else {} -script_dir = os.environ["SCRIPT_DIR"] -data["ai-proj-helper"] = { - "source": {"source": "directory", "path": script_dir}, - "installLocation": script_dir, - "lastUpdated": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z") -} -with open(path, "w") as f: - json.dump(data, f, indent=2) -PYEOF -echo "✅ 已注册技能市场到 ~/.claude/plugins/known_marketplaces.json" +# ── Install skills to ~/.claude/skills/ ────────────────────────────── +echo "📦 安装技能到 ~/.claude/skills/ ..." +SKILLS_DIR="$HOME/.claude/skills" +mkdir -p "$SKILLS_DIR" + +SKILL_COUNT=0 +for plugin_dir in "$SCRIPT_DIR"/skills-*/; do + for skill_path in "$plugin_dir"*-plugin/; do + [ -d "$skill_path" ] || continue + skill_md="$skill_path/skills/SKILL.md" + [ -f "$skill_md" ] || continue + + # Extract skill name: ai-proj-plugin -> ai-proj + dir_name=$(basename "$skill_path") + skill_name="${dir_name%-plugin}" + + target_dir="$SKILLS_DIR/$skill_name" + mkdir -p "$target_dir" + + # Copy SKILL.md (overwrite if exists) + cp "$skill_md" "$target_dir/SKILL.md" + SKILL_COUNT=$((SKILL_COUNT + 1)) + done +done +echo " 已安装 $SKILL_COUNT 个技能" +echo "✅ 技能安装完成 → $SKILLS_DIR" echo "" echo "┌─────────────────────────────────────┐" @@ -173,8 +203,12 @@ echo "│ ✅ 初始化完成! │" echo "└─────────────────────────────────────┘" echo "" echo "已完成配置:" -echo " ✅ MCP 服务器 → $MCP_CONFIG" -echo " ✅ 技能市场 → ~/.claude/plugins/known_marketplaces.json" +if $HAS_CLAUDE; then + echo " ✅ MCP 服务器 (claude mcp add)" +else + echo " ✅ MCP 服务器 → $MCP_CONFIG" +fi +echo " ✅ 技能 ($SKILL_COUNT 个) → $SKILLS_DIR" echo "" -echo "下次启动 Claude Code 即可使用。" -echo "如需更改模式,编辑 claude-config.yaml 后重新运行 ./init.sh" +echo "重启 Claude Code 即可使用。" +echo "如需更改配置,编辑 claude-config.yaml 后重新运行 ./init.sh"