OpenShift MCP Server Deployment on ARO
This content is authored by Red Hat experts, but has not yet been tested on every supported configuration.
This guide walks through deploying the OpenShift Kubernetes MCP Server on an Azure Red Hat OpenShift (ARO) cluster. You install the server with Helm, grant read-only cluster access to authorized users or groups, enable OAuth/OIDC on the MCP HTTP endpoint, and expose the service on a TLS-terminated OpenShift route.
The MCP server runs in read-only mode with destructive operations disabled. With OAuth enabled, callers must present a valid bearer token; the server uses token passthrough so each user’s identity (not a shared service account) is used for Kubernetes API calls.
OAuth on the MCP server is a preview feature. Configuration fields may change. Validate in a non-production cluster before production rollout. See the upstream OAuth configuration and Entra ID guides.
Prerequisites
- OpenShift CLI (
oc) installed and configured - Helm 3.x installed
- Git installed
- Cluster admin credentials for the ARO cluster
- Network access to the cluster API endpoint
- Permission to register an OAuth/OIDC application (Azure AD app registration for most ARO clusters, or cluster admin for an
OAuthClient) - A dedicated Entra ID group (recommended) or OpenShift user/group that will access the MCP server
Security and authentication
Two separate security layers apply:
| Layer | Purpose | How this guide configures it |
|---|---|---|
| MCP HTTP endpoint | Controls who can call /mcp |
require_oauth: true in Helm config (OIDC bearer token required) |
| Kubernetes API | Controls what MCP tools can read | mcp-readonly ClusterRole bound to your group (token passthrough) |
Without OAuth, a public OpenShift route allows anyone to use the MCP server’s cluster credentials. Do not expose the route without enabling OAuth (or keep the service internal only; see Internal access only at the end).
Important: When require_oauth is true, you must use cluster_auth_mode: passthrough. Do not bind mcp-readonly only to the pod service account—bind it to the users or groups that will authenticate (for example, an Entra ID group on ARO).
Deployment procedure
Step 1: Login to ARO Cluster
Authenticate to the ARO cluster using the OpenShift CLI. Replace the placeholders with your admin username, password, and cluster API URL.
Step 2: Create New Project
Create a dedicated namespace (project) for the MCP server deployment.
Step 3: Create RBAC for MCP Users
Create a ClusterRole with read-only permissions. Save one of the following manifests as mcp-readonly-clusterrole.yaml (do not apply both options—they use the same name).
Option A: Full Read-Only RBAC (Recommended)
Option B: Minimum RBAC
Step 4: Apply ClusterRole
Step 5: Grant Cluster Access to MCP Users
Bind the ClusterRole to the Entra ID group (or OpenShift group) whose members may use the MCP server. Replace <mcp-users-group> with your group name or group ID.
Verify bindings:
Step 6: Register an OAuth / OIDC Client
Register an application with the identity provider your ARO cluster uses.
Option A: Microsoft Entra ID (typical for ARO)
- In Azure Portal → Microsoft Entra ID → App registrations, create a new application.
- Add a Web redirect URI for the MCP OAuth callback (update the hostname after Step 15):
- Create a client secret and note the Application (client) ID and Directory (tenant) ID.
- Grant delegated permissions (
openid,profile,email) and admin consent as needed.
See the upstream Entra ID setup guide for token exchange details if your cluster requires on-behalf-of flow.
Option B: OpenShift OAuth OAuthClient (cluster-local OAuth)
Step 7: Store OAuth Client Secret
Store the client secret in the mcp-server namespace (do not commit secrets to Git).
The Helm chart renders OAuth settings into a ConfigMap. For production, restrict who can read ConfigMaps in mcp-server, use Sealed Secrets or External Secrets, or manage config.toml via a private values file in your pipeline—not in source control.
Step 8: Clone the OpenShift MCP Server Repository
Step 9: Review Default Helm Values
The chart uses a config block (rendered to config.toml), not a legacy mcp.args section.
Step 10: Create ARO Values Overlay
Create values-aro-mcp.yaml with OpenShift settings, OAuth, and a TLS route. Replace placeholders for your tenant, client ID, and cluster domain.
Step 11: Install the Helm Chart
Retrieve the client secret from the Kubernetes secret at install time (recommended):
Step 12: Verify Deployment
Confirm the route uses edge TLS termination and note the hostname. Update the Entra ID or OAuthClient redirect URI if the hostname differs from your placeholder.
Step 13: Verify Unauthenticated Access Is Denied
A request without a bearer token must not succeed when require_oauth is enabled.
Expect HTTP 401 Unauthorized (or another non-2xx auth error), not a successful initialize result.
Step 14: Test With a Bearer Token
Obtain an access token for a user in the mcp-readonly group. For Entra ID / oc users, use the OpenShift access token after login:
A successful response returns HTTP 200 with a JSON-RPC result containing server capabilities.
MCP clients (Cursor, VS Code, MCP Inspector) should use the route URL and complete the OAuth flow; see the upstream Keycloak OIDC setup for inspector-based testing patterns.
Step 15: Configure MCP Clients
Point clients at:
Enable OAuth in the client using the same client ID and scopes configured in Step 6. Each authenticated user receives only the Kubernetes permissions granted by mcp-readonly for their identity.
Summary
| Step | Description |
|---|---|
| 1 | Login to ARO cluster |
| 2 | Create mcp-server project |
| 3 | Create mcp-readonly ClusterRole (choose Option A or B) |
| 4 | Apply ClusterRole |
| 5 | Bind role to MCP users group |
| 6 | Register OAuth/OIDC client (Entra ID or OpenShift) |
| 7 | Store client secret in cluster |
| 8 | Clone openshift-mcp-server repository |
| 9 | Review chart values.yaml |
| 10 | Create values-aro-mcp.yaml with OAuth |
| 11 | Helm install with overlays |
| 12 | Verify pods, logs, and route |
| 13 | Confirm unauthenticated requests are rejected |
| 14 | Test with bearer token over HTTPS |
| 15 | Configure MCP clients with OAuth |
Internal access only (optional)
For development, you may skip a public route:
- Set
ingress.enabled: falsein your values overlay. - Do not run
oc exposeon the service. - Use
oc port-forward svc/kubernetes-mcp-server 8080:8080 -n mcp-serverfrom a workstation that already has a validoclogin.
This limits exposure to your local machine but is not a substitute for OAuth on shared or production clusters.