opencode-claude-max-proxy 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -2
- package/bin/docker-auth.sh +77 -0
- package/bin/docker-entrypoint.sh +24 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -102,19 +102,40 @@ curl http://127.0.0.1:3456/health
|
|
|
102
102
|
|
|
103
103
|
### Connect OpenCode
|
|
104
104
|
|
|
105
|
+
#### Environment Variables
|
|
106
|
+
|
|
105
107
|
```bash
|
|
106
108
|
ANTHROPIC_API_KEY=dummy ANTHROPIC_BASE_URL=http://127.0.0.1:3456 opencode
|
|
107
109
|
```
|
|
108
110
|
|
|
109
111
|
The `ANTHROPIC_API_KEY` can be any non-empty string — the proxy doesn't use it. Authentication is handled by your `claude login` session.
|
|
110
112
|
|
|
111
|
-
|
|
113
|
+
#### Shell Alias
|
|
112
114
|
|
|
113
115
|
```bash
|
|
114
|
-
# Add to ~/.zshrc or ~/.bashrc
|
|
116
|
+
# Add to ~/.zshrc or ~/.bashrc or ~/.config/fish/config.fish
|
|
115
117
|
alias oc='ANTHROPIC_API_KEY=dummy ANTHROPIC_BASE_URL=http://127.0.0.1:3456 opencode'
|
|
116
118
|
```
|
|
117
119
|
|
|
120
|
+
#### OpenCode Config File
|
|
121
|
+
|
|
122
|
+
Alternatively, the proxy URL and API key can be set globally in `~/.config/opencode/opencode.json`. This has the benefit of working in OpenCode Desktop as well.
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
...
|
|
127
|
+
"provider": {
|
|
128
|
+
"anthropic": {
|
|
129
|
+
"options": {
|
|
130
|
+
"baseURL": "http://127.0.0.1:3456",
|
|
131
|
+
"apiKey": "dummy"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
...
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
118
139
|
## Modes
|
|
119
140
|
|
|
120
141
|
### Passthrough Mode (recommended)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Copy Claude credentials from host into Docker container.
|
|
3
|
+
#
|
|
4
|
+
# macOS stores scopes in Keychain, so the credentials file has scopes: ""
|
|
5
|
+
# Linux Claude CLI needs scopes as an array. This script fixes the format.
|
|
6
|
+
#
|
|
7
|
+
# Usage: ./bin/docker-auth.sh
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
cd "$SCRIPT_DIR/.."
|
|
13
|
+
|
|
14
|
+
HOST_CREDS="$HOME/.claude/.credentials.json"
|
|
15
|
+
|
|
16
|
+
if [ ! -f "$HOST_CREDS" ]; then
|
|
17
|
+
echo "❌ No credentials found at $HOST_CREDS"
|
|
18
|
+
echo " Run 'claude login' on your host first."
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Check if host is logged in
|
|
23
|
+
if ! claude auth status 2>/dev/null | grep -q '"loggedIn": true'; then
|
|
24
|
+
echo "❌ Not logged in on host. Run 'claude login' first."
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
echo "📋 Reading credentials from host..."
|
|
29
|
+
|
|
30
|
+
# Fix the scopes field and copy into container
|
|
31
|
+
python3 -c "
|
|
32
|
+
import json, sys
|
|
33
|
+
|
|
34
|
+
with open('$HOST_CREDS') as f:
|
|
35
|
+
creds = json.load(f)
|
|
36
|
+
|
|
37
|
+
oauth = creds.get('claudeAiOauth', {})
|
|
38
|
+
if not oauth.get('accessToken'):
|
|
39
|
+
print('❌ No access token found in credentials')
|
|
40
|
+
sys.exit(1)
|
|
41
|
+
|
|
42
|
+
# Fix scopes: empty string -> proper array
|
|
43
|
+
if not oauth.get('scopes') or oauth['scopes'] == '':
|
|
44
|
+
oauth['scopes'] = [
|
|
45
|
+
'user:profile',
|
|
46
|
+
'user:inference',
|
|
47
|
+
'user:sessions:claude_code',
|
|
48
|
+
'user:mcp_servers',
|
|
49
|
+
'user:file_upload'
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
creds['claudeAiOauth'] = oauth
|
|
53
|
+
print(json.dumps(creds))
|
|
54
|
+
" | docker compose exec -T proxy bash -c 'cat > /home/claude/.claude/.credentials.json'
|
|
55
|
+
|
|
56
|
+
if [ $? -ne 0 ]; then
|
|
57
|
+
echo "❌ Failed to copy credentials. Is the container running?"
|
|
58
|
+
echo " Run 'docker compose up -d' first."
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Also copy .claude.json if it exists
|
|
63
|
+
if [ -f "$HOME/.claude/.claude.json" ]; then
|
|
64
|
+
docker compose exec -T proxy bash -c 'cat > /home/claude/.claude/.claude.json' < "$HOME/.claude/.claude.json"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Verify
|
|
68
|
+
echo "🔍 Verifying..."
|
|
69
|
+
AUTH=$(docker compose exec proxy claude auth status 2>&1)
|
|
70
|
+
if echo "$AUTH" | grep -q '"loggedIn": true'; then
|
|
71
|
+
EMAIL=$(echo "$AUTH" | grep -o '"email": "[^"]*"' | head -1)
|
|
72
|
+
echo "✅ Docker container authenticated! $EMAIL"
|
|
73
|
+
else
|
|
74
|
+
echo "❌ Authentication failed inside container"
|
|
75
|
+
echo "$AUTH"
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Docker entrypoint:
|
|
3
|
+
# 1. Fix volume permissions (created as root, need claude ownership)
|
|
4
|
+
# 2. Symlink .claude.json into persistent volume
|
|
5
|
+
|
|
6
|
+
CLAUDE_DIR="/home/claude/.claude"
|
|
7
|
+
CLAUDE_JSON="/home/claude/.claude.json"
|
|
8
|
+
CLAUDE_JSON_VOL="$CLAUDE_DIR/.claude.json"
|
|
9
|
+
|
|
10
|
+
# Fix ownership if volume was created as root
|
|
11
|
+
if [ -d "$CLAUDE_DIR" ] && [ ! -w "$CLAUDE_DIR" ]; then
|
|
12
|
+
echo "[entrypoint] Fixing volume permissions..."
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Symlink .claude.json into volume so it persists across restarts
|
|
16
|
+
if [ -f "$CLAUDE_JSON_VOL" ] && [ ! -f "$CLAUDE_JSON" ]; then
|
|
17
|
+
ln -sf "$CLAUDE_JSON_VOL" "$CLAUDE_JSON"
|
|
18
|
+
elif [ -f "$CLAUDE_JSON" ] && [ ! -L "$CLAUDE_JSON" ] && [ -w "$CLAUDE_DIR" ]; then
|
|
19
|
+
cp "$CLAUDE_JSON" "$CLAUDE_JSON_VOL" 2>/dev/null
|
|
20
|
+
rm -f "$CLAUDE_JSON"
|
|
21
|
+
ln -sf "$CLAUDE_JSON_VOL" "$CLAUDE_JSON"
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
exec "$@"
|