← Discover MCPs and Agents
f
MCPAI & MLGitHub

freebucks-proxy

Multi-account OpenAI-compatible gateway for coding models. Pooled keys, session lifecycle, TLS stealth, embedded admin dashboard. No ads, no CLI, just /v1/chat/completions.

Links

README

From the repo.

freebucks-proxy

freebucks-proxy is a Go wire gateway in front of the upstream service: pooled multi-account OpenAI-compatible and Anthropic-compatible endpoints, an embedded Svelte dashboard, optional browser-like TLS stealth, and automatic session lifecycle.

What it is

  • Speaks OpenAI chat (POST /v1/chat/completions, GET /v1/models) and an Anthropic-compatible layer, then translates to the upstream wire protocol.
  • Runs in pooled, bridge, or hybrid mode (EffectiveMode):
    • PooledAUTH_TOKENS set + BRIDGE_ENABLED=0; pool only.
    • BridgeAUTH_TOKENS empty; each request carries its own token.
    • Hybrid (default with AUTH_TOKENS) — API_KEYS credential uses the pool, any other credential relays upstream as a bridge token.
  • Dashboard at /admin (Svelte SPA embedded in the binary).
  • Credit metering follows the wire prices map (upstream credits, wire fields freebucks*): charged once per session-hour at session start, refunded on early DELETE, and refilled at the daily reset the server advertises (resetTimeZone/resetAt in the session payload — the account's own local midnight; Pacific midnight only on servers that omit the zone). The proxy's own counters (per-day requests, spend buckets, IP re-admit caps) keep bucketing on the Pacific day (pool/spend.go:bucketStart).

Quickstart

cp .env.example .env   # then edit: AUTH_TOKENS, ADMIN_TOKEN, ...
task build             # frontend bundle + gateway binary (output in bin/)
task dev               # run the gateway from source

Both tasks are defined in Taskfile.yml. With plain Go instead of a Task runner, go build ./backend/... compiles everything and the gateway's main package lives under backend/cmd/.

Run from GHCR (release image, no local build):

cp .env.example .env   # then edit: AUTH_TOKENS, ADMIN_TOKEN, ...
export VERSION="$(gh release view --json tagName -q .tagName)"
docker compose pull
docker compose up -d

That resolves the newest release tag (prereleases excluded); pin VERSION to it for a reproducible deploy, or leave VERSION unset to follow the latest image. gh resolves the repository from the checkout — pass --repo <owner>/<name> if you run it elsewhere. Verify GET /healthz → 200, and note /admin sits behind the login gate (redirects to /admin/login).

Then:

  • GET http://localhost:3457/healthz → 200
  • GET http://localhost:3457/v1/models → live model list
  • http://localhost:3457/admin → dashboard

Defaults that matter (.env.example): SAFE_MODE=true (anti-ban preset), COST_MODE=free. The per-day/per-minute request caps are gone — upstream quota and 429s are the enforcement — and per-IP rate limiting is off by default (RATE_LIMIT_PER_IP=0; set it and RATE_LIMIT_BURST to enable).

Configuration persistence: the first boot imports the effective config (process env wins over .env over defaults) into the dashboard DB (DB_PATH, a SQLite file under data/, mode 0600) as config: overlay rows plus a config:migrated_env_v1 marker — later boots are no-ops via the marker. The DB is then the persisted home the dashboard saves write to, secrets included (AUTH_TOKENS, ADMIN_TOKEN, API_KEYS, WEBHOOK_URL rows); keep its 0600 mode on copies/backups. Explicit process env still wins at runtime, so a migrated row never overrides the environment.

Update safety (read before every recreate)

Two-path layout: the live store is the DB_PATH file on the db_data named volume (compose pins it under /app/data — an overlay row can never repoint the open file), while the host checkout bind (.:/app/state, the working directory) holds .env, logs, and the pre-volume bind DB under ./data/. A fresh volume auto-imports that bind DB on first boot — display history plus the full operator state (settings overlay with secrets, pages, sessions, tokens, pool blobs), per-table, idempotent, secrets as opaque DB values — then later boots are strict no-ops. Legacy files are never deleted. Never copy a live DB with plain cp of the .db/-wal/-shm trio; stop first or use the backup script.

Every update runs three commands (any trip = roll back, never cut traffic):

docker compose stop                           # whole stack, incl. the optional https front
scripts/backup-state.sh                      # snapshot + count manifest
docker compose up -d --build                  # recreate on the same volume
ADMIN_TOKEN="$ADMIN_TOKEN" scripts/verify-state.sh   # healthz + 401 probe + migrate.noop + manifest counts

The gate requires /healthz 200, a wrong-token login 401, a strict no-op boot (migrate.fresh=false, migrate.noop=true, applied=[]), and live row counts matching the backup manifest (operator tables exact, pool_state anti-stranding, history grow-only). First-ever volume adoption boots fresh=true while it carries the bind DB — confirm the carried legacy state log line against the manifest, restart once, then the gate goes green.

One-time: the freebucks-proxy rename

The project was renamed from freebuff-proxy (repository, binary, compose service, container, image). Two things need care exactly once:

git remote set-url origin https://github.com/trefeon/freebucks-proxy.git
docker compose down --remove-orphans   # clears the pre-rename container
  • --remove-orphans matters: the service was renamed, so the old container is no longer part of the stack — leaving it running means two gateways sharing one account pool, which burns quota twice and supersedes sessions.
  • The image path follows the repository name (ghcr.io/trefeon/freebucks-proxy), so it exists only once a release is published after the rename. Until then, pin VERSION to a tag from the previous image path or wait for that release.
  • The DB filename and session-state filename are deliberately unchanged (DB_PATH, SESSION_STATE_FILE): the live volume keeps its store, and pointing either at a new name on an existing volume would open an empty DB.
  • Installed as a background service? Its unit/task name and install paths changed too. Uninstall the old one before installing the new: run the old binary with -uninstall-service (pre-rename systemd unit freebuff-proxy.service, launchd com.freebuff-proxy, or the freebuff-proxy scheduled task), then move your .env from the old config directory to the new one — the renamed installer writes freebucks-proxy paths, so the old service would otherwise keep serving from the same account pool while the new one starts empty.

Layout

  • backend/ — gateway source.
  • frontend/ — dashboard SPA source.
  • scripts/ — upstream sync / drift tooling, plus the client tool-name corpus generator (extract-tool-calls.sh).
  • docs/ — client-compatibility recipes, upstream CLI notes, and architecture decisions (docs/decisions/).

Contributing

Protected main: branch → PR → green CI → squash merge, Conventional Commits. See AGENTS.md for the full operating guide. Never commit secrets.

Collected info

  • 296 stars
  • 64 forks
  • Language: Go
  • Source updated: 9/24/2026

Config for your environment

Replace {MCP_ENDPOINT_URL} with this MCP’s endpoint URL (from its repo or docs above). No API key — you connect directly.

Tool

OS

Config file: ~/.cursor/mcp.json

{
  "mcpServers": {
    "mcp-server": {
      "url": "{MCP_ENDPOINT_URL}"
    }
  }
}

Paste into mcpServers in the config file. Restart Cursor after saving.

If this MCP is also published on mcpchannel.ai, you can subscribe from Browse and use the gateway config there instead.