# How to Add a New Platform Channel to Agent Reach: A Step-by-Step Guide

> Learn how to add a new platform channel to Agent Reach. Follow our step-by-step guide to subclass the Channel base class, implement key methods, and register your new channel.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: architecture
- Published: 2026-06-14

---

**To add a new platform channel to Agent Reach, subclass the `Channel` base class from [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py), implement the `can_handle` and `check` methods, optionally define `read` and `search` functionality, and register your instance in the `ALL_CHANNELS` list within [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py).**

Agent Reach (Panniantong/Agent-Reach) treats every supported internet platform as a **Channel**—a modular wrapper that tells the core routing logic which URLs it can handle and how to validate required dependencies. Adding support for a new platform requires implementing a minimal contract and registering your component in the channel registry. This guide provides the exact file paths, method signatures, and implementation patterns used in the source code.

## Understanding the Channel Architecture

Every channel in Agent Reach inherits from the abstract `Channel` class defined in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py). The architecture requires two core methods:

- **`can_handle(self, url: str) -> bool`**: Determines if this channel should process a given URL based on domain matching or pattern recognition.
- **`check(self, config=None)`**: Validates that required upstream tools (binaries, APIs, or credentials) are installed and configured. Returns a tuple `(status, message)` where `status` is one of `ok`, `warn`, `off`, or `error`.

Optional methods include `read(self, url: str) -> str` for content extraction and `search(self, query: str) -> List[str]` for platform-specific search functionality, as implemented in [`agent_reach/channels/youtube.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/youtube.py) and [`agent_reach/channels/reddit.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/reddit.py).

## Step 1: Create the Channel Class

Create a new file in `agent_reach/channels/` (e.g., [`myplatform.py`](https://github.com/Panniantong/Agent-Reach/blob/main/myplatform.py)) and subclass `Channel`. Define the class attributes and implement `can_handle`:

```python

# agent_reach/channels/myplatform.py

import shutil
from urllib.parse import urlparse
from .base import Channel

class MyPlatformChannel(Channel):
    name = "myplatform"
    description = "MyPlatform – articles and comments"
    backends = ["mycli"]  # Required binaries or tools

    tier = 1            # 0=no config, 1=API key/binary, 2=complex auth

    def can_handle(self, url: str) -> bool:
        domain = urlparse(url).netloc.lower()
        return "myplatform.com" in domain

```

## Step 2: Implement the Check Method

The `check` method validates dependencies and returns a status tuple. The **tier** attribute indicates setup complexity: **tier 0** works out-of-the-box (like `WebChannel`), **tier 1** requires a free API key or simple binary, and **tier 2** needs extra setup like cookie authentication.

```python
    def check(self, config=None):
        binary = shutil.which("mycli")
        if not binary:
            return "off", "mycli 未安装。安装：pip install mycli"
        
        try:
            import subprocess
            r = subprocess.run([binary, "--version"], capture_output=True,
                               encoding="utf-8", timeout=5)
            if r.returncode == 0:
                return "ok", "mycli 已就绪"
        except Exception:
            pass
        return "warn", "mycli 已安装但无法运行"

```

The doctor check located in [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) aggregates these results across all channels to report system health.

## Step 3: Add Content Access Methods (Optional)

If your platform supports reading content or searching, implement the standard signatures:

```python
    def read(self, url: str) -> str:
        """Return article text as plain Markdown."""
        import subprocess
        binary = shutil.which("mycli")
        r = subprocess.run([binary, "read", url], capture_output=True,
                           encoding="utf-8", timeout=15)
        return r.stdout

    def search(self, query: str) -> List[str]:
        """Return list of URLs matching the query."""
        # Implementation specific to platform API

        pass

```

## Step 4: Register in the Channel Registry

Import your class in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) and add an instance to `ALL_CHANNELS`:

```python

# agent_reach/channels/__init__.py

from .myplatform import MyPlatformChannel  # Add import

ALL_CHANNELS: List[Channel] = [
    # ... existing channels ...

    MyPlatformChannel(),  # Add instance

]

```

This registration makes the channel visible to the doctor check and the core router.

## Step 5: Update CLI and Testing

To include your platform in `agent-reach --help` output, update [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) where the `--list-platforms` option iterates through `Channel.name` and `Channel.description`.

Create tests following the pattern in [`tests/test_twitter_channel.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_twitter_channel.py):

```python

# tests/test_myplatform_channel.py

def test_myplatform_can_handle():
    from agent_reach.channels import get_channel
    ch = get_channel("myplatform")
    assert ch is not None
    assert ch.can_handle("https://myplatform.com/article/123")

def test_myplatform_check_off(monkeypatch):
    monkeypatch.setattr("shutil.which", lambda _: None)
    ch = get_channel("myplatform")
    status, _ = ch.check()
    assert status == "off"

```

Run the full test suite with `pytest tests/ -v` to ensure no regressions.

## Complete Working Example

Here is a complete implementation for a hypothetical platform requiring the `mycli` binary:

```python

# agent_reach/channels/myplatform.py

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

"""MyPlatform — read and search via `mycli`."""

import shutil
import subprocess
from typing import List
from .base import Channel


class MyPlatformChannel(Channel):
    name = "myplatform"
    description = "MyPlatform – articles and comments"
    backends = ["mycli"]
    tier = 1

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

    def check(self, config=None):
        binary = shutil.which("mycli")
        if not binary:
            return "off", "mycli 未安装。安装：pip install mycli"
        try:
            r = subprocess.run([binary, "--version"], capture_output=True,
                               encoding="utf-8", timeout=5)
            if r.returncode == 0:
                return "ok", "mycli 已就绪"
        except Exception:
            pass
        return "warn", "mycli 已安装但无法运行"

    def read(self, url: str) -> str:
        binary = shutil.which("mycli")
        r = subprocess.run([binary, "read", url], capture_output=True,
                           encoding="utf-8", timeout=15)
        return r.stdout

```

## Summary

- **Subclass `Channel`** from [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) and set `name`, `description`, `backends`, and `tier` attributes.
- **Implement `can_handle`** to route URLs to your channel based on domain or pattern matching.
- **Implement `check`** returning `(status, message)` to validate dependencies, using statuses `ok`, `warn`, `off`, or `error`.
- **Register the instance** in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) by adding it to `ALL_CHANNELS`.
- **Add optional `read`/`search` methods** following signatures from existing channels like [`youtube.py`](https://github.com/Panniantong/Agent-Reach/blob/main/youtube.py) and [`reddit.py`](https://github.com/Panniantong/Agent-Reach/blob/main/reddit.py).
- **Test thoroughly** using `pytest` and verify integration with [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) and [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py).

## Frequently Asked Questions

### What is the minimum required implementation for a new Agent Reach channel?

You must subclass `Channel` and implement `can_handle(self, url: str) -> bool` for URL routing and `check(self, config=None)` for dependency validation. The `check` method must return a tuple of `(status, message)` where status is one of `ok`, `warn`, `off`, or `error`. All other methods like `read` and `search` are optional.

### How does the tier system work in Agent Reach channels?

The `tier` attribute categorizes setup complexity: **tier 0** channels work out-of-the-box without configuration (e.g., `WebChannel`), **tier 1** channels require a free API key or simple binary installation, and **tier 2** channels need complex authentication like cookie-based logins. This tier system helps users understand setup requirements when running the doctor check.

### Why is my new channel not appearing in the doctor check results?

The doctor check in [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) iterates over `ALL_CHANNELS` defined in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py). If your channel is missing, ensure you have imported the class in [`__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/__init__.py) and appended an instance to the `ALL_CHANNELS` list. Also verify there are no import errors preventing the module from loading.

### Can I implement a channel without the `read` or `search` methods?

Yes. The `read` and `search` methods are optional. If your platform only needs to validate that it can handle certain URLs (for routing purposes) but does not support content extraction or search, you only need to implement `can_handle` and `check`. The base class provides default implementations that raise `NotImplementedError` for these optional operations.