# How to Add a New Platform Channel to Agent Reach: A Complete Developer Guide

> Learn how to add a new platform channel to Agent Reach. This guide details subclassing the Channel base class, implementing methods, and registering your channel for seamless integration.

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

---

**To add a new platform channel to Agent Reach, subclass the `Channel` base class in [`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, and register the 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 provides a modular architecture where every supported internet platform is implemented as a **Channel**. This design allows developers to extend the framework by adding support for new platforms without modifying core routing logic. The repository `Panniantong/Agent-Reach` uses a consistent pattern across all integrations, from **YouTube** to **Reddit**, making it straightforward to add your own platform support.

## Understanding the Channel Architecture

### What is a Channel?

A channel is a thin wrapper that communicates three essential capabilities to Agent Reach's core router:

1. **URL Handling**: The `can_handle` method determines if the channel can process a given URL.
2. **Dependency Verification**: The `check` method validates whether required upstream tools are installed and configured.
3. **Content Operations**: Optional methods like `read` and `search` implement platform-specific functionality.

The abstract base class defining this contract lives in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py). All concrete implementations must inherit from this `Channel` class and override the required methods.

### The Tier System

Agent Reach categorizes channels into three tiers based on configuration complexity:

- **Tier 0 (Zero-config)**: Works out-of-the-box without external dependencies (e.g., `WebChannel`).
- **Tier 1**: Requires a free API key or a simple binary installation (e.g., `TwitterChannel`).
- **Tier 2**: Needs complex authentication such as cookies or OAuth flows.

The `tier` class attribute signals setup difficulty to users when they run the doctor diagnostic tool in [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py).

## Step-by-Step Implementation Guide

### 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` from [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py). Define the required class attributes:

```python

# agent_reach/channels/myplatform.py

from .base import Channel
import shutil

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

```

### Step 2: Implement Required Methods

Every channel must implement `can_handle` and `check`. The `can_handle` method receives a URL string and returns a boolean indicating whether this channel should handle it:

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

```

The `check` method returns a tuple `(status, message)` where status is one of `ok`, `warn`, `off`, or `error`:

```python
    def check(self, config=None):
        binary = shutil.which("mycli")
        if not binary:
            return "off", "mycli not installed. Install: 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 ready"
        except Exception:
            pass
        return "warn", "mycli installed but not functioning"

```

Optionally implement `read` and `search` following the patterns 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):

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

```

### Step 3: Register in ALL_CHANNELS

Import and instantiate your channel in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py). Add it to the `ALL_CHANNELS` list to make it visible to the doctor check and core router:

```python

# agent_reach/channels/__init__.py

from .myplatform import MyPlatformChannel

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

    MyPlatformChannel(),
]

```

### Step 4: Update CLI Documentation (Optional)

To include your platform in the `--list-platforms` output, modify [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) to display the `Channel.name` and `Channel.description` attributes.

### Step 5: Write Tests

Add test coverage in [`tests/test_channels.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_channels.py) or create a dedicated file like [`tests/test_myplatform_channel.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_myplatform_channel.py). Follow the pattern from [`tests/test_twitter_channel.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_twitter_channel.py) to verify both success and failure states:

```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):
    # Simulate missing binary

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

```

## Complete Working Example

Here is a full implementation combining all components:

```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 not installed"
        try:
            r = subprocess.run([binary, "--version"], capture_output=True,
                               encoding="utf-8", timeout=5)
            if r.returncode == 0:
                return "ok", "mycli ready"
        except Exception:
            pass
        return "warn", "mycli installed but not functioning"

    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

    def search(self, query: str) -> List[str]:
        binary = shutil.which("mycli")
        r = subprocess.run([binary, "search", query], capture_output=True,
                           encoding="utf-8", timeout=15)
        return r.stdout.strip().split("\n") if r.stdout else []

```

## How the Doctor Validates Channels

The [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) module aggregates `check` results from all registered channels. When users run diagnostics, the doctor iterates through `ALL_CHANNELS` from [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py), calling `check()` on each instance. The returned status codes determine the diagnostic output:

- **ok**: Dependency satisfied and functioning
- **warn**: Installed but potentially misconfigured
- **off**: Not installed (acceptable for optional platforms)
- **error**: Critical failure requiring attention

This architecture ensures that adding a new platform channel to Agent Reach automatically integrates it into the system health checks without additional configuration.

## Summary

- **Subclass `Channel`**: Inherit from the base class in [`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`.
- **Implement `can_handle`**: Return `True` for URLs your platform supports by parsing the domain or path.
- **Implement `check`**: Return a status tuple verifying that required binaries or API keys are available.
- **Register**: Import the class and append an instance to `ALL_CHANNELS` in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py).
- **Test**: Verify `can_handle` logic and `check` responses for both installed and missing dependencies.

## Frequently Asked Questions

### What methods are required when adding a new platform channel to Agent Reach?

You must implement `can_handle(self, url: str) -> bool` and `check(self, config=None) -> Tuple[str, str]`. The `can_handle` method determines URL routing, while `check` validates dependencies. Optional methods include `read` for fetching content and `search` for querying platforms, following the signatures defined in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py).

### How does Agent Reach determine if a channel can handle a specific URL?

The core router calls `can_handle` on each registered channel in `ALL_CHANNELS` until one returns `True`. Parse the URL using `urllib.parse.urlparse` to check domains or path patterns, as demonstrated 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).

### What is the difference between tier 0, tier 1, and tier 2 channels?

**Tier 0** channels require no configuration and work immediately (like `WebChannel`). **Tier 1** channels need a free API key or simple binary installation (like `TwitterChannel`). **Tier 2** channels require complex setup such as authentication cookies or OAuth flows. The `tier` attribute in your channel class signals this to users via the doctor diagnostic tool.

### Where should I add tests for my new channel?

Create a test file in the `tests/` directory, such as [`tests/test_myplatform_channel.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_myplatform_channel.py), following the structure of [`tests/test_twitter_channel.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_twitter_channel.py). Test both the `can_handle` method with various URLs and the `check` method under different dependency states (installed, missing, and misconfigured). Run `pytest tests/ -v` to validate your implementation against the full suite.