ExtractMCPServers parses MCP server entries from raw JSON content. It handles both .mcp.json format and .claude/settings.json format. Environment variable values are stripped; only key names are retained. Returns nil without error if the JSON is valid but contains no mcpServers.
(content []byte)
| 42 | // Environment variable values are stripped; only key names are retained. |
| 43 | // Returns nil without error if the JSON is valid but contains no mcpServers. |
| 44 | func ExtractMCPServers(content []byte) ([]MCPServer, error) { |
| 45 | var raw rawMCPConfig |
| 46 | if err := json.Unmarshal(content, &raw); err != nil { |
| 47 | return nil, err |
| 48 | } |
| 49 | |
| 50 | if len(raw.MCPServers) == 0 { |
| 51 | return nil, nil |
| 52 | } |
| 53 | |
| 54 | servers := make([]MCPServer, 0, len(raw.MCPServers)) |
| 55 | for name, entry := range raw.MCPServers { |
| 56 | srv := MCPServer{ |
| 57 | Name: name, |
| 58 | Command: entry.Command, |
| 59 | Args: entry.Args, |
| 60 | URL: entry.URL, |
| 61 | Disabled: entry.Disabled, |
| 62 | } |
| 63 | |
| 64 | if len(entry.Env) > 0 { |
| 65 | srv.EnvKeys = slices.Sorted(maps.Keys(entry.Env)) |
| 66 | } |
| 67 | |
| 68 | servers = append(servers, srv) |
| 69 | } |
| 70 | |
| 71 | sort.Slice(servers, func(i, j int) bool { |
| 72 | return servers[i].Name < servers[j].Name |
| 73 | }) |
| 74 | |
| 75 | return servers, nil |
| 76 | } |