# How to Add New Platform Channels to Agent Reach: 4-Step Implementation Guide

> Learn how to add new platform channels to Agent Reach with this 4-step guide. Implement channel handling and registration for seamless integration.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: how-to-guide
- Published: 2026-06-16

---

**To add a new platform channel to Agent Reach, subclass the `Channel` base class in `agent_reach/channels/<platform>.py`, implement `can_handle` for URL detection and `check` for backend health verification, then register the instance in the `ALL_CHANNELS` list inside [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py).**

Agent Reach treats every external platform—from Twitter to Reddit—as a **channel**, which is a lightweight Python class that integrates with the core routing logic. Adding support for a new platform follows a standardized four-step pattern defined in the repository's architecture, requiring no modifications to the core engine.

## Step 1: Create a Channel Module

Create a new Python file in `agent_reach/channels/<platform>.py` that subclasses `Channel` from [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py). Define the class attributes `name`, `description`, `backends`, and `tier`, then implement the `can_handle` method.

The `name` attribute serves as the identifier used in CLI options and configuration files. The `backends` list defines an ordered priority of upstream tools, where the first successful backend becomes the `active_backend`. The `tier` field categorizes setup complexity: `0` for zero-config, `1` for free-key, or `2` for manual setup.

Here is the implementation pattern for an Instagram channel:

```python

# agent_reach/channels/instagram.py

"""Instagram — probe `instabot` for read/search capability."""

from .base import Channel
from agent_reach.probe import probe_command


class InstagramChannel(Channel):
    name = "instagram"
    description = "Instagram posts & stories"
    backends = ["instabot", "opencli"]
    tier = 1

    def can_handle(self, url: str) -> bool:
        """Return True for URLs that belong to Instagram."""
        from urllib.parse import urlparse
        domain = urlparse(url).netloc.lower()
        return "instagram.com" in domain

    def check(self, config=None):
        """Probe the backends in order, set ``self.active_backend``."""
        self.active_backend = None
        findings = []

        for backend in self.ordered_backends(config):
            if backend == "instabot":
                result = self._check_instabot()
            elif backend == "opencli":
                result = self._check_opencli()
            else:
                continue

            if result is None:
                continue
            findings.append((backend, *result))

        # Pick the first "ok", then "warn", otherwise report errors

        for wanted in ("ok", "warn"):
            for backend, status, message in findings:
                if status == wanted:
                    self.active_backend = backend
                    return status, message

        if findings:
            return "error", "\n".join(m for _, _, m in findings)

        return "warn", "instabot 未安装。请参考项目文档进行安装。"

    def _check_instabot(self):
        """Probe `instabot`. Returns None / (status, message)."""
        probe = probe_command("instabot", ["status"], timeout=10, retries=1,
                              package="instabot")
        if probe.status == "missing":
            return None
        if probe.status != "ok":
            return "error", f"instabot 健康检查失败：{probe.hint}"
        return "ok", "instabot 已就绪（可读取、搜索 Instagram 内容）"

    def _check_opencli(self):
        """Reuse the generic OpenCLI backend check."""
        from agent_reach.backends import opencli_status
        st = opencli_status()
        if not st.installed:
            return None
        if st.broken:
            return "error", st.hint
        if st.ready:
            return "ok", "OpenCLI 可用（复用浏览器登录态）"
        return "warn", st.hint

```

The `ordered_backends` method (inherited from the base class) automatically respects user overrides via the configuration key `<channel>_backend` or environment variables like `INSTAGRAM_BACKEND`, inserting the specified backend at the front of the candidate list.

## Step 2: Register the Channel in the Registry

Edit [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) to import your new class and append an instance to the `ALL_CHANNELS` list:

```python

# agent_reach/channels/__init__.py

from .instagram import InstagramChannel   # NEW IMPORT

ALL_CHANNELS: List[Channel] = [
    GitHubChannel(),
    TwitterChannel(),
    YouTubeChannel(),
    RedditChannel(),
    BilibiliChannel(),
    XiaoHongShuChannel(),
    LinkedInChannel(),
    XiaoyuzhouChannel(),
    V2EXChannel(),
    XueqiuChannel(),
    RSSChannel(),
    ExaSearchChannel(),
    WebChannel(),
    InstagramChannel(),                 # NEW INSTANCE

]

```

This registry is the discovery mechanism used by the `doctor` command to run health checks across all platforms. Without this registration step, the channel remains invisible to the CLI and core routing logic.

## Step 3: Implement Backend Probing Logic

The `check` method verifies whether required upstream tools are installed and functional. Use the `probe_command` helper from [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) for standard CLI tools, or implement custom validation logic as shown in the reference implementation at [`agent_reach/channels/twitter.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py).

Your `check` method must return one of the following patterns:

- **`None`** — Backend is not installed; exclude from candidates
- **`("ok", "message")`** — Fully functional; preferred status
- **`("warn", "message")`** — Installed but requires configuration (e.g., authentication)
- **`("error", "message")`** — Broken or unusable

The method must also set `self.active_backend` to the selected backend string, or leave it as `None` if no viable backend exists. This follows the same two-stage probing pattern used in existing channels, where results are collected first, then filtered by priority status.

## Step 4: Update Documentation and Tests

While the CLI automatically pulls `Channel.description` for the `--list` flag, add platform-specific documentation under `docs/` detailing installation requirements and environment variables. For testing, mirror the style of existing unit tests in `tests/test_channels/` to verify `can_handle` URL matching and `check` method outcomes under mock conditions.

## Using Your New Channel

Once registered, interact with your channel programmatically or via CLI:

```python
from agent_reach.channels import get_channel

insta = get_channel('instagram')
url = "https://www.instagram.com/p/CG0UU3ZBzZb/"

# Check URL support

assert insta.can_handle(url) is True

# Run health check

status, msg = insta.check()
print(f"Backend: {insta.active_backend}, Status: {status}")

```

Override the backend priority via configuration:

```yaml

# config.yaml

instagram_backend: opencli

```

Or via environment variable:

```bash
export INSTAGRAM_BACKEND=opencli

```

## Summary

- **Create** a new file in `agent_reach/channels/<platform>.py` subclassing `Channel` with `name`, `description`, `backends`, and `tier` attributes.
- **Implement** `can_handle(url)` to detect platform-specific URLs and `check(config)` to probe backend health using `probe_command` or custom logic.
- **Register** the channel instance in `ALL_CHANNELS` inside [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) to enable discovery by the `doctor` command and core router.
- **Return** standardized tuples from `check` (`ok`, `warn`, `error`, or `None`) and set `self.active_backend` to the working backend.
- **Configure** backend priority via the `<channel>_backend` config key or `<CHANNEL>_BACKEND` environment variable, handled automatically by `ordered_backends`.

## Frequently Asked Questions

### What is the difference between `can_handle` and `check` in an Agent Reach channel?

The `can_handle` method determines whether a given URL belongs to the platform (e.g., checking if the domain contains "instagram.com"), while the `check` method verifies that the external tool or API (the backend) is actually installed and functional on the system. `can_handle` runs during URL routing; `check` runs during health verification or initial setup.

### How do I specify which backend my channel should prioritize?

Users can override the default backend priority via a configuration file key named `<channel>_backend` (e.g., `instagram_backend: opencli`) or an environment variable like `INSTAGRAM_BACKEND`. The base class method `ordered_backends(config)` automatically moves the specified backend to the front of the candidate list before probing begins.

### What should my `check` method return if the backend tool is not installed?

If the backend is not installed, your probe should return `None`, which signals to the channel to exclude that backend from the candidate list. The parent `check` method will then iterate through remaining backends, ultimately returning `("warn", "message")` if no installations are found, or `("error", "message")` if installations exist but are broken.

### Do I need to modify the core routing logic to support a new platform?

No. Agent Reach uses a registry pattern in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py). Simply adding your channel class to the `ALL_CHANNELS` list is sufficient to make it visible to the CLI `doctor` command, the `get_channel()` factory function, and the core routing engine without touching any files outside the `channels/` directory.