# Deploy a Hybrid reShapr Proxy

> For AI agents: the complete documentation index is available at https://reshapr.io/llms.txt and the full documentation bundle at https://reshapr.io/llms-full.txt.

> Verified with reShapr `1.0.0` on September 22, 2026.

> Run a reShapr proxy in another trust domain and connect it to an existing control plane.

# Deploy a Hybrid reShapr Proxy

Use this procedure to run a reShapr proxy close to MCP clients or backend APIs while its configuration remains managed by an existing control plane.

The proxy initiates the control-plane connection and registers a logical Gateway. MCP requests and backend API calls use the routes you configure; they are not relayed through the control plane as part of proxy synchronization.

## Prerequisites

You need:

- a reShapr `1.0.0` control plane reachable from the proxy over gRPC;
- the reShapr `1.0.0` CLI, authenticated with `reshapr login`;
- Docker or Podman on the proxy host;
- `curl` and `jq` for verification;
- a Service and Configuration Plan for a non-destructive backend operation;
- local access to port `7777` for this verification, or a separately configured TLS proxy for remote MCP clients.

The examples use Docker. Set `CONTAINER_ENGINE=podman` to use the same commands with Podman.

```bash
export CONTAINER_ENGINE=docker
export RESHAPR_IMAGE=registry.reshapr.io/reshapr/reshapr-proxy:1.0.0
```

## 1. Select a Gateway Group

List the Gateway Groups available to your organization:

```bash
reshapr gateway-group list
```

Record the ID and labels of an existing group, or create a dedicated group:

```bash
reshapr gateway-group create "Hybrid production" \
  --labels '{"environment":"production","location":"customer-network"}'
```

The command returns a generated ID. Store that value for later commands:

```bash
export GATEWAY_GROUP_ID='<gateway-group-id>'
```

The labels advertised for the proxy's Gateway in step 3 must match this group's labels. The CLI accepts a JSON object, while `RESHAPR_GATEWAY_LABELS` uses semicolon-separated `key=value` pairs. Labels select configuration; they do not establish network or security boundaries.

## 2. Create a dedicated Gateway token

Create an API token with the shortest validity that fits your operating procedure:

```bash
reshapr api-token create hybrid-gateway-01 --validity-days 30
```

The CLI displays the token once. Store it in your secret manager. To avoid placing it in shell history for this session, read it into an environment variable:

```bash
read -r -s -p 'Gateway API token: ' RESHAPR_CTRL_TOKEN
export RESHAPR_CTRL_TOKEN
printf '\n'
```

Use a dedicated token per operational boundary so that it can be rotated or revoked without affecting unrelated proxy deployments.

## 3. Start the proxy

Set the control-plane address. This procedure advertises `localhost:7777` and verifies the MCP endpoint from the proxy host over HTTP. Do not include a URL scheme in either hostname value.

```bash
export RESHAPR_CTRL_HOST='<control-plane-host>'
export RESHAPR_CTRL_PORT='443'
export RESHAPR_GATEWAY_FQDNS='localhost:7777'
```

The following command expects TLS on the control-plane connection. For a trusted development network that deliberately uses plaintext gRPC, set `RESHAPR_CTRL_TLS_PLAINTEXT=true` and use its plaintext port instead.

```bash
${CONTAINER_ENGINE} run --detach \
  --name reshapr-hybrid-gateway \
  --restart unless-stopped \
  --publish 7777:7777 \
  --env RESHAPR_CTRL_HOST="${RESHAPR_CTRL_HOST}" \
  --env RESHAPR_CTRL_PORT="${RESHAPR_CTRL_PORT}" \
  --env RESHAPR_CTRL_TLS_PLAINTEXT=false \
  --env RESHAPR_CTRL_TOKEN="${RESHAPR_CTRL_TOKEN}" \
  --env RESHAPR_GATEWAY_ID=hybrid-gateway-01 \
  --env RESHAPR_GATEWAY_FQDNS="${RESHAPR_GATEWAY_FQDNS}" \
  --env 'RESHAPR_GATEWAY_LABELS=environment=production;location=customer-network' \
  "${RESHAPR_IMAGE}"
```

Use a unique `RESHAPR_GATEWAY_ID` for each running proxy. This value identifies the logical Gateway registered by that proxy. If the host cannot reach the control plane, check DNS, egress firewall rules, the configured port, and the TLS mode before changing the registration settings.

## 4. Check readiness

Query the proxy locally:

```bash
curl --fail --silent http://localhost:7777/q/health/ready | jq '.status'
```

The expected status is `"UP"`. If readiness fails, inspect the startup and registration messages:

```bash
${CONTAINER_ENGINE} logs --tail 100 reshapr-hybrid-gateway
```

Readiness confirms that the proxy completed its initial connection and Gateway registration. It does not confirm that a particular Exposition targets this Gateway.

## 5. Target the Gateway Group

Create an Exposition from an existing Configuration Plan and target the group selected in step 1:

```bash
export CONFIGURATION_PLAN_ID='<configuration-plan-id>'

reshapr expo create \
  --configuration "${CONFIGURATION_PLAN_ID}" \
  --gateway-group "${GATEWAY_GROUP_ID}" \
  --name hybrid-endpoint
```

The structured creation response contains endpoint details but not the Exposition ID. Resolve the unique ID by the name just created:

```bash
export EXPOSITION_ID="$(
  reshapr expo list --all --output json \
    | jq -er '.[] | select(.name == "hybrid-endpoint") | .id'
)"
```

Confirm that the Exposition is active and that `ENDPOINTS` contains the hostname advertised by the proxy's registered Gateway:

```bash
reshapr expo list
reshapr expo get "${EXPOSITION_ID}"
```

If the Exposition remains inactive, compare the proxy's `RESHAPR_GATEWAY_LABELS` with the labels shown by `reshapr gateway-group list`, then inspect the proxy logs.

## 6. Verify the MCP endpoint

Build the MCP URL from the Exposition ID. With the direct local configuration in this guide, it uses HTTP:

```bash
export MCP_URL="http://localhost:7777/mcp/${EXPOSITION_ID}"
```

Discover the stateless MCP server:

```bash
curl --silent --show-error \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json, text/event-stream' \
  --header 'MCP-Protocol-Version: 2026-07-28' \
  --header 'Mcp-Method: server/discover' \
  --data '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"reshapr-docs","version":"1.0.0"},"io.modelcontextprotocol/clientCapabilities":{}}}}' \
  "${MCP_URL}" | jq '.result | {supportedVersions, capabilities}'
```

The response must include `2026-07-28` in `supportedVersions`. List the exposed Tools:

```bash
curl --silent --show-error \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json, text/event-stream' \
  --header 'MCP-Protocol-Version: 2026-07-28' \
  --header 'Mcp-Method: tools/list' \
  --data '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"reshapr-docs","version":"1.0.0"},"io.modelcontextprotocol/clientCapabilities":{}}}}' \
  "${MCP_URL}" | jq '.result.tools[] | {name, description}'
```

Choose a read-only Tool whose backend effect you understand, then call it with valid arguments:

```bash
export TOOL_NAME='<read-only-tool-name>'
export TOOL_ARGUMENTS='{}'

jq -n \
  --arg name "${TOOL_NAME}" \
  --argjson arguments "${TOOL_ARGUMENTS}" \
  '{jsonrpc:"2.0",id:3,method:"tools/call",params:{name:$name,arguments:$arguments,_meta:{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{name:"reshapr-docs",version:"1.0.0"},"io.modelcontextprotocol/clientCapabilities":{}}}}' | \
curl --silent --show-error \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json, text/event-stream' \
  --header 'MCP-Protocol-Version: 2026-07-28' \
  --header 'Mcp-Method: tools/call' \
  --header "Mcp-Name: ${TOOL_NAME}" \
  --data @- \
  "${MCP_URL}" | jq '.result'
```

A successful, expected backend response verifies the client-to-proxy and proxy-to-backend paths. It does not prove that other Tools or network routes are correctly configured.

## Roll back

Delete the Exposition created by this procedure before removing its dedicated Gateway Group:

```bash
reshapr expo delete "${EXPOSITION_ID}"
${CONTAINER_ENGINE} rm --force reshapr-hybrid-gateway
```

List API tokens, then delete the dedicated token by its generated ID:

```bash
reshapr api-token list
reshapr api-token delete '<api-token-id>' --force
```

If you created the Gateway Group only for this procedure and no other Exposition uses it, remove it:

```bash
reshapr gateway-group delete "${GATEWAY_GROUP_ID}"
```

Deleting the token prevents later registration with that credential. A proxy that is already running can retain its last synchronized configuration during a control-plane connectivity loss, so stop the container as well when access must end immediately.

## Result

You now have a reShapr `1.0.0` proxy running in another trust domain, registered as a logical Gateway with a dedicated credential, selected through Gateway Group labels, and verified through its MCP endpoint.

## Limits

- The topology does not by itself prove data residency or compliance. Validate DNS, routing, proxies, identity providers, observability exporters, and backend dependencies.
- Proxy-to-control-plane TLS depends on `RESHAPR_CTRL_TLS_PLAINTEXT=false` and a correctly configured control-plane TLS endpoint. MCP client ingress and backend TLS are separate boundaries.
- Remote MCP clients need a TLS ingress, load balancer, or reverse proxy. Configure it first, then advertise its host and optional port through `RESHAPR_GATEWAY_FQDNS` instead of `localhost:7777`.
- Live configuration propagation is not a zero-downtime upgrade or rollback guarantee.
- A production deployment also needs durable secret injection, ingress TLS, resource limits, health supervision, logging, and an image update policy.

## Next step

Read **[Deployment Models and Trust Boundaries](../explanations/deployment-models-trust-boundaries.md)** for the complete traffic map and **[Control Plane to Proxy Synchronization](../explanations/control-plane-gateway-synchronization.md)** for registration and recovery behavior.

For production Kubernetes controls, continue with **[Deploy reShapr on Kubernetes for Production](./deploy-kubernetes-production.md)**.
