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

> Learn how to add a new platform to Agent Reach by developing a Python module. Follow our complete channel development workflow to integrate new channels efficiently.

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

---

**Adding a new platform to Agent Reach requires creating a Python module that subclasses the abstract `Channel` base class, implementing the `can_handle` and `check` methods to declare URL patterns and health-check logic, and registering the new instance in the `ALL_CHANNELS` registry located in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py).**

Agent Reach is an open-source agent framework built around a **plug-in channel architecture** that routes agent requests to external platform APIs and CLI tools. Each supported service—from YouTube to Twitter—lives as an independent module under `agent_reach/channels/` that inherits from the base `Channel` class. This design allows developers to extend the system with new platform integrations without modifying the core routing logic in [`agent_reach/core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/core.py).

## Understanding the Channel Architecture

The Agent Reach platform abstraction layer consists of three core components defined in the source code:

1. **`Channel` base class** ([`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py)): Defines the contract that every platform must implement, including `can_handle(url)` for URL detection and `check()` for backend health verification.
2. **Channel registry** ([`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py)): Maintains the `ALL_CHANNELS` list that the `doctor` command iterates to discover available platforms.
3. **Probe utilities** ([`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py)): Provides `probe_command()` to verify that external CLI binaries exist and respond correctly.

When you add a new platform, you create a **declarative wrapper** that tells Agent Reach how to detect URLs for your service and which external tools (backends) can fulfill requests. The core engine never executes platform-specific logic directly; it delegates to your channel's methods.

## Step-by-Step Implementation Workflow

### Step 1: Create the Channel Module

Create a new Python file in the channels directory:

```bash
touch agent_reach/channels/myplatform.py

```

In this file, import the base class and define your channel subclass:

```python

# agent_reach/channels/myplatform.py

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

class MyPlatformChannel(Channel):
    name = "myplatform"
    description = "MyPlatform – read and search content"
    backends = ["mycli", "OpenCLI", "myapi"]
    tier = 1  # 0 = zero-config, 1 = free key required, 2 = manual setup

```

### Step 2: Implement URL Detection

Override the `can_handle` method to identify URLs belonging to your platform. This method receives a raw URL string and returns a boolean:

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

```

The `AgentReach` router uses this method to determine which channel should process a given user request.

### Step 3: Implement Backend Health Checks

The `check` method probes each candidate backend in order and selects the first usable one. It must return a tuple of `(status, message)` where status is one of `ok`, `warn`, `off`, or `error`:

```python
    def check(self, config=None):
        """Health-check that picks the first usable backend."""
        self.active_backend = None
        findings = []

        for backend in self.ordered_backends(config):
            if backend == "mycli":
                result = self._check_mycli()
            elif backend == "OpenCLI":
                result = self._check_opencli()
            else:
                result = self._check_api()
            
            if result:
                findings.append((backend, *result))

        # Prefer 'ok' over 'warn'

        for wanted in ("ok", "warn"):
            for backend, status, message in findings:
                if status == wanted:
                    self.active_backend = backend
                    return status, message
        
        return ("error", "No MyPlatform backends available.")

```

Use `self.ordered_backends(config)` to respect user-level backend overrides via environment variables or configuration files.

### Step 4: Add Backend-Specific Probe Helpers

Implement private methods that use `probe_command` to verify CLI availability:

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

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

```

### Step 5: Register the Channel

Open [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) and import your new class, then append an instance to the `ALL_CHANNELS` list:

```python

# agent_reach/channels/__init__.py

from .myplatform import MyPlatformChannel  # New import

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

    MyPlatformChannel(),  # New instance

]

```

This registration makes the channel discoverable to the `doctor` command and the `AgentReach` core.

### Step 6: Verify with the Doctor Command

Run the built-in diagnostic tool to verify your implementation:

```bash
agent-reach doctor

```

The doctor iterates through `ALL_CHANNELS`, calls `check()` on each, and reports the status. If your `check` method returns `ok` or `warn`, the platform appears as available in the output.

## Complete Working Example

Here is a full implementation skeleton combining all required components:

```python

# agent_reach/channels/myplatform.py

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

"""MyPlatform channel implementation for Agent Reach."""

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


class MyPlatformChannel(Channel):
    name = "myplatform"
    description = "MyPlatform – read and search"
    backends = ["mycli", "OpenCLI", "myapi"]
    tier = 1

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

    def check(self, config=None):
        """Health-check that picks the first usable backend."""
        self.active_backend = None
        findings = []

        for backend in self.ordered_backends(config):
            if backend == "mycli":
                result = self._check_mycli()
            elif backend == "OpenCLI":
                result = self._check_opencli()
            else:
                result = self._check_api()
            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

        return ("error", "MyPlatform backends not found.")

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

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

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

```

## How Backend Selection Works

The `Channel` base class provides `ordered_backends(config)` which returns the `backends` list filtered by any user-specified preference. When a user sets the `MYPLATFORM_BACKEND` environment variable or configuration key, the method moves that backend to the front of the list.

The `check` method iterates through this ordered list and calls your backend-specific probe logic. The first backend returning `ok` becomes `self.active_backend`, which the agent uses for subsequent operations. If only `warn` statuses are available, the channel operates in degraded mode. If all backends return `error` or `None`, the channel is marked offline.

## Summary

- **Create** a new module in `agent_reach/channels/<platform>.py` subclassing `Channel` from [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py).
- **Implement** `can_handle(url)` to recognize platform URLs and `check(config)` to probe available backends using `probe_command`.
- **Register** the channel instance in `ALL_CHANNELS` inside [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py).
- **Verify** installation using `agent-reach doctor`, which automatically detects the new channel via the registry.
- **Extend** functionality by adding methods like `read`, `search`, or `transcribe` that call the active backend, following the pattern in [`agent_reach/channels/youtube.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/youtube.py).

## Frequently Asked Questions

### Do I need to modify Agent Reach core files to add a platform?

No. The architecture is designed for zero-impact extension. You only create a new file in `agent_reach/channels/` and add one line to [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py). The `AgentReach` class in [`agent_reach/core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/core.py) delegates to `doctor.check_all()`, which automatically discovers your channel through the `ALL_CHANNELS` registry.

### What are the tier levels in the Channel class?

The `tier` attribute indicates setup complexity: **0** means zero-configuration (works out of the box), **1** requires a free API key or simple CLI installation, and **2** indicates manual setup or paid API requirements. This helps the `doctor` command prioritize which channels to recommend for installation.

### How does the automatic backend detection work?

The `check` method probes each backend string in `self.ordered_backends(config)` using platform-specific logic you implement. The `probe_command` utility in [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) runs the backend CLI with version flags to verify it exists and executes correctly. The first successful backend is stored in `self.active_backend` and used for all subsequent operations.

### Can I add optional capabilities like search or transcription?

Yes. While `can_handle` and `check` are required, you can add optional methods such as `read`, `search`, or `transcribe` following the conventions in [`agent_reach/channels/youtube.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/youtube.py). The agent inspects available methods at runtime, so adding these capabilities extends the platform's functionality without breaking existing code.