Files
ai-proj-helper/init.sh
John Qiu 3547db27d7 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 <noreply@anthropic.com>
2026-03-15 00:26:24 +10:30

215 lines
7.3 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ai-proj-helper 初始化脚本
# 配置 MCP 连接 + 安装技能到 ~/.claude/skills/
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
MCP_CONFIG="$HOME/.claude/.mcp.json"
MCP_BRIDGE_DIR="$SCRIPT_DIR/mcp-task-bridge"
CONFIG_FILE="$SCRIPT_DIR/claude-config.yaml"
API_BASE="https://ai.pipexerp.com/api/v1"
SSE_URL="${API_BASE}/mcp/sse"
# Default values
MODE=""
TOKEN=""
# ── Parse command line arguments ──────────────────────────────────────
while [[ $# -gt 0 ]]; do
case $1 in
--mode) MODE="$2"; shift 2 ;;
--token) TOKEN="$2"; shift 2 ;;
-h|--help)
echo "Usage: ./init.sh [--mode sse|stdio] [--token MCP_API_KEY]"
echo ""
echo "Options:"
echo " --mode MCP connection mode: sse (remote, recommended) or stdio (local)"
echo " --token MCP API Key (aiproj_pk_xxx)"
echo ""
echo "Without arguments, runs in interactive mode."
exit 0
;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
# ── Read config defaults ─────────────────────────────────────────────
read_config_value() {
local key="$1"
local default="$2"
if [ -f "$CONFIG_FILE" ]; then
local val
val=$(grep "^ ${key}:" "$CONFIG_FILE" 2>/dev/null | head -1 | sed 's/^[^:]*: *//' | sed 's/ *#.*//' | tr -d '"' | tr -d "'")
if [ -n "$val" ]; then
echo "$val"
return
fi
fi
echo "$default"
}
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 "┌─────────────────────────────────────┐"
echo "│ ai-proj MCP 初始化 │"
echo "└─────────────────────────────────────┘"
echo ""
echo "MCP 连接模式:"
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
case "$mode_choice" in
2|stdio) MODE="stdio" ;;
*) MODE="sse" ;;
esac
fi
# ── Token input ───────────────────────────────────────────────────────
if [ -z "$TOKEN" ]; then
echo ""
echo "请输入 MCP API Key:"
echo " 格式: aiproj_pk_xxxxxxxx"
echo " 获取: 登录 AI-Proj → 设置 → MCP API Keys → 创建"
echo ""
read -sp "API Key: " TOKEN
echo ""
fi
if [ -z "$TOKEN" ]; then
echo "❌ API Key 不能为空"
exit 1
fi
echo ""
echo "配置信息:"
echo " 模式: $MODE"
echo " Claude CLI: $($HAS_CLAUDE && echo '检测到' || echo '未检测到 (回退写 .mcp.json)')"
if [ "$MODE" = "sse" ]; then
echo " URL: $SSE_URL"
else
echo " API: $API_BASE"
fi
echo ""
# ── Configure MCP ────────────────────────────────────────────────────
if [ "$MODE" = "sse" ]; then
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": {
"type": "sse",
"url": "$SSE_URL",
"headers": {
"X-API-Key": "$TOKEN"
}
}
}
}
EOF
echo "✅ 已生成 $MCP_CONFIG (SSE 模式)"
fi
elif [ "$MODE" = "stdio" ]; then
if [ ! -d "$MCP_BRIDGE_DIR" ]; then
echo "📦 mcp-task-bridge 未找到,正在克隆..."
git clone https://gitea.pipexerp.com/pipexerp/mcp-task-bridge.git "$MCP_BRIDGE_DIR"
fi
if [ ! -f "$MCP_BRIDGE_DIR/dist/index.js" ]; then
echo "🔨 构建 mcp-task-bridge..."
cd "$MCP_BRIDGE_DIR"
npm install
npm run build
cd "$SCRIPT_DIR"
fi
BRIDGE_ENTRY="$MCP_BRIDGE_DIR/dist/index.js"
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": {
"command": "node",
"args": ["$BRIDGE_ENTRY"],
"env": {
"NODE_ENV": "production",
"TASK_API_BASE": "$API_BASE",
"TASK_API_TOKEN": "$TOKEN",
"MCP_SERVER_NAME": "ai-proj"
}
}
}
}
EOF
echo "✅ 已生成 $MCP_CONFIG (stdio 模式)"
fi
fi
# ── 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 "┌─────────────────────────────────────┐"
echo "│ ✅ 初始化完成! │"
echo "└─────────────────────────────────────┘"
echo ""
echo "已完成配置:"
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"