diff --git a/windows-dev-stack/README.md b/windows-dev-stack/README.md index 3ed8828..85c57af 100644 --- a/windows-dev-stack/README.md +++ b/windows-dev-stack/README.md @@ -85,12 +85,12 @@ gh auth login `deploy.ps1` 自动写入以下客户端的 MCP 配置: -| 客户端 | 配置文件 | -|--------|---------| -| Claude Desktop | `%APPDATA%\Claude\claude_desktop_config.json` | -| Cursor | `%USERPROFILE%\.cursor\mcp.json` | -| Windsurf | `%APPDATA%\Windsurf\mcp_config.json` | -| VS Code | `%APPDATA%\Code\User\mcp.json` | +| 客户端 | 配置文件 / 方式 | +|--------|----------------| +| Claude Desktop | `%APPDATA%\Claude\claude_desktop_config.json`(`mcpServers` 格式) | +| Cursor | `%USERPROFILE%\.cursor\mcp.json`(`mcpServers` 格式) | +| Windsurf | `%APPDATA%\Windsurf\mcp_config.json`(`mcpServers` 格式) | +| **VS Code Copilot Agent** | `%APPDATA%\Code\User\settings.json` → `mcp.servers`(VS Code 专用格式) | | Claude Code CLI | `claude mcp add --scope user`(写入用户级 MCP) | --- diff --git a/windows-dev-stack/deploy.ps1 b/windows-dev-stack/deploy.ps1 index 95ab49a..a5106e1 100644 --- a/windows-dev-stack/deploy.ps1 +++ b/windows-dev-stack/deploy.ps1 @@ -155,6 +155,50 @@ function Merge-McpConfig { Write-OK "$Label -> $ConfigFile" } +# ────────────────────────────────────────────────────────────── +# 辅助:写入 VS Code settings.json 中的 mcp.servers(VS Code 专用格式) +# VS Code Copilot Agent 读取 settings.json -> "mcp" -> "servers" +# 而非 mcp.json 中的 "mcpServers"(那是 Claude Desktop / Cursor 格式) +# ────────────────────────────────────────────────────────────── +function Merge-VsCodeMcpSettings { + param( + [string] $ServerName, + [hashtable] $Entry, + [string] $Label + ) + $settingsFile = "$env:APPDATA\Code\User\settings.json" + $dir = Split-Path $settingsFile + if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } + + function ConvertTo-OrderedHashtable($obj) { + if ($obj -is [System.Management.Automation.PSCustomObject]) { + $h = [ordered]@{} + foreach ($p in $obj.PSObject.Properties) { $h[$p.Name] = ConvertTo-OrderedHashtable $p.Value } + return $h + } elseif ($obj -is [System.Collections.IEnumerable] -and $obj -isnot [string]) { + return @($obj | ForEach-Object { ConvertTo-OrderedHashtable $_ }) + } + return $obj + } + + $cfg = [ordered]@{} + if (Test-Path $settingsFile) { + try { + $raw = Get-Content $settingsFile -Raw | ConvertFrom-Json + $cfg = ConvertTo-OrderedHashtable $raw + } catch { + Write-Warn "settings.json 解析失败,将新建 mcp 节点:$_" + } + } + + if (-not $cfg.ContainsKey("mcp")) { $cfg["mcp"] = [ordered]@{} } + if (-not $cfg["mcp"].ContainsKey("servers")) { $cfg["mcp"]["servers"] = [ordered]@{} } + $cfg["mcp"]["servers"][$ServerName] = $Entry + + $cfg | ConvertTo-Json -Depth 15 | Set-Content $settingsFile -Encoding UTF8 + Write-OK "$Label -> $settingsFile [mcp.servers.$ServerName]" +} + # ══════════════════════════════════════════════════════════════ # Step 1: Node.js LTS # ══════════════════════════════════════════════════════════════ @@ -450,7 +494,7 @@ if ($unityEntry) { Merge-McpConfig "$env:USERPROFILE\.cursor\mcp.json" $unityMcpEntry "Cursor" $wsDirC = if (Test-Path "$env:APPDATA\Windsurf") { "$env:APPDATA\Windsurf" } else { "$env:USERPROFILE\.codeium\windsurf" } Merge-McpConfig "$wsDirC\mcp_config.json" $unityMcpEntry "Windsurf" - Merge-McpConfig "$env:APPDATA\Code\User\mcp.json" $unityMcpEntry "VS Code" + Merge-VsCodeMcpSettings "unity-mcp" $unityMcpEntry "VS Code Copilot Agent (Unity MCP)" # Claude Code CLI(Windows) if (Get-Command claude -ErrorAction SilentlyContinue) { & claude mcp remove unity-mcp --scope user 2>&1 | Out-Null @@ -498,7 +542,7 @@ if (-not (Test-Path $godotSrcDir)) { Merge-McpConfig "$env:USERPROFILE\.cursor\mcp.json" $godotMcpEntry "Cursor (Godot)" "godot-mcp-pro" $wsDirG = if (Test-Path "$env:APPDATA\Windsurf") { "$env:APPDATA\Windsurf" } else { "$env:USERPROFILE\.codeium\windsurf" } Merge-McpConfig "$wsDirG\mcp_config.json" $godotMcpEntry "Windsurf (Godot)" "godot-mcp-pro" - Merge-McpConfig "$env:APPDATA\Code\User\mcp.json" $godotMcpEntry "VS Code (Godot)" "godot-mcp-pro" + Merge-VsCodeMcpSettings "godot-mcp-pro" $godotMcpEntry "VS Code Copilot Agent (Godot MCP Pro)" if (Get-Command claude -ErrorAction SilentlyContinue) { & claude mcp remove godot-mcp-pro --scope user 2>&1 | Out-Null & claude mcp add --scope user godot-mcp-pro node $godotEntry 2>&1 | Out-Null