mirror of https://github.com/knative/func.git
mcp: extends flags support for existing tools (#2889)
Signed-off-by: kapil <kapilsareen584@gmail.com>
This commit is contained in:
parent
9a71fa4725
commit
a90f07fdfb
279
pkg/mcp/mcp.go
279
pkg/mcp/mcp.go
|
@ -29,19 +29,25 @@ func NewServer() *MCPServer {
|
|||
|
||||
mcpServer.AddTool(
|
||||
mcp.NewTool("create",
|
||||
mcp.WithDescription("Creates a knative function in the current directory"),
|
||||
mcp.WithString("name",
|
||||
mcp.Required(),
|
||||
mcp.Description("Name of the function to be created"),
|
||||
),
|
||||
mcp.WithString("language",
|
||||
mcp.Required(),
|
||||
mcp.Description("Language/Runtime of the function to be created"),
|
||||
),
|
||||
mcp.WithDescription("Creates a Knative function project in the current or specified directory"),
|
||||
mcp.WithString("cwd",
|
||||
mcp.Required(),
|
||||
mcp.Description("Current working directory of the MCP client"),
|
||||
),
|
||||
mcp.WithString("name",
|
||||
mcp.Required(),
|
||||
mcp.Description("Name of the function to be created (used as subdirectory)"),
|
||||
),
|
||||
mcp.WithString("language",
|
||||
mcp.Required(),
|
||||
mcp.Description("Language runtime to use (e.g., node, go, python)"),
|
||||
),
|
||||
|
||||
// Optional flags
|
||||
mcp.WithString("template", mcp.Description("Function template (e.g., http, cloudevents)")),
|
||||
mcp.WithString("repository", mcp.Description("URI to Git repo containing the template")),
|
||||
mcp.WithBoolean("confirm", mcp.Description("Prompt to confirm options interactively")),
|
||||
mcp.WithBoolean("verbose", mcp.Description("Print verbose logs")),
|
||||
),
|
||||
handleCreateTool,
|
||||
)
|
||||
|
@ -51,7 +57,7 @@ func NewServer() *MCPServer {
|
|||
mcp.WithDescription("Deploys the function to the cluster"),
|
||||
mcp.WithString("registry",
|
||||
mcp.Required(),
|
||||
mcp.Description("Name of the registry to be used to push the function image"),
|
||||
mcp.Description("Registry to be used to push the function image"),
|
||||
),
|
||||
mcp.WithString("cwd",
|
||||
mcp.Required(),
|
||||
|
@ -61,17 +67,41 @@ func NewServer() *MCPServer {
|
|||
mcp.Required(),
|
||||
mcp.Description("Builder to be used to build the function image"),
|
||||
),
|
||||
mcp.WithBoolean("remote",
|
||||
mcp.DefaultBool(false),
|
||||
mcp.Description("If true, the function will be deployed remotely"),
|
||||
),
|
||||
|
||||
// Optional flags
|
||||
mcp.WithString("image", mcp.Description("Full image name (overrides registry)")),
|
||||
mcp.WithString("namespace", mcp.Description("Namespace to deploy the function into")),
|
||||
mcp.WithString("git-url", mcp.Description("Git URL containing the function source")),
|
||||
mcp.WithString("git-branch", mcp.Description("Git branch for remote deployment")),
|
||||
mcp.WithString("git-dir", mcp.Description("Directory inside the Git repository")),
|
||||
mcp.WithString("builder-image", mcp.Description("Custom builder image")),
|
||||
mcp.WithString("domain", mcp.Description("Domain for the function route")),
|
||||
mcp.WithString("platform", mcp.Description("Target platform to build for (e.g., linux/amd64)")),
|
||||
mcp.WithString("path", mcp.Description("Path to the function directory")),
|
||||
mcp.WithString("build", mcp.Description(`Build control: "true", "false", or "auto"`)),
|
||||
mcp.WithString("pvc-size", mcp.Description("Custom volume size for remote builds")),
|
||||
mcp.WithString("service-account", mcp.Description("Kubernetes ServiceAccount to use")),
|
||||
mcp.WithString("remote-storage-class", mcp.Description("Storage class for remote volume")),
|
||||
|
||||
mcp.WithBoolean("confirm", mcp.Description("Prompt for confirmation before deploying")),
|
||||
mcp.WithBoolean("push", mcp.Description("Push image to registry before deployment")),
|
||||
mcp.WithBoolean("verbose", mcp.Description("Print verbose logs")),
|
||||
mcp.WithBoolean("registry-insecure", mcp.Description("Skip TLS verification for registry")),
|
||||
mcp.WithBoolean("build-timestamp", mcp.Description("Use actual time in image metadata")),
|
||||
mcp.WithBoolean("remote", mcp.Description("Trigger remote deployment")),
|
||||
),
|
||||
handleDeployTool,
|
||||
)
|
||||
|
||||
mcpServer.AddTool(
|
||||
mcp.NewTool("list",
|
||||
mcp.WithDescription("Lists all the functions deployed in the cluster"),
|
||||
mcp.WithDescription("Lists all deployed functions in the current or specified namespace"),
|
||||
|
||||
// Optional flags
|
||||
mcp.WithBoolean("all-namespaces", mcp.Description("List functions in all namespaces (overrides --namespace)")),
|
||||
mcp.WithString("namespace", mcp.Description("The namespace to list functions in (default is current/active)")),
|
||||
mcp.WithString("output", mcp.Description("Output format: human, plain, json, xml, yaml")),
|
||||
mcp.WithBoolean("verbose", mcp.Description("Enable verbose output")),
|
||||
),
|
||||
handleListTool,
|
||||
)
|
||||
|
@ -85,12 +115,24 @@ func NewServer() *MCPServer {
|
|||
),
|
||||
mcp.WithString("builder",
|
||||
mcp.Required(),
|
||||
mcp.Description("Builder to be used to build the function image"),
|
||||
mcp.Description("Builder to be used to build the function image (pack, s2i, host)"),
|
||||
),
|
||||
mcp.WithString("registry",
|
||||
mcp.Required(),
|
||||
mcp.Description("Name of the registry to be used to push the function image"),
|
||||
mcp.Description("Registry to be used to push the function image (e.g. ghcr.io/user)"),
|
||||
),
|
||||
|
||||
// Optional flags
|
||||
mcp.WithString("builder-image", mcp.Description("Custom builder image to use with buildpacks")),
|
||||
mcp.WithString("image", mcp.Description("Full image name (overrides registry + function name)")),
|
||||
mcp.WithString("path", mcp.Description("Path to the function directory (default is current dir)")),
|
||||
mcp.WithString("platform", mcp.Description("Target platform, e.g. linux/amd64 (for s2i builds)")),
|
||||
|
||||
mcp.WithBoolean("confirm", mcp.Description("Prompt for confirmation before proceeding")),
|
||||
mcp.WithBoolean("push", mcp.Description("Push image to registry after building")),
|
||||
mcp.WithBoolean("verbose", mcp.Description("Enable verbose logging output")),
|
||||
mcp.WithBoolean("registry-insecure", mcp.Description("Skip TLS verification for insecure registries")),
|
||||
mcp.WithBoolean("build-timestamp", mcp.Description("Use actual time for image timestamp (buildpacks only)")),
|
||||
),
|
||||
handleBuildTool,
|
||||
)
|
||||
|
@ -102,6 +144,14 @@ func NewServer() *MCPServer {
|
|||
mcp.Required(),
|
||||
mcp.Description("Name of the function to be deleted"),
|
||||
),
|
||||
|
||||
// Optional flags
|
||||
mcp.WithString("namespace", mcp.Description("Namespace to delete from (default: current or active)")),
|
||||
mcp.WithString("path", mcp.Description("Path to the function project (default is current directory)")),
|
||||
mcp.WithString("all", mcp.Description(`Delete all related resources like Pipelines, Secrets ("true"/"false")`)),
|
||||
|
||||
mcp.WithBoolean("confirm", mcp.Description("Prompt to confirm before deletion")),
|
||||
mcp.WithBoolean("verbose", mcp.Description("Enable verbose output")),
|
||||
),
|
||||
handleDeleteTool,
|
||||
)
|
||||
|
@ -185,12 +235,33 @@ func handleCreateTool(
|
|||
return mcp.NewToolResultError(err.Error()), nil
|
||||
}
|
||||
|
||||
cmd := exec.Command("func", "create", "-l", language, name)
|
||||
cmd.Dir = cwd
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(err.Error()), nil
|
||||
args := []string{"create", "-l", language}
|
||||
|
||||
// Optional flags
|
||||
if v := request.GetString("template", ""); v != "" {
|
||||
args = append(args, "--template", v)
|
||||
}
|
||||
if v := request.GetString("repository", ""); v != "" {
|
||||
args = append(args, "--repository", v)
|
||||
}
|
||||
if request.GetBool("confirm", false) {
|
||||
args = append(args, "--confirm")
|
||||
}
|
||||
if request.GetBool("verbose", false) {
|
||||
args = append(args, "--verbose")
|
||||
}
|
||||
|
||||
// `name` is passed as a positional argument (directory to create in)
|
||||
args = append(args, name)
|
||||
|
||||
cmd := exec.Command("func", args...)
|
||||
cmd.Dir = cwd
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("func create failed: %s", out)), nil
|
||||
}
|
||||
|
||||
body := []byte(fmt.Sprintf(`{"result": "%s"}`, out))
|
||||
return mcp.NewToolResultText(string(body)), nil
|
||||
}
|
||||
|
@ -211,20 +282,74 @@ func handleDeployTool(
|
|||
if err != nil {
|
||||
return mcp.NewToolResultError(err.Error()), nil
|
||||
}
|
||||
remote, err := request.RequireBool("remote")
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(err.Error()), nil
|
||||
|
||||
args := []string{"deploy", "--builder", builder, "--registry", registry}
|
||||
|
||||
// Optional flags
|
||||
if v := request.GetString("image", ""); v != "" {
|
||||
args = append(args, "--image", v)
|
||||
}
|
||||
var cmd *exec.Cmd
|
||||
if remote {
|
||||
cmd = exec.Command("func", "deploy", "--registry", registry, "--builder", builder, "--remote")
|
||||
} else {
|
||||
cmd = exec.Command("func", "deploy", "--registry", registry, "--builder", builder)
|
||||
if v := request.GetString("namespace", ""); v != "" {
|
||||
args = append(args, "--namespace", v)
|
||||
}
|
||||
if v := request.GetString("git-url", ""); v != "" {
|
||||
args = append(args, "--git-url", v)
|
||||
}
|
||||
if v := request.GetString("git-branch", ""); v != "" {
|
||||
args = append(args, "--git-branch", v)
|
||||
}
|
||||
if v := request.GetString("git-dir", ""); v != "" {
|
||||
args = append(args, "--git-dir", v)
|
||||
}
|
||||
if v := request.GetString("builder-image", ""); v != "" {
|
||||
args = append(args, "--builder-image", v)
|
||||
}
|
||||
if v := request.GetString("domain", ""); v != "" {
|
||||
args = append(args, "--domain", v)
|
||||
}
|
||||
if v := request.GetString("platform", ""); v != "" {
|
||||
args = append(args, "--platform", v)
|
||||
}
|
||||
if v := request.GetString("path", ""); v != "" {
|
||||
args = append(args, "--path", v)
|
||||
}
|
||||
if v := request.GetString("build", ""); v != "" {
|
||||
args = append(args, "--build", v)
|
||||
}
|
||||
if v := request.GetString("pvc-size", ""); v != "" {
|
||||
args = append(args, "--pvc-size", v)
|
||||
}
|
||||
if v := request.GetString("service-account", ""); v != "" {
|
||||
args = append(args, "--service-account", v)
|
||||
}
|
||||
if v := request.GetString("remote-storage-class", ""); v != "" {
|
||||
args = append(args, "--remote-storage-class", v)
|
||||
}
|
||||
|
||||
if request.GetBool("confirm", false) {
|
||||
args = append(args, "--confirm")
|
||||
}
|
||||
if request.GetBool("push", false) {
|
||||
args = append(args, "--push")
|
||||
}
|
||||
if request.GetBool("verbose", false) {
|
||||
args = append(args, "--verbose")
|
||||
}
|
||||
if request.GetBool("registry-insecure", false) {
|
||||
args = append(args, "--registry-insecure")
|
||||
}
|
||||
if request.GetBool("build-timestamp", false) {
|
||||
args = append(args, "--build-timestamp")
|
||||
}
|
||||
if request.GetBool("remote", false) {
|
||||
args = append(args, "--remote")
|
||||
}
|
||||
|
||||
cmd := exec.Command("func", args...)
|
||||
cmd.Dir = cwd
|
||||
out, err := cmd.Output()
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(err.Error()), nil
|
||||
return mcp.NewToolResultError(fmt.Sprintf("func deploy failed: %s", out)), nil
|
||||
}
|
||||
body := []byte(fmt.Sprintf(`{"result": "%s"}`, out))
|
||||
return mcp.NewToolResultText(string(body)), nil
|
||||
|
@ -234,10 +359,26 @@ func handleListTool(
|
|||
ctx context.Context,
|
||||
request mcp.CallToolRequest,
|
||||
) (*mcp.CallToolResult, error) {
|
||||
cmd := exec.Command("func", "list")
|
||||
out, err := cmd.Output()
|
||||
args := []string{"list"}
|
||||
|
||||
// Optional flags
|
||||
if request.GetBool("all-namespaces", false) {
|
||||
args = append(args, "--all-namespaces")
|
||||
}
|
||||
if v := request.GetString("namespace", ""); v != "" {
|
||||
args = append(args, "--namespace", v)
|
||||
}
|
||||
if v := request.GetString("output", ""); v != "" {
|
||||
args = append(args, "--output", v)
|
||||
}
|
||||
if request.GetBool("verbose", false) {
|
||||
args = append(args, "--verbose")
|
||||
}
|
||||
|
||||
cmd := exec.Command("func", args...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(err.Error()), nil
|
||||
return mcp.NewToolResultError(fmt.Sprintf("func list failed: %s", out)), nil
|
||||
}
|
||||
body := []byte(fmt.Sprintf(`{"result": "%s"}`, out))
|
||||
return mcp.NewToolResultText(string(body)), nil
|
||||
|
@ -260,11 +401,43 @@ func handleBuildTool(
|
|||
return mcp.NewToolResultError(err.Error()), nil
|
||||
}
|
||||
|
||||
cmd := exec.Command("func", "build", "--builder", builder, "--registry", registry)
|
||||
args := []string{"build", "--builder", builder, "--registry", registry}
|
||||
|
||||
// Optional flags
|
||||
if v := request.GetString("builder-image", ""); v != "" {
|
||||
args = append(args, "--builder-image", v)
|
||||
}
|
||||
if v := request.GetString("image", ""); v != "" {
|
||||
args = append(args, "--image", v)
|
||||
}
|
||||
if v := request.GetString("path", ""); v != "" {
|
||||
args = append(args, "--path", v)
|
||||
}
|
||||
if v := request.GetString("platform", ""); v != "" {
|
||||
args = append(args, "--platform", v)
|
||||
}
|
||||
|
||||
if v := request.GetBool("confirm", false); v {
|
||||
args = append(args, "--confirm")
|
||||
}
|
||||
if v := request.GetBool("push", false); v {
|
||||
args = append(args, "--push")
|
||||
}
|
||||
if v := request.GetBool("verbose", false); v {
|
||||
args = append(args, "--verbose")
|
||||
}
|
||||
if v := request.GetBool("registry-insecure", false); v {
|
||||
args = append(args, "--registry-insecure")
|
||||
}
|
||||
if v := request.GetBool("build-timestamp", false); v {
|
||||
args = append(args, "--build-timestamp")
|
||||
}
|
||||
|
||||
cmd := exec.Command("func", args...)
|
||||
cmd.Dir = cwd
|
||||
out, err := cmd.Output()
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(err.Error()), nil
|
||||
return mcp.NewToolResultError(fmt.Sprintf("func build failed: %s", out)), nil
|
||||
}
|
||||
body := []byte(fmt.Sprintf(`{"result": "%s"}`, out))
|
||||
return mcp.NewToolResultText(string(body)), nil
|
||||
|
@ -278,11 +451,33 @@ func handleDeleteTool(
|
|||
if err != nil {
|
||||
return mcp.NewToolResultError(err.Error()), nil
|
||||
}
|
||||
cmd := exec.Command("func", "delete", name)
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(err.Error()), nil
|
||||
|
||||
args := []string{"delete", name}
|
||||
|
||||
// Optional flags
|
||||
if v := request.GetString("namespace", ""); v != "" {
|
||||
args = append(args, "--namespace", v)
|
||||
}
|
||||
if v := request.GetString("path", ""); v != "" {
|
||||
args = append(args, "--path", v)
|
||||
}
|
||||
if v := request.GetString("all", ""); v != "" {
|
||||
args = append(args, "--all", v)
|
||||
}
|
||||
|
||||
if request.GetBool("confirm", false) {
|
||||
args = append(args, "--confirm")
|
||||
}
|
||||
if request.GetBool("verbose", false) {
|
||||
args = append(args, "--verbose")
|
||||
}
|
||||
|
||||
cmd := exec.Command("func", args...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(fmt.Sprintf("func delete failed: %s", out)), nil
|
||||
}
|
||||
|
||||
body := []byte(fmt.Sprintf(`{"result": "%s"}`, out))
|
||||
return mcp.NewToolResultText(string(body)), nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue