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>
This commit is contained in:
100
init.sh
100
init.sh
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# ai-proj-helper MCP 初始化脚本
|
# ai-proj-helper 初始化脚本
|
||||||
# 为用户配置 ai-proj MCP 连接
|
# 配置 MCP 连接 + 安装技能到 ~/.claude/skills/
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -51,6 +51,12 @@ read_config_value() {
|
|||||||
|
|
||||||
CONFIG_MODE=$(read_config_value "mode" "sse")
|
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 ────────────────────────────────────────
|
# ── Interactive mode selection ────────────────────────────────────────
|
||||||
if [ -z "$MODE" ]; then
|
if [ -z "$MODE" ]; then
|
||||||
echo "┌─────────────────────────────────────┐"
|
echo "┌─────────────────────────────────────┐"
|
||||||
@@ -58,7 +64,7 @@ if [ -z "$MODE" ]; then
|
|||||||
echo "└─────────────────────────────────────┘"
|
echo "└─────────────────────────────────────┘"
|
||||||
echo ""
|
echo ""
|
||||||
echo "MCP 连接模式:"
|
echo "MCP 连接模式:"
|
||||||
echo " 1) sse - 远程 SSE 连接 (推荐,零依赖)"
|
echo " 1) sse - 远程连接 (推荐,零依赖)"
|
||||||
echo " 2) stdio - 本地进程 (需要 Node.js + mcp-task-bridge)"
|
echo " 2) stdio - 本地进程 (需要 Node.js + mcp-task-bridge)"
|
||||||
echo ""
|
echo ""
|
||||||
read -p "选择模式 [1/2] (default: $([ "$CONFIG_MODE" = "stdio" ] && echo "2" || echo "1")): " mode_choice
|
read -p "选择模式 [1/2] (default: $([ "$CONFIG_MODE" = "stdio" ] && echo "2" || echo "1")): " mode_choice
|
||||||
@@ -87,17 +93,26 @@ fi
|
|||||||
echo ""
|
echo ""
|
||||||
echo "配置信息:"
|
echo "配置信息:"
|
||||||
echo " 模式: $MODE"
|
echo " 模式: $MODE"
|
||||||
|
echo " Claude CLI: $($HAS_CLAUDE && echo '检测到' || echo '未检测到 (回退写 .mcp.json)')"
|
||||||
if [ "$MODE" = "sse" ]; then
|
if [ "$MODE" = "sse" ]; then
|
||||||
echo " SSE: $SSE_URL"
|
echo " URL: $SSE_URL"
|
||||||
else
|
else
|
||||||
echo " API: $API_BASE"
|
echo " API: $API_BASE"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# ── SSE mode ─────────────────────────────────────────────────────────
|
# ── Configure MCP ────────────────────────────────────────────────────
|
||||||
if [ "$MODE" = "sse" ]; then
|
if [ "$MODE" = "sse" ]; then
|
||||||
mkdir -p "$(dirname "$MCP_CONFIG")"
|
if $HAS_CLAUDE; then
|
||||||
cat > "$MCP_CONFIG" << EOF
|
# 新版 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": {
|
"mcpServers": {
|
||||||
"ai-proj": {
|
"ai-proj": {
|
||||||
@@ -110,9 +125,9 @@ if [ "$MODE" = "sse" ]; then
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
echo "✅ 已生成 $MCP_CONFIG (SSE 模式)"
|
echo "✅ 已生成 $MCP_CONFIG (SSE 模式)"
|
||||||
|
fi
|
||||||
|
|
||||||
# ── stdio mode: ensure mcp-task-bridge ────────────────────────────────
|
|
||||||
elif [ "$MODE" = "stdio" ]; then
|
elif [ "$MODE" = "stdio" ]; then
|
||||||
if [ ! -d "$MCP_BRIDGE_DIR" ]; then
|
if [ ! -d "$MCP_BRIDGE_DIR" ]; then
|
||||||
echo "📦 mcp-task-bridge 未找到,正在克隆..."
|
echo "📦 mcp-task-bridge 未找到,正在克隆..."
|
||||||
@@ -129,8 +144,13 @@ elif [ "$MODE" = "stdio" ]; then
|
|||||||
|
|
||||||
BRIDGE_ENTRY="$MCP_BRIDGE_DIR/dist/index.js"
|
BRIDGE_ENTRY="$MCP_BRIDGE_DIR/dist/index.js"
|
||||||
|
|
||||||
mkdir -p "$(dirname "$MCP_CONFIG")"
|
if $HAS_CLAUDE; then
|
||||||
cat > "$MCP_CONFIG" << EOF
|
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": {
|
"mcpServers": {
|
||||||
"ai-proj": {
|
"ai-proj": {
|
||||||
@@ -146,26 +166,36 @@ elif [ "$MODE" = "stdio" ]; then
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
echo "✅ 已生成 $MCP_CONFIG (stdio 模式)"
|
echo "✅ 已生成 $MCP_CONFIG (stdio 模式)"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Register skill marketplace ───────────────────────────────────────
|
# ── Install skills to ~/.claude/skills/ ──────────────────────────────
|
||||||
echo "📦 注册技能市场..."
|
echo "📦 安装技能到 ~/.claude/skills/ ..."
|
||||||
SCRIPT_DIR="$SCRIPT_DIR" python3 << 'PYEOF'
|
SKILLS_DIR="$HOME/.claude/skills"
|
||||||
import json, os, datetime
|
mkdir -p "$SKILLS_DIR"
|
||||||
path = os.path.expanduser("~/.claude/plugins/known_marketplaces.json")
|
|
||||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
SKILL_COUNT=0
|
||||||
data = json.load(open(path)) if os.path.exists(path) else {}
|
for plugin_dir in "$SCRIPT_DIR"/skills-*/; do
|
||||||
script_dir = os.environ["SCRIPT_DIR"]
|
for skill_path in "$plugin_dir"*-plugin/; do
|
||||||
data["ai-proj-helper"] = {
|
[ -d "$skill_path" ] || continue
|
||||||
"source": {"source": "directory", "path": script_dir},
|
skill_md="$skill_path/skills/SKILL.md"
|
||||||
"installLocation": script_dir,
|
[ -f "$skill_md" ] || continue
|
||||||
"lastUpdated": datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
|
|
||||||
}
|
# Extract skill name: ai-proj-plugin -> ai-proj
|
||||||
with open(path, "w") as f:
|
dir_name=$(basename "$skill_path")
|
||||||
json.dump(data, f, indent=2)
|
skill_name="${dir_name%-plugin}"
|
||||||
PYEOF
|
|
||||||
echo "✅ 已注册技能市场到 ~/.claude/plugins/known_marketplaces.json"
|
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 "┌─────────────────────────────────────┐"
|
||||||
@@ -173,8 +203,12 @@ echo "│ ✅ 初始化完成! │"
|
|||||||
echo "└─────────────────────────────────────┘"
|
echo "└─────────────────────────────────────┘"
|
||||||
echo ""
|
echo ""
|
||||||
echo "已完成配置:"
|
echo "已完成配置:"
|
||||||
echo " ✅ MCP 服务器 → $MCP_CONFIG"
|
if $HAS_CLAUDE; then
|
||||||
echo " ✅ 技能市场 → ~/.claude/plugins/known_marketplaces.json"
|
echo " ✅ MCP 服务器 (claude mcp add)"
|
||||||
|
else
|
||||||
|
echo " ✅ MCP 服务器 → $MCP_CONFIG"
|
||||||
|
fi
|
||||||
|
echo " ✅ 技能 ($SKILL_COUNT 个) → $SKILLS_DIR"
|
||||||
echo ""
|
echo ""
|
||||||
echo "下次启动 Claude Code 即可使用。"
|
echo "重启 Claude Code 即可使用。"
|
||||||
echo "如需更改模式,编辑 claude-config.yaml 后重新运行 ./init.sh"
|
echo "如需更改配置,编辑 claude-config.yaml 后重新运行 ./init.sh"
|
||||||
|
|||||||
Reference in New Issue
Block a user