# How to Create and Add a Custom Channel for a New Platform in agent_reach/channels/

> Learn how to create and add a custom channel for a new platform in agent_reach/channels/. Subclass Channel, implement required methods, and register your new channel for Agent-Reach integration.

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

---

**To create and add a custom channel for a new platform in `agent_reach/channels/`, subclass the abstract `Channel` base class from [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py), implement `can_handle`, fill the required metadata attributes, 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).**

Agent Reach uses a registry-based discovery system to identify and route platform URLs through modular channel classes under `agent_reach/channels/`. Every supported platform lives as a Python module that inherits from the abstract `Channel` class, which enforces a public contract through `can_handle` and an optional `check` method. When you create and add a custom channel for a new platform in `agent_reach/channels/`, the CLI doctor command and URL routing logic in [`core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/core.py) automatically pick it up without further changes to the framework core.

## Understand the Channel Base Class

In [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py), the `Channel` abstract base class defines the interface that every platform must implement. It stores meta-information through class attributes and declares two key methods:

- `can_handle(self, url: str) -> bool` — required. Determines whether a given URL belongs to this platform.
- `check(self, config=None)` — optional. Performs runtime health checks and returns a status tuple.

The base class attributes include:

- `name` — the identifier consumed by the CLI.
- `description` — human-readable summary.
- `backends` — list of upstream tools (for example, `["yt-dlp"]`).
- `tier` — difficulty level where `0` means zero-config, `1` requires a free API key, and `2` needs full user setup.

By default, `check` returns `"ok"` and signals built-in support.

## Create a New Channel Module

To create and add a custom channel for a new platform in `agent_reach/channels/`, add a new Python file such as [`agent_reach/channels/myservice.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/myservice.py).

### Define Platform Metadata

Inside the module, subclass `Channel` and assign the required class attributes. These values drive both CLI help text and diagnostic reports.

### Implement URL Detection with can_handle

The `can_handle` method receives a URL string and must return `True` when the netloc matches the platform's domains. As shown in the reference [`agent_reach/channels/twitter.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py) implementation, the typical pattern uses `urllib.parse.urlparse` to extract the netloc and compares it against known domains.

### Add Optional Runtime Validation with check

If your platform relies on an external binary or API key, override `check` to verify availability at runtime. Return a tuple such as `("ok", "message")` or `("warn", "message")` so the `agent_reach cli doctor` command can surface actionable diagnostics.

The following example puts these pieces together:

```python

# agent_reach/channels/myservice.py

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

"""MyService – example custom channel."""

from urllib.parse import urlparse
from .base import Channel


class MyServiceChannel(Channel):
    # 1️⃣ Meta information

    name = "myservice"
    description = "MyService – custom platform"
    backends = ["myservice-cli"]          # upstream tool name(s)

    tier = 1                               # needs a free API key or token

    # 2️⃣ URL detection

    def can_handle(self, url: str) -> bool:
        """Return True when the URL belongs to MyService."""
        netloc = urlparse(url).netloc.lower()
        return "myservice.com" in netloc

    # 3️⃣ Optional health‑check (if we have a CLI we want to verify)

    def check(self, config=None):
        import shutil, subprocess
        binary = shutil.which("myservice")
        if not binary:
            return "warn", "myservice CLI not installed – install with `pipx install myservice-cli`"
        # Example: invoke the CLI with a harmless command to verify auth

        try:
            result = subprocess.run([binary, "status"], capture_output=True,
                                    encoding="utf-8", timeout=5)
            if result.returncode == 0:
                return "ok", "myservice CLI ready"
            return "warn", "myservice CLI present but returned error"
        except Exception:
            return "warn", "myservice CLI invocation failed"

```

## Register the Channel in the Central Registry

Discovery depends on the central list in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py). Import the new class and append an instance to `ALL_CHANNELS`. This single step makes the channel visible to both the doctor command and the URL routing logic in [`core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/core.py).

```python

# agent_reach/channels/__init__.py – register the new channel

from .myservice import MyServiceChannel          # ← add this import

ALL_CHANNELS: List[Channel] = [
    # … existing channel instances …

    MyServiceChannel(),                           # ← add to the list

]

```

Once imported and instantiated here, Agent Reach automatically includes your platform in health checks and URL resolution.

## How the New Channel Integrates with Agent Reach

After you create and add a custom channel for a new platform in `agent_reach/channels/` and register it in `ALL_CHANNELS`, two systems consume it immediately:

- **`agent_reach cli doctor`** iterates over all registered channels and runs their `check` method to report whether required backends are installed and configured.
- **[`core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/core.py)** iterates over `ALL_CHANNELS` at runtime, calling `can_handle` on each instance to route URLs to the correct platform handler.

No changes to [`core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/core.py) or other framework internals are required because the architecture relies entirely on the `ALL_CHANNELS` registry.

## Summary

- The `Channel` abstract base class in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) defines the contract every platform must follow.
- To create and add a custom channel for a new platform in `agent_reach/channels/`, create a module that subclasses `Channel`, implements `can_handle`, and sets `name`, `description`, `backends`, and `tier`.
- Override `check` whenever the platform needs runtime validation beyond the base class default.
- Register the channel by importing it into [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) and adding an instance to `ALL_CHANNELS`.
- The CLI doctor and URL routing in [`core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/core.py) discover the channel automatically through the registry.

## Frequently Asked Questions

### Do I need to modify core.py to support a new channel?

No. The routing logic in [`core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/core.py) iterates over `ALL_CHANNELS` from [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) and calls `can_handle` on each instance. As long as you register your new channel in that list, the framework recognizes it without touching any core files.

### What is the tier attribute used for?

The `tier` class attribute signals how much setup a channel requires. Agent Reach uses `0` for zero-config platforms, `1` for services that need a free API key or token, and `2` for platforms requiring extensive user configuration. This metadata helps users quickly understand prerequisites when running CLI commands.

### Can a channel support multiple domains?

Yes. The `can_handle` method can implement any parsing logic you need. Most implementations extract the netloc with `urllib.parse.urlparse` and check against one or more domain strings, so supporting multiple domains or subdomains is a matter of adjusting the boolean condition inside `can_handle`.

### What happens if I forget to add the channel to ALL_CHANNELS?

If you omit the instance from `ALL_CHANNELS` in [`agent_reach/channels/__init__.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py), the framework will not discover the channel. Consequently, `agent_reach cli doctor` will skip its health check, and URL routing in [`core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/core.py) will never invoke its `can_handle` method, effectively leaving the platform unsupported.