
K8s Helm
- 13 installs
- 941 repo stars
- Updated April 8, 2026
- rohitg00/kubectl-mcp-server
Helps with ai & agent building tasks during AI-assisted development.
About
k8s-helm is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- k8s-helm
- AI & Agent Building
- AI-coding skill
K8s Helm by the numbers
- 13 all-time installs (skills.sh)
- Ranked #11,409 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/rohitg00/kubectl-mcp-server --skill k8s-helmAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 13 |
|---|---|
| repo stars | ★ 941 |
| Last updated | April 8, 2026 |
| Repository | rohitg00/kubectl-mcp-server ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Helm Chart Management
Comprehensive Helm v3 operations using kubectl-mcp-server's 16 Helm tools.
When to Apply
Use this skill when:
- User mentions: "helm", "chart", "release", "values", "repository"
- Operations: installing charts, upgrading releases, rollbacks
- Keywords: "package", "template", "lint", "repo add"
Priority Rules
| Priority | Rule | Impact | Tools |
|---|---|---|---|
| 1 | Template before install (dry run) | CRITICAL | template_helm_chart |
| 2 | Check existing releases first | CRITICAL | list_helm_releases |
| 3 | Lint charts before packaging | HIGH | lint_helm_chart |
| 4 | Note revision before upgrade | HIGH | get_helm_history |
| 5 | Verify values after upgrade | MEDIUM | get_helm_values |
| 6 | Update repos before search | LOW | update_helm_repos |
Quick Reference
| Task | Tool | Example |
|---|---|---|
| Install chart | install_helm_chart | install_helm_chart(name, chart, namespace) |
| Upgrade release | upgrade_helm_release | upgrade_helm_release(name, chart, namespace, values) |
| Rollback | rollback_helm_release | rollback_helm_release(name, namespace, revision) |
| List releases | list_helm_releases | list_helm_releases(namespace) |
| Get values | get_helm_values | get_helm_values(name, namespace) |
| Template (dry run) | template_helm_chart | template_helm_chart(name, chart, namespace) |
Install Chart
install_helm_chart(
name="my-release",
chart="bitnami/nginx",
namespace="web",
values={"replicaCount": 3, "service.type": "LoadBalancer"}
)Upgrade Release
upgrade_helm_release(
name="my-release",
chart="bitnami/nginx",
namespace="web",
values={"replicaCount": 5}
)Rollback Release
rollback_helm_release(
name="my-release",
namespace="web",
revision=1
)Uninstall Release
uninstall_helm_chart(name="my-release", namespace="web")Release Management
List Releases
list_helm_releases(namespace="web")
list_helm_releases()Get Release Details
get_helm_release(name="my-release", namespace="web")Release History
get_helm_history(name="my-release", namespace="web")Get Release Values
get_helm_values(name="my-release", namespace="web")Get Release Manifest
get_helm_manifest(name="my-release", namespace="web")Repository Management
Add Repository
add_helm_repo(name="bitnami", url="https://charts.bitnami.com/bitnami")List Repositories
list_helm_repos()Update Repositories
update_helm_repos()Search Charts
search_helm_charts(keyword="nginx")
search_helm_charts(keyword="postgres", repo="bitnami")Chart Development
Template Chart (Dry Run)
template_helm_chart(
name="my-release",
chart="./my-chart",
namespace="test",
values={"key": "value"}
)Lint Chart
lint_helm_chart(chart="./my-chart")Package Chart
package_helm_chart(chart="./my-chart", destination="./packages")Common Workflows
New Application Deployment
add_helm_repo(name="bitnami", url="...")
search_helm_charts(keyword="postgresql")
template_helm_chart(...)
install_helm_chart(...)
get_helm_release(...)Upgrade with Rollback Safety
get_helm_history(name, namespace)
upgrade_helm_release(name, chart, namespace, values)
rollback_helm_release(name, namespace, revision)Multi-Environment Deployment
install_helm_chart(
name="app",
chart="./charts/app",
namespace="dev",
values={"replicas": 1},
context="development"
)
install_helm_chart(
name="app",
chart="./charts/app",
namespace="staging",
values={"replicas": 2},
context="staging"
)
install_helm_chart(
name="app",
chart="./charts/app",
namespace="prod",
values={"replicas": 5},
context="production"
)Chart Structure
See references/CHART-STRUCTURE.md for best practices on organizing Helm charts.
Troubleshooting
See TROUBLESHOOTING.md for common issues.
Release Stuck in Pending
get_helm_release(name, namespace)
get_pods(namespace, label_selector="app.kubernetes.io/instance=<release>")Failed Installation
get_helm_history(name, namespace)
get_events(namespace)
uninstall_helm_chart(name, namespace)Values Not Applied
get_helm_values(name, namespace)
template_helm_chart(...)
upgrade_helm_release(...)Scripts
See scripts/lint-chart.sh for automated chart validation.
Best Practices
1. Always Template First
template_helm_chart(name, chart, namespace, values)2. Use Semantic Versioning
install_helm_chart(..., version="1.2.3")3. Store Values in Git
values-dev.yamlvalues-staging.yamlvalues-prod.yaml
4. Namespace Isolation
- One namespace per release
- Easier cleanup and RBAC
Prerequisites
- Helm CLI: Required for all Helm operations
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bashRelated Skills
- k8s-deploy - Deployment strategies
- k8s-gitops - GitOps Helm releases
Helm Chart Structure Best Practices
Reference for organizing and structuring Helm charts.
Standard Chart Layout
mychart/
├── Chart.yaml # Chart metadata (required)
├── Chart.lock # Dependency lock file
├── values.yaml # Default configuration values
├── values.schema.json # JSON schema for values validation
├── .helmignore # Patterns to ignore when packaging
├── README.md # Chart documentation
├── LICENSE # License file
├── templates/ # Kubernetes manifests (required)
│ ├── NOTES.txt # Post-install notes
│ ├── _helpers.tpl # Template helpers/partials
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── configmap.yaml
│ ├── secret.yaml
│ ├── serviceaccount.yaml
│ ├── hpa.yaml
│ └── tests/ # Helm test hooks
│ └── test-connection.yaml
├── charts/ # Dependency charts
└── crds/ # Custom Resource DefinitionsChart.yaml
apiVersion: v2
name: mychart
description: A Helm chart for MyApp
type: application
version: 1.0.0
appVersion: "2.5.0"
keywords:
- myapp
- web
home: https://github.com/org/mychart
sources:
- https://github.com/org/mychart
maintainers:
- name: John Doe
email: john@example.com
url: https://johndoe.com
icon: https://example.com/icon.png
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
- name: redis
version: "17.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabledvalues.yaml Best Practices
replicaCount: 1
image:
repository: myapp
pullPolicy: IfNotPresent
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
podAnnotations: {}
podSecurityContext:
fsGroup: 1000
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: ""
annotations: {}
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}_helpers.tpl Template
{{/*
Expand the name of the chart.
*/}}
{{- define "mychart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "mychart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "mychart.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "mychart.labels" -}}
helm.sh/chart: {{ include "mychart.chart" . }}
{{ include "mychart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "mychart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "mychart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "mychart.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "mychart.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}values.schema.json
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["image", "service"],
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1
},
"image": {
"type": "object",
"required": ["repository"],
"properties": {
"repository": {"type": "string"},
"tag": {"type": "string"},
"pullPolicy": {
"type": "string",
"enum": ["Always", "IfNotPresent", "Never"]
}
}
},
"service": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["ClusterIP", "NodePort", "LoadBalancer"]
},
"port": {"type": "integer", "minimum": 1, "maximum": 65535}
}
}
}
}Environment-Specific Values
charts/mychart/
├── values.yaml # Base defaults
├── values-dev.yaml # Development overrides
├── values-staging.yaml # Staging overrides
└── values-prod.yaml # Production overridesvalues-dev.yaml:
replicaCount: 1
resources:
limits:
cpu: 100m
memory: 128Mivalues-prod.yaml:
replicaCount: 3
resources:
limits:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10NOTES.txt Template
Thank you for installing {{ .Chart.Name }}.
Your release is named {{ .Release.Name }}.
To learn more about the release, try:
$ helm status {{ .Release.Name }}
$ helm get all {{ .Release.Name }}
{{- if .Values.ingress.enabled }}
Access your application at:
{{- range .Values.ingress.hosts }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ .host }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
Get the application URL by running:
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "mychart.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
Get the application URL by running:
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "mychart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
Get the application URL by running:
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "mychart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
echo "Visit http://127.0.0.1:8080 to use your application"
{{- end }}Test Template
templates/tests/test-connection.yaml:
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "mychart.fullname" . }}-test-connection"
labels:
{{- include "mychart.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "mychart.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: NeverValidation Checklist
- [ ] Chart.yaml has required fields
- [ ] values.yaml has sensible defaults
- [ ] All templates use helpers for names/labels
- [ ] Resources have limits defined
- [ ] Security contexts are set
- [ ] NOTES.txt provides useful info
- [ ] README.md documents all values
- [ ] Linting passes:
helm lint ./mychart
#!/bin/bash
set -e
CHART_PATH="${1:-.}"
echo "=== Helm Chart Linting ==="
echo "Chart: $CHART_PATH"
echo ""
if [ ! -f "$CHART_PATH/Chart.yaml" ]; then
echo "ERROR: Not a valid Helm chart directory (missing Chart.yaml)"
exit 1
fi
CHART_NAME=$(grep '^name:' "$CHART_PATH/Chart.yaml" | awk '{print $2}')
echo "Chart Name: $CHART_NAME"
echo ""
echo "--- Step 1: Helm Lint ---"
if helm lint "$CHART_PATH"; then
echo "✓ Helm lint passed"
else
echo "✗ Helm lint failed"
exit 1
fi
echo ""
echo "--- Step 2: Template Validation ---"
if helm template test-release "$CHART_PATH" > /dev/null 2>&1; then
echo "✓ Template rendering passed"
else
echo "✗ Template rendering failed"
helm template test-release "$CHART_PATH"
exit 1
fi
echo ""
echo "--- Step 3: Kubernetes Manifest Validation ---"
if command -v kubectl &> /dev/null; then
if helm template test-release "$CHART_PATH" | kubectl apply --dry-run=client -f - > /dev/null 2>&1; then
echo "✓ Kubernetes validation passed"
else
echo "⚠ Kubernetes validation failed (may be expected without cluster)"
fi
else
echo "⚠ kubectl not found, skipping Kubernetes validation"
fi
echo ""
echo "--- Step 4: Structure Check ---"
required_files=("Chart.yaml" "values.yaml" "templates")
for file in "${required_files[@]}"; do
if [ -e "$CHART_PATH/$file" ]; then
echo "✓ $file exists"
else
echo "✗ $file missing"
fi
done
recommended_files=("README.md" "templates/NOTES.txt" "templates/_helpers.tpl")
for file in "${recommended_files[@]}"; do
if [ -e "$CHART_PATH/$file" ]; then
echo "✓ $file exists"
else
echo "⚠ $file recommended but missing"
fi
done
echo ""
echo "--- Step 5: Values Schema Check ---"
if [ -f "$CHART_PATH/values.schema.json" ]; then
echo "✓ values.schema.json exists"
if command -v jsonschema &> /dev/null; then
if jsonschema -i "$CHART_PATH/values.yaml" "$CHART_PATH/values.schema.json" 2>/dev/null; then
echo "✓ Values match schema"
else
echo "⚠ Values may not match schema"
fi
fi
else
echo "⚠ values.schema.json not found (recommended for validation)"
fi
echo ""
echo "--- Step 6: Security Check ---"
templates_dir="$CHART_PATH/templates"
if grep -r "securityContext" "$templates_dir" > /dev/null 2>&1; then
echo "✓ Security contexts found"
else
echo "⚠ No security contexts found (recommended)"
fi
if grep -r "resources:" "$templates_dir" > /dev/null 2>&1; then
echo "✓ Resource limits found"
else
echo "⚠ No resource limits found (recommended)"
fi
echo ""
echo "=== Linting Complete ==="
echo "Run 'helm template <name> $CHART_PATH' to preview rendered manifests"
Helm Troubleshooting Guide
Common Helm issues and resolutions.
Installation Failures
Error: INSTALLATION FAILED: cannot re-use a name
Cause: Release with same name exists (possibly failed).
Diagnosis:
list_helm_releases(namespace)
get_helm_history(name, namespace)Resolution:
uninstall_helm_chart(name, namespace)
install_helm_chart(name, chart, namespace, values)Error: timed out waiting for condition
Cause: Pods not becoming ready within timeout.
Diagnosis:
get_pods(namespace, label_selector="app.kubernetes.io/instance=<release>")
describe_pod(name, namespace)
get_events(namespace)Common Causes:
- Image pull failure
- Insufficient resources
- Failed health checks
- Missing ConfigMaps/Secrets
Resolution:
# Fix the issue, then upgrade
upgrade_helm_release(name, chart, namespace, values)Error: rendered manifests contain a resource that already exists
Cause: Resource exists outside Helm management.
Diagnosis:
# Check if resource exists
get_deployments(namespace) # or other resource typeResolution:
- Delete existing resource manually
- Or use
--forceflag
Upgrade Failures
Error: UPGRADE FAILED: another operation in progress
Cause: Previous operation didn't complete cleanly.
Diagnosis:
get_helm_history(name, namespace)
# Look for pending-* statusResolution:
# If stuck in pending-install
uninstall_helm_chart(name, namespace)
install_helm_chart(name, chart, namespace, values)
# If stuck in pending-upgrade, rollback first
rollback_helm_release(name, namespace, revision=<last-good>)Error: "spec.selector" is immutable
Cause: Trying to change selector labels.
Resolution:
- Delete deployment and reinstall
- Or use a new release name
Rollback Issues
Rollback doesn't restore old values
Cause: Values are tied to revision, not chart version.
Diagnosis:
get_helm_values(name, namespace)
get_helm_history(name, namespace)Resolution:
rollback_helm_release(name, namespace, revision=<specific>)Chart Development Issues
Template rendering fails
Diagnosis:
template_helm_chart(name, chart, namespace, values)
lint_helm_chart(chart)Common Causes:
- Syntax errors in templates
- Missing values
- Incorrect indentation in YAML
Values not applied
Diagnosis:
get_helm_values(name, namespace)
template_helm_chart(name, chart, namespace, values)Common Causes:
- Wrong key path in values
- Values overridden by defaults
- Type mismatch (string vs number)
Release Status Reference
| Status | Meaning | Action |
|---|---|---|
| deployed | Success | None |
| failed | Installation/upgrade failed | Fix and retry |
| pending-install | Install in progress | Wait or cleanup |
| pending-upgrade | Upgrade in progress | Wait or rollback |
| pending-rollback | Rollback in progress | Wait |
| superseded | Old revision | None |
| uninstalling | Uninstall in progress | Wait |
Debug Commands
# Full release info
get_helm_release(name, namespace)
# All revisions
get_helm_history(name, namespace)
# Current values
get_helm_values(name, namespace)
# Rendered manifests
get_helm_manifest(name, namespace)
# Dry-run to test
template_helm_chart(name, chart, namespace, values)
# Validate chart
lint_helm_chart(chart)Best Practices to Avoid Issues
1. Always dry-run first
template_helm_chart(name, chart, namespace, values)2. Check history before upgrade
get_helm_history(name, namespace)3. Use specific versions
install_helm_chart(name, chart, namespace, version="1.2.3", values)4. Keep values in version control
- values-dev.yaml
- values-prod.yaml
5. Test rollback procedure
# Know which revision to rollback to
get_helm_history(name, namespace)