Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

reShapr on OpenShift

Deploy the reShapr MCP platform on OpenShift using Helm and native OpenShift Routes.

This document is the manual operator guide. If you want an agent to perform the workflow for you, use SKILL.md.

What This Deploys

  • reshapr-system: PostgreSQL 17, the reShapr control plane, and the web UI
  • reshapr-proxies: the MCP proxy
  • Public OpenShift Routes:
    • reshapr-ctrl
    • reshapr-ui
    • reshapr-mcp
    • camara-mock (optional, only for demo and verification)
  • Optional demo assets:
    • a Prism-based CAMARA mock
    • three imported CAMARA APIs backed by the in-cluster mock

Architecture

flowchart LR
    routeCtrl["Route: reshapr-ctrl"]
    routeUi["Route: reshapr-ui"]
    routeProxy["Route: reshapr-mcp"]
    routeMock["Route: camara-mock (optional)"]

    subgraph openShiftCluster [OpenShift Cluster]
        subgraph reshaprSystem [reshapr-system]
            postgres["PostgreSQL 17"]
            controlPlane["Control Plane :5555"]
            webUi["Web UI :3333"]
            postgres --> controlPlane
            controlPlane --> webUi
        end

        subgraph reshaprProxies [reshapr-proxies]
            mcpProxy["MCP Proxy :7777"]
            camaraMock["CAMARA Mock (Prism, optional)"]
            simSwap["SIM Swap :4010"]
            locationRetrieval["Location Retrieval :4011"]
            locationVerification["Location Verification :4012"]
            camaraMock --> simSwap
            camaraMock --> locationRetrieval
            camaraMock --> locationVerification
        end

        controlPlane -->|"gRPC :5555"| mcpProxy
    end

    routeCtrl --> controlPlane
    routeUi --> webUi
    routeProxy --> mcpProxy
    routeMock --> camaraMock
Loading

Repository Assets

  • deploy-openshift/routes/: Route manifests for the control plane, web UI, and MCP proxy
  • deploy-openshift/mock/deployment-prism.yaml: optional demo/verification ConfigMap, Deployment, and Service for the CAMARA mock
  • deploy-openshift/mock/route-camara-mock.yaml: optional external Route for the CAMARA mock
  • SKILL.md: agent workflow guidance for the same deployment path

All commands below use committed repository content.

Prerequisites

Requirement Notes
OpenShift cluster 4.12+
oc CLI Authenticated to the target cluster
Helm 3.8+
curl Required for login, health checks, and API import
Permissions Ability to create namespaces, Routes, Deployments, Services, ConfigMaps, PVCs, and Helm releases
Network egress Access to quay.io; access to registry.access.redhat.com, docker.io, and raw.githubusercontent.com is only needed for the optional CAMARA mock

Verify access:

oc whoami
helm version --short

Configuration and Credentials

Export these variables before running the manual workflow:

export CLUSTER_DOMAIN=<cluster-domain>        # e.g. ocp.example.com

export NS_SYSTEM=reshapr-system
export NS_PROXIES=reshapr-proxies
export CHART_VERSION=0.0.6
export IMAGE_TAG=0.1.0

export PG_PASSWORD=<postgres-password>
export API_KEY=<control-plane-api-key>
export ENCRYPTION_KEY=<32-char-encryption-key>
export ADMIN_NAME=admin
export ADMIN_PASSWORD=<admin-password>
export ADMIN_EMAIL=reshapr@example.com
export GATEWAY_TOKEN=<gateway-token>

export MCP_API_KEY=<mcp-client-api-key>      # Optional; used only if your MCP clients require it

export PROXY_FQDN=reshapr-mcp-${NS_PROXIES}.apps.${CLUSTER_DOMAIN}

Notes:

  • ENCRYPTION_KEY must be exactly 16, 24, or 32 characters.
  • API_KEY secures the reShapr control-plane API.
  • GATEWAY_TOKEN is stored by the Helm release with the reshapr- prefix.
  • MCP_API_KEY is not needed for deployment itself; it is only used later if your MCP clients authenticate with x-reshapr-key.
  • The committed manifests under deploy-openshift/routes/ and deploy-openshift/mock/ target the default namespaces reshapr-system and reshapr-proxies. If you change NS_SYSTEM or NS_PROXIES, update the manifest namespaces before applying them.

Manual Deployment

1. Install the control plane

helm install reshapr-control-plane \
  oci://quay.io/reshapr/reshapr-helm-charts/reshapr-control-plane \
  --version "${CHART_VERSION}" \
  --create-namespace --namespace "${NS_SYSTEM}" \
  --set ctrl.image.tag="${IMAGE_TAG}" \
  --set ctrl.podSecurityContext.runAsUser=null \
  --set ctrl.podSecurityContext.runAsGroup=null \
  --set ctrl.podSecurityContext.fsGroup=null \
  --set postgresql.enabled=true \
  --set postgresql.auth.password="${PG_PASSWORD}" \
  --set postgresql.primary.podSecurityContext.enabled=false \
  --set postgresql.primary.containerSecurityContext.enabled=false \
  --set apiKey.value="${API_KEY}" \
  --set encryptionKey.value="${ENCRYPTION_KEY}" \
  --set admin.nameValue="${ADMIN_NAME}" \
  --set admin.passwordValue="${ADMIN_PASSWORD}" \
  --set admin.emailValue="${ADMIN_EMAIL}" \
  --set admin.defaultGatewayTokensValue="reshapr-${GATEWAY_TOKEN}" \
  --set ingress.enabled=false \
  --set reshapr-web-ui.enabled=true \
  --set reshapr-web-ui.image.tag="${IMAGE_TAG}" \
  --set reshapr-web-ui.podSecurityContext.runAsUser=null \
  --set reshapr-web-ui.podSecurityContext.runAsGroup=null \
  --set reshapr-web-ui.podSecurityContext.fsGroup=null \
  --set reshapr-web-ui.ingress.enabled=false

Wait for the control plane:

oc rollout status deployment/reshapr-control-plane-ctrl -n "${NS_SYSTEM}" --timeout=180s
oc wait --for=condition=ready pod -l app.kubernetes.io/name=reshapr-control-plane -n "${NS_SYSTEM}" --timeout=180s

2. Install the MCP proxy

helm install reshapr-proxy \
  oci://quay.io/reshapr/reshapr-helm-charts/reshapr-proxy \
  --version "${CHART_VERSION}" \
  --create-namespace --namespace "${NS_PROXIES}" \
  --set image.tag="${IMAGE_TAG}" \
  --set podSecurityContext.runAsUser=null \
  --set podSecurityContext.runAsGroup=null \
  --set podSecurityContext.fsGroup=null \
  --set gateway.idPrefix="openshift-demo" \
  --set gateway.labels="env=demo;platform=openshift;team=reshapr" \
  --set gateway.fqdns="${PROXY_FQDN}" \
  --set gateway.controlPlane.host="reshapr-control-plane-ctrl.${NS_SYSTEM}.svc.cluster.local" \
  --set gateway.controlPlane.port=5555 \
  --set gateway.controlPlane.token="reshapr-${GATEWAY_TOKEN}" \
  --set ingress.enabled=false

Wait for the proxy:

oc rollout status deployment/reshapr-proxy -n "${NS_PROXIES}" --timeout=120s

3. Apply the tracked Route manifests

oc apply -f deploy-openshift/routes/

This creates the following Routes from the committed manifests:

  • reshapr-ctrl
  • reshapr-ui
  • reshapr-mcp

4. Optional: Deploy the CAMARA mock for demo and verification

You only need this section if you want to:

  • verify the platform with mocked CAMARA upstreams
  • import demo CAMARA APIs into reShapr
  • configure an MCP client against those demo APIs
oc apply -f deploy-openshift/mock/

The committed mock deployment does the following:

  • creates a ConfigMap placeholder for the CAMARA specs
  • downloads the current CAMARA OpenAPI definitions at pod startup
  • runs three Prism mock containers on ports 4010, 4011, and 4012
  • exposes an in-cluster camara-mock Service
  • creates an external camara-mock Route

Wait for the mock deployment:

oc rollout status deployment/camara-mock -n "${NS_PROXIES}" --timeout=120s

Verification

This section verifies the core reShapr install: control plane, web UI, MCP proxy, and the required Routes.

Check the pods:

oc get pods -n "${NS_SYSTEM}" -o wide
oc get pods -n "${NS_PROXIES}" -o wide

List the Routes:

oc get routes -n "${NS_SYSTEM}"
oc get routes -n "${NS_PROXIES}"

Test the main health endpoints:

CTRL_HOST=$(oc get route reshapr-ctrl -n "${NS_SYSTEM}" -o jsonpath='{.spec.host}')
UI_HOST=$(oc get route reshapr-ui -n "${NS_SYSTEM}" -o jsonpath='{.spec.host}')
PROXY_HOST=$(oc get route reshapr-mcp -n "${NS_PROXIES}" -o jsonpath='{.spec.host}')

curl -sk "https://${CTRL_HOST}/q/health/ready"
curl -sk -o /dev/null -w "%{http_code}\n" "https://${UI_HOST}/"
curl -sk "https://${PROXY_HOST}/q/health/ready"

Expected results:

  • control plane returns a ready response
  • web UI returns 200
  • MCP proxy returns a ready response
  • all pods are Running or Completed

You can stop here if you only need the base reShapr platform.

If you deployed the optional CAMARA mock, also confirm deployment/camara-mock is ready and that the camara-mock Route exists. The demo API imports still use the in-cluster camara-mock.${NS_PROXIES}.svc.cluster.local service addresses.

Optional Demo Flow: Import the CAMARA APIs

This section is only required if you deployed the optional CAMARA mock and want demo APIs wired to mocked upstreams.

Log in to the control plane:

CTRL_HOST=$(oc get route reshapr-ctrl -n "${NS_SYSTEM}" -o jsonpath='{.spec.host}')
CTRL_URL="https://${CTRL_HOST}"

TOKEN=$(curl -sk -X POST "${CTRL_URL}/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d "{\"username\":\"${ADMIN_NAME}\",\"password\":\"${ADMIN_PASSWORD}\"}" \
  | grep -o '"token":"[^"]*"' | head -1 | cut -d'"' -f4)

if [[ -z "${TOKEN}" ]]; then
  echo "Failed to obtain an auth token. Check the control-plane Route and admin credentials."
  exit 1
fi

Import the three CAMARA specs and point them at the in-cluster mock service:

curl -sk -X POST "${CTRL_URL}/api/v1/api-specs/import" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -d "{
    \"name\": \"CAMARA SIM Swap\",
    \"type\": \"OPENAPI\",
    \"url\": \"https://raw.githubusercontent.com/camaraproject/SimSwap/r3.3/code/API_definitions/sim-swap.yaml\",
    \"upstream\": \"http://camara-mock.${NS_PROXIES}.svc.cluster.local:4010\"
  }"

curl -sk -X POST "${CTRL_URL}/api/v1/api-specs/import" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -d "{
    \"name\": \"CAMARA Device Location Retrieval\",
    \"type\": \"OPENAPI\",
    \"url\": \"https://raw.githubusercontent.com/camaraproject/DeviceLocation/r3.2/code/API_definitions/location-retrieval.yaml\",
    \"upstream\": \"http://camara-mock.${NS_PROXIES}.svc.cluster.local:4011\"
  }"

curl -sk -X POST "${CTRL_URL}/api/v1/api-specs/import" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -d "{
    \"name\": \"CAMARA Device Location Verification\",
    \"type\": \"OPENAPI\",
    \"url\": \"https://raw.githubusercontent.com/camaraproject/DeviceLocation/r3.2/code/API_definitions/location-verification.yaml\",
    \"upstream\": \"http://camara-mock.${NS_PROXIES}.svc.cluster.local:4012\"
  }"

After the import, confirm the new APIs and generated MCP server names in the reShapr UI.

Optional Demo Flow: Configure MCP Clients

These examples assume you completed the optional CAMARA import flow above.

Get the MCP proxy hostname:

PROXY_HOST=$(oc get route reshapr-mcp -n "${NS_PROXIES}" -o jsonpath='{.spec.host}')

Every reShapr MCP server URL follows this pattern:

https://<proxy-host>/mcp/reshapr/<server-name>

The <server-name> values are generated by reShapr from the imported APIs and plans. Use the names shown in the reShapr UI rather than hard-coding guesses.

Example JSON

{
  "mcpServers": {
    "camara-sim-swap": {
      "url": "https://<proxy-host>/mcp/reshapr/<sim-swap-server-name>"
    },
    "camara-location-retrieval": {
      "url": "https://<proxy-host>/mcp/reshapr/<location-retrieval-server-name>"
    },
    "camara-location-verification": {
      "url": "https://<proxy-host>/mcp/reshapr/<location-verification-server-name>"
    }
  }
}

If your deployment requires MCP client auth, add this header to each server entry:

{
  "headers": {
    "x-reshapr-key": "<mcp-api-key>"
  }
}

Paste the JSON above into your MCP client's configuration, then replace:

  • <proxy-host> with the hostname from the reshapr-mcp Route
  • each <...-server-name> placeholder with the actual name generated by reShapr
  • <mcp-api-key> only if your deployment requires x-reshapr-key

Optional Demo Prompts

Try these prompts with your AI client after the MCP servers are configured:

  • "Check if phone number +99012345678 had a recent SIM swap"
  • "Where is the device with number +99012345678 located?"
  • "Verify if +99012345678 is within 2km of Lyon, France"

Cleanup

Remove the tracked mock and Route resources:

oc delete -f deploy-openshift/mock/ --ignore-not-found=true
oc delete -f deploy-openshift/routes/ --ignore-not-found=true

If you skipped the optional CAMARA mock, deleting deploy-openshift/mock/ is a harmless no-op.

Uninstall the Helm releases:

helm uninstall reshapr-proxy -n "${NS_PROXIES}" --wait
helm uninstall reshapr-control-plane -n "${NS_SYSTEM}" --wait

Delete the PostgreSQL PVC and the namespaces:

oc delete pvc data-reshapr-control-plane-postgresql-0 -n "${NS_SYSTEM}" --ignore-not-found
oc delete namespace "${NS_PROXIES}" --ignore-not-found
oc delete namespace "${NS_SYSTEM}" --ignore-not-found

Troubleshooting

  • Pods do not become ready: Check oc get pods -n "${NS_SYSTEM}" and oc get pods -n "${NS_PROXIES}", then inspect events and logs with oc describe pod ... and oc logs ....

  • The CAMARA mock init container fails: Only relevant if you deployed the optional mock. It downloads specs from raw.githubusercontent.com at startup and also depends on pulling registry.access.redhat.com/ubi9/ubi:latest and stoplight/prism:latest. Verify cluster egress and image pull access.

  • The Route manifests deploy into the wrong namespaces: The committed manifests use reshapr-system and reshapr-proxies. If you choose different namespaces, update the manifest metadata.namespace values before applying them.

  • Login does not return a token: Verify the reshapr-ctrl Route, confirm the control plane is healthy, and re-check ADMIN_NAME and ADMIN_PASSWORD.

  • An MCP client gets 404: Confirm the client is using the server name generated by reShapr after import, not a guessed slug.

  • An MCP client gets 401 or 403: If client auth is enabled, add the x-reshapr-key header with your MCP API key.

Configuration Reference

Variable Description Constraint
CLUSTER_DOMAIN OpenShift cluster base domain Used to compute Route hostnames
NS_SYSTEM Namespace for control plane and database Default manifests assume reshapr-system
NS_PROXIES Namespace for MCP proxy and optional mock server Default manifests assume reshapr-proxies
CHART_VERSION Helm chart version Default: 0.0.6
IMAGE_TAG Application image tag Default: 0.1.0
PG_PASSWORD PostgreSQL password Required
API_KEY reShapr control-plane API key Required
ENCRYPTION_KEY Encryption key for stored secrets Must be exactly 16, 24, or 32 characters
ADMIN_NAME Admin username Default: admin
ADMIN_PASSWORD Admin password Required
ADMIN_EMAIL Admin email Default: reshapr@example.com
GATEWAY_TOKEN Proxy-to-control-plane auth token Stored with a reshapr- prefix
MCP_API_KEY Client key used by MCP consumers Optional; only if your deployment requires MCP client auth
PROXY_FQDN External FQDN for the MCP proxy Route Usually reshapr-mcp-${NS_PROXIES}.apps.${CLUSTER_DOMAIN}

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors