How to Add a New Platform Channel to Agent Reach: Step-by-Step Channel Contract Guide
To add a new platform channel to Agent Reach, create a Python module in agent_reach/channels/ that subclasses the abstract Channel base class, implements the required contract methods (can_handle, read, search, check), defines the metadata attributes (name, description, backends, tier), and exports the class in agent_reach/channels/__init__.py so the core router can discover it.
Agent Reach is an extensible open-source framework that unifies internet platforms through a modular channel architecture. Each platform is encapsulated as a channel that adheres to a strict contract defined in the base class. This guide walks you through the exact steps to add a new platform channel to Agent Reach while satisfying the Channel contract requirements as implemented in the source code.
Understanding the Channel Contract
The Channel contract is defined in agent_reach/channels/base.py. Any concrete channel must inherit from the Channel abstract base class and provide the following attributes and methods:
name(str): Short identifier used in configuration files and CLI commands (e.g.,"twitter"or"github").description(str): Human-readable description displayed by the CLI.backends(List[str]): Ordered list of candidate backend implementations (CLI tools, APIs, etc.).tier(int): Difficulty level where0= zero-config,1= needs a free key, and2= requires full setup.can_handle(url)→bool: ReturnsTruewhen the provided URL belongs to this platform.read(url)→str: Fetches content from a specific URL (post, video, repository).search(query)→str: Executes a search operation on the platform.check(config=None)→(status, msg): Probes available backends, setsself.active_backend, and returns health status.
The base class provides helper methods like ordered_backends(config) which respects user configuration overrides while maintaining the default priority order.
Step-by-Step Implementation Guide
Follow these steps to create a fully functional platform channel that adheres to the Agent Reach architecture.
1. Create the Channel Module
Create a new file named after your platform in snake_case:
# agent_reach/channels/new_platform.py
2. Import the Base Class and Utilities
Import the abstract base class and any probing utilities needed for backend detection:
from .base import Channel
from agent_reach.probe import probe_command
import subprocess
3. Define the Subclass and Metadata
Subclass Channel and define the required class attributes:
class NewPlatformChannel(Channel):
name = "newplatform"
description = "New Platform – read posts and search content"
backends = ["new-cli", "new-api"] # Priority order
tier = 1 # Requires free API key
4. Implement can_handle
Define URL detection logic to determine if a given URL belongs to your platform:
def can_handle(self, url: str) -> bool:
from urllib.parse import urlparse
netloc = urlparse(url).netloc.lower()
return "newplatform.com" in netloc
5. Implement read
Execute the read operation using the active backend:
def read(self, url: str) -> str:
cmd = [self.active_backend, "read", url, "--output", "yaml"]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.stdout
6. Implement search
Implement search functionality similar to read but accepting a query string:
def search(self, query: str) -> str:
cmd = [self.active_backend, "search", query, "--output", "yaml"]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.stdout
7. Implement check with Backend Probing
Probe each backend in order, set self.active_backend to the first working option, and return status. Follow the pattern from TwitterChannel in agent_reach/channels/twitter.py:
def check(self, config=None):
self.active_backend = None
findings = []
for backend in self.ordered_backends(config):
if backend == "new-cli":
probe = probe_command(
"new-cli",
["status"],
timeout=15,
package="new-cli"
)
if probe.status == "missing":
continue
if probe.ok:
self.active_backend = backend
return "ok", "new-cli fully available"
if probe.status == "broken":
findings.append((backend, "error", "new-cli installed but broken"))
else:
findings.append((backend, "warn", "new-cli config issue"))
# Fallback logic
for status in ("ok", "warn", "error"):
for b, s, m in findings:
if s == status:
self.active_backend = b
return s, m
return "warn", "new-cli not installed"
8. Export in __init__.py
Edit agent_reach/channels/__init__.py to import the new channel so the core routing engine discovers it:
from .new_platform import NewPlatformChannel
9. Verify Registration
Run the diagnostic command to confirm your channel registers correctly:
python -m agent_reach.cli doctor
Your new platform should appear in the output table with the status reported by your check() method.
Working Channel Implementation Example
Here is a complete skeleton implementation combining all steps:
# agent_reach/channels/new_platform.py
"""New Platform channel implementation for Agent Reach."""
from .base import Channel
from agent_reach.probe import probe_command
import subprocess
class NewPlatformChannel(Channel):
name = "newplatform"
description = "New Platform – read, search, and check content"
backends = ["new-cli", "new-api"]
tier = 1
def can_handle(self, url: str) -> bool:
from urllib.parse import urlparse
return "newplatform.com" in urlparse(url).netloc.lower()
def read(self, url: str) -> str:
cmd = [self.active_backend, "read", url, "--output", "yaml"]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.stdout
def search(self, query: str) -> str:
cmd = [self.active_backend, "search", query, "--output", "yaml"]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.stdout
def check(self, config=None):
self.active_backend = None
findings = []
for backend in self.ordered_backends(config):
if backend == "new-cli":
probe = probe_command(
"new-cli",
["status"],
timeout=15,
package="new-cli"
)
if probe.status == "missing":
continue
if probe.ok:
self.active_backend = backend
return "ok", "new-cli fully available"
if probe.status == "broken":
findings.append((backend, "error", "new-cli broken"))
else:
findings.append((backend, "warn", "new-cli config issue"))
for status in ("ok", "warn", "error"):
for b, s, m in findings:
if s == status:
self.active_backend = b
return s, m
return "warn", "new-cli not installed"
Update the channels initialization file:
# agent_reach/channels/__init__.py
from .base import Channel
from .twitter import TwitterChannel
from .github import GitHubChannel
from .new_platform import NewPlatformChannel # Add this line
Summary
- Subclass
Channelfromagent_reach/channels/base.pyto create a new platform channel. - Define metadata (
name,description,backends,tier) as class attributes. - Implement the four contract methods:
can_handle(url),read(url),search(query), andcheck(config). - Use
ordered_backends(config)to respect user configuration while maintaining backend priority. - Set
self.active_backendin thecheck()method to indicate which backend is operational. - Export the class in
agent_reach/channels/__init__.pyto register it with the core routing system.
Frequently Asked Questions
What is the Channel contract in Agent Reach?
The Channel contract is an abstract interface defined in agent_reach/channels/base.py that requires implementing can_handle, read, search, and check methods, plus metadata attributes (name, description, backends, tier). This contract ensures all platforms integrate consistently with the CLI and routing system.
How do I handle multiple backends in a new channel?
Define an ordered list of backend strings in the backends class attribute. In the check() method, iterate through self.ordered_backends(config) and test each backend using probe_command() or similar logic. Set self.active_backend to the first working backend and return appropriate status messages.
Where does Agent Reach discover available channels?
The core routing system discovers channels through imports in agent_reach/channels/__init__.py. Each channel class must be imported there to be registered. Some versions also maintain a CHANNELS dictionary in agent_reach/core.py that maps channel names to instances.
What tier value should I use for my platform channel?
Use tier=0 for zero-configuration channels that work immediately, tier=1 for platforms requiring a free API key or simple authentication, and tier=2 for platforms requiring complex setup or paid credentials. This value helps users understand the onboarding difficulty when running agent_reach doctor.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →