diff --git a/docs/chart_template_guide/builtin_objects.md b/docs/chart_template_guide/builtin_objects.md
index 077b2fc304c3edff27f3f0f22d6e8e143f3152bd..3c393e7bb5703b88df02faf1836b350255008cb2 100644
--- a/docs/chart_template_guide/builtin_objects.md
+++ b/docs/chart_template_guide/builtin_objects.md
@@ -20,6 +20,11 @@ In the previous section, we use `{{.Release.Name}}` to insert the name of a rele
 - `Files`: This provides access to all non-special files in a chart. While you cannot use it to access templates, you can use it to access other files in the chart. See the section _Accessing Files_ for more.
   - `Files.Get` is a function for getting a file by name (`.Files.Get config.ini`)
   - `Files.GetBytes` is a function for getting the contents of a file as an array of bytes instead of as a string. This is useful for things like images.
+- `Capabilities`: This provides information about what capabilities the Kubernetes cluster supports.
+  - `Capabilities.APIVersions` is a set of versions.
+  - `Capabilities.APIVersions.Has $version` indicates whether a version (`batch/v1`) is enabled on the cluster.
+  - `Capabilities.KubeVersion` provides a way to look up the Kubernetes version. It has the following values: `Major`, `Minor`, `GitVersion`, `GitCommit`, `GitTreeState`, `BuildDate`, `GoVersion`, `Compiler`, and `Platform`.
+  - `Capabilities.TillerVersion` provides a way to look up the Tiller version. It has the following values: `SemVer`, `GitCommit`, and `GitTreeState`.
 
 The values are available to any top-level template. As we will see later, this does not necessarily mean that they will be available _everywhere_.
 
diff --git a/docs/charts.md b/docs/charts.md
index 55382264ecb1d49c3079dbb26b44d4059f3a91ab..2a119ab486ab99356650df77e133d0a65ecba625 100644
--- a/docs/charts.md
+++ b/docs/charts.md
@@ -305,6 +305,10 @@ sensitive_.
   files that are present. Files can be accessed using `{{index .Files "file.name"}}`
   or using the `{{.Files.Get name}}` or `{{.Files.GetString name}}` functions. You can
   also access the contents of the file as `[]byte` using `{{.Files.GetBytes}}`
+- `Capabilities`: A map-like object that contains information about the versions
+  of Kubernetes (`{{.Capabilities.KubeVersion}}`, Tiller
+  (`{{.Capabilities.TillerVersion}}`, and the supported Kubernetes API versions
+  (`{{.Capabilities.APIVersions.Has "batch/v1"`)
 
 **NOTE:** Any unknown Chart.yaml fields will be dropped. They will not
 be accessible inside of the `Chart` object. Thus, Chart.yaml cannot be
diff --git a/pkg/chartutil/capabilities.go b/pkg/chartutil/capabilities.go
new file mode 100644
index 0000000000000000000000000000000000000000..6b231b4475a773b295c3f197648cea46e2248e9a
--- /dev/null
+++ b/pkg/chartutil/capabilities.go
@@ -0,0 +1,56 @@
+/*
+Copyright 2017 The Kubernetes Authors All rights reserved.
+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 chartutil
+
+import (
+	tversion "k8s.io/helm/pkg/proto/hapi/version"
+	"k8s.io/kubernetes/pkg/version"
+)
+
+// DefaultVersionSet is the default version set, which includes only Core V1 ("v1").
+var DefaultVersionSet = NewVersionSet("v1")
+
+// Capabilities describes the capabilities of the Kubernetes cluster that Tiller is attached to.
+type Capabilities struct {
+	// List of all supported API versions
+	APIVersions VersionSet
+	// KubeVerison is the Kubernetes version
+	KubeVersion *version.Info
+	// TillerVersion is the Tiller version
+	//
+	// This always comes from pkg/version.GetVersionProto().
+	TillerVersion *tversion.Version
+}
+
+// VersionSet is a set of Kubernetes API versions.
+type VersionSet map[string]interface{}
+
+// NewVersionSet creates a new version set from a list of strings.
+func NewVersionSet(apiVersions ...string) VersionSet {
+	vs := VersionSet{}
+	for _, v := range apiVersions {
+		vs[v] = struct{}{}
+	}
+	return vs
+}
+
+// Has returns true if the version string is in the set.
+//
+//	vs.Has("extensions/v1beta1")
+func (v VersionSet) Has(apiVersion string) bool {
+	_, ok := v[apiVersion]
+	return ok
+}
diff --git a/pkg/chartutil/capabilities_test.go b/pkg/chartutil/capabilities_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..ac20f0038c31125a0d6cbc7d55cc497e1bad8692
--- /dev/null
+++ b/pkg/chartutil/capabilities_test.go
@@ -0,0 +1,54 @@
+/*
+Copyright 2017 The Kubernetes Authors All rights reserved.
+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 chartutil
+
+import (
+	"testing"
+)
+
+func TestVersionSet(t *testing.T) {
+	vs := NewVersionSet("v1", "extensions/v1beta1")
+	if d := len(vs); d != 2 {
+		t.Errorf("Expected 2 versions, got %d", d)
+	}
+
+	if !vs.Has("extensions/v1beta1") {
+		t.Error("Expected to find extensions/v1beta1")
+	}
+
+	if vs.Has("Spanish/inquisition") {
+		t.Error("No one expects the Spanish/inquisition")
+	}
+}
+
+func TestDefaultVersionSet(t *testing.T) {
+	if !DefaultVersionSet.Has("v1") {
+		t.Error("Expected core v1 version set")
+	}
+	if d := len(DefaultVersionSet); d != 1 {
+		t.Errorf("Expected only one version, got %d", d)
+	}
+}
+
+func TestCapabilities(t *testing.T) {
+	cap := Capabilities{
+		APIVersions: DefaultVersionSet,
+	}
+
+	if !cap.APIVersions.Has("v1") {
+		t.Error("APIVersions should have v1")
+	}
+}
diff --git a/pkg/chartutil/values.go b/pkg/chartutil/values.go
index a4cb1a2221e071f37b3d34522affe12555495950..499cb89b0b97f8aa946cb9d8879a0ed398adc7cc 100644
--- a/pkg/chartutil/values.go
+++ b/pkg/chartutil/values.go
@@ -332,7 +332,20 @@ type ReleaseOptions struct {
 }
 
 // ToRenderValues composes the struct from the data coming from the Releases, Charts and Values files
+//
+// WARNING: This function is deprecated for Helm > 2.1.99 Use ToRenderValuesCaps() instead. It will
+// remain in the codebase to stay SemVer compliant.
+//
+// In Helm 3.0, this will be changed to accept Capabilities as a fourth parameter.
 func ToRenderValues(chrt *chart.Chart, chrtVals *chart.Config, options ReleaseOptions) (Values, error) {
+	caps := &Capabilities{APIVersions: DefaultVersionSet}
+	return ToRenderValuesCaps(chrt, chrtVals, options, caps)
+}
+
+// ToRenderValuesCaps composes the struct from the data coming from the Releases, Charts and Values files
+//
+// This takes both ReleaseOptions and Capabilities to merge into the render values.
+func ToRenderValuesCaps(chrt *chart.Chart, chrtVals *chart.Config, options ReleaseOptions, caps *Capabilities) (Values, error) {
 
 	top := map[string]interface{}{
 		"Release": map[string]interface{}{
@@ -344,8 +357,9 @@ func ToRenderValues(chrt *chart.Chart, chrtVals *chart.Config, options ReleaseOp
 			"Revision":  options.Revision,
 			"Service":   "Tiller",
 		},
-		"Chart": chrt.Metadata,
-		"Files": NewFiles(chrt.Files),
+		"Chart":        chrt.Metadata,
+		"Files":        NewFiles(chrt.Files),
+		"Capabilities": caps,
 	}
 
 	vals, err := CoalesceValues(chrt, chrtVals)
diff --git a/pkg/chartutil/values_test.go b/pkg/chartutil/values_test.go
index e7b120924b947a5ac52700c79012624e793fcfb3..2c519b099fc10f500593488b57e841efd1f43152 100644
--- a/pkg/chartutil/values_test.go
+++ b/pkg/chartutil/values_test.go
@@ -24,8 +24,11 @@ import (
 	"text/template"
 
 	"github.com/golang/protobuf/ptypes/any"
+
 	"k8s.io/helm/pkg/proto/hapi/chart"
 	"k8s.io/helm/pkg/timeconv"
+	"k8s.io/helm/pkg/version"
+	kversion "k8s.io/kubernetes/pkg/version"
 )
 
 func TestReadValues(t *testing.T) {
@@ -69,7 +72,7 @@ water:
 	}
 }
 
-func TestToRenderValues(t *testing.T) {
+func TestToRenderValuesCaps(t *testing.T) {
 
 	chartValues := `
 name: al Rashid
@@ -108,7 +111,13 @@ where:
 		Revision:  5,
 	}
 
-	res, err := ToRenderValues(c, v, o)
+	caps := &Capabilities{
+		APIVersions:   DefaultVersionSet,
+		TillerVersion: version.GetVersionProto(),
+		KubeVersion:   &kversion.Info{Major: "1"},
+	}
+
+	res, err := ToRenderValuesCaps(c, v, o, caps)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -125,7 +134,7 @@ where:
 		t.Errorf("Expected release revision %d, got %q", 5, rev)
 	}
 	if relmap["IsUpgrade"].(bool) {
-		t.Errorf("Expected upgrade to be false.")
+		t.Error("Expected upgrade to be false.")
 	}
 	if !relmap["IsInstall"].(bool) {
 		t.Errorf("Expected install to be true.")
@@ -133,6 +142,15 @@ where:
 	if data := res["Files"].(Files)["scheherazade/shahryar.txt"]; string(data) != "1,001 Nights" {
 		t.Errorf("Expected file '1,001 Nights', got %q", string(data))
 	}
+	if !res["Capabilities"].(*Capabilities).APIVersions.Has("v1") {
+		t.Error("Expected Capabilities to have v1 as an API")
+	}
+	if res["Capabilities"].(*Capabilities).TillerVersion.SemVer == "" {
+		t.Error("Expected Capabilities to have a Tiller version")
+	}
+	if res["Capabilities"].(*Capabilities).KubeVersion.Major != "1" {
+		t.Error("Expected Capabilities to have a Kube version")
+	}
 
 	var vals Values
 	vals = res["Values"].(Values)
diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go
index 93b0b0b60f46e04b54e284c34f19f6189fe72133..34d7ad79d83b5fadd6c994de9ec0e66132a7a7de 100644
--- a/pkg/engine/engine.go
+++ b/pkg/engine/engine.go
@@ -222,10 +222,11 @@ func recAllTpls(c *chart.Chart, templates map[string]renderable, parentVals char
 		}
 
 		cvals = map[string]interface{}{
-			"Values":  newVals,
-			"Release": parentVals["Release"],
-			"Chart":   c.Metadata,
-			"Files":   chartutil.NewFiles(c.Files),
+			"Values":       newVals,
+			"Release":      parentVals["Release"],
+			"Chart":        c.Metadata,
+			"Files":        chartutil.NewFiles(c.Files),
+			"Capabilities": parentVals["Capabilities"],
 		}
 	}
 
diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go
index fe395a974cc55a6d1c2d19cc0de85f133d7364f5..5b98d4886976fd205ca9c7ff57758b13d4937937 100644
--- a/pkg/lint/rules/template.go
+++ b/pkg/lint/rules/template.go
@@ -51,7 +51,8 @@ func Templates(linter *support.Linter) {
 	}
 
 	options := chartutil.ReleaseOptions{Name: "testRelease", Time: timeconv.Now(), Namespace: "testNamespace"}
-	valuesToRender, err := chartutil.ToRenderValues(chart, chart.Values, options)
+	caps := &chartutil.Capabilities{APIVersions: chartutil.DefaultVersionSet}
+	valuesToRender, err := chartutil.ToRenderValuesCaps(chart, chart.Values, options, caps)
 	if err != nil {
 		// FIXME: This seems to generate a duplicate, but I can't find where the first
 		// error is coming from.
diff --git a/pkg/tiller/hooks.go b/pkg/tiller/hooks.go
index c03107cbec720f14b275e34bf5ea3e366153ea14..1687f2f3b5884b72cd630dad70271484a8722962 100644
--- a/pkg/tiller/hooks.go
+++ b/pkg/tiller/hooks.go
@@ -24,6 +24,7 @@ import (
 
 	"github.com/ghodss/yaml"
 
+	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/proto/hapi/release"
 )
 
@@ -61,21 +62,6 @@ type simpleHead struct {
 	} `json:"metadata,omitempty"`
 }
 
-type versionSet map[string]struct{}
-
-func newVersionSet(apiVersions ...string) versionSet {
-	vs := versionSet{}
-	for _, v := range apiVersions {
-		vs[v] = struct{}{}
-	}
-	return vs
-}
-
-func (v versionSet) Has(apiVersion string) bool {
-	_, ok := v[apiVersion]
-	return ok
-}
-
 // manifest represents a manifest file, which has a name and some content.
 type manifest struct {
 	name    string
@@ -104,7 +90,7 @@ type manifest struct {
 //
 // Files that do not parse into the expected format are simply placed into a map and
 // returned.
-func sortManifests(files map[string]string, apis versionSet, sort SortOrder) ([]*release.Hook, []manifest, error) {
+func sortManifests(files map[string]string, apis chartutil.VersionSet, sort SortOrder) ([]*release.Hook, []manifest, error) {
 	hs := []*release.Hook{}
 	generic := []manifest{}
 
diff --git a/pkg/tiller/hooks_test.go b/pkg/tiller/hooks_test.go
index f20a1bde6ed0e21a18da2f10c7aeca5eae0e9275..b9bfed71ac20e6cf4e95615df83254451758f68a 100644
--- a/pkg/tiller/hooks_test.go
+++ b/pkg/tiller/hooks_test.go
@@ -21,6 +21,7 @@ import (
 
 	"github.com/ghodss/yaml"
 
+	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/proto/hapi/release"
 )
 
@@ -118,7 +119,7 @@ metadata:
 		manifests[o.path] = o.manifest
 	}
 
-	hs, generic, err := sortManifests(manifests, newVersionSet("v1", "v1beta1"), InstallOrder)
+	hs, generic, err := sortManifests(manifests, chartutil.NewVersionSet("v1", "v1beta1"), InstallOrder)
 	if err != nil {
 		t.Fatalf("Unexpected error: %s", err)
 	}
@@ -183,7 +184,7 @@ metadata:
 }
 
 func TestVersionSet(t *testing.T) {
-	vs := newVersionSet("v1", "v1beta1", "extensions/alpha5", "batch/v1")
+	vs := chartutil.NewVersionSet("v1", "v1beta1", "extensions/alpha5", "batch/v1")
 
 	if l := len(vs); l != 4 {
 		t.Errorf("Expected 4, got %d", l)
diff --git a/pkg/tiller/release_server.go b/pkg/tiller/release_server.go
index 30bebe636a2a77cef5995ec053e49c4b75f1fa05..01f653be13cd465a98ca89c7c5ed402471f2f672 100644
--- a/pkg/tiller/release_server.go
+++ b/pkg/tiller/release_server.go
@@ -361,12 +361,16 @@ func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*rele
 		Revision:  int(revision),
 	}
 
-	valuesToRender, err := chartutil.ToRenderValues(req.Chart, req.Values, options)
+	caps, err := capabilities(s.clientset.Discovery())
+	if err != nil {
+		return nil, nil, err
+	}
+	valuesToRender, err := chartutil.ToRenderValuesCaps(req.Chart, req.Values, options, caps)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender)
+	hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender, caps.APIVersions)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -589,6 +593,23 @@ func (s *ReleaseServer) InstallRelease(c ctx.Context, req *services.InstallRelea
 	return res, err
 }
 
+// capabilities builds a Capabilities from discovery information.
+func capabilities(disc discovery.DiscoveryInterface) (*chartutil.Capabilities, error) {
+	sv, err := disc.ServerVersion()
+	if err != nil {
+		return nil, err
+	}
+	vs, err := getVersionSet(disc)
+	if err != nil {
+		return nil, fmt.Errorf("Could not get apiVersions from Kubernetes: %s", err)
+	}
+	return &chartutil.Capabilities{
+		APIVersions:   vs,
+		KubeVersion:   sv,
+		TillerVersion: version.GetVersionProto(),
+	}, nil
+}
+
 // prepareRelease builds a release for an install operation.
 func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*release.Release, error) {
 	if req.Chart == nil {
@@ -600,6 +621,11 @@ func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re
 		return nil, err
 	}
 
+	caps, err := capabilities(s.clientset.Discovery())
+	if err != nil {
+		return nil, err
+	}
+
 	revision := 1
 	ts := timeconv.Now()
 	options := chartutil.ReleaseOptions{
@@ -609,12 +635,12 @@ func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re
 		Revision:  revision,
 		IsInstall: true,
 	}
-	valuesToRender, err := chartutil.ToRenderValues(req.Chart, req.Values, options)
+	valuesToRender, err := chartutil.ToRenderValuesCaps(req.Chart, req.Values, options, caps)
 	if err != nil {
 		return nil, err
 	}
 
-	hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender)
+	hooks, manifestDoc, notesTxt, err := s.renderResources(req.Chart, valuesToRender, caps.APIVersions)
 	if err != nil {
 		// Return a release with partial data so that client can show debugging
 		// information.
@@ -659,12 +685,10 @@ func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re
 	return rel, err
 }
 
-func getVersionSet(client discovery.ServerGroupsInterface) (versionSet, error) {
-	defVersions := newVersionSet("v1")
-
+func getVersionSet(client discovery.ServerGroupsInterface) (chartutil.VersionSet, error) {
 	groups, err := client.ServerGroups()
 	if err != nil {
-		return defVersions, err
+		return chartutil.DefaultVersionSet, err
 	}
 
 	// FIXME: The Kubernetes test fixture for cli appears to always return nil
@@ -672,14 +696,14 @@ func getVersionSet(client discovery.ServerGroupsInterface) (versionSet, error) {
 	// the default API list. This is also a safe value to return in any other
 	// odd-ball case.
 	if groups == nil {
-		return defVersions, nil
+		return chartutil.DefaultVersionSet, nil
 	}
 
 	versions := unversioned.ExtractGroupVersions(groups)
-	return newVersionSet(versions...), nil
+	return chartutil.NewVersionSet(versions...), nil
 }
 
-func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values) ([]*release.Hook, *bytes.Buffer, string, error) {
+func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values, vs chartutil.VersionSet) ([]*release.Hook, *bytes.Buffer, string, error) {
 	renderer := s.engine(ch)
 	files, err := renderer.Render(ch, values)
 	if err != nil {
@@ -706,10 +730,6 @@ func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values
 	// Sort hooks, manifests, and partials. Only hooks and manifests are returned,
 	// as partials are not used after renderer.Render. Empty manifests are also
 	// removed here.
-	vs, err := getVersionSet(s.clientset.Discovery())
-	if err != nil {
-		return nil, nil, "", fmt.Errorf("Could not get apiVersions from Kubernetes: %s", err)
-	}
 	hooks, manifests, err := sortManifests(files, vs, InstallOrder)
 	if err != nil {
 		// By catching parse errors here, we can prevent bogus releases from going