|  | 
|  | 1 | +package main | 
|  | 2 | + | 
|  | 3 | +import ( | 
|  | 4 | +	"context" | 
|  | 5 | +	"fmt" | 
|  | 6 | +	"maps" | 
|  | 7 | +	"os" | 
|  | 8 | +	"slices" | 
|  | 9 | +	"strings" | 
|  | 10 | + | 
|  | 11 | +	internalk8s "github.com/containers/kubernetes-mcp-server/pkg/kubernetes" | 
|  | 12 | +	"github.com/containers/kubernetes-mcp-server/pkg/toolsets" | 
|  | 13 | + | 
|  | 14 | +	_ "github.com/containers/kubernetes-mcp-server/pkg/toolsets/config" | 
|  | 15 | +	_ "github.com/containers/kubernetes-mcp-server/pkg/toolsets/core" | 
|  | 16 | +	_ "github.com/containers/kubernetes-mcp-server/pkg/toolsets/helm" | 
|  | 17 | +) | 
|  | 18 | + | 
|  | 19 | +type OpenShift struct{} | 
|  | 20 | + | 
|  | 21 | +func (o *OpenShift) IsOpenShift(ctx context.Context) bool { | 
|  | 22 | +	return true | 
|  | 23 | +} | 
|  | 24 | + | 
|  | 25 | +var _ internalk8s.Openshift = (*OpenShift)(nil) | 
|  | 26 | + | 
|  | 27 | +func main() { | 
|  | 28 | +	readme, err := os.ReadFile(os.Args[1]) | 
|  | 29 | +	if err != nil { | 
|  | 30 | +		panic(err) | 
|  | 31 | +	} | 
|  | 32 | +	// Available Toolsets | 
|  | 33 | +	toolsetsList := toolsets.Toolsets() | 
|  | 34 | +	maxNameLen, maxDescLen := len("Toolset"), len("Description") | 
|  | 35 | +	for _, toolset := range toolsetsList { | 
|  | 36 | +		nameLen := len(toolset.GetName()) | 
|  | 37 | +		descLen := len(toolset.GetDescription()) | 
|  | 38 | +		if nameLen > maxNameLen { | 
|  | 39 | +			maxNameLen = nameLen | 
|  | 40 | +		} | 
|  | 41 | +		if descLen > maxDescLen { | 
|  | 42 | +			maxDescLen = descLen | 
|  | 43 | +		} | 
|  | 44 | +	} | 
|  | 45 | +	availableToolsets := strings.Builder{} | 
|  | 46 | +	availableToolsets.WriteString(fmt.Sprintf("| %-*s | %-*s |\n", maxNameLen, "Toolset", maxDescLen, "Description")) | 
|  | 47 | +	availableToolsets.WriteString(fmt.Sprintf("|-%s-|-%s-|\n", strings.Repeat("-", maxNameLen), strings.Repeat("-", maxDescLen))) | 
|  | 48 | +	for _, toolset := range toolsetsList { | 
|  | 49 | +		availableToolsets.WriteString(fmt.Sprintf("| %-*s | %-*s |\n", maxNameLen, toolset.GetName(), maxDescLen, toolset.GetDescription())) | 
|  | 50 | +	} | 
|  | 51 | +	updated := replaceBetweenMarkers( | 
|  | 52 | +		string(readme), | 
|  | 53 | +		"<!-- AVAILABLE-TOOLSETS-START -->", | 
|  | 54 | +		"<!-- AVAILABLE-TOOLSETS-END -->", | 
|  | 55 | +		availableToolsets.String(), | 
|  | 56 | +	) | 
|  | 57 | + | 
|  | 58 | +	// Available Toolset Tools | 
|  | 59 | +	toolsetTools := strings.Builder{} | 
|  | 60 | +	for _, toolset := range toolsetsList { | 
|  | 61 | +		toolsetTools.WriteString("<details>\n\n<summary>" + toolset.GetName() + "</summary>\n\n") | 
|  | 62 | +		tools := toolset.GetTools(&OpenShift{}) | 
|  | 63 | +		for _, tool := range tools { | 
|  | 64 | +			toolsetTools.WriteString(fmt.Sprintf("- **%s** - %s\n", tool.Tool.Name, tool.Tool.Description)) | 
|  | 65 | +			for _, propName := range slices.Sorted(maps.Keys(tool.Tool.InputSchema.Properties)) { | 
|  | 66 | +				property := tool.Tool.InputSchema.Properties[propName] | 
|  | 67 | +				toolsetTools.WriteString(fmt.Sprintf("  - `%s` (`%s`)", propName, property.Type)) | 
|  | 68 | +				if slices.Contains(tool.Tool.InputSchema.Required, propName) { | 
|  | 69 | +					toolsetTools.WriteString(" **(required)**") | 
|  | 70 | +				} | 
|  | 71 | +				toolsetTools.WriteString(fmt.Sprintf(" - %s\n", property.Description)) | 
|  | 72 | +			} | 
|  | 73 | +			toolsetTools.WriteString("\n") | 
|  | 74 | +		} | 
|  | 75 | +		toolsetTools.WriteString("</details>\n\n") | 
|  | 76 | +	} | 
|  | 77 | +	updated = replaceBetweenMarkers( | 
|  | 78 | +		updated, | 
|  | 79 | +		"<!-- AVAILABLE-TOOLSETS-TOOLS-START -->", | 
|  | 80 | +		"<!-- AVAILABLE-TOOLSETS-TOOLS-END -->", | 
|  | 81 | +		toolsetTools.String(), | 
|  | 82 | +	) | 
|  | 83 | + | 
|  | 84 | +	if err := os.WriteFile(os.Args[1], []byte(updated), 0o644); err != nil { | 
|  | 85 | +		panic(err) | 
|  | 86 | +	} | 
|  | 87 | +} | 
|  | 88 | + | 
|  | 89 | +func replaceBetweenMarkers(content, startMarker, endMarker, replacement string) string { | 
|  | 90 | +	startIdx := strings.Index(content, startMarker) | 
|  | 91 | +	if startIdx == -1 { | 
|  | 92 | +		return content | 
|  | 93 | +	} | 
|  | 94 | +	endIdx := strings.Index(content, endMarker) | 
|  | 95 | +	if endIdx == -1 || endIdx <= startIdx { | 
|  | 96 | +		return content | 
|  | 97 | +	} | 
|  | 98 | +	return content[:startIdx+len(startMarker)] + "\n\n" + replacement + "\n" + content[endIdx:] | 
|  | 99 | +} | 
0 commit comments