feat: add ocp-connect lightweight client + restructure README

- Add standalone `ocp-connect` script for zero-dependency client setup
  (only needs curl + python3, no Node/repo clone required)
- Add `ocp connect` command to main CLI
- Add `authMode` field to /health endpoint
- Restructure README with clear Server Setup / Client Setup sections
- Add dashboard screenshot to README
- Fix smoke test model name (claude-haiku-4-5-20251001)
- Fix auth mode detection for shared/multi/none
- Fix rc file cleanup idempotency (blank line handling)
- Fix key input echo (now hidden with read -rs)
- Add host validation
- Bump version to 3.5.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-11 09:48:33 +10:00
co-authored by Claude Opus 4.6
parent ed53c5e0c5
commit 087e26346f
6 changed files with 526 additions and 68 deletions
+98 -67
View File
@@ -1,6 +1,6 @@
# OCP — Open Claude Proxy # OCP — Open Claude Proxy
> **Status: Stable (v3.4.0)** — Feature-complete. Bug fixes only. > **Status: Stable (v3.5.0)** — Feature-complete. Bug fixes only.
> **Already paying for Claude Pro/Max? Use your subscription as an OpenAI-compatible API — $0 extra cost.** > **Already paying for Claude Pro/Max? Use your subscription as an OpenAI-compatible API — $0 extra cost.**
@@ -29,9 +29,34 @@ Any tool that accepts `OPENAI_BASE_URL` works with OCP:
| **OpenClaw** | `setup.mjs` auto-configures | | **OpenClaw** | `setup.mjs` auto-configures |
| **Any OpenAI client** | Set base URL to `http://127.0.0.1:3456/v1` | | **Any OpenAI client** | Set base URL to `http://127.0.0.1:3456/v1` |
## Quick Start ## Installation
OCP has two roles: **Server** (runs the proxy, needs Claude CLI) and **Client** (connects to a server, zero dependencies).
```
┌─ Server (always-on device) ─────────────────────────────┐
│ Mac mini / NAS / Raspberry Pi / Desktop │
│ Claude CLI + OCP server → bound to 0.0.0.0:3456 │
└───────────────────────┬─────────────────────────────────┘
│ LAN
┌───────────────────┼───────────────────┐
▼ ▼ ▼
Laptop Phone/Tablet Pi / Server
(client) (browser) (client)
```
---
### Server Setup
> **Recommended:** Install OCP on a device that stays powered on — Mac mini, NAS, Raspberry Pi, or a desktop that doesn't sleep. This ensures all clients always have access.
**Prerequisites:**
- Node.js 18+
- [Claude CLI](https://docs.anthropic.com/en/docs/claude-cli) installed and authenticated (`claude auth login`)
```bash ```bash
# 1. Clone and run setup
git clone https://github.com/dtzp555-max/ocp.git git clone https://github.com/dtzp555-max/ocp.git
cd ocp cd ocp
node setup.mjs node setup.mjs
@@ -41,59 +66,23 @@ The setup script will:
1. Verify Claude CLI is installed and authenticated 1. Verify Claude CLI is installed and authenticated
2. Start the proxy on port 3456 2. Start the proxy on port 3456
3. Install auto-start (launchd on macOS, systemd on Linux) 3. Install auto-start (launchd on macOS, systemd on Linux)
4. Symlink `ocp` to `/usr/local/bin` for CLI access
Then point your IDE to the proxy: **Single-machine use** — just set your IDE to use the proxy:
```bash ```bash
export OPENAI_BASE_URL=http://127.0.0.1:3456/v1 export OPENAI_BASE_URL=http://127.0.0.1:3456/v1
``` ```
### Verify **LAN mode** — share with other devices on your network:
```bash
curl http://127.0.0.1:3456/v1/models
# Returns: claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4
```
## LAN Mode — Share with Family
OCP can serve your entire household from a single machine. One Claude Pro/Max subscription, shared across all devices on your network.
```
Wife's laptop ──┐
Son's iPad ───┼──→ OCP :3456 (your Mac) ──→ Claude subscription
Your Pi server ───┤
Your desktop ──┘
```
### Step 1: Enable LAN Access
**Quick start (temporary, until restart):**
```bash
export CLAUDE_BIND=0.0.0.0
export CLAUDE_AUTH_MODE=multi # per-user keys
export OCP_ADMIN_KEY=your-secret-admin-key
ocp restart
```
**Permanent (survives reboot):**
```bash ```bash
# Enable LAN access with per-user auth (recommended)
node setup.mjs --bind 0.0.0.0 --auth-mode multi node setup.mjs --bind 0.0.0.0 --auth-mode multi
``` ```
Then set your admin key in the launchd/systemd environment, or save it to a file: Then create API keys for each person/device:
```bash ```bash
echo "your-secret-admin-key" > ~/.ocp/admin-key
chmod 600 ~/.ocp/admin-key
```
### Step 2: Create Keys for Family Members
```bash
# Set admin key for CLI (or save to ~/.ocp/admin-key)
export OCP_ADMIN_KEY=your-secret-admin-key export OCP_ADMIN_KEY=your-secret-admin-key
# Create a key for each person/device
ocp keys add wife-laptop ocp keys add wife-laptop
# ✓ Key created for "wife-laptop" # ✓ Key created for "wife-laptop"
# API Key: ocp_xDYzOB9ZKYzn... # API Key: ocp_xDYzOB9ZKYzn...
@@ -103,33 +92,72 @@ ocp keys add son-ipad
ocp keys add pi-server ocp keys add pi-server
``` ```
### Step 3: Share Connection Info Run `ocp lan` to see your IP and ready-to-share instructions.
Run `ocp lan` to see your IP and ready-to-share instructions: **Verify:**
```
$ ocp lan
OCP LAN Setup
─────────────────────────────────────
Your IP: 192.168.1.100
Port: 3456
For IDE users, set:
OPENAI_BASE_URL=http://192.168.1.100:3456/v1
OPENAI_API_KEY=<their-key>
Dashboard: http://192.168.1.100:3456/dashboard
Status: ✓ LAN-accessible
```
Give each family member their key and these two settings:
```bash ```bash
export OPENAI_BASE_URL=http://192.168.1.100:3456/v1 curl http://127.0.0.1:3456/v1/models
export OPENAI_API_KEY=ocp_<their-key> # Returns: claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4
``` ```
### Step 4: Monitor Usage ---
### Client Setup
> Clients do **not** need to install Node.js, Claude CLI, or the OCP repo. Only `curl` and `python3` are required (pre-installed on most Linux/Mac systems).
**One-command setup** — download the lightweight `ocp-connect` script:
```bash
curl -fsSL https://raw.githubusercontent.com/dtzp555-max/ocp/main/ocp-connect -o ocp-connect
chmod +x ocp-connect
./ocp-connect <server-ip> --key <your-api-key>
```
Or as a one-liner (no file saved):
```bash
curl -fsSL https://raw.githubusercontent.com/dtzp555-max/ocp/main/ocp-connect | bash -s -- <server-ip> --key <your-api-key>
```
Example:
```
$ ./ocp-connect 192.168.1.100 --key ocp_xDYzOB9ZKYzn
OCP Connect
─────────────────────────────────────
Remote: http://192.168.1.100:3456
Checking connectivity...
✓ Connected
Remote OCP v3.5.0 (auth: multi)
Testing API access...
✓ API accessible (3 models available)
Written to /home/user/.bashrc:
OPENAI_BASE_URL=http://192.168.1.100:3456/v1
OPENAI_API_KEY=ocp_xDYz...
Running smoke test...
✓ Smoke test passed: OK
Done. Reload your shell to apply:
source /home/user/.bashrc
```
After running, reload your shell (`source ~/.bashrc` or `source ~/.zshrc`) and your IDE will automatically use the remote OCP.
**Manual setup** — if you prefer not to use the script:
```bash
export OPENAI_BASE_URL=http://<server-ip>:3456/v1
export OPENAI_API_KEY=ocp_<your-key>
```
Add these lines to `~/.bashrc` or `~/.zshrc` to persist across sessions.
---
### Monitoring (Server-side)
```bash ```bash
# Per-key usage stats # Per-key usage stats
@@ -143,7 +171,9 @@ ocp keys # List all keys
ocp keys revoke son-ipad # Revoke a key ocp keys revoke son-ipad # Revoke a key
``` ```
**Web Dashboard:** Open `http://<your-ip>:3456/dashboard` in any browser for real-time monitoring — per-key usage, request history, plan utilization, and system health. No login needed. **Web Dashboard:** Open `http://<server-ip>:3456/dashboard` in any browser for real-time monitoring — per-key usage, request history, plan utilization, and system health.
![OCP Dashboard](docs/images/dashboard.png)
### Auth Modes ### Auth Modes
@@ -197,6 +227,7 @@ ocp health Proxy diagnostics
ocp keys List all API keys (multi mode) ocp keys List all API keys (multi mode)
ocp keys add <name> Create a new API key ocp keys add <name> Create a new API key
ocp keys revoke <name> Revoke an API key ocp keys revoke <name> Revoke an API key
ocp connect <ip> One-command LAN client setup
ocp lan Show LAN connection info & IP ocp lan Show LAN connection info & IP
ocp settings View tunable settings ocp settings View tunable settings
ocp settings <k> <v> Update a setting at runtime ocp settings <k> <v> Update a setting at runtime
Binary file not shown.

After

Width:  |  Height:  |  Size: 857 KiB

+199
View File
@@ -329,6 +329,203 @@ else:
esac esac
} }
# ── connect ─────────────────────────────────────────────────────────────
cmd_connect_help() {
cat <<'EOF'
ocp connect — Connect this machine to a remote OCP as a LAN client
Configures OPENAI_BASE_URL (and optionally OPENAI_API_KEY) in your shell
rc file so tools like Claude Code point to a remote OCP instance.
Usage:
ocp connect <host-ip> [--port PORT] [--key API_KEY]
Arguments:
host-ip IP address of the machine running OCP
--port PORT Port OCP listens on (default: 3456)
--key API_KEY API key to use (prompted if remote requires auth)
Examples:
ocp connect 192.168.1.10
ocp connect 192.168.1.10 --port 8080
ocp connect 192.168.1.10 --key sk-abc123
EOF
}
cmd_connect() {
local host="" port=3456 key=""
# Parse args
while [[ $# -gt 0 ]]; do
case "$1" in
--port) port="${2:?'--port requires a value'}"; shift 2 ;;
--key) key="${2:?'--key requires a value'}"; shift 2 ;;
--help|-h) cmd_connect_help; return 0 ;;
-*) echo "Unknown option: $1"; cmd_connect_help; return 1 ;;
*) host="$1"; shift ;;
esac
done
if [[ -z "$host" ]]; then
echo "Error: host IP is required."
echo ""
cmd_connect_help
return 1
fi
if ! [[ "$host" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "Error: invalid host '$host'"
return 1
fi
local base_url="http://$host:$port"
echo "OCP Connect"
echo "─────────────────────────────────────"
echo " Remote: $base_url"
echo ""
# Step 1: Test connectivity via /health
echo " Checking connectivity..."
local health_json
health_json=$(curl -sf --max-time 10 "$base_url/health" 2>/dev/null) || {
echo " ✗ Cannot reach $base_url/health"
echo " Make sure OCP is running on $host and bound to 0.0.0.0 (LAN mode)."
return 1
}
echo " ✓ Connected"
echo ""
# Step 2: Show remote info
local remote_version auth_mode
remote_version=$(echo "$health_json" | python3 -c "import sys,json; d=json.loads(sys.stdin.read()); print(d.get('version','?'))" 2>/dev/null || echo "?")
auth_mode=$(echo "$health_json" | python3 -c "import sys,json; d=json.loads(sys.stdin.read()); print(d.get('authMode','none'))" 2>/dev/null || echo "none")
echo " Remote OCP v$remote_version (auth: $auth_mode)"
echo ""
# Step 3: Determine if key is needed
local needs_key=0
if [[ "$auth_mode" != "none" ]]; then
needs_key=1
fi
if [[ $needs_key -eq 1 && -z "$key" ]]; then
echo " Remote requires authentication."
echo " Ask the admin to run: ocp keys add <name>"
printf " Enter API key (or press Enter to skip): "
read -rs key </dev/tty
echo
if [[ -z "$key" ]]; then
echo ""
echo " ✗ No key provided — cannot connect to an auth-required remote without a key."
return 1
fi
fi
# Step 4: Test API access via /v1/models
echo " Testing API access..."
local models_out models_ok=0
if [[ -n "$key" ]]; then
models_out=$(curl -sf --max-time 10 \
-H "Authorization: Bearer $key" \
"$base_url/v1/models" 2>/dev/null) && models_ok=1
else
models_out=$(curl -sf --max-time 10 "$base_url/v1/models" 2>/dev/null) && models_ok=1
fi
if [[ $models_ok -eq 0 ]]; then
echo " ✗ API access failed — key may be invalid or revoked."
return 1
fi
local model_count
model_count=$(echo "$models_out" | python3 -c "import sys,json; print(len(json.loads(sys.stdin.read()).get('data',[])))" 2>/dev/null || echo "?")
echo " ✓ API accessible ($model_count models available)"
echo ""
# Step 5: Detect shell rc file
local rc_file
if [[ "${SHELL:-}" == */zsh ]]; then
rc_file="$HOME/.zshrc"
else
rc_file="$HOME/.bashrc"
fi
# Step 6: Remove any previously written OCP LAN lines
if [[ -f "$rc_file" ]]; then
local tmp_rc
tmp_rc=$(mktemp)
if python3 - "$rc_file" "$tmp_rc" <<'PYEOF'
import sys
src, dst = sys.argv[1], sys.argv[2]
lines = open(src).readlines()
out = []
skip = False
for line in lines:
s = line.rstrip('\n')
if s == '# OCP LAN (added by ocp connect)':
skip = True
continue
if skip and (s == '' or s.startswith('export OPENAI_BASE_URL=') or s.startswith('export OPENAI_API_KEY=')):
continue
skip = False
out.append(line)
open(dst, 'w').writelines(out)
PYEOF
then
cp "$tmp_rc" "$rc_file"
fi
rm -f "$tmp_rc"
fi
# Step 7: Append new config
{
echo ""
echo "# OCP LAN (added by ocp connect)"
echo "export OPENAI_BASE_URL=$base_url/v1"
if [[ -n "$key" ]]; then
echo "export OPENAI_API_KEY=$key"
fi
} >> "$rc_file"
echo " Written to $rc_file:"
echo " OPENAI_BASE_URL=$base_url/v1"
if [[ -n "$key" ]]; then
echo " OPENAI_API_KEY=${key:0:8}..."
fi
echo ""
# Step 8: Quick smoke test — send a minimal chat completion
echo " Running smoke test..."
local chat_payload='{"model":"claude-haiku-4-5-20251001","messages":[{"role":"user","content":"Reply with OK only."}],"max_tokens":10}'
local chat_out chat_ok=0
if [[ -n "$key" ]]; then
chat_out=$(curl -sf --max-time 30 \
-H "Authorization: Bearer $key" \
-H "Content-Type: application/json" \
-d "$chat_payload" \
"$base_url/v1/chat/completions" 2>/dev/null) && chat_ok=1
else
chat_out=$(curl -sf --max-time 30 \
-H "Content-Type: application/json" \
-d "$chat_payload" \
"$base_url/v1/chat/completions" 2>/dev/null) && chat_ok=1
fi
if [[ $chat_ok -eq 1 ]]; then
local reply
reply=$(echo "$chat_out" | python3 -c "import sys,json; d=json.loads(sys.stdin.read()); print(d['choices'][0]['message']['content'].strip())" 2>/dev/null || echo "(response received)")
echo " ✓ Smoke test passed: $reply"
else
echo " ⚠ Smoke test failed (proxy is reachable but chat completion did not succeed)."
echo " The env vars have still been written. Check the remote OCP logs."
fi
echo ""
echo " Done. Reload your shell to apply:"
echo " source $rc_file"
}
# ── lan ───────────────────────────────────────────────────────────────── # ── lan ─────────────────────────────────────────────────────────────────
cmd_lan_help() { cmd_lan_help() {
cat <<'EOF' cat <<'EOF'
@@ -609,6 +806,7 @@ Commands:
clear Clear all sessions clear Clear all sessions
keys Manage API keys (add/list/revoke) keys Manage API keys (add/list/revoke)
lan LAN mode setup guide lan LAN mode setup guide
connect <ip> Connect to a remote OCP (sets env vars in rc file)
restart Restart proxy restart Restart proxy
restart gateway Restart gateway restart gateway Restart gateway
update Update OCP to latest version update Update OCP to latest version
@@ -653,6 +851,7 @@ case "$subcmd" in
clear) cmd_clear ;; clear) cmd_clear ;;
keys) cmd_keys "${1:-}" "${2:-}" ;; keys) cmd_keys "${1:-}" "${2:-}" ;;
lan) cmd_lan ;; lan) cmd_lan ;;
connect) cmd_connect "$@" ;;
restart) cmd_restart "${1:-}" ;; restart) cmd_restart "${1:-}" ;;
update) cmd_update "${1:-}" ;; update) cmd_update "${1:-}" ;;
*) echo "Unknown command: $subcmd"; echo ""; cmd_help; exit 1 ;; *) echo "Unknown command: $subcmd"; echo ""; cmd_help; exit 1 ;;
Executable
+227
View File
@@ -0,0 +1,227 @@
#!/usr/bin/env bash
# ocp-connect — Lightweight client script to connect to a remote OCP instance
# No dependencies beyond curl and python3 (available on most Linux/Mac systems)
#
# Install:
# curl -fsSL https://raw.githubusercontent.com/dtzp555-max/ocp/main/ocp-connect -o ocp-connect
# chmod +x ocp-connect
#
# Or run directly:
# curl -fsSL https://raw.githubusercontent.com/dtzp555-max/ocp/main/ocp-connect | bash -s -- <host-ip> --key <key>
#
set -euo pipefail
show_help() {
cat <<'EOF'
ocp-connect — Connect this machine to a remote OCP (Open Claude Proxy)
Configures OPENAI_BASE_URL and OPENAI_API_KEY in your shell rc file
so tools like Claude Code, Cline, Aider, etc. point to the remote OCP.
Usage:
ocp-connect <host-ip> [options]
Options:
--port PORT Port OCP listens on (default: 3456)
--key API_KEY API key (prompted interactively if remote requires auth)
--help, -h Show this help
Examples:
ocp-connect 192.168.1.10
ocp-connect 192.168.1.10 --port 8080
ocp-connect 192.168.1.10 --key ocp_abc123
What it does:
1. Tests connectivity to the remote OCP
2. Verifies your API key (if auth is enabled)
3. Writes OPENAI_BASE_URL and OPENAI_API_KEY to ~/.bashrc or ~/.zshrc
4. Runs a smoke test to confirm everything works
After running, reload your shell: source ~/.bashrc (or ~/.zshrc)
EOF
}
main() {
local host="" port=3456 key=""
# Parse args
while [[ $# -gt 0 ]]; do
case "$1" in
--port) port="${2:?'--port requires a value'}"; shift 2 ;;
--key) key="${2:?'--key requires a value'}"; shift 2 ;;
--help|-h) show_help; exit 0 ;;
-*) echo "Unknown option: $1"; show_help; exit 1 ;;
*) host="$1"; shift ;;
esac
done
if [[ -z "$host" ]]; then
echo "Error: host IP is required."
echo ""
show_help
exit 1
fi
if ! [[ "$host" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "Error: invalid host '$host'"
exit 1
fi
# Check dependencies
for cmd in curl python3; do
if ! command -v "$cmd" &>/dev/null; then
echo "Error: '$cmd' is required but not found."
exit 1
fi
done
local base_url="http://$host:$port"
echo "OCP Connect"
echo "─────────────────────────────────────"
echo " Remote: $base_url"
echo ""
# Step 1: Test connectivity via /health
echo " Checking connectivity..."
local health_json
health_json=$(curl -sf --max-time 10 "$base_url/health" 2>/dev/null) || {
echo " ✗ Cannot reach $base_url/health"
echo " Make sure OCP is running on $host and bound to 0.0.0.0 (LAN mode)."
exit 1
}
echo " ✓ Connected"
echo ""
# Step 2: Show remote info
local remote_version auth_mode
remote_version=$(echo "$health_json" | python3 -c "import sys,json; d=json.loads(sys.stdin.read()); print(d.get('version','?'))" 2>/dev/null || echo "?")
auth_mode=$(echo "$health_json" | python3 -c "import sys,json; d=json.loads(sys.stdin.read()); print(d.get('authMode','none'))" 2>/dev/null || echo "none")
echo " Remote OCP v$remote_version (auth: $auth_mode)"
echo ""
# Step 3: Determine if key is needed
if [[ "$auth_mode" != "none" && -z "$key" ]]; then
echo " Remote requires authentication."
echo " Ask the OCP admin to run: ocp keys add <name>"
printf " Enter API key (or press Enter to skip): "
read -rs key </dev/tty
echo
if [[ -z "$key" ]]; then
echo ""
echo " ✗ No key provided — cannot connect to an auth-required remote without a key."
exit 1
fi
fi
# Step 4: Test API access via /v1/models
echo " Testing API access..."
local models_out models_ok=0
if [[ -n "$key" ]]; then
models_out=$(curl -sf --max-time 10 \
-H "Authorization: Bearer $key" \
"$base_url/v1/models" 2>/dev/null) && models_ok=1
else
models_out=$(curl -sf --max-time 10 "$base_url/v1/models" 2>/dev/null) && models_ok=1
fi
if [[ $models_ok -eq 0 ]]; then
echo " ✗ API access failed — key may be invalid or revoked."
exit 1
fi
local model_count
model_count=$(echo "$models_out" | python3 -c "import sys,json; print(len(json.loads(sys.stdin.read()).get('data',[])))" 2>/dev/null || echo "?")
echo " ✓ API accessible ($model_count models available)"
echo ""
# Step 5: Detect shell rc file
local rc_file
if [[ "${SHELL:-}" == */zsh ]]; then
rc_file="$HOME/.zshrc"
elif [[ "${SHELL:-}" == */fish ]]; then
echo " Note: fish shell detected. Writing to ~/.bashrc — add to fish config manually."
rc_file="$HOME/.bashrc"
else
rc_file="$HOME/.bashrc"
fi
# Step 6: Remove any previously written OCP LAN lines (idempotent)
if [[ -f "$rc_file" ]]; then
local tmp_rc
tmp_rc=$(mktemp)
if python3 - "$rc_file" "$tmp_rc" <<'PYEOF'
import sys
src, dst = sys.argv[1], sys.argv[2]
lines = open(src).readlines()
out = []
skip = False
for line in lines:
s = line.rstrip('\n')
if s == '# OCP LAN (added by ocp connect)':
skip = True
continue
if skip and (s == '' or s.startswith('export OPENAI_BASE_URL=') or s.startswith('export OPENAI_API_KEY=')):
continue
skip = False
out.append(line)
open(dst, 'w').writelines(out)
PYEOF
then
cp "$tmp_rc" "$rc_file"
fi
rm -f "$tmp_rc"
fi
# Step 7: Append new config
{
echo ""
echo "# OCP LAN (added by ocp connect)"
echo "export OPENAI_BASE_URL=$base_url/v1"
if [[ -n "$key" ]]; then
echo "export OPENAI_API_KEY=$key"
fi
} >> "$rc_file"
echo " Written to $rc_file:"
echo " OPENAI_BASE_URL=$base_url/v1"
if [[ -n "$key" ]]; then
echo " OPENAI_API_KEY=${key:0:8}..."
fi
echo ""
# Step 8: Quick smoke test
echo " Running smoke test..."
# Pick the first available model from /v1/models
local smoke_model
smoke_model=$(echo "$models_out" | python3 -c "import sys,json; d=json.loads(sys.stdin.read()); print(d['data'][0]['id'])" 2>/dev/null || echo "claude-haiku-4-5-20251001")
local chat_payload="{\"model\":\"$smoke_model\",\"messages\":[{\"role\":\"user\",\"content\":\"Reply with OK only.\"}],\"max_tokens\":10}"
local chat_out chat_ok=0
if [[ -n "$key" ]]; then
chat_out=$(curl -sf --max-time 30 \
-H "Authorization: Bearer $key" \
-H "Content-Type: application/json" \
-d "$chat_payload" \
"$base_url/v1/chat/completions" 2>/dev/null) && chat_ok=1
else
chat_out=$(curl -sf --max-time 30 \
-H "Content-Type: application/json" \
-d "$chat_payload" \
"$base_url/v1/chat/completions" 2>/dev/null) && chat_ok=1
fi
if [[ $chat_ok -eq 1 ]]; then
local reply
reply=$(echo "$chat_out" | python3 -c "import sys,json; d=json.loads(sys.stdin.read()); print(d['choices'][0]['message']['content'].strip())" 2>/dev/null || echo "(response received)")
echo " ✓ Smoke test passed: $reply"
else
echo " ⚠ Smoke test failed (proxy is reachable but chat completion did not succeed)."
echo " The env vars have still been written. Check the remote OCP logs."
fi
echo ""
echo " Done. Reload your shell to apply:"
echo " source $rc_file"
}
main "$@"
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "openclaw-claude-proxy", "name": "openclaw-claude-proxy",
"version": "3.4.0", "version": "3.5.0",
"description": "OCP (Open Claude Proxy) — use your Claude Pro/Max subscription as an OpenAI-compatible API for any IDE. Works with Cline, OpenCode, Aider, Continue.dev, OpenClaw, and more.", "description": "OCP (Open Claude Proxy) — use your Claude Pro/Max subscription as an OpenAI-compatible API for any IDE. Works with Cline, OpenCode, Aider, Continue.dev, OpenClaw, and more.",
"type": "module", "type": "module",
"bin": { "bin": {
+1
View File
@@ -1123,6 +1123,7 @@ const server = createServer(async (req, res) => {
uptimeHuman: `${Math.floor(uptimeMs / 3600000)}h ${Math.floor((uptimeMs % 3600000) / 60000)}m`, uptimeHuman: `${Math.floor(uptimeMs / 3600000)}h ${Math.floor((uptimeMs % 3600000) / 60000)}m`,
claudeBinary: CLAUDE, claudeBinary: CLAUDE,
claudeBinaryOk: binaryOk, claudeBinaryOk: binaryOk,
authMode: AUTH_MODE,
auth: authStatus, auth: authStatus,
config: { config: {
timeout: TIMEOUT, timeout: TIMEOUT,