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

To add a new platform channel to Agent Reach, subclass the Channel base class from 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.

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. 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 and agent_reach/channels/reddit.py.

Step 1: Create the Channel Class

Create a new file in agent_reach/channels/ (e.g., myplatform.py) and subclass Channel. Define the class attributes and implement can_handle:


# 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.

    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 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:

    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 and add an instance to ALL_CHANNELS:


# 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 where the --list-platforms option iterates through Channel.name and Channel.description.

Create tests following the pattern in tests/test_twitter_channel.py:


# 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:


# 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 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 by adding it to ALL_CHANNELS.
  • Add optional read/search methods following signatures from existing channels like youtube.py and reddit.py.
  • Test thoroughly using pytest and verify integration with agent_reach/doctor.py and 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 iterates over ALL_CHANNELS defined in agent_reach/channels/__init__.py. If your channel is missing, ensure you have imported the class in __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.

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 →