将一个或多个 Claude (Pro/Max) 订阅账号,通过 Anthropic 兼容的 /v1/messages 端点,
以可审计、可观测、带配额分发(SK)的方式对外提供服务。后端基于 Encore.ts,
前端基于 TanStack Start。
- 管理员:第一个注册的用户自动成为管理员。
- SK(API Key)分发:管理员/用户创建多个 SK,客户端用 SK 调用网关;每个 SK 的请求被审计。
- Claude OAuth 账号池:两种授权模式,token 过期自动刷新,多账号轮询(最近最少使用)。
- 手动浏览器授权:后台生成 PKCE 授权 URL → 用户登录授权 → 粘贴回调 code 完成。
- sessionKey 自动授权:粘贴 claude.ai 的
sessionKeycookie,后台自动完成授权。
- 也支持直接添加 Anthropic API Key 账号。
- 反向代理:
POST /v1/messages透传到api.anthropic.com,注入 Claude Code 伪装头与 system 提示块,SSE 流式原样透传,解析 token 用量写入审计日志。 - 可观测性:落 Postgres 审计表 + 复用 Encore 内置 tracing(本地 dev dashboard)。
db/ 共享 Postgres + drizzle schema(users / api_keys / accounts / oauth_sessions / audit_logs)
auth/ 注册/登录、JWT 鉴权 handler + gateway、/auth/me
keys/ SK 的增删改查 + 反代用的 SK 校验
accounts/ Claude OAuth 两种模式、token 刷新、账号池选择
proxy/ /v1/messages 反代核心、上游头改写、SSE 透传、审计、/audit 查询
frontend/ TanStack Start SSR + Radix UI + Tailwind + Vite(独立 package、生产含 Node 启动器)
deploy/ 自托管:docker-compose、infra-config、一键脚本、迁移、前后端 Dockerfile
# 1. 设置本地 JWT 密钥(已含 .secrets.local.cue 示例)
# 2. 启动后端(需要 Docker 提供本地 Postgres)
encore run
# 健康检查
curl http://localhost:4000/healthz
# 前端
cd frontend && npm install --legacy-peer-deps && npm run dev # http://localhost:3000修改 db/schema.ts 后,生成迁移即可(Encore 在启动时自动应用):
npm run db:generate # drizzle-kit generate -> db/migrations/*.sqlnpx vitest run # 后端单元测试(OAuth PKCE、上游头、用量解析)
cd frontend && npm run typecheck && npm run build需要 docker 与 encore CLI。docker compose up 会一并构建并启动:
Postgres → 一次性迁移 → 后端服务(app)→ 前端 SSR(frontend)。脚本负责:
生成密钥/端口/后端地址 → 生成迁移 → 构建 Encore 后端镜像 → 拉起整套栈。
./deploy/selfhost.sh # 构建并启动整套
./deploy/selfhost.sh logs # 跟随 app + frontend 日志
./deploy/selfhost.sh down # 停止
# 默认端口:后端 8080、前端 3000
# 首次启动后访问前端 http://localhost:3000,在 /login 注册,第一个账号即为管理员。
curl http://localhost:8080/healthz迁移与应用解耦:deploy/migrate.mjs(drizzle 迁移器)在一次性 migrate 容器中执行,
完成后 app 容器才启动,避免自托管镜像不自动迁移的问题。
前端是 TanStack Start SSR,生产由 frontend/server-entry.mjs(Node 原生 server,
零额外依赖)托管,需 Node 22+ 运行时(@tanstack/react-start 引擎要求)。
浏览器要访问的后端地址通过 .env 的 BACKEND_URL 在运行期注入到页面
(window.__BACKEND_URL__),改地址无需重新构建镜像,重启 frontend 容器即可。
注意:
BACKEND_URL是浏览器访问后端的地址,必须是宿主/公网可达地址 (如http://localhost:8080或https://gateway.example.com),不能用 compose 服务名app——那只在容器网络内解析。
远程/生产部署:编辑 deploy/.env 把 BACKEND_URL 改成对外地址,然后:
# 改 deploy/.env 后,仅重启前端使新地址生效(无需 rebuild)
docker compose -f deploy/docker-compose.yml --env-file deploy/.env up -d frontenddeploy/.env 可调端口:APP_PORT(后端)、FRONTEND_PORT(前端)。
生产建议在前端 + 后端前再挂 Nginx/Caddy 做统一域名与 TLS 终止(仓库未内置)。
将 Claude Code / 任意 Anthropic 客户端指向网关,并使用网关签发的 SK:
export ANTHROPIC_BASE_URL=http://your-host:8080
export ANTHROPIC_API_KEY=sk-... # 网关签发的 SKOAuth 授权(token 交换/刷新)或反代上游返回:
{ "error": { "type": "forbidden", "message": "Request not allowed" } }这是 Anthropic 对服务器出口 IP 的地域/风控封锁,非代码问题——api.anthropic.com、
console.anthropic.com、claude.ai 对被封 IP 的所有请求(含无凭据的 /v1/messages 与
根路径)统一返回该 403。常见于非受支持地区或被标记的 VPS IP。
修复:让网关的出站流量经由受支持地区的 HTTP(S) 代理。设置环境变量 UPSTREAM_PROXY,
所有对上游(Anthropic / claude.ai)的请求会自动经此代理:
# 本地 encore run
export UPSTREAM_PROXY=http://user:pass@your-overseas-proxy:8080
# 自托管 compose:写入 deploy/.env
echo 'UPSTREAM_PROXY=http://user:pass@your-overseas-proxy:8080' >> deploy/.env未设置时不走代理(行为不变)。
本项目仅供技术学习与研究。使用订阅账号通过第三方网关转发可能违反 Anthropic 服务条款, 由此产生的账号风险与一切后果由使用者自行承担。