Privacy & Transparency
We see how much you code.
Never what you code.
This page lists every single thing BuddyBrawl installs, collects, and stores — in plain language, including what would happen in the worst case if we were hacked. If a claim on this page is ever wrong, that's a bug and we'll fix it.
What the installer does
npx buddybrawl init adds exactly three things, all inside your own home folder:
- ▸
~/.buddybrawl/config.json— the sync endpoint URL and a random sync token (a password unique to this install). Section 02 names the endpoint. - ▸
~/.buddybrawl/buddy-sync.mjs— the sync script itself. It's plain JavaScript; you can open it and read every line. - ▸One entry in
~/.claude/settings.json— tells Claude Code to run the sync script when a session ends. Re-running setup replaces that one entry (it prints a line when it does). It only ever touches an entry pointing at the script above — hooks you or another tool put there are left exactly as they are, even if the word "buddy-sync" appears in them.
What this means for you: Nothing system-level, no background services, no admin rights. To remove it: npx buddybrawl uninstall — section 06 covers exactly what that does, and why deleting the folder by hand leaves one thing behind.
Want to see it before it happens? npx buddybrawl init --dry-run prints every file it would write and the hook line it would register, then exits without writing, registering, or sending a single request.
What we collect, and when
Two different servers are involved. npx buddybrawl init fetches your config once from www.buddybrawl.xyz. After that, every session syncs straight to our Supabase Functions endpoint (*.supabase.co — Supabase is our database provider); nothing routes back through buddybrawl.xyz. The exact host is printed when setup finishes and saved in ~/.buddybrawl/config.json, so you can always check where your data goes.
At install time:
- ▸A random install ID (32 hex characters, generated locally — not derived from your hostname, username, or any hardware identifier) and the CLI version. It exists only so a stolen sync token can't be replayed from a different machine. No email and no name are sent at install. Your IP address is visible to the server for that one request, as it is for any web request, and we use it only as a rate-limit counter so nobody can mint thousands of tokens; it isn't stored in our database or tied to your buddy.
- ▸If you are re-running setup over an existing install, a one-way hash of the sync token you're replacing — so we can switch the old one off instead of leaving it working forever. The token itself is never sent here, only the hash.
After each response Claude sends (many times per session, not just when you close it):
- ▸Your git email and name (from
git config) — this is your player identity. The email is sent as-is over HTTPS, because it is what we look your account up by; what we keep is a one-way hash of it, never the email itself. It is not hashed before it leaves your machine — the hashing happens on our side. Your git name becomes your public display name on the leaderboard. - ▸Session stats: how long the session ran, how many tool calls and messages, and Claude Code's internal session ID (an opaque identifier, not linked to anything else).
- ▸The names of the built-in tools you used —
Read,Edit,Bashand the like. These are Claude Code's own tools: a fixed, public list that says nothing about you. Only the names — never the arguments you passed, the commands you ran, or what they returned. - ▸MCP tool names are not sent.They're named by whoever set the server up, and they're often named after a company, a client or an internal system —
mcp__acme_internal__read_secretstells you plenty about the person using it. Each one is replaced on your machine bymcp__plus a salted hash (e.g.mcp__a3f9c1d40b27) before anything is sent. We can see that you used two MCP tools; we cannot see which, and neither could anyone who stole the database. The salt is the same never-transmitted value used for file tokens below, so the same MCP server produces a different hash for every user.
This started with version 1.0.23. Before that, MCP tool names were sent as written — it was disclosed on this page at the time, and it was still more than we needed. The sync hook never updates itself, so if you installed earlier, your machine is still sending them until you runnpx buddybrawl initagain. That re-installs the current hook and changes nothing else about your buddy. - ▸A count of how many distinct files you created or edited — sent as opaque hashes (tokens like
f6a23ce90403f3226), never the file names or folder paths themselves. They exist only so we can count unique files. A file you only read is never counted. Each token is salted with a random value generated at install and kept in~/.buddybrawl/config.json. That salt is never transmitted— it never leaves your machine, so the tokens can't be matched back to a guessed path, or lined up against another user's. (To be exact: it is the salt that stays put, not the whole file. Two other values in it are sent — the sync token, which authenticates you, and the install ID described below.) A very large session sends at most 100 of these tokens and at most 50 tool names, so alongside them we send the total count of distinct files and the total count of distinct tools as plain numbers — otherwise your stats would quietly understate a session that touched more than the cap. - ▸The same random install ID that was generated at setup, re-sent with every sync. It lets us check the sync token is being used from the machine it was issued to, so a copied
config.jsondoesn't work somewhere else. It is the random value described above — not derived from your hostname, username, or any hardware identifier. - ▸Your companion name and identity from
~/.claude.json: its name, species, and your Anthropic user ID (used so your buddy looks the same here as in Claude Code), plus its rarity and whether it is shiny — those last two are computed on your machine from that same user ID, not read out of any file. To find the first three the hook parses~/.claude.jsonin full on your own machine, but they are the only things taken from it, and nothing else in it is sent anywhere: not your conversations, not your settings, not any key. If you have hand-written a~/.buddybrawl/buddy.jsonto override your buddy, those same five values are read from it instead — and only those five. If you are still running an older hook, one that also sent along any stray keys you left in that file, our server has never read or stored them either: all it keeps is the name, species and user ID it actually uses.
What this means for you: Is this dangerous? Honestly: not very. Your git email is already stamped on every commit you push to a public repo — most developers' is public knowledge. And file and folder names never leave your machine: they're hashed to opaque tokens before anything is sent, so our database can't reveal what your projects are called or how they're laid out — only how often you code.
What we never collect
- ▸Your source code or the contents of any file.
- ▸Your prompts or conversations with Claude.
- ▸Your API keys, tokens, or credentials of any kind.
- ▸Your GitHub password — sign-in is OAuth, GitHub never shows it to us.
What this means for you: This isn't just policy — it's enforced in the sync script itself (which you can read on your own disk): it reads your Claude Code session transcript locally only to count tool calls and messages, and to hash each distinct file changed — those counts and hashed per-file tokens are what leave your machine, never the transcript itself. File paths are hashed to opaque tokens before they're sent, and input sizes are capped. There is no code path that reads your project files.
Sign-in & cookies
- ▸Signing in on the web uses GitHub OAuth. We store your GitHub username, display name, and avatar — the same things anyone can already see on your GitHub profile. These appear publicly on the leaderboard.
- ▸We set only login-session cookies (from Supabase, our database provider). Their one job is keeping you signed in.
- ▸Zero analytics, zero trackers, zero ads. No Google Analytics, no pixels, no fingerprinting scripts. We don't follow you around the internet — we couldn't even if we wanted to.
What this means for you: If you never sign in on the web, we never see your GitHub account at all — syncing and battling stats work from the hook alone.
If BuddyBrawl were compromised
Worst case — an attacker gets full access to our database. Here is the complete, honest inventory of what they would and wouldn't have:
They would see:
- ▸Player display names (usually your git name) and hashed identifiers derived from git emails — not the emails themselves; those are never stored.
- ▸Session stats (durations, counts) and opaque file-count hashes — no readable file or folder names.
- ▸GitHub usernames and avatars (already public on GitHub).
- ▸Game data: buddies, items, battle history, ELO.
They could not get:
- ▸Your source code or prompts — they were never sent, so they can't leak.
- ▸Your GitHub password — we never had it (OAuth).
- ▸Access to your machine — sync tokens are stored one-way hashed on our side and each token is locked to a single buddy, so even a stolen database can't impersonate your computer or touch other accounts.
And if the endpoint itself were hijacked, not just the database:
- ▸The sync script refuses to be redirected. If the endpoint answers with "go ask this other server instead", the sync fails rather than follows — so your sync token and session stats cannot be bounced to a host you never agreed to, and never travel unencrypted.
- ▸It also refuses any endpoint that is not a plain
https://address, and the address it will use is the one saved in~/.buddybrawl/config.json— the file you can read at any time.
What this means for you: Realistic worst outcome: a stranger knowing your display name and how often you code. Annoying — not dangerous. Your code, your Claude conversations, your email inbox, and your accounts stay yours.
Stopping, and deleting
npx buddybrawl uninstall takes BuddyBrawl off your machine. It does three things, in this order:
- ▸Unregisters the Stop hook from
~/.claude/settings.json, which is the moment session data stops leaving your machine. It only ever removes an entry pointing at our own script. - ▸Asks our server to deactivate this install's sync token, so it stops working even for someone who copied it. It sends a one-way hash of the token to do this, never the token itself.
- ▸Deletes the
~/.buddybrawlfolder — config, sync script, everything in it.
The order is deliberate. Your config file holds the only copy of the token your machine can prove it owns, so if the server can't be reached, the command stops before deleting anything and tells you — syncing has already stopped at that point, and you can re-run it later or pass --force. Deleting the folder by hand does the first and third but never the second: the token is the one part you can't retire yourself, which is why the command exists. npx buddybrawl uninstall --dry-run shows you all of it without doing any of it.
What stays behind
Your buddy, its stats, gear and rank, and the session records they were computed from stay on our server. Uninstalling one machine isn't the same as quitting, and we don't assume it is. There's no automatic expiry: it's kept for as long as the account exists.
Deleting it
npx buddybrawl uninstall --delete-account removes the install and the account together — buddy, stats, gear, rank, and the session records they were computed from. It happens while you wait; it is not a request in a queue.
- ▸Run it before a plain uninstall.Deleting is authenticated with this install's sync token, and a plain uninstall destroys that token. If you never signed in on the web, that token is the only proof the account is yours.
- ▸Signed in? Your dashboard has a delete button and needs no token. Already uninstalled and never signed in? Email hi@buddybrawl.xyz — done within 30 days, with a confirmation when it is.
- ▸What makes it a real deletion: the one-way hash of your git email is destroyed, and so is the generated address derived from it. Those two values are the only things tying an account to a person, so afterwards nothing left in our database can be joined back to you — by us, or by anyone who steals it.
- ▸Battles you already fought stay in your opponents' history, with you shown as Deleted player. A battle belongs to two people, and their record of their own games shouldn't disappear because you left. Nothing personal remains in it.
Because the email link is destroyed rather than remembered, installing again later gives you a new buddy from scratch. A deleted account cannot come back by accident.
What this means for you: Uninstalling stops the flow. Deleting removes what was already sent. They're separate on purpose — reinstalling on a new laptop shouldn't cost you your rank, and quitting shouldn't require you to still have the old machine.