rar-file/claude-rpc
rar-file/claude-rpc has 33 GitHub stars and 4 forks. GitHot measured +1 stars in 24 hours. Last checked 2026-11-14 20:11 UTC. Last push 2026-11-13.
Measured star growth
- in 24h
- +1
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
About
Discord Rich Presence (RPC) for Claude Code — live model, project, tokens, and lifetime stats in your Discord profile. Driven by Claude Code hooks.
Developer ToolsREADME.md
Original

the card's live states — working · thinking · waiting · idle
Discord Rich Presence for Claude Code — your live model, project, tokens, and lifetime stats, driven by the hooks Claude Code already fires.
claude-rpc.com → — see it in one page. · Discord → — help, ideas, show your card.
live — on by default for fresh installs, opt out any time. see community totals
A small Node daemon that takes the lifecycle events Claude Code already fires and pipes them into the Discord rich-presence card on your profile. Your friends see what you're building; your future self gets lifetime stats. Built solo, on weekends.
install
macOS / Linux / any Node 18+ — one command:
npx claude-rpc@latest setup
(The @latest matters — bare npx claude-rpc will happily reuse a stale cached copy.)
That installs claude-rpc globally, wires the hooks into Claude Code, and starts the daemon — no separate start step. Open Claude Code in any project and the card appears within a second. Something looks wrong? claude-rpc doctor (or claude-rpc doctor --fix to auto-repair).
Prefer a one-liner that figures it out for you?
curl -fsSL https://claude-rpc.com/install | sh
Detects Node (installs the npm package) or falls back to the prebuilt Apple-Silicon binary, then runs setup for you.
Homebrew (macOS / Linux):
brew install rar-file/claude-rpc/claude-rpc && claude-rpc setup
Windows (no Node required) — grab claude-rpc.exe from the latest release (the standalone CLI — no installer), then run it from the folder you saved it to:
.\claude-rpc.exe setup
setup copies the exe to a fixed per-user location (so the download can go afterwards) and adds that folder to your user PATH, so claude-rpc <command> works in any new terminal. Prefer a GUI? The release's claude-rpc-<version>-x64-setup.exe (installer, auto-updates) and claude-rpc-<version>-x64-portable.exe (no install) are the desktop app: it runs the same setup for you on first launch, then gives you the settings page in a window and daemon controls in the tray.
That's the whole pitch.
setupregisters a per-user login-autostart entry (a LaunchAgent on macOS, asystemd --userunit on Linux, anHKCU\…\Runvalue on Windows) and wires hooks into Claude Code'ssettings.json, and the daemon reports anonymous totals by default. It ends with one optional y/N — connect GitHub? — which publishes a verified public leaderboard profile only if you say yes (asked once; Enter skips). All of it is reversible (claude-rpc uninstall,community off,profile off) and fully documented inSECURITY.md— read it first if you want to know exactly what runs.
The Discord desktop app must be running. The browser client doesn't expose the local IPC bridge that Rich Presence uses.
other platforms / from source
git clone https://github.com/rar-file/claude-rpc.git
cd claude-rpc
npm install
node ./src/cli.js setup # wires hooks + starts the daemon
Or npm install -g claude-rpc && claude-rpc setup for the global bin. setup starts the daemon for you; manage it afterward with claude-rpc start | stop | status. Every mode survives npm update without losing your clientId — user config lives under the per-OS config dir, not inside node_modules.
use your own Discord app
A working public Discord application is bundled into the default config — you don't need to register your own to get started. If you want a different app name on the card, create one in the Discord Developer Portal, copy the Application ID, and drop it into your config:
# Linux
echo '{ "clientId": "YOUR_ID" }' > ~/.config/claude-rpc/config.json
# macOS
echo '{ "clientId": "YOUR_ID" }' > ~/Library/Application\ Support/claude-rpc/config.json
# Windows (PowerShell)
'{ "clientId": "YOUR_ID" }' | Set-Content $env:APPDATA\claude-rpc\config.json
claude-rpc upgrade-config if you're carrying forward a v0.3-era file.
what claude-rpc does
on discord
A card that updates as you work. The large image swaps between five states (working / thinking / idle / stale / notification — those gifs at the top of this README). The two lines of text rotate through frames you template — current file, today's hours, lifetime totals, top hotspot, code churn, cost — and the daemon skips frames whose required template variables are empty. The SessionEnd hook clears the card instantly when you close Claude Code; no "is it still running?" timeout.
A View on GitHub → button appears automatically when your cwd is a git repo with a github origin. The daemon checks .git/config directly — no shell-out, no surprise GH API call.
A rotation frame can show your subscription usage — Usage · 34% weekly — the exact numbers Claude Code's own /usage screen shows. The daemon asks Anthropic's usage endpoint with the OAuth token Claude Code already stores locally; the token goes only to its issuer, the percentages go only where you template them, and usage.enabled: false turns the whole thing off (SECURITY.md §3d). claude-rpc usage prints the same data as heat-graded bars in your terminal.
on your machine
Local surfaces, all served from your own machine:
web dashboardclaude-rpc serve · port 47474![]() |
settingsclaude-rpc settings · same port![]() |
claude-rpc status (TUI — heatmap, hour histogram, leaderboards)
claude-rpc today (today's stats, focused)
claude-rpc week (weekday breakdown)
claude-rpc preview (every rotation frame rendered with real data)
claude-rpc insights (3–5 auto-generated lines: trend, peak, hotspot)
claude-rpc recap --md (standup-ready: yesterday's projects, ships, churn)
The web dashboard pushes updates via SSE; the TUI refreshes on a 3-second tick.
beyond your machine
Stat cards and badges for a README, a site or a Discord message, all from one command. Run it bare for a menu: pick a card, then a live link (paste once, it refreshes itself), a PNG or an SVG:
claude-rpc share # poster PNG + a ready caption on your clipboard
claude-rpc statcards # menu: card → link / PNG / SVG
claude-rpc statcards stats --link --md | pbcopy # README markdown, straight to the clipboard
claude-rpc statcards poster --png # ./claude-poster.png, 2× for Discord / X
claude-rpc statcards badge --metric streak --svg # ./claude-badge-streak.svg
claude-rpc statcards list # every card and where it can go
Cards: stats (totals + year heatmap), profile, badge, heatmap, poster, session, wrapped. PNGs are drawn by whatever the machine already has (rsvg-convert, or Chrome / Edge / Brave / Chromium headless; Edge ships with Windows), so there is still nothing to install. The link option prints the URL, Markdown and an <img> tag, and copies the Markdown.
Live stats + year heatmap, paste once. With a public profile (claude-rpc profile set --handle <you> && claude-rpc profile on), the community worker serves an always-current stats card with your last 12 months as a heatmap. You don't need gh or a gist, and there's nothing to re-run:
[](https://claude-rpc.com/u/<you>)
?metric=hours shades the grid by time instead of tokens. /heatmap/<you>.svg is the grid on its own. If you link several machines, their days are added together. Shading is relative to your own year, so light and heavy users both get a readable map. To publish lifetime totals only, set "profile": { "heatmap": false } in config.json; the next flush also clears the stored days.
The smaller card and badges are still there:
[](https://claude-rpc.com/u/<you>)
[](https://claude-rpc.com/?ref=badge)
The card shows tokens, sessions, active hours and streak; badge metric= is one of tokens · sessions · hours · streak (optional &label= to retitle). Both refresh themselves as the daemon flushes your profile (~every 30 min). Your profile page at /u/<you> has a one-click "copy" for the whole block.
No public profile? Every card except wrapped also renders offline from your local stats, as PNG or SVG (statcards <card> --png / --svg). The older one-card commands (badge, card, calendar, github-stat, session-card, readme) still work, including --gist.
statcards poster --range week · month · year (also all) — live at /api/card.svg while claude-rpc serve is running
Live equivalents while claude-rpc serve is running (the local dashboard server — the daemon itself serves no HTTP):
http://127.0.0.1:47474/api/badge.svg?metric=hours&range=7dhttp://127.0.0.1:47474/api/card.svg?range=year
Cost numbers come from src/pricing.js, seeded with approximate public list prices. Your actual Claude Code subscription bill is unrelated.
community totals
The badges at the top of this README are live, served by a small Cloudflare Worker (worker/) that holds running totals of sessions and tokens across every install that's reporting. As of v0.7 fresh installs are on by default — setup mints an anonymous UUID v4 and the daemon starts flushing deltas every 30 minutes. Existing users upgrading from a pre-v0.7 config stay off until they explicitly run community on (the consent flow prints the exact payload first).
claude-rpc community # show state + instanceId (last 8 chars)
claude-rpc community off # opt out; instanceId retained for re-enable continuity
claude-rpc community on # explicit consent flow (upgraders / re-enable)
claude-rpc community report # one-shot manual flush (testing)
Each report sends only: a sessionsDelta, a tokensDelta, the claude-rpc version, OS family (linux/darwin/win32), and the anonymous UUID v4. No prompts, paths, models, repos, costs, usernames, or hostnames — the Worker's validateReport is the schema of record. The full Worker source is in this repo so the privacy claim is auditable. Every worker route — path, params, response — is documented in docs/WORKER-API.md.
For a complete account of the sensitive things claude-rpc does — startup persistence, hook injection, every outbound request, and the exact telemetry payload — see SECURITY.md. It's also the reference for supply-chain scanner findings (Socket.dev et al.): the flagged persistence and hook-injection behaviors are inherent to the tool and documented there.
three pieces, glued by json files
No database, no message bus, no background polling when Claude Code isn't running. State on disk you can cat and jq. Zero runtime dependencies — even the Discord Rich Presence IPC client is hand-rolled (src/discord-ipc.js).
- hook (
src/hook.js) — Claude Code spawns it on every lifecycle event. Parses the JSON from stdin and mutates the shared state file. The per-tool-call hooks (PreToolUse/PostToolUse) are wiredasync, so Claude Code never waits on them; the once-per-turn ones cost one node start-up each (~60–90ms wall, Node's own boot included). - daemon (
src/daemon.js) — long-running. Connects to Discord's local IPC, watches the state file, pushes presence frames every few seconds. Idles at ~55MB. Exponential backoff with jitter on reconnect;daemon.logrotates at 5 MB. - scanner (
src/scanner.js) — walks~/.claude/projects/**/*.jsonlfor all-time aggregates (active time, prompts, tools, tokens, streaks, hotspots, lines, languages, cost, bash, web, subagents). Incremental — re-parses only changed files, and runs in a short-lived child process so the daemon never holds the parse memory.
Persistent state, all human-readable JSON:
| Path | What |
|---|---|
$TMPDIR/claude-rpc/state-<session>.json |
Live per-session state, volatile (state.json for events with no session id) |
~/.claude-rpc/aggregate.json |
All-time aggregates |
~/.claude-rpc/events.jsonl |
Notification / compaction events the hook logs (rotated at 5 MB) |
~/.claude-rpc/scan-cache.json |
Per-transcript scan cache |
~/.claude-rpc/private-list.json |
Runtime privacy toggles |
~/.claude/settings.json |
Hook registrations (managed by setup) |
User config lives at %APPDATA%\claude-rpc\config.json (Windows), ~/Library/Application Support/claude-rpc/config.json (macOS), or $XDG_CONFIG_HOME/claude-rpc/config.json (Linux). It only needs to hold overrides — every key has a baked default. { "clientId": "..." } is a complete config file. Defaults live in src/default-config.js; the loader deep-merges over them.
privacy
Per-project, runtime, or auto-detected — whichever fits how you work.
// drop at your project root: <project>/.claude-rpc.json
{ "private": true } // shortcut for visibility: "hidden"
{ "visibility": "name-only" } // project name only, no file/tool detail
{ "projectName": "redacted" } // show this name on Discord instead
Or from the command line, in any project:
claude-rpc private # hide this folder (adds it to ~/.claude-rpc/private-list.json)
claude-rpc private off # show it again
claude-rpc private status # what Discord sees for this folder, and why
Or globally, in config.json:
{ "privacy": { "patterns": ["client-*", "secret-stuff"], "mode": "hidden" } }
If gh is installed and authenticated, GitHub-private repos auto-hide (privacy.githubPrivateMode, default hidden — opt out with privacy.autoDetectGithubPrivate: false). 5-minute cache, 1.5s timeout, silent skip when gh isn't there.
Aggregates and local dashboards are never affected. Privacy is a one-way valve between local state and Discord.
customizing the card
claude-rpc preview # render every rotation frame with your real data
claude-rpc vars # dump the full template-variable list as JSON
Frames have a requires field; the daemon skips a frame when any of its required vars resolve empty / zero. Write seven frames knowing only the relevant ones render.
"idle": {
"details": "Idle in {project}",
"state": "{modelPretty} · {todayHours} today",
"rotation": [
{ "details": "This week · {weekHours}", "state": "{weekPromptsLabel} · {weekTokensFmt} tokens",
"requires": ["weekActiveMs"] },
{ "details": "Code churn · {linesAddedFmt} added",
"state": "{linesNetFmt} net · {topLanguage}",
"requires": ["topLanguage"] }
]
}
The full default config is in src/default-config.js — that's the canonical list of every key. Over 200 template variables are available; claude-rpc vars is the authoritative list.
claude code plugin
Prefer to install from inside Claude Code? There's a plugin for that:
/plugin marketplace add rar-file/claude-rpc
/plugin install claude-rpc@claude-rpc
It's a thin bootstrapper — on the first session it just runs npx claude-rpc@latest setup for you (the same install as above), then stays out of the way. macOS / Linux / WSL; on native Windows use claude-rpc.exe (see install). Nothing extra is added to your sessions — the plugin is a single SessionStart hook with no model-context cost.
commands
claude-rpc help lists them all, grouped; claude-rpc help <command> (or <command> --help) shows one command's options and examples. After setup you rarely need any.
Tab completion: claude-rpc completion install turns it on for bash, zsh, fish or PowerShell (setup offers it too). claude-rpc re<Tab> → recap / restart, claude-rpc scan --<Tab> → --force, and flag values, project names and files complete as well. A typo gets a "did you mean".
full command reference
| Command | What it does |
|---|---|
| Get started | |
setup |
Install Claude Code hooks + login autostart, seed config, start the daemon. --link <code> also links this machine to your verified profile (--wrapped publishes your year too) |
completion |
Tab completion: install, uninstall, or print the bash / zsh / fish / powershell script |
uninstall |
Remove hooks, login autostart, PATH entry and tab completion (keeps your data) |
| Your stats | |
status |
Interactive TUI: heatmap, hour histogram, leaderboards (--dump for plain output) |
today |
Today's stats + when in the day you code |
week |
This week day by day; --compare puts it next to last week |
projects [name] |
Every project ranked by active time (--limit N), or one project's full record + recent daily rhythm |
usage |
Subscription limits: session + weekly %, the same numbers /usage shows |
recap |
Standup summary, yesterday by default (today|week|YYYY-MM-DD, --md, --json) |
insights |
3–5 auto-generated lines about your history |
wrapped |
Your animated year in review; --publish puts it on claude-rpc.com/wrapped/<handle> |
serve |
The local web dashboard (port 47474) |
settings |
Edit the card, daemon and per-project privacy in the browser |
export |
The aggregate as JSON, or daily rows as CSV (--csv --out) |
| Share | |
share [week|month|year|all] |
Saves the poster PNG and copies a caption with your numbers and a link (--no-png, --no-copy, --png <file>) |
statcards [card] |
Cards and badges as a live link, PNG or SVG: stats profile badge heatmap poster session wrapped (--link --png [file] --svg [file] --md --html --metric --range --copy; bare = menu) |
statusline |
One-line status for tmux/shell prompts (--template) |
mcp |
The stats MCP server (stdio); mcp install / mcp uninstall wire it into Claude Code |
| Privacy | |
private [on|off|status] |
Hide this folder from Discord, show it again, or see how it resolves |
pause [30m|2h|off|status] |
Hide the card everywhere for a while (default 1h) |
| Online | |
profile |
Opt-in public leaderboard profile: status | set | on | off | publish | verify |
squad |
Private mini-leaderboards with friends: status | create <name> | join <code> | leave [id] |
link [code] |
One profile across machines: link mints a code on your verified machine, link <code> claims it on the new one |
community |
Anonymous community totals, on by default for fresh installs: status | off | on | report |
| Daemon | |
start / stop / restart |
Lifecycle for the detached daemon |
logs |
Follow the daemon log |
| Troubleshoot | |
doctor |
Diagnostic checklist with one-line fix hints (--fix to auto-repair) |
scan |
Re-count your history from ~/.claude/projects (--force re-parses everything) |
backfill <dir> |
Import transcripts from any folder (backup, other machine) |
preview |
Render every rotation frame against real state |
vars |
The full template-variable list as JSON |
upgrade-config |
Re-run idempotent migrations on config.json |
daemon |
Run the daemon in the foreground (debugging) |
Older names still work and always will within 1.x: install (setup), dump (status --dump), compare (week --compare), project <name> (projects ), rescan (scan --force), resume / unpause (pause off), public (private off), privacy (private status), tail / log (logs), and badge, card, github-stat, calendar, session-card, readme (statcards).
Exit codes: 0 ok · 1 user error · 2 system error · 3 wrong state. --version and --help work as expected.
complete removal
claude-rpc uninstall removes everything that respawns or registers the tool:
its hooks from ~/.claude/settings.json (only its own — third-party hooks are
left untouched) and the login-autostart entry (systemd --user unit on Linux,
LaunchAgent on macOS, HKCU\…\Run value + .vbs shim on Windows). After it
runs, nothing brings the daemon back.
It deliberately leaves your data in place: config.json (under the per-OS
config dir), the stats in ~/.claude-rpc/, and the transient files in the temp
dir (which clear on reboot anyway). Two things it does not touch, by design:
- a daemon already running this session keeps running until
claude-rpc stopor reboot (the autostart-managed one is stopped; a manuallystarted one isn't); - the MCP server, if you wired it — that's a separate
claude-rpc mcp uninstall.
For a clean wipe on macOS/Linux:
claude-rpc mcp uninstall # only if you ran `mcp install`
claude-rpc stop
claude-rpc uninstall
rm -rf ~/.claude-rpc # stats; plus the per-OS config dir if you want it gone
troubleshooting
First step is always claude-rpc doctor — it checks Node, hook registration, daemon liveness, Discord IPC, aggregate freshness, and privacy resolution, with a one-line fix hint per failure.
common issues
- Discord doesn't show anything. Discord desktop must be running. The browser client doesn't expose the local IPC bridge.
claude-rpc logsshows what the daemon is actually doing. - Hooks don't fire.
claude-rpc setupre-registers them and now test-fires a syntheticSessionStartend-to-end, so a broken hook command surfaces immediately. Restart Claude Code afterwards so it re-reads its hook config. - Config error. Bad JSON in
config.jsonno longer crashes anything — the daemon logs one line and falls back to baked defaults.claude-rpc logsshows the parse error verbatim. - Old binary path baked into hooks. Common after manual exe replacement.
claude-rpc setuprewrites hook entries to point at the canonical install location.
platform support
macOS and Linux are first-class. The daemon reacts to on-disk changes with a
directory watcher (fs.watch over FSEvents/inotify — instant) and an mtime
poll as a lazy backstop, so an event is never missed. Login autostart is a
per-user launchd LaunchAgent on macOS and a
systemd --user service on Linux; both start the daemon at
login without sudo and don't fight a manual claude-rpc stop.
Windows is supported — grab claude-rpc.exe (no Node required), then
run claude-rpc.exe setup. One caveat documented honestly: fs.watch on Windows drops
events when a writer commits via atomic rename (which the state file, pause file,
scanner, and settings GUI all do), so on Windows the mtime poll is effectively
the primary path and runs an order of magnitude faster (every ~3s vs ~30s
elsewhere) to compensate. It's a reliable fallback, not yet the native-watch
confidence macOS/Linux get — closing that gap is on the roadmap.
Autostart is an HKCU\…\Run entry launched through a windowless .vbs shim (no
scheduled task, by design — see SECURITY.md).
Everything else — the scanner, dashboards, cards, the worker client — is platform-neutral. CI runs the full suite on Node 18/20/22/24 and builds the macOS and Windows binaries every release.
versioning
What's a stable contract and what's an internal detail you shouldn't build on:
VERSIONING.md. Short version — the worker HTTP API, the CLI
(commands, flags, exit codes), the config.json schema, the claude-rpc vars
template variables, and the local data formats are stable and semver-governed;
daemon internals, the scan cache, the worker's KV layout, and exact wording are
not. The worker's HTTP surface is documented in
docs/WORKER-API.md.
development
npm test # 550+ tests, a few seconds
npm run lint # eslint over src + test + vscode-extension
npm run start # run daemon in foreground
npm run serve # web dashboard against your real data
npm run dashboard # desktop app shell (dev mode; shows the settings page)
npm run build:exe # SEA single-file binary for the current OS
Tests are node --test, zero deps; CI (ci.yml on every push and PR, release.yml on tags) runs the suite (+ the Worker's) across Node 18/20/22/24, and the release run gates the matrix build and npm publish on it. Where the project's headed (and what it'll deliberately never do): ROADMAP.md.
license
MIT © Archer Simmons

