diff --git a/cmd/gotk/create_helmrelease.go b/cmd/gotk/create_helmrelease.go
index 9776f751e2c88502244542d2695257f65afb0dd2..566e8825bdd33cf1fe3dabfb6422b4c6687aabc4 100644
--- a/cmd/gotk/create_helmrelease.go
+++ b/cmd/gotk/create_helmrelease.go
@@ -22,6 +22,7 @@ import (
 	"io/ioutil"
 
 	"github.com/fluxcd/pkg/apis/meta"
+	"github.com/fluxcd/toolkit/internal/flags"
 	"github.com/fluxcd/toolkit/internal/utils"
 
 	"github.com/spf13/cobra"
@@ -90,7 +91,7 @@ var createHelmReleaseCmd = &cobra.Command{
 
 var (
 	hrName            string
-	hrSource          string
+	hrSource          flags.HelmChartSource
 	hrDependsOn       []string
 	hrChart           string
 	hrChartVersion    string
@@ -100,7 +101,7 @@ var (
 
 func init() {
 	createHelmReleaseCmd.Flags().StringVar(&hrName, "release-name", "", "name used for the Helm release, defaults to a composition of '[<target-namespace>-]<HelmRelease-name>'")
-	createHelmReleaseCmd.Flags().StringVar(&hrSource, "source", "", "source that contains the chart (<kind>/<name>)")
+	createHelmReleaseCmd.Flags().Var(&hrSource, "source", hrSource.Description())
 	createHelmReleaseCmd.Flags().StringVar(&hrChart, "chart", "", "Helm chart name or path")
 	createHelmReleaseCmd.Flags().StringVar(&hrChartVersion, "chart-version", "", "Helm chart version, accepts a semver range (ignored for charts from GitRepository sources)")
 	createHelmReleaseCmd.Flags().StringArrayVar(&hrDependsOn, "depends-on", nil, "HelmReleases that must be ready before this release can be installed, supported formats '<name>' and '<namespace>/<name>'")
@@ -115,17 +116,6 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
 	}
 	name := args[0]
 
-	if hrSource == "" {
-		return fmt.Errorf("source is required")
-	}
-	sourceKind, sourceName := utils.ParseObjectKindName(hrSource)
-	if sourceKind == "" {
-		return fmt.Errorf("invalid source '%s', must be in format <kind>/<name>", hrSource)
-	}
-	if !utils.ContainsItemString(supportedHelmChartSourceKinds, sourceKind) {
-		return fmt.Errorf("source kind %s is not supported, can be %v",
-			sourceKind, supportedHelmChartSourceKinds)
-	}
 	if hrChart == "" {
 		return fmt.Errorf("chart name or path is required")
 	}
@@ -157,8 +147,8 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
 					Chart:   hrChart,
 					Version: hrChartVersion,
 					SourceRef: helmv2.CrossNamespaceObjectReference{
-						Kind: sourceKind,
-						Name: sourceName,
+						Kind: hrSource.Kind,
+						Name: hrSource.Name,
 					},
 				},
 			},
diff --git a/cmd/gotk/main.go b/cmd/gotk/main.go
index 58192e213e880f2423ccf984b2458cded3867ec5..afd1b9b2befc34dc8b95ca4bc61e65bc39a1ba41 100644
--- a/cmd/gotk/main.go
+++ b/cmd/gotk/main.go
@@ -110,7 +110,6 @@ var (
 	defaultNamespace    = "gotk-system"
 	defaultNotification = "notification-controller"
 
-	supportedHelmChartSourceKinds  = []string{sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind, sourcev1.BucketKind}
 	supportedSourceBucketProviders = []string{sourcev1.GenericBucketProvider, sourcev1.AmazonBucketProvider}
 )
 
diff --git a/internal/flags/helm_chart_source.go b/internal/flags/helm_chart_source.go
new file mode 100644
index 0000000000000000000000000000000000000000..4531daa7247839befa784ab50e17a6cbaa1ee42a
--- /dev/null
+++ b/internal/flags/helm_chart_source.go
@@ -0,0 +1,72 @@
+/*
+Copyright 2020 The Flux CD contributors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package flags
+
+import (
+	"fmt"
+	"strings"
+
+	sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
+	"github.com/fluxcd/toolkit/internal/utils"
+)
+
+var supportedHelmChartSourceKinds = []string{sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind, sourcev1.BucketKind}
+
+type HelmChartSource struct {
+	Kind string
+	Name string
+}
+
+func (h *HelmChartSource) String() string {
+	if h.Name == "" {
+		return ""
+	}
+	return fmt.Sprintf("%s/%s", h.Kind, h.Name)
+}
+
+func (h *HelmChartSource) Set(str string) error {
+	if strings.TrimSpace(str) == "" {
+		return fmt.Errorf("no helm chart source given, please specify %s",
+			h.Description())
+	}
+
+	sourceKind, sourceName := utils.ParseObjectKindName(str)
+	if sourceKind == "" {
+		return fmt.Errorf("invalid helm chart source '%s', must be in format <kind>/<name>", str)
+	}
+	if !utils.ContainsItemString(supportedKustomizationSourceKinds, sourceKind) {
+		return fmt.Errorf("source kind '%s' is not supported, can be one of: %v",
+			sourceKind, strings.Join(supportedHelmChartSourceKinds, ", "))
+	}
+
+	h.Name = sourceName
+	h.Kind = sourceKind
+
+	return nil
+}
+
+func (h *HelmChartSource) Type() string {
+	return "helmChartSource"
+}
+
+func (h *HelmChartSource) Description() string {
+	return fmt.Sprintf(
+		"source that contains the chart in the format '<kind>/<name>',"+
+			"where kind can be one of: %s",
+		strings.Join(supportedHelmChartSourceKinds, ", "),
+	)
+}