hkcc 0.1.0
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 +768 -0
- package/bunfig.toml +2 -0
- package/dist/hkcc.js +860 -0
- package/dist/index.js +855 -0
- package/dist/public/index.css +1 -0
- package/dist/public/index.html +13 -0
- package/dist/public/index.js +256 -0
- package/migrations/0000_damp_the_hood.sql +31 -0
- package/migrations/0001_high_ulik.sql +12 -0
- package/migrations/meta/0000_snapshot.json +207 -0
- package/migrations/meta/0001_snapshot.json +283 -0
- package/migrations/meta/_journal.json +20 -0
- package/package.json +100 -0
package/README.md
ADDED
|
@@ -0,0 +1,768 @@
|
|
|
1
|
+
# Claude OAuth Proxy
|
|
2
|
+
|
|
3
|
+
A proxy server providing Claude API access through two simultaneous modes:
|
|
4
|
+
|
|
5
|
+
- **SDK Mode (`/sdk/*`)** - Uses locally installed Claude Code CLI via Agent SDK
|
|
6
|
+
- **OAuth Mode (`/api/*`)** - Direct API calls with OAuth tokens
|
|
7
|
+
|
|
8
|
+
Each mode supports both Anthropic and OpenAI-compatible formats:
|
|
9
|
+
|
|
10
|
+
- `/sdk/anthropic/*` or `/api/anthropic/*` - Anthropic Messages API format
|
|
11
|
+
- `/sdk/openai/*` or `/api/openai/*` - OpenAI Chat Completions API format
|
|
12
|
+
|
|
13
|
+
Both modes run simultaneously. Choose based on your setup.
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
graph LR
|
|
19
|
+
Client[Client<br/>SDKs, Apps, CLI] --> Proxy[HKCC Proxy Server]
|
|
20
|
+
|
|
21
|
+
Proxy --> SDK[SDK Mode<br/>/sdk/*]
|
|
22
|
+
Proxy --> OAuth[OAuth Mode<br/>/api/*]
|
|
23
|
+
|
|
24
|
+
SDK --> CLI[Claude Code CLI] --> API[Claude API]
|
|
25
|
+
OAuth --> Transform[Transform Request<br/>+ OAuth Token<br/>+ Magic Headers] --> API
|
|
26
|
+
|
|
27
|
+
Proxy --> DB[(Database<br/>Users & Credentials)]
|
|
28
|
+
|
|
29
|
+
style SDK fill:#e3f2fd
|
|
30
|
+
style OAuth fill:#fff3e0
|
|
31
|
+
style DB fill:#e8f5e9
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Two Modes:**
|
|
35
|
+
|
|
36
|
+
- **SDK Mode** - Routes through locally installed Claude Code CLI (full features)
|
|
37
|
+
- **OAuth Mode** - Direct API calls with OAuth tokens (lightweight, no CLI needed)
|
|
38
|
+
|
|
39
|
+
**Multi-User Support:** Session cookies and per-user API keys with database-backed credential storage
|
|
40
|
+
|
|
41
|
+
See [TECHNICAL.md](TECHNICAL.md) for detailed architecture diagrams and implementation details.
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bun install
|
|
47
|
+
bun dev
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Server starts at `http://127.0.0.1:3000`
|
|
51
|
+
|
|
52
|
+
## Build
|
|
53
|
+
|
|
54
|
+
Build both server and frontend dashboard:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
bun run build.ts
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This creates:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
dist/
|
|
64
|
+
├── index.js # Bundled server
|
|
65
|
+
└── public/ # Frontend dashboard
|
|
66
|
+
├── index.css
|
|
67
|
+
├── index.html
|
|
68
|
+
└── index.js
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Run the built server:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
bun run dist/index.js
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## CLI
|
|
78
|
+
|
|
79
|
+
HKCC can be run as a CLI tool via `npx` or `bunx`, perfect for quick local usage without Docker.
|
|
80
|
+
|
|
81
|
+
### Installation
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Via npx (requires Node.js)
|
|
85
|
+
npx hkcc --help
|
|
86
|
+
|
|
87
|
+
# Via bunx (requires Bun)
|
|
88
|
+
bunx hkcc --help
|
|
89
|
+
|
|
90
|
+
# Or run directly from the repo
|
|
91
|
+
bun run bin/hkcc.ts --help
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Usage Examples
|
|
95
|
+
|
|
96
|
+
**Local SQLite (simplest setup):**
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Run with local SQLite database in current directory
|
|
100
|
+
bunx hkcc --sqlite-path ./data/hkcc.db --db-driver bun-sqlite
|
|
101
|
+
|
|
102
|
+
# Or run from anywhere
|
|
103
|
+
bunx hkcc --sqlite-path ~/hkcc-data/db.sqlite --port 8080
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Turso Cloud Database:**
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
bunx hkcc \
|
|
110
|
+
--db-driver turso \
|
|
111
|
+
--turso-url libsql://your-db.turso.io \
|
|
112
|
+
--turso-token your-auth-token \
|
|
113
|
+
--port 3000
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**CLI Arguments:**
|
|
117
|
+
|
|
118
|
+
| Argument | Alias | Description | Default |
|
|
119
|
+
| --------------- | ----- | -------------------------------------------- | ------------------------------ |
|
|
120
|
+
| `--port` | `-p` | Server port | `3000` or `PORT` env var |
|
|
121
|
+
| `--host` | `-h` | Server host | `127.0.0.1` or `HOST` env var |
|
|
122
|
+
| `--db-driver` | | Database driver (`turso` or `bun-sqlite`) | Auto-detect |
|
|
123
|
+
| `--turso-url` | | Turso connection URL | `TURSO_CONNECTION_URL` env var |
|
|
124
|
+
| `--turso-token` | | Turso auth token | `TURSO_AUTH_TOKEN` env var |
|
|
125
|
+
| `--sqlite-path` | | SQLite database path (relative to CWD) | `./data/hkcc.db` |
|
|
126
|
+
| `--claude-path` | | Path to Claude Code CLI executable | Auto-detect |
|
|
127
|
+
| `--production` | | Enable production mode (static file serving) | Enabled |
|
|
128
|
+
|
|
129
|
+
**Key Features:**
|
|
130
|
+
|
|
131
|
+
- Runs from any directory - database path is relative to CWD
|
|
132
|
+
- Static files (dashboard CSS/JS) served correctly regardless of where you run it
|
|
133
|
+
- Migrations run automatically from the package location
|
|
134
|
+
- All auth modules share the same database instance
|
|
135
|
+
|
|
136
|
+
**CLI vs Server Mode:**
|
|
137
|
+
|
|
138
|
+
| Feature | CLI (`bunx hkcc`) | Server (`bun run src/index.ts`) |
|
|
139
|
+
| ------------ | -------------------------- | --------------------------------- |
|
|
140
|
+
| Entry Point | `bin/hkcc.ts` | `src/index.ts` |
|
|
141
|
+
| Args | CLI arguments | Environment variables |
|
|
142
|
+
| CWD | Database relative to CWD | Database relative to project root |
|
|
143
|
+
| Use Case | Quick start, any directory | Development in project |
|
|
144
|
+
| Static Files | Production mode | Dev mode (hot reload) |
|
|
145
|
+
|
|
146
|
+
## Dashboard
|
|
147
|
+
|
|
148
|
+
The server hosts a web dashboard at the root URL (`/`) for managing OAuth credentials and viewing server status. The dashboard is built with React and Tailwind CSS.
|
|
149
|
+
|
|
150
|
+
## Docker
|
|
151
|
+
|
|
152
|
+
All images require database configuration via environment variables.
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Default (with Claude Code CLI, bundled JS)
|
|
156
|
+
docker build -f Dockerfile -t hkcc:latest .
|
|
157
|
+
docker run -p 3000:3000 \
|
|
158
|
+
-e TURSO_CONNECTION_URL=libsql://your-db.turso.io \
|
|
159
|
+
-e TURSO_AUTH_TOKEN=your-token \
|
|
160
|
+
-v hkcc-claude:/home/claude/.claude \
|
|
161
|
+
hkcc:latest
|
|
162
|
+
|
|
163
|
+
# OAuth-only (smaller image, bundled JS)
|
|
164
|
+
docker build -f Dockerfile.oauth -t hkcc:oauth .
|
|
165
|
+
docker run -p 3000:3000 \
|
|
166
|
+
-e TURSO_CONNECTION_URL=libsql://your-db.turso.io \
|
|
167
|
+
-e TURSO_AUTH_TOKEN=your-token \
|
|
168
|
+
hkcc:oauth
|
|
169
|
+
|
|
170
|
+
# Compiled binary (no Bun runtime needed, with Claude Code CLI)
|
|
171
|
+
docker build -f Dockerfile.compiled -t hkcc:compiled .
|
|
172
|
+
docker run -p 3000:3000 \
|
|
173
|
+
-e TURSO_CONNECTION_URL=libsql://your-db.turso.io \
|
|
174
|
+
-e TURSO_AUTH_TOKEN=your-token \
|
|
175
|
+
-v hkcc-claude:/home/claude/.claude \
|
|
176
|
+
hkcc:compiled
|
|
177
|
+
|
|
178
|
+
# Compiled binary (no Bun runtime, OAuth-only, smallest)
|
|
179
|
+
docker build -f Dockerfile.compiled-oauth -t hkcc:compiled-oauth .
|
|
180
|
+
docker run -p 3000:3000 \
|
|
181
|
+
-e TURSO_CONNECTION_URL=libsql://your-db.turso.io \
|
|
182
|
+
-e TURSO_AUTH_TOKEN=your-token \
|
|
183
|
+
hkcc:compiled-oauth
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Volume mounts:**
|
|
187
|
+
|
|
188
|
+
- **SDK mode images** (`Dockerfile`, `Dockerfile.compiled`): Volume at `/home/claude/.claude`
|
|
189
|
+
- Stores Claude Code CLI authentication for SDK mode
|
|
190
|
+
- **OAuth-only images** (`Dockerfile.oauth`, `Dockerfile.compiled-oauth`): No volume needed
|
|
191
|
+
- All credentials stored in database
|
|
192
|
+
|
|
193
|
+
### Multi-Platform Builds (buildx)
|
|
194
|
+
|
|
195
|
+
Build images for both ARM64 (Apple Silicon) and AMD64 (Intel/AMD) architectures:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# Create and use buildx builder (one-time setup)
|
|
199
|
+
docker buildx create --use
|
|
200
|
+
|
|
201
|
+
# Build for multiple platforms and push to registry
|
|
202
|
+
docker buildx build --platform linux/amd64,linux/arm64 \
|
|
203
|
+
-t your-registry/hkcc:latest \
|
|
204
|
+
-f Dockerfile \
|
|
205
|
+
--push .
|
|
206
|
+
|
|
207
|
+
# Build for multiple platforms (load local - only works for single arch)
|
|
208
|
+
docker buildx build --platform linux/amd64,linux/arm64 \
|
|
209
|
+
-t hkcc:latest \
|
|
210
|
+
-f Dockerfile \
|
|
211
|
+
--output type=local,dest=./output .
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Note**: All Dockerfiles now support Docker buildx for multi-platform builds. The compiled variants automatically detect the target platform and compile the appropriate binary.
|
|
215
|
+
|
|
216
|
+
### Docker Image Variants
|
|
217
|
+
|
|
218
|
+
| Dockerfile | Claude Code CLI | Runtime | Base OS | Size | Best For |
|
|
219
|
+
| --------------------------- | --------------- | ------------- | ------- | ----- | ----------------------------------------- |
|
|
220
|
+
| `Dockerfile` | Yes | Bun JS | Alpine | 327MB | Development, hot reload, full features |
|
|
221
|
+
| `Dockerfile.oauth` | No | Bun JS | Alpine | 107MB | OAuth-only deployments, smaller footprint |
|
|
222
|
+
| `Dockerfile.compiled` | Yes | Native binary | Debian | 425MB | Production with SDK mode, faster startup |
|
|
223
|
+
| `Dockerfile.compiled-oauth` | No | Native binary | Debian | 204MB | Production OAuth-only, smallest image |
|
|
224
|
+
|
|
225
|
+
**Key Differences:**
|
|
226
|
+
|
|
227
|
+
- **Bundled JS (`.js`)**: Requires Bun runtime at runtime. Larger base image but faster builds.
|
|
228
|
+
- **Native Binary**: Pre-compiled executable. No Bun runtime needed, faster cold start, slower builds.
|
|
229
|
+
- **Claude Code CLI**: Required for SDK mode (`/sdk/*`). Adds ~220MB to image size.
|
|
230
|
+
- **Alpine vs Debian**: Alpine is smaller but uses musl libc. Debian uses glibc, needed for Claude Code CLI.
|
|
231
|
+
|
|
232
|
+
### Docker Compose
|
|
233
|
+
|
|
234
|
+
For easier deployment and configuration management, use Docker Compose. Create a `docker-compose.yml` file:
|
|
235
|
+
|
|
236
|
+
**Basic setup with Turso cloud database (recommended for production):**
|
|
237
|
+
|
|
238
|
+
```yaml
|
|
239
|
+
version: "3.8"
|
|
240
|
+
|
|
241
|
+
services:
|
|
242
|
+
hkcc:
|
|
243
|
+
image: huakunshen/hkcc:latest # or build locally: build: .
|
|
244
|
+
container_name: hkcc-proxy
|
|
245
|
+
restart: unless-stopped
|
|
246
|
+
ports:
|
|
247
|
+
- "3000:3000"
|
|
248
|
+
environment:
|
|
249
|
+
# Server configuration
|
|
250
|
+
- HOST=0.0.0.0
|
|
251
|
+
- PORT=3000
|
|
252
|
+
|
|
253
|
+
# Database - Turso (cloud)
|
|
254
|
+
- TURSO_CONNECTION_URL=libsql://your-db.turso.io
|
|
255
|
+
- TURSO_AUTH_TOKEN=your-auth-token
|
|
256
|
+
|
|
257
|
+
# Optional: Disable registration after creating accounts
|
|
258
|
+
# - HKCC_REGISTRATION_ENABLED=false
|
|
259
|
+
volumes:
|
|
260
|
+
# Persist Claude Code CLI authentication (SDK mode only)
|
|
261
|
+
- hkcc-claude:/home/claude/.claude
|
|
262
|
+
|
|
263
|
+
volumes:
|
|
264
|
+
hkcc-claude:
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**OAuth-only deployment (smaller image, no SDK mode):**
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
version: "3.8"
|
|
271
|
+
|
|
272
|
+
services:
|
|
273
|
+
hkcc:
|
|
274
|
+
image: huakunshen/hkcc:oauth # Uses OAuth-only image (smaller)
|
|
275
|
+
container_name: hkcc-oauth-proxy
|
|
276
|
+
restart: unless-stopped
|
|
277
|
+
ports:
|
|
278
|
+
- "3000:3000"
|
|
279
|
+
environment:
|
|
280
|
+
- HOST=0.0.0.0
|
|
281
|
+
- PORT=3000
|
|
282
|
+
- TURSO_CONNECTION_URL=libsql://your-db.turso.io
|
|
283
|
+
- TURSO_AUTH_TOKEN=your-auth-token
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Using local SQLite database (no external database needed):**
|
|
287
|
+
|
|
288
|
+
```yaml
|
|
289
|
+
version: "3.8"
|
|
290
|
+
|
|
291
|
+
services:
|
|
292
|
+
hkcc:
|
|
293
|
+
image: huakunshen/hkcc:latest
|
|
294
|
+
container_name: hkcc-proxy
|
|
295
|
+
restart: unless-stopped
|
|
296
|
+
ports:
|
|
297
|
+
- "3000:3000"
|
|
298
|
+
environment:
|
|
299
|
+
- HOST=0.0.0.0
|
|
300
|
+
- PORT=3000
|
|
301
|
+
# No TURSO variables = uses local SQLite at ./data/hkcc.db
|
|
302
|
+
# Optional: Custom database path
|
|
303
|
+
# - SQLITE_DATABASE_PATH=/app/data/hkcc.db
|
|
304
|
+
volumes:
|
|
305
|
+
# Persist local SQLite database
|
|
306
|
+
- hkcc-data:/app/data
|
|
307
|
+
# Persist Claude Code CLI authentication (SDK mode)
|
|
308
|
+
- hkcc-claude:/home/claude/.claude
|
|
309
|
+
|
|
310
|
+
volumes:
|
|
311
|
+
hkcc-data:
|
|
312
|
+
hkcc-claude:
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Compiled binary with faster startup (production-optimized):**
|
|
316
|
+
|
|
317
|
+
```yaml
|
|
318
|
+
version: "3.8"
|
|
319
|
+
|
|
320
|
+
services:
|
|
321
|
+
hkcc:
|
|
322
|
+
image: huakunshen/hkcc:compiled # Native binary, no Bun runtime
|
|
323
|
+
container_name: hkcc-compiled
|
|
324
|
+
restart: unless-stopped
|
|
325
|
+
ports:
|
|
326
|
+
- "3000:3000"
|
|
327
|
+
environment:
|
|
328
|
+
- HOST=0.0.0.0
|
|
329
|
+
- PORT=3000
|
|
330
|
+
- TURSO_CONNECTION_URL=libsql://your-db.turso.io
|
|
331
|
+
- TURSO_AUTH_TOKEN=your-auth-token
|
|
332
|
+
volumes:
|
|
333
|
+
- hkcc-claude:/home/claude/.claude
|
|
334
|
+
|
|
335
|
+
volumes:
|
|
336
|
+
hkcc-claude:
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**Using environment file for secrets:**
|
|
340
|
+
|
|
341
|
+
Create a `.env` file (git-ignored):
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# .env
|
|
345
|
+
TURSO_CONNECTION_URL=libsql://your-db.turso.io
|
|
346
|
+
TURSO_AUTH_TOKEN=your-auth-token
|
|
347
|
+
HKCC_REGISTRATION_ENABLED=false
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Update `docker-compose.yml` to use it:
|
|
351
|
+
|
|
352
|
+
```yaml
|
|
353
|
+
services:
|
|
354
|
+
hkcc:
|
|
355
|
+
image: huakunshen/hkcc:latest
|
|
356
|
+
container_name: hkcc-proxy
|
|
357
|
+
restart: unless-stopped
|
|
358
|
+
ports:
|
|
359
|
+
- "3000:3000"
|
|
360
|
+
env_file:
|
|
361
|
+
- .env
|
|
362
|
+
volumes:
|
|
363
|
+
- hkcc-claude:/home/claude/.claude
|
|
364
|
+
|
|
365
|
+
volumes:
|
|
366
|
+
hkcc-claude:
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Deploy with Docker Compose:**
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
# Start the service
|
|
373
|
+
docker compose up -d
|
|
374
|
+
|
|
375
|
+
# View logs
|
|
376
|
+
docker compose logs -f
|
|
377
|
+
|
|
378
|
+
# Stop the service
|
|
379
|
+
docker compose down
|
|
380
|
+
|
|
381
|
+
# Stop and remove volumes (WARNING: deletes data)
|
|
382
|
+
docker compose down -v
|
|
383
|
+
|
|
384
|
+
# Rebuild with local changes
|
|
385
|
+
docker compose up -d --build
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Key considerations:**
|
|
389
|
+
|
|
390
|
+
| Image Variant | SDK Mode | OAuth Mode | Volume Needed | Best Use Case |
|
|
391
|
+
| --------------------- | -------- | ---------- | ---------------------- | -------------------------- |
|
|
392
|
+
| `hkcc:latest` | ✅ | ✅ | `/home/claude/.claude` | Full features, development |
|
|
393
|
+
| `hkcc:oauth` | ❌ | ✅ | ❌ | OAuth-only, smaller image |
|
|
394
|
+
| `hkcc:compiled` | ✅ | ✅ | `/home/claude/.claude` | Production, faster startup |
|
|
395
|
+
| `hkcc:compiled-oauth` | ❌ | ✅ | ❌ | OAuth-only, production |
|
|
396
|
+
|
|
397
|
+
**Database options:**
|
|
398
|
+
|
|
399
|
+
- **Turso (cloud)**: Set `TURSO_CONNECTION_URL` and `TURSO_AUTH_TOKEN` - Best for production, multi-instance setups
|
|
400
|
+
- **Local SQLite**: Don't set Turso variables - Automatically uses `/app/data/hkcc.db` - Best for single-instance, development
|
|
401
|
+
|
|
402
|
+
## API Endpoints
|
|
403
|
+
|
|
404
|
+
### Health & Status
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
curl http://127.0.0.1:3000/health
|
|
408
|
+
curl http://127.0.0.1:3000/oauth/status
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### SDK Mode (`/sdk/*`) - Requires Claude Code CLI
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
# Anthropic Messages API
|
|
415
|
+
curl -X POST http://127.0.0.1:3000/sdk/anthropic/v1/messages \
|
|
416
|
+
-H "Content-Type: application/json" \
|
|
417
|
+
-d '{"model":"claude-sonnet-4-5-20250929","max_tokens":1024,"messages":[{"role":"user","content":"Hello!"}]}'
|
|
418
|
+
|
|
419
|
+
# OpenAI Chat Completions API
|
|
420
|
+
curl -X POST http://127.0.0.1:3000/sdk/openai/v1/chat/completions \
|
|
421
|
+
-H "Content-Type: application/json" \
|
|
422
|
+
-d '{"model":"gpt-4","messages":[{"role":"user","content":"Hello!"}]}'
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### OAuth Mode (`/api/*`) - Requires OAuth Authentication
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
# Anthropic Messages API
|
|
429
|
+
curl -X POST http://127.0.0.1:3000/api/anthropic/v1/messages \
|
|
430
|
+
-H "Content-Type: application/json" \
|
|
431
|
+
-d '{"model":"claude-sonnet-4-5-20250929","max_tokens":1024,"messages":[{"role":"user","content":"Hello!"}]}'
|
|
432
|
+
|
|
433
|
+
# OpenAI Chat Completions API
|
|
434
|
+
curl -X POST http://127.0.0.1:3000/api/openai/v1/chat/completions \
|
|
435
|
+
-H "Content-Type: application/json" \
|
|
436
|
+
-d '{"model":"gpt-4","messages":[{"role":"user","content":"Hello!"}]}'
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Model Mapping
|
|
440
|
+
|
|
441
|
+
| OpenAI Model | Claude Model |
|
|
442
|
+
| -------------------------------- | ---------------------------- |
|
|
443
|
+
| `gpt-4`, `gpt-4-turbo`, `gpt-4o` | `claude-sonnet-4-5-20250929` |
|
|
444
|
+
| `gpt-3.5-turbo` | `claude-haiku-3-5-20241022` |
|
|
445
|
+
|
|
446
|
+
## Database Setup (Required)
|
|
447
|
+
|
|
448
|
+
The server stores user accounts, OAuth credentials, and API keys in a database. Both cloud (Turso) and local SQLite databases are supported.
|
|
449
|
+
|
|
450
|
+
### Auto-Detection (Recommended)
|
|
451
|
+
|
|
452
|
+
The server automatically detects which database to use:
|
|
453
|
+
|
|
454
|
+
- If `TURSO_CONNECTION_URL` and `TURSO_AUTH_TOKEN` are set → uses Turso (cloud)
|
|
455
|
+
- Otherwise → uses local SQLite at `./data/hkcc.db`
|
|
456
|
+
|
|
457
|
+
For new users, no configuration is needed - the server will automatically use local SQLite.
|
|
458
|
+
|
|
459
|
+
### Local SQLite (Default)
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
# No configuration needed - uses ./data/hkcc.db by default
|
|
463
|
+
bun dev
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
To customize the database file location:
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
SQLITE_DATABASE_PATH=./custom/path/db.sqlite
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### Turso (Cloud Database)
|
|
473
|
+
|
|
474
|
+
Set the database environment variables in `.env`:
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
TURSO_CONNECTION_URL=libsql://your-db.turso.io
|
|
478
|
+
TURSO_AUTH_TOKEN=your-auth-token
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Manual Override
|
|
482
|
+
|
|
483
|
+
Override auto-detection with:
|
|
484
|
+
|
|
485
|
+
```bash
|
|
486
|
+
DB_DRIVER=turso # Force Turso
|
|
487
|
+
# or
|
|
488
|
+
DB_DRIVER=bun-sqlite # Force local SQLite
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### Migrations
|
|
492
|
+
|
|
493
|
+
Migrations run automatically on server startup. For manual migration management:
|
|
494
|
+
|
|
495
|
+
```bash
|
|
496
|
+
bun drizzle-kit push # Apply schema to database
|
|
497
|
+
bun drizzle-kit studio # Open database GUI
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## User Authentication
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
# Register
|
|
504
|
+
curl -X POST http://127.0.0.1:3000/auth/register \
|
|
505
|
+
-H "Content-Type: application/json" \
|
|
506
|
+
-d '{"email": "user@example.com", "password": "password123", "username": "myuser"}'
|
|
507
|
+
|
|
508
|
+
# Login
|
|
509
|
+
curl -X POST http://127.0.0.1:3000/auth/login \
|
|
510
|
+
-H "Content-Type: application/json" \
|
|
511
|
+
-d '{"email": "user@example.com", "password": "password123"}'
|
|
512
|
+
|
|
513
|
+
# Get current user
|
|
514
|
+
curl http://127.0.0.1:3000/auth/me -b "hkcc_session=SESSION_TOKEN"
|
|
515
|
+
|
|
516
|
+
# Logout
|
|
517
|
+
curl -X POST http://127.0.0.1:3000/auth/logout -b "hkcc_session=SESSION_TOKEN"
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Registration can be disabled by setting `HKCC_REGISTRATION_ENABLED=false` after creating your account.
|
|
521
|
+
|
|
522
|
+
## OAuth Authentication
|
|
523
|
+
|
|
524
|
+
After logging in, authenticate with OAuth providers via the dashboard or API:
|
|
525
|
+
|
|
526
|
+
```bash
|
|
527
|
+
# Get Anthropic authorization URL
|
|
528
|
+
curl http://127.0.0.1:3000/oauth/anthropic/login?mode=max
|
|
529
|
+
|
|
530
|
+
# Get OpenAI/Codex authorization URL
|
|
531
|
+
curl http://127.0.0.1:3000/oauth/openai/login
|
|
532
|
+
|
|
533
|
+
# Check OAuth status
|
|
534
|
+
curl http://127.0.0.1:3000/oauth/anthropic/status
|
|
535
|
+
curl http://127.0.0.1:3000/oauth/openai/status
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### PKCE Authentication Flow
|
|
539
|
+
|
|
540
|
+
The server uses OAuth 2.0 with PKCE (Proof Key for Code Exchange) for secure authentication:
|
|
541
|
+
|
|
542
|
+
```mermaid
|
|
543
|
+
sequenceDiagram
|
|
544
|
+
participant User
|
|
545
|
+
participant Browser
|
|
546
|
+
participant Proxy as HKCC Proxy
|
|
547
|
+
participant Claude as claude.ai
|
|
548
|
+
|
|
549
|
+
User->>Browser: Click "Login with Claude"
|
|
550
|
+
Browser->>Proxy: GET /oauth/anthropic/login
|
|
551
|
+
Proxy->>Proxy: Generate PKCE<br/>code_verifier<br/>code_challenge
|
|
552
|
+
Proxy-->>Browser: Authorization URL + state
|
|
553
|
+
|
|
554
|
+
Browser->>Claude: Redirect to authorization URL
|
|
555
|
+
Claude->>User: Show consent screen
|
|
556
|
+
User->>Claude: Approve access
|
|
557
|
+
Claude-->>Browser: Redirect with auth code
|
|
558
|
+
|
|
559
|
+
Browser->>Proxy: GET /oauth/anthropic/callback?code=xxx
|
|
560
|
+
Proxy->>Claude: POST /oauth/token<br/>(code + verifier)
|
|
561
|
+
Claude-->>Proxy: access_token + refresh_token
|
|
562
|
+
Proxy->>Proxy: Store credentials in database
|
|
563
|
+
Proxy-->>Browser: Redirect to dashboard
|
|
564
|
+
Browser->>User: Authentication complete
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
**Security features:**
|
|
568
|
+
|
|
569
|
+
- PKCE prevents authorization code interception attacks
|
|
570
|
+
- State parameter prevents CSRF attacks
|
|
571
|
+
- Tokens stored securely in database with user isolation
|
|
572
|
+
- Automatic token refresh before expiration
|
|
573
|
+
|
|
574
|
+
### API Access Modes
|
|
575
|
+
|
|
576
|
+
| Mode | Authentication | Credentials Used |
|
|
577
|
+
| ------------------- | ------------------------------- | --------------------------- |
|
|
578
|
+
| Dashboard (browser) | Session cookie (`hkcc_session`) | User's database credentials |
|
|
579
|
+
| Per-user API key | `hkcc_sk_xxx` in header | User's database credentials |
|
|
580
|
+
|
|
581
|
+
### Per-User API Keys
|
|
582
|
+
|
|
583
|
+
Each registered user can create up to 5 personal API keys for external applications like Cherry Studio, Cursor, or custom scripts.
|
|
584
|
+
|
|
585
|
+
**Create an API key** (via dashboard or API):
|
|
586
|
+
|
|
587
|
+
```bash
|
|
588
|
+
# Create key via API (requires session cookie)
|
|
589
|
+
curl -X POST http://127.0.0.1:3000/auth/api-keys \
|
|
590
|
+
-H "Content-Type: application/json" \
|
|
591
|
+
-b "hkcc_session=SESSION_TOKEN" \
|
|
592
|
+
-d '{"name": "Cherry Studio"}'
|
|
593
|
+
|
|
594
|
+
# Response includes the full key (shown only once):
|
|
595
|
+
# {"success":true,"key":"hkcc_sk_a1b2c3d4e5f6...","apiKey":{"id":1,"keyPrefix":"hkcc_sk_a1b2...","name":"Cherry Studio"}}
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
**Use the API key** in external clients:
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
curl -X POST http://127.0.0.1:3000/api/anthropic/v1/messages \
|
|
602
|
+
-H "x-api-key: hkcc_sk_a1b2c3d4e5f6..." \
|
|
603
|
+
-H "Content-Type: application/json" \
|
|
604
|
+
-d '{"model":"claude-sonnet-4-5-20250929","max_tokens":100,"messages":[{"role":"user","content":"Hello"}]}'
|
|
605
|
+
|
|
606
|
+
# Or use Authorization header:
|
|
607
|
+
curl -X POST http://127.0.0.1:3000/api/anthropic/v1/messages \
|
|
608
|
+
-H "Authorization: Bearer hkcc_sk_a1b2c3d4e5f6..." \
|
|
609
|
+
...
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
**Manage API keys**:
|
|
613
|
+
|
|
614
|
+
```bash
|
|
615
|
+
# List keys
|
|
616
|
+
curl http://127.0.0.1:3000/auth/api-keys -b "hkcc_session=SESSION_TOKEN"
|
|
617
|
+
|
|
618
|
+
# Delete a key
|
|
619
|
+
curl -X DELETE http://127.0.0.1:3000/auth/api-keys/1 -b "hkcc_session=SESSION_TOKEN"
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
### Token Refresh
|
|
623
|
+
|
|
624
|
+
A cron job runs every hour to automatically refresh tokens expiring within 60 minutes. Claude access tokens have an 8-hour TTL (480 minutes).
|
|
625
|
+
|
|
626
|
+
## SDK Integration
|
|
627
|
+
|
|
628
|
+
### Vercel AI SDK
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
632
|
+
import { generateText } from "ai";
|
|
633
|
+
|
|
634
|
+
const anthropic = createAnthropic({
|
|
635
|
+
baseURL: "http://127.0.0.1:3000/api/anthropic", // OAuth mode
|
|
636
|
+
apiKey: "hkcc_sk_your_personal_api_key", // Per-user API key
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
const { text } = await generateText({
|
|
640
|
+
model: anthropic("claude-sonnet-4-5-20250929"),
|
|
641
|
+
prompt: "Hello!",
|
|
642
|
+
});
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
### Anthropic SDK
|
|
646
|
+
|
|
647
|
+
```typescript
|
|
648
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
649
|
+
|
|
650
|
+
const client = new Anthropic({
|
|
651
|
+
baseURL: "http://127.0.0.1:3000/api/anthropic", // OAuth mode
|
|
652
|
+
apiKey: "hkcc_sk_your_personal_api_key", // Per-user API key
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
const message = await client.messages.create({
|
|
656
|
+
model: "claude-sonnet-4-5-20250929",
|
|
657
|
+
max_tokens: 1024,
|
|
658
|
+
messages: [{ role: "user", content: "Hello!" }],
|
|
659
|
+
});
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
### OpenAI SDK
|
|
663
|
+
|
|
664
|
+
```typescript
|
|
665
|
+
import OpenAI from "openai";
|
|
666
|
+
|
|
667
|
+
const client = new OpenAI({
|
|
668
|
+
baseURL: "http://127.0.0.1:3000/api/anthropic/openai/v1", // OAuth mode with OpenAI format
|
|
669
|
+
apiKey: "hkcc_sk_your_personal_api_key", // Per-user API key
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
const completion = await client.chat.completions.create({
|
|
673
|
+
model: "claude-sonnet-4-5-20250929",
|
|
674
|
+
messages: [{ role: "user", content: "Hello!" }],
|
|
675
|
+
});
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
## Environment Variables
|
|
679
|
+
|
|
680
|
+
```bash
|
|
681
|
+
# Server Configuration
|
|
682
|
+
PORT=3000 # Server port (default: 3000)
|
|
683
|
+
HOST=127.0.0.1 # Server host (default: 127.0.0.1)
|
|
684
|
+
|
|
685
|
+
# Database (Required)
|
|
686
|
+
TURSO_CONNECTION_URL=libsql://your-db.turso.io
|
|
687
|
+
TURSO_AUTH_TOKEN=your-auth-token
|
|
688
|
+
|
|
689
|
+
# Registration Control
|
|
690
|
+
HKCC_REGISTRATION_ENABLED=true # Set to "false" to disable new user registration
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
## Development
|
|
694
|
+
|
|
695
|
+
```bash
|
|
696
|
+
bun run dev # Run with hot reload
|
|
697
|
+
bun run build.ts # Build server and frontend
|
|
698
|
+
bun test # Run tests
|
|
699
|
+
bun run format # Format code
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
## Project Structure
|
|
703
|
+
|
|
704
|
+
```
|
|
705
|
+
src/
|
|
706
|
+
├── index.ts # Server entry point (development)
|
|
707
|
+
├── app.ts # Elysia app factory
|
|
708
|
+
├── auth/ # OAuth & user authentication, API key management
|
|
709
|
+
├── db/ # Drizzle ORM schema and database connection
|
|
710
|
+
├── cron/ # Scheduled jobs (token refresh)
|
|
711
|
+
├── proxy/ # SDK and OAuth proxy implementations
|
|
712
|
+
├── routes/ # OAuth and auth endpoints
|
|
713
|
+
├── adapters/ # Request/response format adapters
|
|
714
|
+
├── transform/ # Request/response transformations
|
|
715
|
+
├── middleware/ # API key validation, error handling
|
|
716
|
+
├── mcp-bridge/ # MCP tool bridging for client tools
|
|
717
|
+
└── utils/ # Utilities (Claude Code detection)
|
|
718
|
+
|
|
719
|
+
bin/
|
|
720
|
+
└── hkcc.ts # CLI entry point (npx/bunx)
|
|
721
|
+
|
|
722
|
+
public/ # Frontend source (React + Tailwind)
|
|
723
|
+
├── index.tsx # React entry point
|
|
724
|
+
└── pages/ # Dashboard pages
|
|
725
|
+
|
|
726
|
+
build.ts # Build script for server, CLI, and frontend
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
See [TECHNICAL.md](./TECHNICAL.md) for architecture details.
|
|
730
|
+
|
|
731
|
+
## Tech Stack
|
|
732
|
+
|
|
733
|
+
- **Runtime**: Bun
|
|
734
|
+
- **Framework**: Elysia
|
|
735
|
+
- **Frontend**: React, TanStack Router, Tailwind CSS
|
|
736
|
+
- **Type-Safe Client**: Eden
|
|
737
|
+
- **Database**: Turso (libSQL) with Drizzle ORM
|
|
738
|
+
- **Validation**: Zod + Elysia's t.Object
|
|
739
|
+
|
|
740
|
+
## Docker Build
|
|
741
|
+
|
|
742
|
+
```bash
|
|
743
|
+
# Build and push with timestamp tags for all variants
|
|
744
|
+
DATE_TAG=$(date +%Y-%m-%d-%H-%M-%S)
|
|
745
|
+
|
|
746
|
+
# Default (latest + oauth + compiled + compiled-oauth)
|
|
747
|
+
docker buildx build --push --platform linux/amd64,linux/arm64 \
|
|
748
|
+
-t huakunshen/hkcc:latest \
|
|
749
|
+
-t huakunshen/hkcc:latest-${DATE_TAG} \
|
|
750
|
+
-f Dockerfile .
|
|
751
|
+
|
|
752
|
+
docker buildx build --push --platform linux/amd64,linux/arm64 \
|
|
753
|
+
-t huakunshen/hkcc:oauth \
|
|
754
|
+
-t huakunshen/hkcc:oauth-${DATE_TAG} \
|
|
755
|
+
-f Dockerfile.oauth .
|
|
756
|
+
|
|
757
|
+
docker buildx build --push --platform linux/amd64,linux/arm64 \
|
|
758
|
+
-t huakunshen/hkcc:compiled \
|
|
759
|
+
-t huakunshen/hkcc:compiled-${DATE_TAG} \
|
|
760
|
+
-f Dockerfile.compiled .
|
|
761
|
+
|
|
762
|
+
docker buildx build --push --platform linux/amd64,linux/arm64 \
|
|
763
|
+
-t huakunshen/hkcc:compiled-oauth \
|
|
764
|
+
-t huakunshen/hkcc:compiled-oauth-${DATE_TAG} \
|
|
765
|
+
-f Dockerfile.compiled-oauth .
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
**Note:** Each image is tagged with both the standard tag (e.g., `latest`, `oauth`) and a timestamped tag (e.g., `oauth-2026-01-29-21-03-17`) for version tracking. All images support both `linux/amd64` and `linux/arm64` platforms.
|