Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions charts/mcp-stack/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)

### Added

#### **🔐 ServiceAccount Support** ([#1718](https://github.com/IBM/mcp-context-forge/pull/1718))
* Optional ServiceAccount configuration for cloud IAM integration (AWS IRSA, GCP Workload Identity)
* `serviceAccount.create` - Create a dedicated ServiceAccount for all pods (default: `false`)
* `serviceAccount.name` - Custom ServiceAccount name (uses release fullname if empty)
* `serviceAccount.annotations` - IAM role annotations for cloud provider integration
* `serviceAccount.automountServiceAccountToken` - Control token mounting (default: `true`)
* Applied to all Deployments and Jobs in the chart
* Disabled by default to maintain backward compatibility

#### **🔧 Extra Environment Variables Support** ([#2047](https://github.com/IBM/mcp-context-forge/issues/2047))
* `extraEnv` - Inject additional environment variables directly into the gateway container
* `extraEnvFrom` - Mount environment variables from existing Secrets or ConfigMaps
* Enables injection of sensitive credentials (SSO secrets, external DB URLs) without modifying templates
* Placed after derived URLs so user values can override `DATABASE_URL`/`REDIS_URL` if needed
* Schema validation catches common mistakes (missing `name`, invalid `secretKeyRef` shape)

### Fixed

* **PgBouncer ServiceAccount** ([#1718](https://github.com/IBM/mcp-context-forge/pull/1718)) - Added missing `serviceAccountName` to pgbouncer deployment for consistency with other components

### Changed

#### **⚡ Metrics Performance Defaults** ([#1799](https://github.com/IBM/mcp-context-forge/issues/1799))
Expand Down
12 changes: 8 additions & 4 deletions charts/mcp-stack/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# mcp-stack

![Version: 1.0.0-BETA-1](https://img.shields.io/badge/Version-1.0.0--BETA--1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.0.0-BETA-1](https://img.shields.io/badge/AppVersion-1.0.0--BETA--1-informational?style=flat-square)
![Version: 1.0.0-BETA-2](https://img.shields.io/badge/Version-1.0.0--BETA--2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.0.0-BETA-2](https://img.shields.io/badge/AppVersion-1.0.0--BETA--2-informational?style=flat-square)

A full-stack Helm chart for IBM's **Model Context Protocol (MCP) Gateway
& Registry - Context-Forge**. It bundles:
Expand Down Expand Up @@ -314,8 +314,8 @@ Kubernetes: `>=1.21.0-0`
| mcpContextForge.env.redis.port | int | `6379` | |
| mcpContextForge.envFrom[0].secretRef.name | string | `"mcp-gateway-secret"` | |
| mcpContextForge.envFrom[1].configMapRef.name | string | `"mcp-gateway-config"` | |
| mcpContextForge.extraEnv | list | `[]` | Additional environment variables to inject directly |
| mcpContextForge.extraEnvFrom | list | `[]` | Additional environment variables from secrets or configmaps |
| mcpContextForge.extraEnv | list | `[]` | |
| mcpContextForge.extraEnvFrom | list | `[]` | |
| mcpContextForge.hpa | object | `{"enabled":true,"maxReplicas":10,"minReplicas":2,"targetCPUUtilizationPercentage":90,"targetMemoryUtilizationPercentage":90}` | ------------------------------------------------------------------ |
| mcpContextForge.image.pullPolicy | string | `"Always"` | |
| mcpContextForge.image.repository | string | `"ghcr.io/ibm/mcp-context-forge"` | |
Expand Down Expand Up @@ -608,6 +608,7 @@ Kubernetes: `>=1.21.0-0`
| postgres.credentials.password | string | `"test123"` | |
| postgres.credentials.user | string | `"admin"` | |
| postgres.enabled | bool | `true` | |
| postgres.existingSecret | string | `""` | |
| postgres.external.database | string | `""` | |
| postgres.external.databaseKey | string | `"dbname"` | |
| postgres.external.enabled | bool | `false` | |
Expand All @@ -620,7 +621,6 @@ Kubernetes: `>=1.21.0-0`
| postgres.external.portKey | string | `"port"` | |
| postgres.external.user | string | `""` | |
| postgres.external.userKey | string | `"user"` | |
| postgres.existingSecret | string | `""` | |
| postgres.image.pullPolicy | string | `"IfNotPresent"` | |
| postgres.image.repository | string | `"postgres"` | |
| postgres.image.tag | string | `"17"` | |
Expand Down Expand Up @@ -715,4 +715,8 @@ Kubernetes: `>=1.21.0-0`
| redisCommander.resources.requests.memory | string | `"128Mi"` | |
| redisCommander.service.port | int | `8081` | |
| redisCommander.service.type | string | `"ClusterIP"` | |
| serviceAccount.annotations | object | `{}` | Annotations for the ServiceAccount (e.g., AWS IRSA, GCP Workload Identity) |
| serviceAccount.automountServiceAccountToken | bool | `true` | Mount the ServiceAccount token in pods. Only applies when create=true (existing ServiceAccounts control their own token mounting) |
| serviceAccount.create | bool | `false` | Create a ServiceAccount for all pods in this release |
| serviceAccount.name | string | `""` | ServiceAccount name. If empty and create=true, uses release fullname. If create=false, uses this name or "default" |

14 changes: 14 additions & 0 deletions charts/mcp-stack/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{- /* --------------------------------------------------------------------
Helper: mcp-stack.serviceAccountName
Returns the ServiceAccount name to use.
If serviceAccount.create is true and name is empty, uses fullname.
If serviceAccount.create is false, uses the provided name or "default".
-------------------------------------------------------------------- */}}
{{- define "mcp-stack.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "mcp-stack.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

{{- /* --------------------------------------------------------------------
Helper: mcp-stack.postgresSecretName
Returns the Secret name that the Postgres deployment should mount.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ spec:
- name: {{ . }}
{{- end }}
{{- end }}
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
containers:
- name: mcp-fast-time-server
image: "{{ .Values.mcpFastTimeServer.image.repository }}:{{ .Values.mcpFastTimeServer.image.tag }}"
Expand Down
1 change: 1 addition & 0 deletions charts/mcp-stack/templates/deployment-mcpgateway.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ spec:
- name: {{ . }}
{{- end }}
{{- end }}
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
containers:
- name: mcp-context-forge
image: "{{ .Values.mcpContextForge.image.repository }}:{{ .Values.mcpContextForge.image.tag }}"
Expand Down
1 change: 1 addition & 0 deletions charts/mcp-stack/templates/deployment-pgadmin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ spec:
- name: {{ . }}
{{- end }}
{{- end }}
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
containers:
- name: pgadmin
image: "{{ .Values.pgadmin.image.repository }}:{{ .Values.pgadmin.image.tag }}"
Expand Down
1 change: 1 addition & 0 deletions charts/mcp-stack/templates/deployment-pgbouncer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ spec:
- name: {{ . }}
{{- end }}
{{- end }}
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
containers:
- name: pgbouncer
image: "{{ .Values.pgbouncer.image.repository }}:{{ .Values.pgbouncer.image.tag }}"
Expand Down
1 change: 1 addition & 0 deletions charts/mcp-stack/templates/deployment-postgres.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ spec:
- name: {{ . }}
{{- end }}
{{- end }}
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
initContainers:
{{- if and .Values.postgres.upgrade.enabled (eq $targetVersion "18") .Values.postgres.upgrade.backupCompleted }}
# Init container to upgrade PostgreSQL data from version 17 to 18
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ spec:
- name: {{ . }}
{{- end }}
{{- end }}
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
containers:
- name: redis-commander
image: "{{ .Values.redisCommander.image.repository }}:{{ .Values.redisCommander.image.tag }}"
Expand Down
1 change: 1 addition & 0 deletions charts/mcp-stack/templates/deployment-redis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ spec:
- name: {{ . }}
{{- end }}
{{- end }}
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
containers:
- name: redis
image: "{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}"
Expand Down
1 change: 1 addition & 0 deletions charts/mcp-stack/templates/job-migration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ spec:
app.kubernetes.io/component: migration
spec:
restartPolicy: {{ .Values.migration.restartPolicy }}
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}

containers:
- name: migration
Expand Down
1 change: 1 addition & 0 deletions charts/mcp-stack/templates/job-postgres-backup.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ spec:
template:
spec:
restartPolicy: Never
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
containers:
- name: postgres-backup
image: "{{ .Values.postgres.image.repository }}:{{ .Values.postgres.image.tag }}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ spec:
template:
spec:
restartPolicy: Never
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
containers:
- name: postgres-migration-check
image: "{{ .Values.postgres.image.repository }}:18"
Expand Down
1 change: 1 addition & 0 deletions charts/mcp-stack/templates/minio-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ spec:
app.kubernetes.io/component: minio
app: {{ include "mcp-stack.fullname" . }}-minio
spec:
serviceAccountName: {{ include "mcp-stack.serviceAccountName" . }}
containers:
- name: minio
image: "{{ .Values.minio.image.repository }}:{{ .Values.minio.image.tag }}"
Expand Down
13 changes: 13 additions & 0 deletions charts/mcp-stack/templates/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "mcp-stack.serviceAccountName" . }}
labels:
{{- include "mcp-stack.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
{{- end }}
30 changes: 30 additions & 0 deletions charts/mcp-stack/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,36 @@
},
"additionalProperties": false
},
"serviceAccount": {
"type": "object",
"description": "ServiceAccount configuration for all pods in the release",
"properties": {
"create": {
"type": "boolean",
"description": "Create a ServiceAccount",
"default": false
},
"name": {
"type": "string",
"description": "ServiceAccount name (uses fullname if empty)",
"default": ""
},
"annotations": {
"type": "object",
"description": "Annotations for the ServiceAccount (e.g., IRSA, Workload Identity)",
"additionalProperties": {
"type": "string"
},
"default": {}
},
"automountServiceAccountToken": {
"type": "boolean",
"description": "Mount the ServiceAccount token in pods",
"default": true
}
},
"additionalProperties": false
},
"mcpContextForge": {
"type": "object",
"description": "MCP Context-Forge Gateway configuration",
Expand Down
20 changes: 20 additions & 0 deletions charts/mcp-stack/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@ global:
nameOverride: "" # short name applied to all resources (optional)
fullnameOverride: "" # fully-qualified name override (optional)

########################################################################
# SERVICE ACCOUNT
# Configure ServiceAccount for all pods in the release.
# Note: All pods (gateway, postgres, redis, minio, etc.) share the same
# ServiceAccount. For fine-grained IAM control, deploy components in
# separate releases or use Kustomize overlays.
########################################################################
serviceAccount:
# -- Create a ServiceAccount for all pods in this release
create: false
# -- ServiceAccount name. If empty and create=true, uses release fullname. If create=false, uses this name or "default"
name: ""
# -- Annotations for the ServiceAccount (e.g., AWS IRSA, GCP Workload Identity)
# @default -- `{}`
annotations: {}
# eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/my-role
# iam.gke.io/gcp-service-account: [email protected]
# -- Mount the ServiceAccount token in pods. Only applies when create=true (existing ServiceAccounts control their own token mounting)
automountServiceAccountToken: true

########################################################################
# MCP CONTEXT-FORGE (Gateway / API tier)
########################################################################
Expand Down
Loading