# How to Add a New Platform to Agent Reach: Complete Workflow Guide

> Learn the workflow for adding a new platform to Agent Reach. Subclass Channel, implement methods, and register your new platform in this complete guide.

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

---

**To add a new platform to Agent Reach, create a Python module in `agent_reach/channels/` that subclasses the abstract `Channel` class, implements the `can_handle()` and `check()` methods, and registers 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 uses a plug-in channel architecture that isolates platform-specific logic into independent modules. Located in the Panniantong/Agent-Reach repository, this design means you can extend the tool to support new services—whether social networks, APIs, or content platforms—without touching the core routing logic. Each channel inherits from `Channel` in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py), declares its candidate backends, and implements health checks that the `doctor` command automatically discovers.

## Understanding the Channel Architecture

At the heart of the system is the abstract base class `Channel` defined in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py). This contract requires every implementation to expose four key attributes—`name`, `description`, `backends`, and `tier`—along with two critical methods: `can_handle(url)` for URL pattern matching and `check(config)` for backend validation.

The `ALL_CHANNELS` registry in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) serves as the single source of truth. When you run `agent-reach doctor`, the system iterates over this list and invokes each channel's `check()` method to report service availability. Because the core only routes calls to these registered channels, adding support for a new platform is a matter of implementing the interface and appending your class to the registry.

## Step-by-Step Workflow for Adding a Platform

### 1. Scaffold the Channel File

Create a new Python file at `agent_reach/channels/<platform>.py`, where `<platform>` is a lowercase identifier for your service (e.g., [`myplatform.py`](https://github.com/Panniantong/Agent-Reach/blob/main/myplatform.py)). This file will house your subclass and backend-specific logic.

### 2. Subclass Channel and Define Metadata

Import `Channel` from `.base` and declare the required class attributes:

- **`name`**: Machine-readable identifier (e.g., `"myplatform"`).
- **`description`**: Human-readable summary shown in the doctor report.
- **`backends`**: Ordered list of CLI tools or APIs the channel can use (e.g., `["mycli", "opencli", "rest_api"]`).
- **`tier`**: Integer indicating setup difficulty (`0` for zero-config, `1` for free API key, `2` for manual setup).

### 3. Implement URL Detection with can_handle()

The `can_handle(self, url: str) -> bool` method determines whether a given URL belongs to your platform. Use standard library tools like `urllib.parse.urlparse` to inspect the network location, as demonstrated in the existing `YouTubeChannel` and `TwitterChannel` implementations.

```python
from urllib.parse import urlparse

def can_handle(self, url: str) -> bool:
    """Return True if the URL belongs to this platform."""
    return "myplatform.com" in urlparse(url).netloc.lower()

```

### 4. Implement Health Checks with check()

The `check(self, config=None)` method probes each candidate backend using `probe_command` from `agent_reach/probe` and sets `self.active_backend` to the first working option. It must return a tuple of `(status, message)`, where `status` is one of `"ok"`, `"warn"`, `"off"`, or `"error"`.

Iterate through `self.ordered_backends(config)` to respect user overrides (via environment variables or config files). For CLI tools, use `probe_command(binary, ["--version"], package="binary_name")` to verify installation and basic functionality.

```python
from agent_reach.probe import probe_command

def check(self, config=None):
    """Probe backends and return health status."""
    self.active_backend = None
    
    for backend in self.ordered_backends(config):
        if backend == "mycli":
            probe = probe_command("mycli", ["--version"], package="mycli")
            if probe.ok:
                self.active_backend = "mycli"
                return "ok", "mycli ready."
    
    return "off", "No MyPlatform backends found."

```

### 5. Register in ALL_CHANNELS

Open [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) and import your class at the top. Append an instance to the `ALL_CHANNELS` list alongside existing channels like `TwitterChannel()` and `YouTubeChannel()`.

```python
from .myplatform import MyPlatformChannel

ALL_CHANNELS: List[Channel] = [
    GitHubChannel(),
    TwitterChannel(),
    YouTubeChannel(),
    # ... existing channels ...

    MyPlatformChannel(),  # New platform added here

]

```

### 6. Test with the Doctor Command

Run `agent-reach doctor` from your terminal. The system will automatically detect your new channel, execute its `check()` method, and display the status in the health report. If the status shows `"ok"` or `"warn"`, the channel is ready to accept URLs.

## Complete Implementation Example

Here is a minimal but complete channel implementation that supports CLI and API fallbacks:

```python

# agent_reach/channels/myplatform.py

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

"""MyPlatform — example channel implementation."""

from urllib.parse import urlparse
from agent_reach.probe import probe_command
from .base import Channel


class MyPlatformChannel(Channel):
    name = "myplatform"
    description = "MyPlatform content access"
    backends = ["mycli", "opencli", "rest_api"]
    tier = 1  # Requires API key or local CLI

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

    def check(self, config=None):
        """Probe ordered backends and activate the first available."""
        self.active_backend = None
        
        for backend in self.ordered_backends(config):
            if backend == "mycli":
                result = self._probe_mycli()
            elif backend == "opencli":
                result = self._probe_opencli()
            else:
                result = self._probe_api()
            
            if result:
                status, msg = result
                if status in ("ok", "warn"):
                    self.active_backend = backend
                    return status, msg
        
        return "off", "MyPlatform backends not found."

    def _probe_mycli(self):
        probe = probe_command("mycli", ["--version"], package="mycli")
        if probe.status == "missing":
            return None
        if not probe.ok:
            return "warn", "mycli installed but health check failed."
        return "ok", "mycli available for read/search."

    def _probe_opencli(self):
        from agent_reach.backends import opencli_status
        st = opencli_status()
        if not st.installed:
            return None
        return ("ok", "OpenCLI ready") if st.ready else ("warn", st.hint)

    def _probe_api(self):
        import urllib.request
        try:
            urllib.request.urlopen("https://api.myplatform.com/ping", timeout=5)
            return "ok", "Public API reachable."
        except Exception:
            return None

```

## How Backends and Probing Work

Agent Reach uses an **ordered backend** system that allows graceful fallbacks. The base class provides `ordered_backends(config)`, which checks for a user-specified override (e.g., `MYPLATFORM_BACKEND=opencli` in environment or config) before defaulting to the order defined in the `backends` list.

The `probe_command()` utility in [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) executes the binary with specified arguments and returns an object with `status` attributes (`missing`, `broken`, `ok`, `timeout`). This ensures that the `doctor` command reports accurate availability rather than simply checking if a file exists on disk.

Statuses returned by `check()` follow strict semantics:
- **`ok`**: Fully functional, ready for all operations.
- **`warn`**: Functional with limitations (e.g., rate limits, outdated version).
- **`off`**: Not installed or not configured.
- **`error`**: Installation detected but critically broken.

## Summary

- **Architecture**: Agent Reach uses a plug-in system where each platform is a Python module under `agent_reach/channels/` inheriting from `Channel`.
- **Required Implementation**: You must define `name`, `description`, `backends`, `tier`, and implement `can_handle()` for URL matching and `check()` for health validation.
- **Registration**: Import the new class into [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) and append an instance to `ALL_CHANNELS`.
- **Validation**: Use `agent-reach doctor` to automatically run your `check()` logic and verify backend availability without modifying core routing code.
- **Backends**: Declare multiple CLI tools or APIs in order of preference; `ordered_backends()` respects user configuration overrides.

## Frequently Asked Questions

### What methods must I implement when adding a new platform to Agent Reach?

You must implement `can_handle(self, url)` to recognize platform URLs and `check(self, config)` to validate backend availability. The base class `Channel` in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) provides the `ordered_backends()` helper, but you are responsible for writing the logic that probes each candidate backend and sets `self.active_backend`.

### How does Agent Reach handle multiple backends for the same platform?

The `backends` class attribute defines an ordered list of candidate tools. The `check()` method iterates through `self.ordered_backends(config)`, which returns the list while respecting any user-defined override from environment variables or config files. The first backend returning `"ok"` or `"warn"` becomes `active_backend` and receives all subsequent traffic for that platform.

### Why does the doctor command show my new channel as "off"?

A status of `"off"` indicates that `probe_command` could not locate the backend binary or the API endpoint returned a connection failure. Verify that the CLI tool is in your system `PATH`, the API credentials are configured in your Agent Reach config, and your `check()` method correctly handles the probing logic for each backend in the list.

### Can I add platforms that require API keys or authentication?

Yes. Set `tier = 1` (free key required) or `tier = 2` (complex manual setup) in your channel class. Use the `config` parameter passed to `check()` to read API keys from environment variables or configuration files. While `probe_command` handles CLI binaries, you can implement custom HTTP checks or library initialization inside `check()` to verify that credentials are valid before returning `"ok"`.