How to Add a New Platform Channel to Agent Reach: A Complete Implementation Guide
To add a new platform channel in 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 for auto-discovery.
Agent Reach's architecture treats every supported internet platform as a channel—a pluggable component that knows how to read, search, and interact with a specific service. Channels follow a consistent lifecycle defined in [agent_reach/channels/base.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py), making it straightforward to extend the system with new platforms. This guide walks through the exact procedure used by existing channels like Twitter and YouTube.
Understanding the Channel Base Class
Every channel inherits from Channel, which defines the contract that the core routing system expects.
Core Metadata Properties
| Property | Purpose |
|---|---|
name |
Short identifier used in CLI arguments and configuration keys |
description |
Human-readable description displayed by diagnostics |
backends |
Ordered list of upstream command-line tools that can fulfill the channel |
tier |
Setup difficulty: 0 = zero-config, 1 = needs free API key, 2 = needs full user setup |
active_backend |
Set by check() to the first usable backend found |
Key Inherited Methods
ordered_backends(self, config)— Returns the backend list respecting user overrides from configuration or environment variablescheck(self, config)— Probes available backends and selects the first healthy one; default implementation marks channel as "built-in"
The [agent_reach/channels/twitter.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py) file demonstrates a production-ready override of check() with multi-backend probing logic.
Step-by-Step Implementation Procedure
Step 1: Create the Channel Module
Create a new file in the channels directory:
touch agent_reach/channels/myplatform.py
Step 2: Import Required Dependencies
# agent_reach/channels/myplatform.py
from .base import Channel
from agent_reach.probe import probe_command
The probe_command utility from [agent_reach/probe.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) runs health checks on external CLI tools and returns structured status information.
Step 3: Define the Channel Class with Metadata
class MyPlatformChannel(Channel):
name = "myplatform"
description = "MyPlatform – read and search content from myplatform.com"
backends = ["myplatform-cli", "OpenCLI"]
tier = 1 # Requires API key or authentication setup
Step 4: Implement can_handle() for URL Routing
The core router in [agent_reach/core.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/core.py) uses this method to dispatch URLs to the correct channel:
def can_handle(self, url: str) -> bool:
from urllib.parse import urlparse
domain = urlparse(url).netloc.lower()
return "myplatform.com" in domain or "myp.com" in domain
Step 5: Implement check() for Backend Discovery
This method probes each backend in priority order and selects the first usable one:
def check(self, config=None):
"""Probe backends and activate the first healthy one."""
self.active_backend = None
findings = []
for backend in self.ordered_backends(config):
if backend == "myplatform-cli":
result = self._probe_myplatform_cli()
elif backend == "OpenCLI":
result = self._probe_opencli()
else:
continue
if result is None:
continue # Backend not installed
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 with:\n"
" pipx install myplatform-cli\n"
"Or configure OpenCLI for browser-based access."
)
Step 6: Add Backend-Specific Probe Methods
def _probe_myplatform_cli(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"CLI installed but failing.\n{probe.hint}"
if probe.ok and "authenticated" in probe.output.lower():
return "ok", "myplatform-cli ready (authenticated)"
return "warn", "CLI installed but not authenticated; run: myplatform login"
Step 7: (Optional) Implement Platform Operations
Add read(), search(), or other methods that delegate to the active backend:
def read(self, url: str) -> str:
"""Fetch content from a MyPlatform URL."""
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 MyPlatform read operation")
def search(self, query: str, limit: int = 10):
"""Search MyPlatform content."""
if self.active_backend == "myplatform-cli":
result = probe_command("myplatform", ["search", query, "--limit", str(limit)])
return self._parse_search_results(result.output)
# Add OpenCLI fallback as needed
raise RuntimeError("Search requires myplatform-cli backend")
Step 8: Register in Package Index
Edit [agent_reach/channels/__init__.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/__init__.py) to enable auto-discovery:
from .myplatform import MyPlatformChannel # Add this line
Step 9: Verify with Diagnostics
Run the built-in health checker:
python -m agent_reach.cli doctor
Expected output:
✔ MyPlatform (myplatform) – ok – myplatform-cli
Complete Working Template
Copy this skeleton to start a new channel immediately:
# agent_reach/channels/myplatform.py
"""MyPlatform channel implementation for Agent Reach."""
from .base import Channel
from agent_reach.probe import probe_command
class MyPlatformChannel(Channel):
"""Channel for myplatform.com content platform."""
name = "myplatform"
description = "MyPlatform – read and search myplatform.com content"
backends = ["myplatform-cli", "OpenCLI"]
tier = 1
# ------------------------------------------------------------------
# URL routing
# ------------------------------------------------------------------
def can_handle(self, url: str) -> bool:
from urllib.parse import urlparse
domain = urlparse(url).netloc.lower()
return "myplatform.com" in domain
# ------------------------------------------------------------------
# Backend health checking and selection
# ------------------------------------------------------------------
def check(self, config=None):
self.active_backend = None
findings = []
for backend in self.ordered_backends(config):
result = self._probe_backend(backend, config)
if result:
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 self._format_failure(findings)
def _probe_backend(self, backend, config):
"""Dispatch to appropriate probe method."""
probes = {
"myplatform-cli": self._probe_myplatform_cli,
"OpenCLI": self._probe_opencli,
}
probe_fn = probes.get(backend)
return probe_fn(config) if probe_fn else None
def _probe_myplatform_cli(self, config):
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"CLI broken: {probe.hint}"
if probe.ok and "ready" in probe.output.lower():
return "ok", "myplatform-cli ready"
return "warn", "CLI installed but not ready; run: myplatform auth"
def _probe_opencli(self, config):
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 (browser session)"
return "warn", st.hint
def _format_failure(self, findings):
if findings:
return "error", "\n".join(m for _, _, m in findings)
return "warn", "Install myplatform-cli: pipx install myplatform-cli"
# ------------------------------------------------------------------
# Platform operations
# ------------------------------------------------------------------
def read(self, url: str) -> str:
if not self.active_backend:
raise RuntimeError("Channel not checked or no backend available")
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(f"Unknown backend: {self.active_backend}")
Using Your New Channel
Once registered, the channel integrates automatically:
from agent_reach.core import AgentReach
ar = AgentReach()
url = "https://myplatform.com/article/abc123"
# Automatic channel selection via can_handle()
content = ar.read(url)
print(content)
# Or use the channel directly
from agent_reach.channels.myplatform import MyPlatformChannel
channel = MyPlatformChannel()
status, message = channel.check(ar.config)
print(f"MyPlatform status: {status} – {message}")
Key Files Reference
| File | Purpose | Source |
|---|---|---|
agent_reach/channels/base.py |
Abstract Channel class, ordered_backends(), default check() |
View source |
agent_reach/channels/twitter.py |
Production example with multi-backend probing | View source |
agent_reach/channels/__init__.py |
Channel registration for auto-discovery | View source |
agent_reach/probe.py |
probe_command() utility for CLI health checks |
View source |
agent_reach/core.py |
URL routing logic using can_handle() |
View source |
Summary
- Inherit from
Channelinagent_reach/channels/base.pyto create a new platform integration - Define metadata (
name,description,backends,tier) for discovery and diagnostics - Implement
can_handle()so the router can dispatch URLs to your channel - Implement
check()to probe and select from available backends usingprobe_command() - Register in
__init__.pyfor automatic discovery byAgentReachcore - Verify with
python -m agent_reach.cli doctorbefore deploying
Frequently Asked Questions
What is the minimum code required to add a new platform channel?
You need a class inheriting from Channel with name, description, backends, tier defined, plus implementations of can_handle() and check(). The [agent_reach/channels/base.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) default check() works for built-in channels, but most real platforms need custom backend probing as shown in [agent_reach/channels/twitter.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/twitter.py).
How does Agent Reach choose which channel handles a URL?
The AgentReach core iterates through all registered channels and calls can_handle(url) on each. The first channel returning True receives the operation. Implement can_handle() to parse URL hostnames or path patterns specific to your platform.
What backend probing statuses does probe_command() return?
The utility in [agent_reach/probe.py](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) returns structured status: missing (command not found), broken (command fails), timeout (no response), ok (works as expected), plus output and hint fields for user guidance. Your check() method should map these to the channel-level statuses: "ok", "warn", or "error".
Can a channel support multiple backends with fallback?
Yes. List multiple backends in priority order: backends = ["preferred-cli", "fallback-cli", "OpenCLI"]. The ordered_backends() method respects user configuration overrides, and your check() implementation should probe each in sequence, selecting the first healthy option. This pattern is demonstrated in the Twitter channel's check() method.
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 →