package tools import ( "context" "github.com/modelcontextprotocol/go-sdk/mcp" ) // configure.go — изменяющие инструменты конфигурации (compose/env и версии). // Требуют read_only=false и обычно помечаются require_approval в agent.yaml. func registerConfigureTools(s *mcp.Server) { addPatternTool(s, &mcp.Tool{ Name: "set_compose", Description: "Заменить текущий docker-compose сервиса, создать версию и отправить агенту. Изменяет конфигурацию.", InputSchema: schema(map[string]any{ "server": serverProp(), "app_id": intProps("Идентификатор сервиса", true), "content": strProps("Полный текст docker-compose (YAML)", true), }, []string{"app_id", "content"}), }, appPatterns, func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) { args := requestArgs(req) id, res := appIDArg(args) if res != nil { return res, nil } content, err := requireString(args, "content") if err != nil { return errorResult(err.Error()), nil } api, res := openAPI(ctx, args, true) if res != nil { return res, nil } defer api.Close() return result(api.SetCompose(ctx, id, content)) }) addPatternTool(s, &mcp.Tool{ Name: "set_env", Description: "Заменить текущий env-файл сервиса (например .env), создать версию и отправить агенту. Изменяет конфигурацию.", InputSchema: schema(map[string]any{ "server": serverProp(), "app_id": intProps("Идентификатор сервиса", true), "filename": strProps("Имя env-файла, например .env", true), "content": strProps("Полное содержимое env-файла", true), }, []string{"app_id", "filename", "content"}), }, envPatterns, func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) { args := requestArgs(req) id, res := appIDArg(args) if res != nil { return res, nil } filename, err := requireString(args, "filename") if err != nil { return errorResult(err.Error()), nil } content, err := requireString(args, "content") if err != nil { return errorResult(err.Error()), nil } api, res := openAPI(ctx, args, true) if res != nil { return res, nil } defer api.Close() return result(api.SetEnv(ctx, id, filename, content)) }) addPatternTool(s, &mcp.Tool{ Name: "restore_compose", Description: "Восстановить версию compose (создаёт новую текущую версию) и отправить агенту. Разрушительно: требует confirm=\"true\".", InputSchema: schema(map[string]any{ "server": serverProp(), "version_id": intProps("Идентификатор версии compose", true), "confirm": boolProps("Подтверждение разрушительной операции (обязательно true)", true), }, []string{"version_id", "confirm"}), }, versionPatterns, func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) { args := requestArgs(req) if res := confirmGate(args, "restore_compose"); res != nil { return res, nil } id, res := versionIDArg(args) if res != nil { return res, nil } api, res := openAPI(ctx, args, true) if res != nil { return res, nil } defer api.Close() return result(api.RestoreCompose(ctx, id)) }) addPatternTool(s, &mcp.Tool{ Name: "restore_env_version", Description: "Восстановить версию env-файла (создаёт новую текущую версию) и отправить агенту. Разрушительно: требует confirm=\"true\".", InputSchema: schema(map[string]any{ "server": serverProp(), "version_id": intProps("Идентификатор версии env", true), "confirm": boolProps("Подтверждение разрушительной операции (обязательно true)", true), }, []string{"version_id", "confirm"}), }, versionPatterns, func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) { args := requestArgs(req) if res := confirmGate(args, "restore_env_version"); res != nil { return res, nil } id, res := versionIDArg(args) if res != nil { return res, nil } api, res := openAPI(ctx, args, true) if res != nil { return res, nil } defer api.Close() return result(api.RestoreEnvVersion(ctx, id)) }) addPatternTool(s, &mcp.Tool{ Name: "update_config", Description: "Повторно отправить агенту текущую конфигурацию сервиса из БД (compose + env). Изменяет файлы на хосте.", InputSchema: schema(map[string]any{ "server": serverProp(), "app_id": intProps("Идентификатор сервиса", true), }, []string{"app_id"}), }, appPatterns, func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) { args := requestArgs(req) id, res := appIDArg(args) if res != nil { return res, nil } api, res := openAPI(ctx, args, true) if res != nil { return res, nil } defer api.Close() return result(api.UpdateConfig(ctx, id)) }) }