# BGmi: bangumi tracking from the terminal, with a web UI on the side

> BGmi is a Python command line program for tracking subscribed anime, with a web front end, pluggable download backends and a v5 rewrite around per episode download state. It targets people running a download client at home, and its v5 release broke several v4 habits on purpose.

**BGmi/BGmi** — [looking for maintainers] BGmi is a cli tool with Web UI for subscribed bangumi.

- Repository: https://github.com/BGmi/BGmi
- Stars: 1,025 · Forks: 40
- Language: Python
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/bgmi-bgmi

## One program for the subscription list, the download client and the library folder

BGmi is a command line program for following anime series, in the sense of keeping a list of what you want to watch, checking the data sources for new episodes, and sending those episodes to a download client. The README describes it plainly as a cli tool with a Web UI for subscribed bangumi, and the feature list spells out the parts: a front end for managing and watching subscribed series with danmaku support, download filters based on keywords, subtitle groups and regular expressions, an ICS calendar for mobile devices, and Bangumi Script, which lets you add your own series parsers.

The design choice that matters is where the download actually happens. BGmi does not download. It hands a task to a client you already run, and the config exposes four of them, aria2, Transmission, qbittorrent and deluge, selected by a single download_delegate value. The same config also carries filters, so the rule about which release group and which resolution you want is applied before the task reaches the client.

The audience is therefore fairly specific: someone with a home server, a NAS, or a always-on box where a torrent client lives, who wants a subscription list managed as text as much as in a browser. The v5 release notes even mention bgmi install pulling a newer front end from a GitHub Release, so the web interface is treated as a swappable component rather than baked into the package.

## v5 moved download state from the series to the episode

The v5 rewrite is the single most important thing to understand before upgrading, because it changes what the tool remembers and what it does by default.

Before v5, a series carried its progress as a whole. In v5, download state is recorded per episode, so a single failed episode no longer forces you to roll back the progress of the entire series. Two new commands make that usable: seen mark adds an episode to the downloaded record by hand, and seen forget removes one so the next update retries it.

```bash
bgmi seen forget "Re:CREATORS" 5
bgmi update "Re:CREATORS"
bgmi seen mark "Re:CREATORS" 6
```

The sequence reads as the recovery workflow: forget the episode that failed, run update to pick it up again, and mark an episode you handled yourself so the tracker stops asking for it. The seen mark and seen forget commands replaced the older mark command, and they take an episode number rather than a series.

The other default change matters just as much for a running pipeline. In v5, update performs the download by default, and the old --download flag is no longer used. Any script that called bgmi update --download will now pass a flag that no longer means anything, while a script that called plain bgmi update and expected only a list refresh will start downloading. Neither is subtle, and both are the kind of change that belongs in a major version.

## Download backends are entry points, not if statements

The pyproject.toml shows how the download clients are wired. The package declares entry points under a bgmi.downloader group, and the visible ones map a name to a class in bgmi.downloader:

```toml
[project.entry-points."bgmi.downloader"]
"aria2-rpc" = 'bgmi.downloader:Aria2DownloadRPC'
"transmission-rpc" = 'bgmi.downloader:TransmissionRPC'
```

The dependency list includes stevedore, which is the plugin loader that makes those entry points work, and it also includes the client specific libraries transmission-rpc and qbittorrent-api, so each backend talks to its client over that client's own API rather than shelling out to a binary.

The same structure explains the config layout, where each client has its own section with an address and credentials, an aria2 section with an rpc_url and rpc_token, a transmission section with rpc_host, rpc_port, rpc_username, rpc_password and rpc_path, a qbittorrent section with rpc_host, rpc_port, rpc_username, rpc_password and category, and a deluge section with an rpc_url and rpc_password. A file in the tree called downloader.md covers the extension download method, and the v3 notes list qbittorrent-webapi and deluge-rpc among the additions, so the backend list grew over time.

The practical consequence is that choosing a backend is a config change, and the same BGmi install can point at a different client on a different machine without touching the code. It is also why the aria2 entry names its field rpc_url rather than a generic host, and why the comment warns that it is the aria2c RPC URL and not the jsonrpc URL.

## Install with pipx, then run bgmi install to lay down the config

The recommended install path is pipx, which keeps the tool and its dependencies out of your system Python, and the README offers pip as the alternative and a git clone from source as the not recommended option.

```bash
pipx install bgmi
```

The next step is the initialisation, which writes the first configuration:

```bash
bgmi install
```

That command matters more than it looks, because of how configuration is layered. BGmi can be configured by a config file or by environment variables, and the README is explicit that once the config file exists, the file wins and the environment variables are only used to generate that first file. The env var layer is therefore a bootstrap mechanism, not an override, and the README states plainly that the environment variables are for producing the first config file only.

The environment variable naming is mechanical. Names start with BGMI_, are upper case, and use an underscore between levels, so BGMI_DATA_SOURCE corresponds to data_source and BGMI_HTTP_ADMIN_TOKEN corresponds to admin_token in the http section. Five things cannot be set that way at all, and the README lists them: enable_global_include_keywords, enable_global_filters, global_include_keywords, global_filters and the save_path_map table. Those have to be written into the config file.

Upgrading follows the same split. With pipx the sequence is pipx upgrade bgmi followed by bgmi upgrade, and with pip it is pip install bgmi -U followed by bgmi upgrade. A v4 database needs bgmi upgrade to migrate it, so skipping that command is the difference between a working upgrade and a broken one.

## The config file lives at ${BGMI_PATH}/config.toml and defaults to ~/.bgmi/

The config file path is ${BGMI_PATH}/config.toml, and when the BGMI_PATH environment variable is not set, ${BGMI_PATH} defaults to ~/.bgmi/. The format is TOML, adopted in v3, and the file is a readable summary of the whole tool rather than a set of scattered options.

A trimmed view of what a generated file contains:

```toml
data_source = "bangumi_moe"
download_delegate = "aria2-rpc"
save_path = "tmp/bangumi"
enable_path_formatter = false
path_formatter = "{name}/S{season:02d}/S{season:02d}E{episode:02d}.{suffix}"
max_path = 3
```

The comments in the shipped file explain the intent of each key, including that max_path limits how many pages are fetched per series when searching for episodes, and that enable_path_formatter reorganises finished downloads into the path_formatter layout. The file also holds a save_path_map table for per series download paths, where an absolute path can stop the web UI from showing video files correctly, and a proxy setting for an HTTP proxy URL.

For small edits the README offers a command rather than a text editor:

```shell
bgmi config set http admin_token --value 'my super secret token'
```

That command works for flat values, and the README is careful about its limit: complex settings such as global_filters cannot be changed this way and have to be edited in the file. The same file carries the Web UI password as http.admin_token, and it is worth noticing that the generated example in the README ships with a real looking token string in it, so a fresh install should have that value replaced before the UI is exposed.

## The path formatter is what makes the output a media library

Without the formatter, BGmi keeps the traditional layout, downloading each episode into ${save_path}/{series name}/{episode number}/. With enable_path_formatter turned on, the flow changes in a way that matters for reliability.

The downloader first places the task in ${save_path}/.downloads/{task ID}/, so an in-progress file never collides with a file that is already in its final place. When the task completes, bgmi update runs a postprocess step that moves the file to the location the formatter describes, and the same postprocess can be run by hand with bgmi postprocess.

The default template is the Plex style naming that media servers expect:

```toml
path_formatter = "{name}/S{season:02d}/S{season:02d}E{episode:02d}.{suffix}"
```

Two details in that template carry their weight. The season and episode numbers are zero padded, and the placeholders come from the subscription metadata rather than from the folder name, which is why v5 also added --season to the add command, with the note that it works on an existing subscription and updates the season number directly, and --episode-offset to correct an offset in the total episode count. The v5 release also added --display-name for the name the media library shows.

This staging behaviour is the difference between a downloader that fights with your media server and one that does not. A file that appears under its final name only after the download completes, and only after the tool has moved it, is a file your server will index once.

## Choosing a data source is close to a one way door

BGmi can pull from three sources, bangumi_moe as the default, mikan_project, and dmhy, and the switch is a single command:

```bash
bgmi source mikan_project
```

The warning attached to it is the part worth reading before you try. Changing the data source clears the series database, though it does not affect scripts written with bgmi script. Downloaded video files are not deleted, but they will no longer appear in the front end, because the front end resolves what to show from the database that was just cleared.

If the new source is mikan_project, credentials have to be configured first, through mikan_username and mikan_password in the config file or the MIKAN_USERNAME and MIKAN_PASSWORD environment variables. The other sources do not need them.

The v5 release also added an MCP interface to bgmi_http, so that MCP clients can manage subscriptions, filters, updates and download state, and the feature list describes the intent plainly, letting an AI agent manage your series list. The package metadata backs that up with a fastapi server, uvicorn, and an mcp dependency, and the second console script bgmi_http points at bgmi.front.server:main. It is an early, new part of the surface, and it is also the part where the Web UI password and the download client credentials meet an external caller, so it deserves a deliberate decision about who is allowed to talk to it.

## A production stable tag and a repository looking for maintainers

The version numbers and the project metadata tell two different stories, and both are useful.

The release history is regular. Tags v5.0.0b1 on 2026-07-17, v5.0.0 on 2026-09-05 and v5.0.2 on 2026-09-27, with the last push to the repository on 2026-09-30. The pyproject.toml carries version 5.0.2, requires-python >=3.11,<4, and a classifier of Development Status :: 5 - Production/Stable, with support declared for CPython and PyPy on Python 3.11, 3.12 and 3.13. The dependencies are pinned exactly, including click, fastapi, sqlalchemy and pydantic, which is what makes a reproducible install possible but also means the package tracks those versions closely.

The repository description, however, reads [looking for maintainers]. That single line is the honest signal about the project's social state, and it is worth taking at face value. The listed maintainer is Trim21 and the author is RicterZ, and the tree includes AGENTS.md and AGENTS.user-script.md alongside a pre-commit config and a taskfile.yaml, so the project is set up for contributors and for automated agents.

The licence is MIT, which is the least constrained of the common choices for a tool of this kind, so a fork for a private library is straightforward. The cost of adoption is not the licence but the Python floor, the migration step after a major version, and the fact that a project asking for maintainers will eventually need someone to answer the issues.

## Conclusion

BGmi fits a self hosted setup where a torrent client already runs on a home server or NAS and you want subscriptions, filters and a media library layout managed from one place. It does not fit someone who only wants a subscription calendar, since the ICS output is a by product rather than the point, and it does not fit a Python older than 3.11. Before installing, read the v5 incompatible changes, run bgmi install once, and confirm that the download_delegate you pick matches the client already running on the machine, because switching that setting is what decides whether anything downloads at all.

## FAQ

### How do I install BGmi?

The README recommends pipx install bgmi, with pip install bgmi as an alternative and a git clone from source marked as not recommended. The current stable version needs Python 3.11 or later, and you run bgmi install afterwards to create the first configuration.

### Which download clients can BGmi use?

Four backends are listed: aria2, Transmission, qbittorrent and deluge, selected through the download_delegate setting with values aria2-rpc, transmission-rpc, qbittorrent-webapi and deluge-rpc. Each one is configured in its own section of the config file with the host, port and credentials of the client.

### How do I re-download one episode that failed in BGmi v5?

v5 records download state per episode, so you remove the failed episode with bgmi seen forget and then run bgmi update. The reverse command, bgmi seen mark, records an episode you handled manually so it is not fetched again.

### Where is the BGmi configuration file stored?

The config file is ${BGMI_PATH}/config.toml, and ${BGMI_PATH} defaults to ~/.bgmi/ when the environment variable is not set. Environment variables prefixed with BGMI_ are only used to generate that first file, and once the file exists the file takes precedence.

### What changed in BGmi v5?

v5 records download state per episode and adds seen mark and seen forget, adds a path formatter and postprocess for media library layouts, adds --season, --episode-offset and --display-name to the add command, adds an MCP interface to bgmi_http, and requires Python 3.11 or later. The update command now downloads by default and the old --download parameter is no longer used.

## Sources

- [BGmi/BGmi on GitHub](https://github.com/BGmi/BGmi)
- [Issues](https://github.com/BGmi/BGmi/issues)
- [License: MIT](https://github.com/BGmi/BGmi/blob/master/LICENSE)
- [README](https://github.com/BGmi/BGmi/blob/master/README.md)
- [Releases](https://github.com/BGmi/BGmi/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/bgmi-bgmi
