Skip to content

Use the remote gateway

Run the harness on your own machine, as an ordinary user. Its files and tools run there; SSH to the gateway is unnecessary. Obtain the HTTPS URL, your caller JWT and accepted model IDs from the administrator. Never use a provider key.

Run from a reviewed checkout on your client machine with Bash, Python 3, Git, Node.js 22+ and npm. Use a user configuration without saved provider logins or conflicting managed settings. Keep the harness's normal tool approval and sandbox controls enabled.

1. Set the connection

Start Bash, then enter the URL and caller token. The token prompt is hidden. Use an origin such as https://gateway.example.com:8443, without /v1.

bash
set +x
set +a
unset PRAXIS_CALLER_JWT
{
  read -r -p 'Praxis HTTPS origin: ' PRAXIS_URL
  read -r -s -p 'Caller JWT: ' PRAXIS_CALLER_JWT; printf '\n'
  read -r -p 'Private CA PEM absolute path (Enter for system trust): ' PRAXIS_CA
}

Copy unchanged in the same shell:

PRAXIS_URL="${PRAXIS_URL%/}"
if [[ "$PRAXIS_URL" =~ ^https://[A-Za-z0-9][A-Za-z0-9.-]*(:[0-9]+)?$ && -n "$PRAXIS_CALLER_JWT" ]]; then
  export PRAXIS_URL PRAXIS_CALLER_JWT
  if [[ -n "$PRAXIS_CA" ]]; then
    export NODE_EXTRA_CA_CERTS="$PRAXIS_CA"
    export CODEX_CA_CERTIFICATE="$PRAXIS_CA"
  fi
  printf 'Connection settings loaded.\n'
else
  unset PRAXIS_URL PRAXIS_CALLER_JWT
  printf 'Invalid connection settings. Repeat the prompts before continuing.\n'
  printf 'Use an HTTPS DNS/IPv4 origin without a path, and a nonempty caller JWT.\n'
fi

For private-CA deployments, these are the documented trust settings for Claude Code, OpenCode. Never set an insecure-TLS flag. The JWT is a secret usable by its bearer until expiry/key rotation. The harness process and its tools can read it; keep it out of projects and logs.

2. Prepare the client

After successful validation, create a private temporary JWT file and select the shared launcher. The file contains only your caller token, never a provider key:

unset HARNESS GATEWAY
if [[ -n "${PRAXIS_URL:-}" && -n "${PRAXIS_CALLER_JWT:-}" ]]; then
  CALLER_JWT="$(mktemp "${TMPDIR:-/tmp}/praxis-caller.XXXXXX")" &&
  printf '%s' "$PRAXIS_CALLER_JWT" > "$CALLER_JWT" && {
    HARNESS=(python3 "$PWD/scripts/common/harness.py")
    GATEWAY=(--url "$PRAXIS_URL" --token-file "$CALLER_JWT")
    if [[ -n "$PRAXIS_CA" ]]; then GATEWAY+=(--ca-file "$PRAXIS_CA"); fi
  }
  unset PRAXIS_CALLER_JWT
else
  unset HARNESS GATEWAY
  printf 'Repeat connection setup before continuing.\n'
fi

Install the pinned CLIs under your own account, without sudo:

python3 - <<'PYCLIENT'
import json, pathlib, subprocess
versions = json.loads(pathlib.Path("configs/common/harness-versions.json").read_text())
subprocess.run(["npm", "install", "--global", "--prefix", str(pathlib.Path.home() / ".local"),
                *[f"{name}@{version}" for name, version in versions.items()]], check=True)
PYCLIENT
export PATH="$HOME/.local/bin:$PATH"
claude --version
opencode --version
mkdir -p ~/projects/praxis-example
cd ~/projects/praxis-example
git init -q

3. Choose an enabled provider

Qwen through vLLM

Enter the model ID supplied by the administrator, qwen3-8b or qwen3.8-27b-int4, then choose one client:

printf 'Installed vLLM model ID: '
IFS= read -r VLLM_MODEL

The launcher adds /vllm and the model's context settings: 16,384 tokens for 8B, or 32,768 for 27B. OpenCode and Claude allow up to 4,096 or 8,192 output tokens respectively, including thinking. Update the server and client together; the larger 27B budgets need fresh qualification. CPU inference can take minutes.

Per-launch settings, configuration files and remote credentials This is the same [launcher and per-harness configuration](../common/harness-configuration.md) used on all-in-one hosts, with your gateway URL, caller JWT and CA added. OpenCode gets `OPENCODE_CONFIG_CONTENT`, and Claude gets environment variables and flags. The helper starts the CLI; Praxis remains the proxy on the server. File-based alternatives are shown in that reference. Replace loopback addresses with your HTTPS gateway and retain `/vllm` for local inference. Keep caller JWTs out of committed files; never put upstream provider keys in a harness config. Model discovery and switching are separate checks from configuring a route.
"${HARNESS[@]}" opencode --provider vllm --model "$VLLM_MODEL" "${GATEWAY[@]}"
"${HARNESS[@]}" claude-code --provider vllm --model "$VLLM_MODEL" "${GATEWAY[@]}"

OpenAI

The administrator enables OpenAI and gives you an approved model ID. Read it, then choose either client:

printf 'Approved OpenAI model ID: '
IFS= read -r OPENAI_MODEL
"${HARNESS[@]}" opencode --provider openai --model "$OPENAI_MODEL" "${GATEWAY[@]}"

Anthropic

The administrator enables Anthropic independently of OpenAI. Read the approved model ID, then choose either client:

printf 'Approved Anthropic model ID: '
IFS= read -r ANTHROPIC_MODEL
"${HARNESS[@]}" claude-code --provider anthropic --model "$ANTHROPIC_MODEL" "${GATEWAY[@]}"
"${HARNESS[@]}" opencode --provider anthropic --model "$ANTHROPIC_MODEL" "${GATEWAY[@]}"

These commands retain normal tool approvals and use native APIs. They do not enable translation between provider APIs. Cloud calls use the administrator's provider account and billing.

Disconnect, renew and stop

The gateway survives your logout. The harness follows your client machine's normal lifecycle: resume a saved session using its own resume command, or use tmux on a remote client host if the process must survive SSH disconnects.

On 401, obtain a replacement JWT and repeat connection setup. On 429, stop repeated retries and ask the administrator to check the shared quota and request throttle. When finished, close the harness and remove only the temporary caller file created above:

rm -- "$CALLER_JWT"
unset CALLER_JWT PRAXIS_CALLER_JWT GATEWAY

Model menus

The launcher selects one approved provider/model per session. OpenCode uses /models; Claude uses /model. These menus do not constitute an automatically aggregated Praxis catalog. Keep the explicit model selection unless the administrator has qualified another entry for this gateway.