Somewhere in your ~/.claude directory, a hero has been questing for weeks.
Every prompt you typed was a spell. Every 3 AM debugging session, a night march. Every
compaction survived, a memory reforged. TokenQuest reads that history — entirely on your
machine — and hands you the character sheet you already earned: level, eight attributes,
a class, a chronotype race, gear, a spellbook, and a place in
the Halls of Heroes.
No account. No email. Nothing to watch — it plays itself while you work. The first thing it does is replay your history: “you're already Level 34.”
The short version of how this works
- One file. The whole agent is tq.py — plain, readable, stdlib-only Python. Read it before you run it; that's the intended experience.
- Your data stays home. The game runs on
127.0.0.1, derived from your own transcripts. Unless you opt into the mirror (or link machines), the only thing that ever leaves is a ~600-byte standing for the leaderboard — fourteen labeled measurements you can inspect first with--dry-run(sample below); the opt-in mirror adds your scrubbed display feed, and opt-in machine linking exchanges same-scrubbed tally sheets — both spelled out further down. - Your history is kept from day one. Your starting level counts the transcripts
still on your disk — Claude Code prunes them after ~30 days, so long-time users may
start lower than they've truly earned. From your first run, tq.py keeps its own local
ledger that pruning can't touch, and the Halls remember your high-water mark: from
here on, progress is never lost. (Tip: set
cleanupPeriodDaysin your Claude Code settings — e.g.365— so future transcripts stick around longer; tq.py reminds you if your history window looks short.) - The road ahead stays dark. World content drips from the server as your hero advances — no spoilers on your disk, just like the .exe days.
- The display code can't phone home. The game's panel is display-only HTML,
fetched once and changed only when you run
--update— never silently. (World data — the content drip — does refresh at each--playstart; the no-exfil guarantee rests on the browser-enforced wall below, not on code immutability.) And tq.py serves it behind a Content-Security-Policy your browser enforces: the panel can talk only to your own127.0.0.1server. Even a hostile panel couldn't silently send your data anywhere — that's a wall, not a promise (tq.py's CSP comment states the wall's two honest limits, too). - Everything is reversible. The script never installs cron, never self-updates,
never needs sudo. Uninstall = delete the file and
~/.tokenquest.
Do it yourself (the four commands)
curl -fsSL https://questful.online/get/tq.py -o tq.py python3 tq.py --dry-run # see what a push would send (sends nothing) python3 tq.py --register --handle YourHeroName # claim your hero (prints your recovery passphrase ONCE) python3 tq.py --play # your game, at http://127.0.0.1:8123 — pushes every 5 min while it runs # on Windows: replace python3 with py -3
The mirror, plainly (--mirror on —
optional, off by default): normally your game exists only on your machine. The mirror asks us
to host a copy of your living panel at a share link, so you — or anyone you hand the link —
can watch your hero from any browser, phone included, even while your machine is off. It also
acts as an off-site backup of your history. The trade: each push then uploads your panel's
display feed too, scrubbed first (details below) — though still carrying your timezone and
your first-seen date: to anyone holding the link it is your
daily activity calendar. The link ends in a rotatable watch
key — a view key, not a credential: --mirror rotate invalidates an escaped
link, --mirror off deletes everything we stored.
Keeping it running: --play is a
plain foreground process — it stops when your terminal closes or your SSH session ends. Run it
under tmux (or nohup python3 tq.py --play &) to keep the local
dashboard up; the printed cron line keeps your hero fresh on the board either way. And if what
you really want is “see my game from anywhere, no process needed” — that is exactly what the
mirror is for. Runs happily on a VPS — if you use Claude Code over SSH, run it there;
VS Code forwards the port automatically. One caveat for shared machines: the local
server trusts the local machine — any account on the same box can read your
unscrubbed feed, project names included, so run it where you're the only user, or start it
with --local-key yourkey: then every request needs ?token=yourkey
(the printed URL includes it). --reclaim brings your hero to a new machine.
Windows & locked-down networks: on Windows,
python3 opens the Microsoft Store — use py -3 (or
python); tq.py's own printouts use the right command for your OS. If the
download fails oddly, or --register/--push dies with a certificate
error on a corporate network, your proxy is likely re-signing TLS — tq.py will say so, and
the one-line fix is NO_PROXY=questful.online (or download tq.py in your browser
instead of curl). Some corporate filters also block this domain as “newly registered” — that
needs an IT allow-list; nothing on your end can fix it.
One hero per project — and the party camp: by
default all your Claude work feeds one hero. If you'd rather split it,
--profile work --projects "client*" makes a named sub-hero fed by only the
projects that match (it can register on the board as its own hero, under any name you like —
tip: not the client's). Once you have profiles or camp members, --play opens on
the party camp: all your heroes around one campfire, and the fire itself is the
party's number — it grows with your heroes' summed adventures and never shrinks. Each hero's
own world is one click away. Play on several machines? Two stories, pick per machine:
--link folds another machine into this hero — one character, the sum of
all your machines, on the board and on every machine's own panel (mint a pairing code with
--link-code on a set-up machine, run --link <code> on the new
one; your passphrase never travels). Or, for machines — or people — you want visible as
separate heroes, register a hero on each, then
--camp add tokens/YourOtherHero seats the others at this box's
fire — your whole party, one camp. The camp page itself talks only to your own 127.0.0.1
server; for camp members, your agent reads their public Hall standings from the board
(the same numbers /halls shows), only while the page is open. Curate
with --camp add / remove / list; it's a plain JSON file
(~/.tokenquest/camp.json) if you'd rather edit by hand.
What leaves your machine — the whole payload
This is a real --dry-run output, in full. Fourteen aggregate measurements, a
motto, an avatar. No project names, no file paths, no prompt text, no daily series, no
histograms. The server derives your stats from these — the formulas live in one place, so
the agent on your disk never needs updating.
{
"measurements": {
"user_prompts": 821, "total_active_min": 7187,
"avg_session_min": 37, "active_days": 24,
"corpus_days": 25, "tokens_total": 3428299977,
"tokens_io": 14294654, "user_words": 30004,
"user_chars_typed": 171303, "compactions": 0,
"agent_launches": 8, "workflow_uses": 0,
"peak_day_io_tokens": 1481071, "cost_io_usd": 344.97
},
"motto": "120h adventured · 14.3M tokens slain",
"avatar": "⚔"
}
The opt-in mirror sends more (your panel's display feed) — scrubbed first:
project names, your --server machine label, the weekday-hour matrix and
unrecognized MCP tool names never leave your box
(your timezone and first-seen date stay in — the panel needs
them to draw your days). --dry-run summarizes that payload too when the mirror
is on: its size, what was scrubbed, what's kept. Off by default.
Opt-in machine linking (--link)
sends the same class of extra: each linked machine's push uploads its per-day tally
sheet — exactly the mirror's scrubbed shape, never transcripts, prompts, code, or project
names — and downloads its siblings', so every machine (and the board, and the mirror if on)
shows the one summed hero. Sheets stay private to your hero's own machines — device-token
read, never published. --dry-run notes the exchange when linked;
--devices list / remove manages machines, removal is instant.
Fair warning about the paste-a-prompt method
Pasting instructions into your agent is exactly the pattern security guidance tells you to distrust — so distrust it: the message below tells your Claude to download tq.py, audit it, and explain it to you before anything runs, and to stop if anything looks off. The top of tq.py carries THE TRUST MAP — an exhaustive list of every network request the script can make — written to be checked against the code, not taken on faith. Auditing us first isn't paranoia here; it's the intended on-ramp. If you'd rather stay hands-on, the four commands above do the same thing.
TokenQuest is part of Questful — every real-world signal deserves a hero.