# How to Add a Custom Platform Channel to Agent Reach: Complete Implementation Guide

> Learn to add a custom platform channel to Agent Reach with this complete implementation guide. Follow step-by-step instructions to create and register your new channel seamlessly.

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

---

**To add a custom platform channel to Agent Reach, create a Python module in `agent_reach/channels/` that inherits from the `Channel` base class, implement the `can_handle()` and `check()` methods, and register the class in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py)**.

Agent Reach treats every internet platform as a pluggable channel within its [`agent_reach/channels/`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/) package. Whether you need to integrate a niche forum or a proprietary API, extending the framework requires implementing a consistent interface defined in the abstract base class.

## Understanding the Channel Architecture

The abstract `Channel` class in [[`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py)](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) defines the contract that all platform implementations must follow. Every channel declares metadata properties that the CLI and router consume:

- **name**: Short identifier used in configuration keys and CLI arguments
- **description**: Human-readable summary for diagnostic output  
- **backends**: Ordered list of command-line tools capable of fulfilling requests
- **tier**: Complexity level (0=zero-config, 1=requires API key, 2=requires full setup)
- **active_backend**: Runtime selection of the first healthy backend from the list

The base class provides two critical helper methods. The `ordered_backends(self, config)` method respects user overrides via configuration or environment variables, while `check(self, config)` validates backend availability. Real channels override `check()` to probe specific binaries, as demonstrated in [[`agent_reach/channels/twitter.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py)](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py).

## Step-by-Step Implementation Guide

### Step 1: Create the Channel Module

Create a new file at `agent_reach/channels/<platform>.py`. This module will contain your platform-specific logic and configuration.

### Step 2: Import Required Dependencies

Import the base class and probing utilities from the framework:

```python
from .base import Channel
from agent_reach.probe import probe_command

```

### Step 3: Define Channel Metadata

Set the required class attributes that identify your platform:

```python
class MyPlatformChannel(Channel):
    name = "myplatform"
    description = "MyPlatform integration for content retrieval"
    backends = ["myplatform-cli", "OpenCLI"]
    tier = 1

```

### Step 4: Implement URL Detection with `can_handle()`

This method determines if the channel handles a given URL by inspecting the domain:

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

```

### Step 5: Implement Backend Probing with `check()`

Override `check()` to probe each backend and select the first healthy one:

```python
def check(self, config=None):
    self.active_backend = None
    findings = []
    
    for backend in self.ordered_backends(config):
        if backend == "myplatform-cli":
            result = self._check_myplatform_cli()
        elif backend == "OpenCLI":
            result = self._check_opencli()
        else:
            continue
            
        if result is None:
            continue
        findings.append((backend, *result))
    
    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", "MyPlatform CLI not installed. Install with: pipx install myplatform-cli"

```

### Step 6: Register the Channel

Edit [[`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py)](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) to import your class for auto-discovery:

```python
from .myplatform import MyPlatformChannel

```

### Step 7: Verify with Diagnostics

Run the built-in diagnostics to confirm your channel is recognized:

```bash
python -m agent_reach.cli doctor

```

You should see output similar to:

```

✔ MyPlatform (myplatform) – ok – myplatform-cli

```

## Complete Working Example

Here is a complete, production-ready template for [`agent_reach/channels/myplatform.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/myplatform.py):

```python
from .base import Channel
from agent_reach.probe import probe_command


class MyPlatformChannel(Channel):
    name = "myplatform"
    description = "MyPlatform integration"
    backends = ["myplatform-cli", "OpenCLI"]
    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):
        self.active_backend = None
        findings = []
        
        for backend in self.ordered_backends(config):
            if backend == "myplatform-cli":
                result = self._check_native()
            elif backend == "OpenCLI":
                result = self._check_opencli()
            else:
                continue
                
            if result:
                findings.append((backend, *result))
        
        for wanted in ("ok", "warn"):
            for backend, status, msg in findings:
                if status == wanted:
                    self.active_backend = backend
                    return status, msg
        
        return "warn", "No backend available"

    def _check_native(self):
        probe = probe_command(
            "myplatform", ["status"], timeout=15, retries=1, package="myplatform-cli"
        )
        if probe.status == "missing":
            return None
        if probe.status == "broken":
            return "error", f"CLI broken: {probe.hint}"
        if probe.ok and "ready" in probe.output.lower():
            return "ok", "Native CLI ready"
        return "warn", "CLI installed but not authenticated"

```

## Optional: Adding Read and Search Capabilities

To support content retrieval, implement the `read()` method that delegates to the active backend:

```python
def read(self, url: str):
    if self.active_backend == "myplatform-cli":
        return probe_command("myplatform", ["read", url]).output
    if self.active_backend == "OpenCLI":
        return probe_command("opencli", ["myplatform", "get", url]).output
    raise RuntimeError("No active backend for read")

```

## Key Files Reference

- **[[`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py)](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py)** - Abstract `Channel` class with `ordered_backends()` and default `check()` implementations
- **[[`agent_reach/channels/twitter.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py)](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py)** - Reference implementation showing multi-backend probing patterns
- **[[`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py)](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py)** - Registration point where channels are imported for discovery
- **[[`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py)](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py)** - `probe_command()` utility for checking CLI tool availability

## Summary

- Create a new module in `agent_reach/channels/` inheriting from `Channel`
- Implement `can_handle()` to recognize your platform's URLs using domain parsing
- Override `check()` to probe and select healthy backends from your `backends` list
- Register the class in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) to enable auto-discovery
- Verify your implementation using `python -m agent_reach.cli doctor`

## Frequently Asked Questions

### What is the minimum required code to add a custom platform channel to Agent Reach?

You need a class inheriting from `Channel` with `name`, `description`, and `backends` defined, plus implementations of `can_handle()` and `check()`. Register this class in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) to enable discovery by the CLI and router.

### How does Agent Reach determine which channel handles a specific URL?

The router iterates through all registered channels and calls `can_handle(url)` on each instance. The first channel returning `True` receives the request. This logic ensures that platforms with specific domain patterns are matched correctly.

### Can I use multiple backends for a single platform channel?

Yes. The `backends` list accepts multiple CLI tools in priority order. The `check()` method probes each until finding a healthy one, storing the selection in `active_backend` for subsequent operations. This provides fallback options if the primary tool is unavailable.

### Where should I place my custom channel files in the repository?

Place new channel modules at `agent_reach/channels/<platform_name>.py` following the existing naming convention. The filename should match the platform identifier, and you must import the class in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) for the auto-discovery machinery to locate it.