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

To add a new platform channel to Agent Reach, create a Python module in agent_reach/channels/ that inherits from the abstract Channel base class, implement the can_handle() and check() methods, and register the class in agent_reach/channels/__init__.py to enable automatic discovery.

Agent Reach treats every supported internet platform as a channel that lives in the agent_reach/channels/ package. Each channel inherits from the abstract base class defined in [agent_reach/channels/base.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py), which standardizes how the framework detects, probes, and routes platform-specific operations. This guide explains the architectural requirements and provides a production-ready template to add a new platform channel to Agent Reach.

Understand the Channel Architecture

The Channel base class defines the lifecycle contract that every platform must implement. Subclasses must declare four metadata properties and override two critical methods.

Metadata Properties:

  • name: A short identifier used in CLI arguments and configuration keys (e.g., "twitter").
  • description: Human-readable diagnostic text describing the platform.
  • backends: An ordered list of command-line tools that can fulfill requests for this channel (e.g., ["twitter-cli", "OpenCLI"]). The first healthy backend becomes the active instance.
  • tier: An integer indicating setup complexity: 0 for zero-config, 1 for requiring a free API key, or 2 for full user setup.

Core Methods:

  • can_handle(self, url: str) -> bool: Determines if a given URL belongs to this platform by parsing the domain or path.
  • check(self, config): Probes each candidate backend in ordered_backends and sets active_backend to the first usable tool. Returns a tuple of (status, message) where status is "ok", "warn", or "error".

The base class also provides ordered_backends(self, config), which returns the backend list respecting any user override via configuration variables or environment settings.

Step-by-Step Implementation

Step 1: Create the Channel Module

Create a new file at agent_reach/channels/<platform>.py. This module will contain your channel class and any helper functions for probing backends.


# agent_reach/channels/myplatform.py

from .base import Channel
from agent_reach.probe import probe_command

Step 2: Define Metadata and Class Properties

Declare the metadata fields as class attributes. The backends list should prioritize native CLIs over generic fallbacks.

class MyPlatformChannel(Channel):
    name = "myplatform"
    description = "MyPlatform – short description"
    backends = ["myplatform-cli", "OpenCLI", "legacy-cli"]
    tier = 1  # Requires API key but minimal setup

    active_backend = None

Step 3: Implement URL Detection with can_handle

The can_handle method must return True if the supplied URL belongs to your platform. Parse the hostname using urllib.parse to ensure robust matching.

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

Step 4: Implement Backend Probing with check

The check method iterates through ordered_backends, probes each candidate using probe_command, and selects the first healthy backend. Follow the pattern used in [agent_reach/channels/twitter.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py) for multi-backend support.

    def check(self, config=None):
        """Probe each backend in order; the first usable backend becomes active."""
        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))

        # Prefer "ok", then "warn"

        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(msg for _, _, msg in findings)

        return "warn", (
            "MyPlatform CLI not installed. Install it with:\n"
            "  pipx install myplatform-cli\n"
            "or use OpenCLI if you have a browser session."
        )

    def _check_myplatform_cli(self):
        """Return None if missing, or (status, message) tuple."""
        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"myplatform-cli exists but failed to run.\n{probe.hint}"
        if probe.ok and "ready" in probe.output.lower():
            return "ok", "myplatform-cli ready (search, read, …)"
        return "warn", "myplatform-cli installed but not authenticated"

    def _check_opencli(self):
        from agent_reach.backends import opencli_status
        st = opencli_status()
        if not st.installed:
            return None
        if st.broken:
            return "error", st.hint
        if st.ready:
            return "ok", "OpenCLI usable (browser-based login)"
        return "warn", st.hint

Step 5: Register in Package Index

Edit [agent_reach/channels/__init__.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) to import your new class so the auto-discovery machinery can locate it.

from .myplatform import MyPlatformChannel  # Add this line

Step 6: Verify with Diagnostics

Run the built-in diagnostics to confirm your channel is discovered and its check() method passes.

python -m agent_reach.cli doctor

You should see output similar to:


✔ MyPlatform (myplatform) – ok – myplatform-cli

Production-Ready Code Template

Copy the complete skeleton below into agent_reach/channels/myplatform.py to accelerate your implementation.


# agent_reach/channels/myplatform.py

"""MyPlatform channel implementation."""

from .base import Channel
from agent_reach.probe import probe_command


class MyPlatformChannel(Channel):
    name = "myplatform"
    description = "MyPlatform – short description"
    backends = ["myplatform-cli", "OpenCLI"]
    tier = 1
    active_backend = None

    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 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.\n"
            "  pipx install myplatform-cli\n"
            "or use OpenCLI if you have a logged-in browser."
        )

    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"myplatform-cli broken.\n{probe.hint}"
        if probe.ok and "ready" in probe.output.lower():
            return "ok", "myplatform-cli ready"
        return "warn", "myplatform-cli installed but not authenticated"

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

    def read(self, url: str):
        """Delegate reading to the selected backend."""
        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 Source Files

Summary

  • Inherit from Channel: All platform support modules must subclass the abstract base class in agent_reach/channels/base.py.
  • Implement can_handle: This method routes URLs to the correct channel by inspecting domains or path patterns.
  • Implement check: Probe candidate backends using probe_command and set active_backend to the first healthy tool.
  • Register the class: Import the new channel in agent_reach/channels/__init__.py to enable discovery.
  • Verify diagnostics: Run python -m agent_reach.cli doctor to validate the channel health and backend connectivity.

Frequently Asked Questions

What is the minimum required to implement a functional channel?

You must implement can_handle(self, url) to return True for your platform's URLs and check(self, config) to return a status tuple. While you can return hardcoded values from check for development, production channels should probe actual backend binaries using probe_command to ensure the tool is installed and authenticated.

How does Agent Reach decide which channel handles a specific URL?

The AgentReach router iterates through all registered channels and calls can_handle(url) on each instance. The first channel returning True receives the operation. Order matters, so ensure your URL patterns are specific enough to avoid collisions with generic channels.

Can a single channel support multiple backend tools?

Yes. Define multiple entries in the backends class property. The ordered_backends method respects user overrides, and your check implementation should probe each candidate in order. The first backend reporting "ok" or "warn" status becomes active_backend, allowing graceful fallbacks from native CLIs to generic tools like OpenCLI.

Why doesn't my new channel appear in the doctor diagnostics?

If python -m agent_reach.cli doctor skips your channel, verify that you imported the class in [agent_reach/channels/__init__.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) and that the file exists at agent_reach/channels/<name>.py. Also ensure the class name follows the *Channel naming convention and that Python can parse the module without syntax errors.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →