Discord Rich Presence for ani-cli
Live anime title, episode, sub/dub, a real playback countdown, and cover art —
with no wrapper command and ani-cli left unpatched.
1. Download the latest anirpc-windows-x64.zip from
Releases and
extract it anywhere without spaces in the path.
2. Double-click anirpc.exe. It sets one environment variable and exits.
3. Open a new terminal and run ani-cli as usual.
That's it. Nothing to launch, no wrapper command, no Discord account setup, no token. Presence appears the moment playback starts.
Note
Windows will likely warn you on first run — "Windows protected your PC". The exe is unsigned (code-signing certificates cost money), so SmartScreen flags it until it earns download reputation. Click More info → Run anyway. If you'd rather not, use the script install instead — it does exactly the same thing and is three lines of readable PowerShell.
To undo everything: anirpc.exe --uninstall
The exe bundles Python, but it cannot bundle the rest — ani-cli is itself a bash script, so a Unix shell is a hard requirement either way:
| Need | Why |
|---|---|
| ani-cli 5.x | The thing this attaches to |
| mpv | The player ani-cli drives |
| Git for Windows (git-bash / MSYS2) | ani-cli already needs it; anirpc's shim runs under it |
| Discord desktop app | Rich Presence does not exist in the browser |
| Python 3.8+ | Only for source installs — the exe needs none |
Windows only. The daemon talks to mpv and Discord over Windows named pipes. A Linux port is in progress on the
linux-portbranch and is not released yet — see Linux.
| Field | Where it comes from |
|---|---|
| Anime title, episode | --force-media-title, which ani-cli passes to mpv |
| Sub / Dub | mpv's audio track language, falling back to --dub in ani-cli's argv |
| Countdown | mpv's live time-pos + duration |
| Resolution | mpv's video-params/h |
| Cover art, episode total, AniList link | AniList GraphQL, cached locally |
Sub/dub is deduced because ani-cli keeps $mode to itself and never tells
the player. The audio track's language tag is the ground truth for what is
actually playing; reading --dub out of ani-cli's command line is the fallback.
ani-cli picks its player from ANI_CLI_PLAYER (ani-cli:405). The installer
points that at bin/anirpc-mpv, a shim that starts the daemon and then hands
off to the real mpv. ani-cli itself is never modified — which matters,
because ani-cli -U self-updates with patch and would conflict with a
patched script.
ani-cli ──ANI_CLI_PLAYER──> bin/anirpc-mpv ──exec──> mpv.exe
│ │
run/session.json private IPC pipe
└──────> anirpc.exe <┘
│
└──> Discord IPC pipe
The shim's name must keep mpv in it: ani-cli branches on
case "$player_function" in *mpv*) (ani-cli:316), and only that branch
passes --force-media-title — which is where the title and episode come from.
Cover art is the AniList image URL, not an uploaded Discord asset, so there is nothing to configure on the Discord application itself.
Everything lives in config.json, next to the exe. It ships working, so this
is all optional.
| Key | Default | Meaning |
|---|---|---|
client_id |
(shipped) | Discord Application ID — also sets the header text |
activity_type |
3 |
3 = Watching, 2 = Listening, 0 = Playing |
timestamp_mode |
"remaining" |
remaining = "18:22 left"; elapsed counts up |
show_cover_art |
true |
AniList cover as the large image |
show_anilist_button |
true |
"View on AniList" button |
detect_dub_from_audio_track |
true |
Trust the audio language tag over argv |
idle_exit_seconds |
300 |
Daemon self-exits after this long idle |
debug |
false |
Also log to stderr |
activity_type must stay 2 or 3 for timestamp_mode: "remaining" —
Discord rejects an end timestamp on other types. With 0 (Playing), use
"elapsed".
The bold line above the title is the Discord application's name, not
something this tool sets. The shipped ID belongs to an app named Anime, so
profiles read "Watching Anime". To change it, make your own app —
Developer Portal → New
Application, name it whatever you want the header to say, copy the
Application ID from General Information, and put it in config.json:
{ "client_id": "1234567890123456789" }No bot, no OAuth, no token. An Application ID is a public identifier, not a secret — which is exactly why one can ship in this repo — and anirpc never asks for your Discord credentials.
If the exe is quarantined, or you'd rather read what you run:
git clone https://github.com/KernelSpecter/anicli-rpc
cd anicli-rpc
powershell -ExecutionPolicy Bypass -File .\install.ps1Uninstall with -Uninstall. This path needs Python 3.8+ on PATH — standard
library only, nothing to pip install. The shim prefers anirpc.exe when it's
present and falls back to the interpreter, so both installs work side by side.
Check run/anirpc.log first. A healthy session shows one presence: line per
actual change, not a steady stream:
11:06:30 daemon: start
11:06:30 mpv: connected \\.\pipe\anirpc-mpv-1868-1786599389
11:06:31 discord: connected via \\.\pipe\discord-ipc-0
11:06:31 presence: Frieren: Beyond Journey's End | Episode 4 of 28 · Sub
Nothing shows up at all
Discord must be the desktop app (not a browser tab) and already running
before playback starts. Then check
Settings → Activity Privacy → Share your detected activities is on.
discord: pipe closed during handshake in the log
Discord wasn't running, or was mid-restart, when the daemon tried to connect. Start Discord, then start the next episode.
"Program ... not found" when starting ani-cli
The shim lost its exec bit — zip extraction drops it. Re-run anirpc.exe,
which chmods and verifies it. Or do it by hand in git-bash:
chmod +x ./bin/anirpc-mpvButtons don't appear
Discord does not render activity buttons on your own profile. Other people see them.
Wrong sub/dub
Some streams carry no audio language tag. Set
"detect_dub_from_audio_track": false to trust ani-cli's --dub flag instead.
See what would be published, without Discord
anirpc.exe --dry-runPrints each activity payload as it changes, and runs alongside the real daemon.
Note it never contacts Discord, so it cannot confirm your client_id or the
connection — only what the payload would be.
Moving the folder
Re-run anirpc.exe to repoint ANI_CLI_PLAYER. The new path must still
contain no spaces: ani-cli launches the player unquoted (ani-cli:318), so
a space breaks it.
Not released yet, and deliberately so. The daemon's transport is Windows named
pipes; on Linux both the mpv and Discord IPC endpoints are Unix domain sockets,
which need a genuinely different implementation (open() on a socket fails
with ENXIO). The port lives on
linux-port.
It is written but unverified — it has never run against a real Linux Discord client. If you're on Linux and want to help, testing that branch is the single most useful contribution right now. Please report back in an issue.
ani-cli by pystardust, which this hooks into without touching. Metadata from AniList.
MIT licensed — see LICENSE.
