Channel Contract in Agent-Reach: The 4 Methods Platform Modules Must Implement

Platform modules in Agent-Reach must implement four core methods—can_handle, check, read, and search—to enable automatic URL routing, backend health diagnostics, and content retrieval across diverse internet services.

Agent-Reach is a unified CLI framework for accessing content across disparate web platforms. The channel contract defines the strict interface that every platform module must fulfill, allowing the core engine in agent_reach/core.py to route requests without knowing implementation details. This contract is enforced by the abstract Channel base class and concrete expectations for four critical operations.

The Four-Method Channel Contract

The contract is anchored by the abstract Channel class in agent_reach/channels/base.py. Each concrete channel must inherit from this base and provide specific implementations for the following four methods to integrate with the routing and diagnostic systems.

1. can_handle(url) – Route Detection

The can_handle method determines whether a channel can process a specific URL. Defined as an abstract method in agent_reach/channels/base.py (lines 40-44), it accepts a URL string and returns a boolean indicating ownership.


# From agent_reach/channels/base.py

def can_handle(self, url: str) -> bool:
    """Return True if this channel handles the URL."""
    raise NotImplementedError

Concrete implementations perform pattern matching. For example, TwitterChannel checks for twitter.com domains, while YouTubeChannel identifies youtube.com and youtu.be links, allowing the router to dispatch URLs to the correct backend.

2. check(config) – Backend Health Verification

The check method probes available backends to verify installation and functionality. It returns a tuple of (status, message) where status is "ok", "warn", "off", or "error", and sets self.active_backend to the selected backend instance.

While agent_reach/channels/base.py declares the abstract signature, concrete channels override this to probe specific tools. TwitterChannel in agent_reach/channels/twitter.py (lines 19-52) checks for twitter-cli, and YouTubeChannel in agent_reach/channels/youtube.py (lines 35-48) probes for yt-dlp availability.

def check(self, config=None):
    """Verify backend and return (status, message) tuple."""
    # Implementation probes self.backends

    status, msg = self._probe_backends(config)
    self.active_backend = self._select_backend()
    return status, msg

3. read(url) – Content Retrieval

The read method fetches raw content for a given URL. Unlike can_handle and check, this method is not abstract in the base class, but channels supporting content retrieval must implement it. The generic fallback in agent_reach/channels/web.py (lines 24-32) demonstrates a standard HTTP GET implementation that other channels can emulate.


# From agent_reach/channels/web.py

def read(self, url: str) -> str:
    """Fetch raw HTML/content via HTTP."""
    import requests
    response = requests.get(url, timeout=10)
    response.raise_for_status()
    return response.text

The search method executes platform-specific queries and returns a list of result objects. This enables the CLI to perform searches across YouTube, Twitter, and other indexed services. While the base class does not enforce this method, channels like TwitterChannel implement it to wrap API calls or CLI commands, returning structured data for the core engine to process.

def search(self, query: str) -> List[Any]:
    """Search platform and return list of results."""
    # Platform-specific implementation

    pass

How the Core Engine Uses the Contract

The agent_reach/core.py router relies on can_handle to select the appropriate channel for a URL. Once selected, it invokes check to verify readiness before calling read for content retrieval or search for queries. Additionally, agent_reach/doctor.py iterates through all registered channels, executing check to report system health and missing dependencies, utilizing the status tuples returned by each channel.

Implementation Example: Creating a Custom Channel

Below is a complete implementation of a hypothetical ExampleChannel demonstrating all four required methods:

from typing import List, Any, Tuple
from agent_reach.channels.base import Channel
from agent_reach.probe import probe_command

class ExampleChannel(Channel):
    name = "example"
    description = "Example platform module"
    backends = ["example-cli"]
    tier = 1

    def can_handle(self, url: str) -> bool:
        """Check if URL belongs to example.com domain."""
        return "example.com" in url.lower()

    def check(self, config=None) -> Tuple[str, str]:
        """Verify example-cli is installed and functional."""
        probe = probe_command("example-cli", ["--version"], 
                          package="example-cli")
        if probe.status == "missing":
            self.active_backend = None
            return "off", "example-cli not installed"
        self.active_backend = "example-cli"
        return "ok", "example-cli ready"

    def read(self, url: str) -> str:
        """Fetch content via HTTP GET."""
        import requests
        resp = requests.get(url, timeout=5)
        resp.raise_for_status()
        return resp.text

    def search(self, query: str) -> List[Any]:
        """Search platform using CLI."""
        import subprocess
        result = subprocess.run(
            ["example-cli", "search", query],
            capture_output=True, text=True
        )
        return result.stdout.splitlines()

Summary

  • can_handle: Returns True if the channel supports the provided URL, enabling automatic routing in agent_reach/core.py.
  • check: Validates backend availability and configuration, returning status tuples used by agent_reach/doctor.py for diagnostics.
  • read: Retrieves raw content for URLs; required for fetch operations, implemented in agent_reach/channels/web.py for HTTP-based platforms.
  • search: Executes platform-specific queries, returning lists of results for channels supporting search capabilities.

Frequently Asked Questions

Is the read method mandatory for all channels?

No. While can_handle and check are mandatory for all channels, read is only required for channels that support content retrieval. Channels focused solely on search functionality or metadata extraction may omit read but must still inherit from the base Channel class in agent_reach/channels/base.py.

What happens if can_handle returns False for all registered channels?

If no channel's can_handle method returns True for a given URL, the router in agent_reach/core.py typically falls back to the generic WebChannel implemented in agent_reach/channels/web.py, which uses standard HTTP GET requests to retrieve content.

How does the check method report configuration errors?

The check method returns a tuple of (status, message). Status values include "ok" for healthy backends, "warn" for degraded but functional states, "off" for missing dependencies, and "error" for configuration failures. The agent_reach/doctor.py module aggregates these reports to display system health diagnostics.

Can I implement only search without read?

Yes. Channels may implement any subset of the optional methods. If your platform supports search API access but not direct content reading (or vice versa), you only need to implement the relevant methods. The core router dispatches calls based on the method signatures present, though you must still provide can_handle and check to satisfy the base contract.

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 →