New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

hkcc

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hkcc

Claude proxy server with Agent SDK and OAuth modes

latest
Source
npmnpm
Version
0.1.4
Version published
Maintainers
1
Created
Source

Claude OAuth Proxy

A proxy server providing Claude API access through two simultaneous modes:

  • SDK Mode (/sdk/*) - Uses locally installed Claude Code CLI via Agent SDK
  • OAuth Mode (/api/*) - Direct API calls with OAuth tokens

Each mode supports both Anthropic and OpenAI-compatible formats:

  • /sdk/anthropic/* or /api/anthropic/* - Anthropic Messages API format
  • /sdk/openai/* or /api/openai/* - OpenAI Chat Completions API format

Both modes run simultaneously. Choose based on your setup.

Architecture

graph LR
    Client[Client<br/>SDKs, Apps, CLI] --> Proxy[HKCC Proxy Server]

    Proxy --> SDK[SDK Mode<br/>/sdk/*]
    Proxy --> OAuth[OAuth Mode<br/>/api/*]

    SDK --> CLI[Claude Code CLI] --> API[Claude API]
    OAuth --> Transform[Transform Request<br/>+ OAuth Token<br/>+ Magic Headers] --> API

    Proxy --> DB[(Database<br/>Users & Credentials)]

    style SDK fill:#e3f2fd
    style OAuth fill:#fff3e0
    style DB fill:#e8f5e9

Two Modes:

  • SDK Mode - Routes through locally installed Claude Code CLI (full features)
  • OAuth Mode - Direct API calls with OAuth tokens (lightweight, no CLI needed)

Multi-User Support: Session cookies and per-user API keys with database-backed credential storage

⚠️ Runtime Requirement This package MUST be run with Bun (>=1.0.0). It uses bun:sqlite under the hood for the database layer, which is not compatible with Node.js.

See TECHNICAL.md for detailed architecture diagrams and implementation details.

Quick Start

bun install
bun dev

Server starts at http://127.0.0.1:3000

Build

Build both server and frontend dashboard:

bun run build.ts

This creates:

dist/
├── index.js      # Bundled server
└── public/       # Frontend dashboard
    ├── index.css
    ├── index.html
    └── index.js

Run the built server:

bun run dist/index.js

CLI

HKCC can be run as a CLI tool via npx or bunx, perfect for quick local usage without Docker.

Installation

⚠️ Bun Required: Even when using npx, Bun must be installed on your system because the bundled CLI uses bun:sqlite internally.

# Via bunx (recommended - uses Bun directly)
bunx hkcc --help

# Via npx (Bun must be installed on system)
npx hkcc --help

# Or run directly from the repo
bun run bin/hkcc.ts --help

Usage Examples

Local SQLite (simplest setup):

# Run with local SQLite database in current directory
bunx hkcc --sqlite-path ./data/hkcc.db --db-driver bun-sqlite

# Or run from anywhere
bunx hkcc --sqlite-path ~/hkcc-data/db.sqlite --port 8080

Turso Cloud Database:

bunx hkcc \
  --db-driver turso \
  --turso-url libsql://your-db.turso.io \
  --turso-token your-auth-token \
  --port 3000

CLI Arguments:

ArgumentAliasDescriptionDefault
--port-pServer port3000 or PORT env var
--host-hServer host127.0.0.1 or HOST env var
--db-driverDatabase driver (turso or bun-sqlite)Auto-detect
--turso-urlTurso connection URLTURSO_CONNECTION_URL env var
--turso-tokenTurso auth tokenTURSO_AUTH_TOKEN env var
--sqlite-pathSQLite database path (relative to CWD)./data/hkcc.db
--claude-pathPath to Claude Code CLI executableAuto-detect
--productionEnable production mode (static file serving)Enabled

Key Features:

  • Runs from any directory - database path is relative to CWD
  • Static files (dashboard CSS/JS) served correctly regardless of where you run it
  • Migrations run automatically from the package location
  • All auth modules share the same database instance

CLI vs Server Mode:

FeatureCLI (bunx hkcc)Server (bun run src/index.ts)
Entry Pointbin/hkcc.tssrc/index.ts
ArgsCLI argumentsEnvironment variables
CWDDatabase relative to CWDDatabase relative to project root
Use CaseQuick start, any directoryDevelopment in project
Static FilesProduction modeDev mode (hot reload)

Dashboard

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.

Docker

All images require database configuration via environment variables.

# Default (with Claude Code CLI, bundled JS)
docker build -f Dockerfile -t hkcc:latest .
docker run -p 3000:3000 \
  -e TURSO_CONNECTION_URL=libsql://your-db.turso.io \
  -e TURSO_AUTH_TOKEN=your-token \
  -v hkcc-claude:/home/claude/.claude \
  hkcc:latest

# OAuth-only (smaller image, bundled JS)
docker build -f Dockerfile.oauth -t hkcc:oauth .
docker run -p 3000:3000 \
  -e TURSO_CONNECTION_URL=libsql://your-db.turso.io \
  -e TURSO_AUTH_TOKEN=your-token \
  hkcc:oauth

# Compiled binary (no Bun runtime needed, with Claude Code CLI)
docker build -f Dockerfile.compiled -t hkcc:compiled .
docker run -p 3000:3000 \
  -e TURSO_CONNECTION_URL=libsql://your-db.turso.io \
  -e TURSO_AUTH_TOKEN=your-token \
  -v hkcc-claude:/home/claude/.claude \
  hkcc:compiled

# Compiled binary (no Bun runtime, OAuth-only, smallest)
docker build -f Dockerfile.compiled-oauth -t hkcc:compiled-oauth .
docker run -p 3000:3000 \
  -e TURSO_CONNECTION_URL=libsql://your-db.turso.io \
  -e TURSO_AUTH_TOKEN=your-token \
  hkcc:compiled-oauth

Volume mounts:

  • SDK mode images (Dockerfile, Dockerfile.compiled): Volume at /home/claude/.claude
    • Stores Claude Code CLI authentication for SDK mode
  • OAuth-only images (Dockerfile.oauth, Dockerfile.compiled-oauth): No volume needed
    • All credentials stored in database

Multi-Platform Builds (buildx)

Build images for both ARM64 (Apple Silicon) and AMD64 (Intel/AMD) architectures:

# Create and use buildx builder (one-time setup)
docker buildx create --use

# Build for multiple platforms and push to registry
docker buildx build --platform linux/amd64,linux/arm64 \
  -t your-registry/hkcc:latest \
  -f Dockerfile \
  --push .

# Build for multiple platforms (load local - only works for single arch)
docker buildx build --platform linux/amd64,linux/arm64 \
  -t hkcc:latest \
  -f Dockerfile \
  --output type=local,dest=./output .

Note: All Dockerfiles now support Docker buildx for multi-platform builds. The compiled variants automatically detect the target platform and compile the appropriate binary.

Docker Image Variants

DockerfileClaude Code CLIRuntimeBase OSSizeBest For
DockerfileYesBun JSAlpine327MBDevelopment, hot reload, full features
Dockerfile.oauthNoBun JSAlpine107MBOAuth-only deployments, smaller footprint
Dockerfile.compiledYesNative binaryDebian425MBProduction with SDK mode, faster startup
Dockerfile.compiled-oauthNoNative binaryDebian204MBProduction OAuth-only, smallest image

Key Differences:

  • Bundled JS (.js): Requires Bun runtime at runtime. Larger base image but faster builds.
  • Native Binary: Pre-compiled executable. No Bun runtime needed, faster cold start, slower builds.
  • Claude Code CLI: Required for SDK mode (/sdk/*). Adds ~220MB to image size.
  • Alpine vs Debian: Alpine is smaller but uses musl libc. Debian uses glibc, needed for Claude Code CLI.

Docker Compose

For easier deployment and configuration management, use Docker Compose. Create a docker-compose.yml file:

Basic setup with Turso cloud database (recommended for production):

version: "3.8"

services:
  hkcc:
    image: huakunshen/hkcc:latest # or build locally: build: .
    container_name: hkcc-proxy
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      # Server configuration
      - HOST=0.0.0.0
      - PORT=3000

      # Database - Turso (cloud)
      - TURSO_CONNECTION_URL=libsql://your-db.turso.io
      - TURSO_AUTH_TOKEN=your-auth-token

      # Optional: Disable registration after creating accounts
      # - HKCC_REGISTRATION_ENABLED=false
    volumes:
      # Persist Claude Code CLI authentication (SDK mode only)
      - hkcc-claude:/home/claude/.claude

volumes:
  hkcc-claude:

OAuth-only deployment (smaller image, no SDK mode):

version: "3.8"

services:
  hkcc:
    image: huakunshen/hkcc:oauth # Uses OAuth-only image (smaller)
    container_name: hkcc-oauth-proxy
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - HOST=0.0.0.0
      - PORT=3000
      - TURSO_CONNECTION_URL=libsql://your-db.turso.io
      - TURSO_AUTH_TOKEN=your-auth-token

Using local SQLite database (no external database needed):

version: "3.8"

services:
  hkcc:
    image: huakunshen/hkcc:latest
    container_name: hkcc-proxy
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - HOST=0.0.0.0
      - PORT=3000
      # No TURSO variables = uses local SQLite at ./data/hkcc.db
      # Optional: Custom database path
      # - SQLITE_DATABASE_PATH=/app/data/hkcc.db
    volumes:
      # Persist local SQLite database
      - hkcc-data:/app/data
      # Persist Claude Code CLI authentication (SDK mode)
      - hkcc-claude:/home/claude/.claude

volumes:
  hkcc-data:
  hkcc-claude:

Compiled binary with faster startup (production-optimized):

version: "3.8"

services:
  hkcc:
    image: huakunshen/hkcc:compiled # Native binary, no Bun runtime
    container_name: hkcc-compiled
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - HOST=0.0.0.0
      - PORT=3000
      - TURSO_CONNECTION_URL=libsql://your-db.turso.io
      - TURSO_AUTH_TOKEN=your-auth-token
    volumes:
      - hkcc-claude:/home/claude/.claude

volumes:
  hkcc-claude:

Using environment file for secrets:

Create a .env file (git-ignored):

# .env
TURSO_CONNECTION_URL=libsql://your-db.turso.io
TURSO_AUTH_TOKEN=your-auth-token
HKCC_REGISTRATION_ENABLED=false

Update docker-compose.yml to use it:

services:
  hkcc:
    image: huakunshen/hkcc:latest
    container_name: hkcc-proxy
    restart: unless-stopped
    ports:
      - "3000:3000"
    env_file:
      - .env
    volumes:
      - hkcc-claude:/home/claude/.claude

volumes:
  hkcc-claude:

Deploy with Docker Compose:

# Start the service
docker compose up -d

# View logs
docker compose logs -f

# Stop the service
docker compose down

# Stop and remove volumes (WARNING: deletes data)
docker compose down -v

# Rebuild with local changes
docker compose up -d --build

Key considerations:

Image VariantSDK ModeOAuth ModeVolume NeededBest Use Case
hkcc:latest/home/claude/.claudeFull features, development
hkcc:oauthOAuth-only, smaller image
hkcc:compiled/home/claude/.claudeProduction, faster startup
hkcc:compiled-oauthOAuth-only, production

Database options:

  • Turso (cloud): Set TURSO_CONNECTION_URL and TURSO_AUTH_TOKEN - Best for production, multi-instance setups
  • Local SQLite: Don't set Turso variables - Automatically uses /app/data/hkcc.db - Best for single-instance, development

API Endpoints

Health & Status

curl http://127.0.0.1:3000/health
curl http://127.0.0.1:3000/oauth/status

SDK Mode (/sdk/*) - Requires Claude Code CLI

# Anthropic Messages API
curl -X POST http://127.0.0.1:3000/sdk/anthropic/v1/messages \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-4-5-20250929","max_tokens":1024,"messages":[{"role":"user","content":"Hello!"}]}'

# OpenAI Chat Completions API
curl -X POST http://127.0.0.1:3000/sdk/openai/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4","messages":[{"role":"user","content":"Hello!"}]}'

OAuth Mode (/api/*) - Requires OAuth Authentication

# Anthropic Messages API
curl -X POST http://127.0.0.1:3000/api/anthropic/v1/messages \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-4-5-20250929","max_tokens":1024,"messages":[{"role":"user","content":"Hello!"}]}'

# OpenAI Chat Completions API
curl -X POST http://127.0.0.1:3000/api/openai/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4","messages":[{"role":"user","content":"Hello!"}]}'

Model Mapping

OpenAI ModelClaude Model
gpt-4, gpt-4-turbo, gpt-4oclaude-sonnet-4-5-20250929
gpt-3.5-turboclaude-haiku-3-5-20241022

Database Setup (Required)

The server stores user accounts, OAuth credentials, and API keys in a database. Both cloud (Turso) and local SQLite databases are supported.

The server automatically detects which database to use:

  • If TURSO_CONNECTION_URL and TURSO_AUTH_TOKEN are set → uses Turso (cloud)
  • Otherwise → uses local SQLite at ./data/hkcc.db

For new users, no configuration is needed - the server will automatically use local SQLite.

Local SQLite (Default)

# No configuration needed - uses ./data/hkcc.db by default
bun dev

To customize the database file location:

SQLITE_DATABASE_PATH=./custom/path/db.sqlite

Turso (Cloud Database)

Set the database environment variables in .env:

TURSO_CONNECTION_URL=libsql://your-db.turso.io
TURSO_AUTH_TOKEN=your-auth-token

Manual Override

Override auto-detection with:

DB_DRIVER=turso          # Force Turso
# or
DB_DRIVER=bun-sqlite     # Force local SQLite

Migrations

Migrations run automatically on server startup. For manual migration management:

bun drizzle-kit push     # Apply schema to database
bun drizzle-kit studio   # Open database GUI

User Authentication

# Register
curl -X POST http://127.0.0.1:3000/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "password": "password123", "username": "myuser"}'

# Login
curl -X POST http://127.0.0.1:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "password": "password123"}'

# Get current user
curl http://127.0.0.1:3000/auth/me -b "hkcc_session=SESSION_TOKEN"

# Logout
curl -X POST http://127.0.0.1:3000/auth/logout -b "hkcc_session=SESSION_TOKEN"

Registration can be disabled by setting HKCC_REGISTRATION_ENABLED=false after creating your account.

OAuth Authentication

After logging in, authenticate with OAuth providers via the dashboard or API:

# Get Anthropic authorization URL
curl http://127.0.0.1:3000/oauth/anthropic/login?mode=max

# Get OpenAI/Codex authorization URL
curl http://127.0.0.1:3000/oauth/openai/login

# Check OAuth status
curl http://127.0.0.1:3000/oauth/anthropic/status
curl http://127.0.0.1:3000/oauth/openai/status

PKCE Authentication Flow

The server uses OAuth 2.0 with PKCE (Proof Key for Code Exchange) for secure authentication:

sequenceDiagram
    participant User
    participant Browser
    participant Proxy as HKCC Proxy
    participant Claude as claude.ai

    User->>Browser: Click "Login with Claude"
    Browser->>Proxy: GET /oauth/anthropic/login
    Proxy->>Proxy: Generate PKCE<br/>code_verifier<br/>code_challenge
    Proxy-->>Browser: Authorization URL + state

    Browser->>Claude: Redirect to authorization URL
    Claude->>User: Show consent screen
    User->>Claude: Approve access
    Claude-->>Browser: Redirect with auth code

    Browser->>Proxy: GET /oauth/anthropic/callback?code=xxx
    Proxy->>Claude: POST /oauth/token<br/>(code + verifier)
    Claude-->>Proxy: access_token + refresh_token
    Proxy->>Proxy: Store credentials in database
    Proxy-->>Browser: Redirect to dashboard
    Browser->>User: Authentication complete

Security features:

  • PKCE prevents authorization code interception attacks
  • State parameter prevents CSRF attacks
  • Tokens stored securely in database with user isolation
  • Automatic token refresh before expiration

API Access Modes

ModeAuthenticationCredentials Used
Dashboard (browser)Session cookie (hkcc_session)User's database credentials
Per-user API keyhkcc_sk_xxx in headerUser's database credentials

Per-User API Keys

Each registered user can create up to 5 personal API keys for external applications like Cherry Studio, Cursor, or custom scripts.

Create an API key (via dashboard or API):

# Create key via API (requires session cookie)
curl -X POST http://127.0.0.1:3000/auth/api-keys \
  -H "Content-Type: application/json" \
  -b "hkcc_session=SESSION_TOKEN" \
  -d '{"name": "Cherry Studio"}'

# Response includes the full key (shown only once):
# {"success":true,"key":"hkcc_sk_a1b2c3d4e5f6...","apiKey":{"id":1,"keyPrefix":"hkcc_sk_a1b2...","name":"Cherry Studio"}}

Use the API key in external clients:

curl -X POST http://127.0.0.1:3000/api/anthropic/v1/messages \
  -H "x-api-key: hkcc_sk_a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-4-5-20250929","max_tokens":100,"messages":[{"role":"user","content":"Hello"}]}'

# Or use Authorization header:
curl -X POST http://127.0.0.1:3000/api/anthropic/v1/messages \
  -H "Authorization: Bearer hkcc_sk_a1b2c3d4e5f6..." \
  ...

Manage API keys:

# List keys
curl http://127.0.0.1:3000/auth/api-keys -b "hkcc_session=SESSION_TOKEN"

# Delete a key
curl -X DELETE http://127.0.0.1:3000/auth/api-keys/1 -b "hkcc_session=SESSION_TOKEN"

Token Refresh

A cron job runs every hour to automatically refresh tokens expiring within 60 minutes. Claude access tokens have an 8-hour TTL (480 minutes).

SDK Integration

Vercel AI SDK

import { createAnthropic } from "@ai-sdk/anthropic";
import { generateText } from "ai";

const anthropic = createAnthropic({
  baseURL: "http://127.0.0.1:3000/api/anthropic", // OAuth mode
  apiKey: "hkcc_sk_your_personal_api_key", // Per-user API key
});

const { text } = await generateText({
  model: anthropic("claude-sonnet-4-5-20250929"),
  prompt: "Hello!",
});

Anthropic SDK

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  baseURL: "http://127.0.0.1:3000/api/anthropic", // OAuth mode
  apiKey: "hkcc_sk_your_personal_api_key", // Per-user API key
});

const message = await client.messages.create({
  model: "claude-sonnet-4-5-20250929",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello!" }],
});

OpenAI SDK

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "http://127.0.0.1:3000/api/anthropic/openai/v1", // OAuth mode with OpenAI format
  apiKey: "hkcc_sk_your_personal_api_key", // Per-user API key
});

const completion = await client.chat.completions.create({
  model: "claude-sonnet-4-5-20250929",
  messages: [{ role: "user", content: "Hello!" }],
});

Environment Variables

# Server Configuration
PORT=3000                        # Server port (default: 3000)
HOST=127.0.0.1                   # Server host (default: 127.0.0.1)

# Database (Required)
TURSO_CONNECTION_URL=libsql://your-db.turso.io
TURSO_AUTH_TOKEN=your-auth-token

# Registration Control
HKCC_REGISTRATION_ENABLED=true   # Set to "false" to disable new user registration

Development

bun run dev          # Run with hot reload
bun run build.ts     # Build server and frontend
bun test             # Run tests
bun run format       # Format code

Project Structure

src/
├── index.ts           # Server entry point (development)
├── app.ts             # Elysia app factory
├── auth/              # OAuth & user authentication, API key management
├── db/                # Drizzle ORM schema and database connection
├── cron/              # Scheduled jobs (token refresh)
├── proxy/             # SDK and OAuth proxy implementations
├── routes/            # OAuth and auth endpoints
├── adapters/          # Request/response format adapters
├── transform/         # Request/response transformations
├── middleware/        # API key validation, error handling
├── mcp-bridge/        # MCP tool bridging for client tools
└── utils/             # Utilities (Claude Code detection)

bin/
└── hkcc.ts            # CLI entry point (npx/bunx)

public/                # Frontend source (React + Tailwind)
├── index.tsx          # React entry point
└── pages/             # Dashboard pages

build.ts               # Build script for server, CLI, and frontend

See TECHNICAL.md for architecture details.

Tech Stack

  • Runtime: Bun (>=1.0.0) - Required (uses bun:sqlite)
  • Framework: Elysia
  • Frontend: React, TanStack Router, Tailwind CSS
  • Type-Safe Client: Eden
  • Database: Turso (libSQL) with Drizzle ORM
  • Validation: Zod + Elysia's t.Object

Docker Build

# Build and push with timestamp tags for all variants
DATE_TAG=$(date +%Y-%m-%d-%H-%M-%S)

# Default (latest + oauth + compiled + compiled-oauth)
docker buildx build --push --platform linux/amd64,linux/arm64 \
  -t huakunshen/hkcc:latest \
  -t huakunshen/hkcc:latest-${DATE_TAG} \
  -f Dockerfile .

docker buildx build --push --platform linux/amd64,linux/arm64 \
  -t huakunshen/hkcc:oauth \
  -t huakunshen/hkcc:oauth-${DATE_TAG} \
  -f Dockerfile.oauth .

docker buildx build --push --platform linux/amd64,linux/arm64 \
  -t huakunshen/hkcc:compiled \
  -t huakunshen/hkcc:compiled-${DATE_TAG} \
  -f Dockerfile.compiled .

docker buildx build --push --platform linux/amd64,linux/arm64 \
  -t huakunshen/hkcc:compiled-oauth \
  -t huakunshen/hkcc:compiled-oauth-${DATE_TAG} \
  -f Dockerfile.compiled-oauth .

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.

Keywords

claude

FAQs

Package last updated on 01 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts