# cheapo A CLI that finds all those free games from all those game stores. And, if you want, posts them to a Chatto channel. Free games CLI in Go — lists current free game offers (Epic Games Store, Steam) and can use `watch` to wait for **new** free games. Inspired by / reference: [free-games-claimer](https://github.com/DoSpamu/free-games-claimer) (a fork of [vogler/free-games-claimer](https://github.com/vogler/free-games-claimer)) and [free-games-notifier](https://github.com/jaixmario/free-games-notifier). Unlike the reference projects, we need **no browser and no login**: we read the public store endpoints directly (details: `AGENTS.md`). Claiming the games is not part of this tool — it only detects and reports them. ## Install / build ```bash go build -o bin/cheapo ./cmd/cheapo ``` Prerequisites: Go ≥ 1.27. For linting: `gopls` (`go install golang.org/x/tools/gopls@latest`), formatting with `gofmt` (details: `AGENTS.md`). ## Usage ```bash # Games free right now (Germany, German) cheapo list # As JSON (e.g. for further processing / bot) cheapo list --json # Other region / locale cheapo list --country AT --locale en-US # Wait for new free games (polling every 15 min, baseline = current state) cheapo watch # Different interval, single check cheapo watch --interval 5m cheapo watch --once # Other stores / upcoming free games (preview, Epic only) cheapo list --store steam cheapo list --store all cheapo list --upcoming ``` Example output: ``` 🎮 Monument Valley By: Netflix, Inc. Instead of: 6.99 € Free until: 02.11.2026 17:00 (CET) https://store.epicgames.com/en-US/p/monument-valley-1d99d3 ``` `cheapo watch` is suitable as a long runner for a systemd service or cron/timer; every newly detected game is reported on stderr as soon as a poll finds it. ## Roadmap / MCP (later) Planned next step: expose the tools (`list`, `watch`) as an **MCP server**, so they can be used e.g. by Hermes or other MCP clients. Planned: - Transport: stdio (classic) — one binary `cheapo mcp` - Tools: `list_free_games` (immediately) and `check_now` (single poll, for cron/eventing) - The watch logic (`internal/watch`) stays reusable; the MCP server only wraps it. - **Not implemented yet** — deliberately a second step after the CLI stabilizes. ### More platforms - **Steam** ✅ done: `cheapo list --store steam` or `--store all`. Free-to-keep via HTML scrape of `store.steampowered.com/search/?maxprice=free&specials=1`, free weekend via `store.steampowered.com/api/featuredcategories/` (details: `AGENTS.md`). With `--store` you choose `epic`, `steam` or `all` (default). - **Epic "upcoming"** ✅ done: `cheapo list --upcoming` shows announced upcoming free promotions (Epic only; Steam ignores the flag). ## Architecture ``` cmd/cheapo/ Cobra CLI (list, watch; --store epic|steam|all) internal/game/ Provider-agnostic game type + provider interface internal/epic/ Epic client (freeGamesPromotions, public JSON endpoint) internal/steam/ Steam client (search scrape + featuredcategories API) internal/watch/ Polling/eventing across all providers: reports only new games ``` ## Reference: how the original project works The reference project (vogler/free-games-claimer) automates a real browser with Playwright: login (session cookies, 2FA, captcha handling), detecting the "Free Now" tiles on the store page and clicking through the purchase process. The free games **info** comes from the same backend JSON that we query directly — details and sources in [AGENTS.md](AGENTS.md).