Skip to content

Commit c9dc0ae

Browse files
authored
create module manifest tool implementation #12
create module manifest tool implementation
2 parents e07bc79 + ca4a5a5 commit c9dc0ae

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

internal/modules/controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func (m *ModuleController) RegisterModuleTools(mcp *server.MCPServer) {
2727
mcp.AddTool(m.listModulesTool(), m.listModules)
2828
mcp.AddTool(m.createModuleTool(), m.createModule)
2929
mcp.AddTool(m.updateModuleTool(), m.updateModule)
30+
mcp.AddTool(m.createModuleManifestTool(), m.createModuleManifestModule)
3031
}
3132

3233
func (m *ModuleController) validateModuleValues(schema []byte, values map[string]interface{}) (bool, error, error) {

internal/modules/manifest.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package modules
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"gopkg.in/yaml.v2"
8+
9+
"github.com/mark3labs/mcp-go/mcp"
10+
11+
"github.com/cyclops-ui/cyclops/cyclops-ctrl/api/v1alpha1"
12+
13+
"github.com/cyclops-ui/mcp-cyclops/internal/mapper"
14+
)
15+
16+
func (m *ModuleController) createModuleManifestTool() mcp.Tool {
17+
return mcp.NewTool("create_module_manifest",
18+
mcp.WithDescription("Create a Module manifest based on values. Before calling this tool, make sure to call get_template_schema to validate values for the given template"),
19+
mcp.WithString("module_name",
20+
mcp.Required(),
21+
mcp.Description("Name of the Module to update"),
22+
),
23+
mcp.WithString("template_type",
24+
mcp.Required(),
25+
mcp.Description("Type of the Template Stores to create"),
26+
mcp.Enum("git", "helm", "oci"),
27+
),
28+
mcp.WithString("repo",
29+
mcp.Required(),
30+
mcp.Description("Template repo (Helm or Git repo)"),
31+
),
32+
mcp.WithString("path",
33+
mcp.Required(),
34+
mcp.Description("In case of a git repo, folder of the template in the repository. For a helm chart, the name of the chart"),
35+
),
36+
mcp.WithString("version",
37+
mcp.Required(),
38+
mcp.Description("Semantic version of the chart, or in case of a git repo can be a reference as commit hash or branch/tag"),
39+
),
40+
mcp.WithString("values",
41+
mcp.Required(),
42+
mcp.Description("Helm-like values in JSON string format to create the module with"),
43+
),
44+
)
45+
}
46+
47+
func (m *ModuleController) createModuleManifestModule(_ context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
48+
moduleName := request.Params.Arguments["module_name"].(string)
49+
valuesRaw := request.Params.Arguments["values"].(string)
50+
templateType := request.Params.Arguments["template_type"].(string)
51+
repo := request.Params.Arguments["repo"].(string)
52+
path := request.Params.Arguments["path"].(string)
53+
version := request.Params.Arguments["version"].(string)
54+
55+
initialValues, err := m.templateRepo.GetTemplateInitialValues(repo, path, version, v1alpha1.TemplateSourceType(templateType))
56+
if err != nil {
57+
return nil, err
58+
}
59+
60+
var values map[string]interface{}
61+
if len(valuesRaw) > 0 {
62+
if err := json.Unmarshal([]byte(valuesRaw), &values); err != nil {
63+
return nil, fmt.Errorf("failed to parse current values: %w", err)
64+
}
65+
} else {
66+
values = make(map[string]interface{})
67+
}
68+
69+
values = mapper.DeepMerge(initialValues, values)
70+
71+
template, err := m.templateRepo.GetTemplate(repo, path, version, "", v1alpha1.TemplateSourceType(templateType))
72+
if err != nil {
73+
return nil, err
74+
}
75+
76+
valid, validationError, err := m.validateModuleValues(template.RawSchema, values)
77+
if err != nil {
78+
return nil, err
79+
}
80+
81+
if !valid {
82+
return mcp.NewToolResultError(validationError.Error()), nil
83+
}
84+
85+
valuesBytes, err := json.Marshal(values)
86+
if err != nil {
87+
return nil, err
88+
}
89+
90+
module := mapper.CreateModule(moduleName, repo, path, version, templateType, valuesBytes)
91+
92+
moduleData, err := yaml.Marshal(module)
93+
if err != nil {
94+
return nil, err
95+
}
96+
97+
return mcp.NewToolResultText(string(moduleData)), nil
98+
}

0 commit comments

Comments
 (0)