How Agent-Reach Switched Bilibili Backends from yt-dlp to bili-cli and OpenCLI

Agent-Reach deprecated yt-dlp in favor of bili-cli and OpenCLI after Bilibili's risk-control system began returning HTTP 412 errors, implementing a three-tier fallback chain that probes external binaries in order until one reports "ok".

Agent-Reach provides a dedicated BilibiliChannel for extracting content from the Chinese video platform. The channel implementation in agent_reach/channels/bilibili.py manages backend switching logic that replaced the unreliable yt-dlp integration with purpose-built tools, ensuring stable access to video streams and metadata even as platform restrictions evolve.

Why yt-dlp Was Removed from the Bilibili Channel

The original implementation relied on yt-dlp to fetch video streams from Bilibili. Bilibili's risk-control system started returning HTTP 412 (Precondition Failed) for every yt-dlp request, even when executed with warmed cookies, proxies, or the latest version. As documented in the module docstring (lines 4-9 of agent_reach/channels/bilibili.py), the maintainers removed yt-dlp entirely and replaced it with the more reliable bili-cli and OpenCLI solutions.

The Three-Tier Backend Architecture

The BilibiliChannel supports three mutually exclusive backends, probed in order of preference:

bili-cli (Primary Backend)

The bili-cli backend uses the bilibili-cli binary (installable via pipx install bilibili-cli). This backend provides search, hot-list retrieval, video detail extraction, and audio extraction without requiring a logged-in session. Availability is determined by probe_command("bili", ["--version"], ...) at lines 82-94 of bilibili.py. If the command is missing, the backend is ignored; otherwise, the probe result determines the status (ok, warn, or error).

OpenCLI (Secondary Backend)

OpenCLI reuses the user's Chrome session via the OpenCLI bridge, enabling subtitle extraction and other features that require a logged-in browser. The channel queries opencli_status() from agent_reach/backends/opencli.py (lines 96-110 of bilibili.py). This status object reports whether the Chrome extension is installed, connected, or idle, allowing the channel to return the appropriate availability status without false negatives when the extension is merely sleeping.

B站搜索 API (Zero-Dependency Fallback)

The B站搜索 API serves as a zero-dependency fallback that only supports keyword search. The _search_api_ok() method (lines 24-32 of bilibili.py) sends a test request to https://api.bilibili.com/x/web-interface/search/all/v2?keyword=test&page=1 and verifies the JSON response contains code == 0. If the API is reachable, the backend reports ok and becomes available for search operations.

How Automatic Backend Selection Works

The check() method implements the switching logic. It iterates through the backends in the order defined by ordered_backends(), which respects user configuration. The first backend reporting "ok" becomes the active_backend.

If a backend fails with an error but a later backend succeeds, the error messages are collected and appended to the success message. This allows users to see both the functional backend and any broken alternatives simultaneously (lines 46-72 of bilibili.py). All backend contracts are defined in the base class at agent_reach/channels/base.py.

Working with the BilibiliChannel API

The following example demonstrates how the channel automatically selects and uses the appropriate backend:

from agent_reach.channels.bilibili import BilibiliChannel

# Create channel and probe available backends

chan = BilibiliChannel()
status, message = chan.check()
print(f"Active backend: {chan.active_backend}")
print(message)

# Search uses whichever backend is active (bili-cli preferred)

results = chan.search("Python programming")
print(results)

# Read video URL routes to bili-cli or OpenCLI automatically

video_info = chan.read("https://www.bilibili.com/video/BV1xx411y7Zt")
print(video_info)

When bili-cli is installed, the channel invokes it internally (e.g., bili search ...). When only OpenCLI is available, the channel calls opencli bilibili .... The probing utilities in agent_reach/probe.py safely execute these external commands and interpret their exit statuses.

Summary

  • yt-dlp was removed due to HTTP 412 blocking from Bilibili's risk-control system, making it unusable even with cookies and proxies.
  • Three backends exist: bili-cli (full features, no login), OpenCLI (requires Chrome/subtitles), and a public search API (search only).
  • Automatic selection occurs via check() and ordered_backends(), which probes each option until one reports "ok".
  • Error aggregation ensures users see both successful connections and any failed backend warnings in the status message.
  • Key files: agent_reach/channels/bilibili.py (main logic), agent_reach/backends/opencli.py (Chrome integration), agent_reach/probe.py (command probing).

Frequently Asked Questions

Why did Agent-Reach stop supporting yt-dlp for Bilibili?

Bilibili's anti-bot measures began returning HTTP 412 errors for all yt-dlp requests, rendering the tool ineffective regardless of cookie warming, proxy rotation, or version updates. The maintainers removed yt-dlp support entirely and replaced it with bili-cli and OpenCLI, which use different request patterns that currently bypass these restrictions.

What is the difference between bili-cli and OpenCLI backends?

bili-cli is a standalone Python package that provides video search, hot-lists, and audio extraction without requiring a Bilibili login. OpenCLI bridges to your Chrome browser to reuse an authenticated session, which is necessary for subtitle extraction and accessing restricted content. bili-cli is preferred for anonymous access, while OpenCLI is required for features needing authentication.

How does the automatic fallback to the search API work?

If neither bili-cli nor OpenCLI is installed on the system, the BilibiliChannel automatically falls back to the B站搜索 API. This public endpoint requires zero installation but only supports keyword search functionality. The _search_api_ok() method verifies API reachability before marking this backend as available, ensuring the channel always has at least minimal search capability.

Do I need to configure which backend to use manually?

No. The channel automatically probes available backends in the order defined by ordered_backends() when you call check(). However, you can influence the selection by installing the preferred tools—install bilibili-cli via pipx for the best experience, or add the OpenCLI Chrome extension if you need subtitle support. The channel respects this installation order unless explicitly configured otherwise.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →