How to Add a Custom Backend for an Unsupported Platform in Agent Reach

To add a custom backend for an unsupported platform in Agent Reach, create a new channel class inheriting from Channel in agent_reach/channels/, implement the can_handle and check methods, and register it in agent_reach/channels/__init__.py.

Agent Reach is an extensible automation framework that treats every internet platform as a channel. When you need to integrate an unsupported platform, you extend the channel architecture in the Panniantong/Agent-Reach repository. This guide walks through the exact steps to add a custom backend for an unsupported platform in Agent Reach, referencing the actual source files and implementation patterns used by existing channels like Twitter and YouTube.

Understand the Channel Architecture

The foundation of every platform integration is the abstract Channel base class defined in agent_reach/channels/base.py. Each channel represents a specific platform (e.g., Twitter, YouTube) and manages one or more backends—upstream runtimes like yt-dlp, twitter-cli, or OpenCLI that perform the actual work.

The Channel contract requires these specific attributes and methods:

  • name (str): Short identifier used in configuration keys (<channel>_backend).
  • description (str): Human-readable description shown by the doctor command.
  • backends (List[str]): Ordered list of candidate backends; the first usable one becomes active_backend.
  • tier (int): 0 for zero-config, 1 for free API key, 2 for complex setup.
  • can_handle(url): Returns True if the URL belongs to this platform.
  • check(config): Probes the backends, sets self.active_backend, and returns a (status, message) tuple.

The base class provides the generic ordered_backends implementation, so you normally do not need to override backend selection logic.

Create a New Channel Module

Create a file named <platform>.py under agent_reach/channels/. Use existing channels such as agent_reach/channels/twitter.py or agent_reach/channels/youtube.py as templates. Below is a minimal example for a fictional "ExampleSocial" platform that reuses the shared OpenCLI backend.


# agent_reach/channels/example_social.py

# -*- coding: utf-8 -*-

"""ExampleSocial – a new platform that reuses the OpenCLI backend."""

from .base import Channel
from agent_reach.backends import opencli_status

class ExampleSocialChannel(Channel):
    name = "examplesocial"
    description = "ExampleSocial posts and comments"
    # OpenCLI can drive this platform; list dedicated CLIs here if needed

    backends = ["OpenCLI"]
    tier = 0  # No API key required

    def can_handle(self, url: str) -> bool:
        from urllib.parse import urlparse
        host = urlparse(url).netloc.lower()
        return "examplesocial.com" in host

    def check(self, config=None):
        """Probe OpenCLI; delegate to the shared status helper."""
        st = opencli_status()
        if not st.installed:
            return "warn", (
                "OpenCLI 未安装。安装方式:\n"
                "  npm install -g @jackwener/opencli"
            )
        if st.broken:
            return "error", st.hint
        if st.ready:
            self.active_backend = "OpenCLI"
            return "ok", "OpenCLI 可用(复用浏览器登录态)"
        return "warn", st.hint

Key implementation details:

  • The channel name becomes the configuration key examplesocial_backend.
  • The backends list tells the framework which runtimes to probe; the probing logic for OpenCLI resides in agent_reach/backends/opencli.py.
  • The check method mirrors the pattern in agent_reach/channels/twitter.py—it calls opencli_status(), assigns self.active_backend, and returns a status tuple.

Implementing a Dedicated Backend

If your platform requires a specific CLI tool (e.g., example-cli) instead of OpenCLI, add it to the backends list and implement a private probing method similar to _check_twitter_cli in agent_reach/channels/twitter.py. This method should verify the binary exists and return availability status.

Register the Channel in the Global Registry

After creating the channel module, you must expose it to the framework by updating the global registry in agent_reach/channels/__init__.py.

Import your new class and append an instance to ALL_CHANNELS:


# agent_reach/channels/__init__.py

...
from .example_social import ExampleSocialChannel
...
ALL_CHANNELS: List[Channel] = [
    GitHubChannel(),
    TwitterChannel(),
    YouTubeChannel(),
    RedditChannel(),
    BilibiliChannel(),
    XiaoHongShuChannel(),
    LinkedInChannel(),
    XiaoyuzhouChannel(),
    V2EXChannel(),
    XueqiuChannel(),
    RSSChannel(),
    ExaSearchChannel(),
    WebChannel(),
    ExampleSocialChannel(),   # <-- newly added

]

This registration makes the channel visible to the CLI doctor command and the core routing logic.

Implement Platform-Specific Operations

If the platform supports reading posts, searching, or transcribing media, implement the corresponding optional methods. For example, a read method might invoke an upstream API wrapper. Follow the lazy import pattern used in YouTubeChannel.transcribe to avoid loading heavy dependencies when the feature is unused:

def transcribe(self, url: str, config=None):
    from agent_reach.utils.media import download_audio
    # Implementation here

Test Your Custom Backend

Validate your implementation by running the project's test suite:

pytest tests/ -v

Create unit tests in tests/test_<platform>_channel.py following the structure of tests/test_twitter_channel.py. Verify that:

  • can_handle() correctly identifies platform URLs.
  • check() sets active_backend to the expected backend under different probe outcomes.
  • The channel appears in the get_all_channels() registry.

Summary

Frequently Asked Questions

What is the difference between a channel and a backend in Agent Reach?

A channel is the abstract representation of a platform (e.g., Twitter, YouTube) that inherits from the Channel base class in agent_reach/channels/base.py. A backend is the actual runtime tool or CLI (e.g., twitter-cli, yt-dlp, OpenCLI) that executes commands for that platform. The channel's check() method probes the backends list to determine which runtime is available and sets active_backend accordingly.

Can I use multiple backends for a single platform?

Yes. The backends attribute accepts an ordered list of strings. Agent Reach probes them sequentially, and the first usable backend becomes the active_backend. For example, the Twitter channel in agent_reach/channels/twitter.py can fall back from a dedicated CLI to OpenCLI if the primary tool is unavailable.

How do I handle authentication for my custom backend?

Authentication is typically handled by the backend itself (e.g., OpenCLI inherits browser login states). If your backend requires API keys, set tier = 1 or tier = 2 in your channel class and read the configuration in the check() method. Store sensitive credentials in Agent Reach's config system rather than hardcoding them in agent_reach/channels/<platform>.py.

Where should I place unit tests for my new channel?

Create a test file in the tests/ directory following the naming convention test_<platform>_channel.py. Mirror the test patterns found in tests/test_twitter_channel.py, which verify that can_handle() correctly identifies URLs and that check() sets the active_backend attribute under different probe outcomes.

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 →