extractMCPServers collects MCP server definitions from two sources: 1. .mcp.json at the root (read directly, not collected in config_files) 2. settings.json files already collected (passed as raw bytes) Servers are deduplicated by name (first occurrence wins) and sorted.
(realRoot string, settingsFiles []rawConfigContent)
| 96 | // 2. settings.json files already collected (passed as raw bytes) |
| 97 | // Servers are deduplicated by name (first occurrence wins) and sorted. |
| 98 | func extractMCPServers(realRoot string, settingsFiles []rawConfigContent) []MCPServer { |
| 99 | seen := make(map[string]struct{}) |
| 100 | var servers []MCPServer |
| 101 | |
| 102 | addServers := func(extracted []MCPServer) { |
| 103 | for _, s := range extracted { |
| 104 | if _, ok := seen[s.Name]; !ok { |
| 105 | seen[s.Name] = struct{}{} |
| 106 | servers = append(servers, s) |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | // Source 1: .mcp.json read directly from disk. |
| 112 | // Resolve symlinks before reading to prevent reading files outside the root. |
| 113 | if extracted, err := readMCPFile(realRoot); err == nil && len(extracted) > 0 { |
| 114 | addServers(extracted) |
| 115 | } |
| 116 | |
| 117 | // Source 2: settings.json files (raw bytes from the Build loop) |
| 118 | for _, sf := range settingsFiles { |
| 119 | extracted, err := ExtractMCPServers(sf.content) |
| 120 | if err != nil { |
| 121 | log.Debug().Err(err).Str("path", sf.path).Msg("failed to parse MCP servers from settings") |
| 122 | continue |
| 123 | } |
| 124 | addServers(extracted) |
| 125 | } |
| 126 | |
| 127 | if len(servers) == 0 { |
| 128 | return nil |
| 129 | } |
| 130 | |
| 131 | sort.Slice(servers, func(i, j int) bool { |
| 132 | return servers[i].Name < servers[j].Name |
| 133 | }) |
| 134 | |
| 135 | return servers |
| 136 | } |
| 137 | |
| 138 | // readMCPFile reads and parses .mcp.json from the given root directory. |
| 139 | // It resolves symlinks and verifies the file stays inside the root before reading. |
no test coverage detected