How to Add New Platform Channels to Agent Reach: 4-Step Implementation Guide
To add a new platform channel to Agent Reach, subclass the Channel base class in agent_reach/channels/<platform>.py, implement can_handle for URL detection and check for backend health verification, then register the instance in the ALL_CHANNELS list inside agent_reach/channels/__init__.py.
Agent Reach treats every external platform—from Twitter to Reddit—as a channel, which is a lightweight Python class that integrates with the core routing logic. Adding support for a new platform follows a standardized four-step pattern defined in the repository's architecture, requiring no modifications to the core engine.
Step 1: Create a Channel Module
Create a new Python file in agent_reach/channels/<platform>.py that subclasses Channel from agent_reach/channels/base.py. Define the class attributes name, description, backends, and tier, then implement the can_handle method.
The name attribute serves as the identifier used in CLI options and configuration files. The backends list defines an ordered priority of upstream tools, where the first successful backend becomes the active_backend. The tier field categorizes setup complexity: 0 for zero-config, 1 for free-key, or 2 for manual setup.
Here is the implementation pattern for an Instagram channel:
# agent_reach/channels/instagram.py
"""Instagram — probe `instabot` for read/search capability."""
from .base import Channel
from agent_reach.probe import probe_command
class InstagramChannel(Channel):
name = "instagram"
description = "Instagram posts & stories"
backends = ["instabot", "opencli"]
tier = 1
def can_handle(self, url: str) -> bool:
"""Return True for URLs that belong to Instagram."""
from urllib.parse import urlparse
domain = urlparse(url).netloc.lower()
return "instagram.com" in domain
def check(self, config=None):
"""Probe the backends in order, set ``self.active_backend``."""
self.active_backend = None
findings = []
for backend in self.ordered_backends(config):
if backend == "instabot":
result = self._check_instabot()
elif backend == "opencli":
result = self._check_opencli()
else:
continue
if result is None:
continue
findings.append((backend, *result))
# Pick the first "ok", then "warn", otherwise report errors
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", "instabot 未安装。请参考项目文档进行安装。"
def _check_instabot(self):
"""Probe `instabot`. Returns None / (status, message)."""
probe = probe_command("instabot", ["status"], timeout=10, retries=1,
package="instabot")
if probe.status == "missing":
return None
if probe.status != "ok":
return "error", f"instabot 健康检查失败:{probe.hint}"
return "ok", "instabot 已就绪(可读取、搜索 Instagram 内容)"
def _check_opencli(self):
"""Reuse the generic OpenCLI backend check."""
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 可用(复用浏览器登录态)"
return "warn", st.hint
The ordered_backends method (inherited from the base class) automatically respects user overrides via the configuration key <channel>_backend or environment variables like INSTAGRAM_BACKEND, inserting the specified backend at the front of the candidate list.
Step 2: Register the Channel in the Registry
Edit agent_reach/channels/__init__.py to import your new class and append an instance to the ALL_CHANNELS list:
# agent_reach/channels/__init__.py
from .instagram import InstagramChannel # NEW IMPORT
ALL_CHANNELS: List[Channel] = [
GitHubChannel(),
TwitterChannel(),
YouTubeChannel(),
RedditChannel(),
BilibiliChannel(),
XiaoHongShuChannel(),
LinkedInChannel(),
XiaoyuzhouChannel(),
V2EXChannel(),
XueqiuChannel(),
RSSChannel(),
ExaSearchChannel(),
WebChannel(),
InstagramChannel(), # NEW INSTANCE
]
This registry is the discovery mechanism used by the doctor command to run health checks across all platforms. Without this registration step, the channel remains invisible to the CLI and core routing logic.
Step 3: Implement Backend Probing Logic
The check method verifies whether required upstream tools are installed and functional. Use the probe_command helper from agent_reach/probe.py for standard CLI tools, or implement custom validation logic as shown in the reference implementation at agent_reach/channels/twitter.py.
Your check method must return one of the following patterns:
None— Backend is not installed; exclude from candidates("ok", "message")— Fully functional; preferred status("warn", "message")— Installed but requires configuration (e.g., authentication)("error", "message")— Broken or unusable
The method must also set self.active_backend to the selected backend string, or leave it as None if no viable backend exists. This follows the same two-stage probing pattern used in existing channels, where results are collected first, then filtered by priority status.
Step 4: Update Documentation and Tests
While the CLI automatically pulls Channel.description for the --list flag, add platform-specific documentation under docs/ detailing installation requirements and environment variables. For testing, mirror the style of existing unit tests in tests/test_channels/ to verify can_handle URL matching and check method outcomes under mock conditions.
Using Your New Channel
Once registered, interact with your channel programmatically or via CLI:
from agent_reach.channels import get_channel
insta = get_channel('instagram')
url = "https://www.instagram.com/p/CG0UU3ZBzZb/"
# Check URL support
assert insta.can_handle(url) is True
# Run health check
status, msg = insta.check()
print(f"Backend: {insta.active_backend}, Status: {status}")
Override the backend priority via configuration:
# config.yaml
instagram_backend: opencli
Or via environment variable:
export INSTAGRAM_BACKEND=opencli
Summary
- Create a new file in
agent_reach/channels/<platform>.pysubclassingChannelwithname,description,backends, andtierattributes. - Implement
can_handle(url)to detect platform-specific URLs andcheck(config)to probe backend health usingprobe_commandor custom logic. - Register the channel instance in
ALL_CHANNELSinsideagent_reach/channels/__init__.pyto enable discovery by thedoctorcommand and core router. - Return standardized tuples from
check(ok,warn,error, orNone) and setself.active_backendto the working backend. - Configure backend priority via the
<channel>_backendconfig key or<CHANNEL>_BACKENDenvironment variable, handled automatically byordered_backends.
Frequently Asked Questions
What is the difference between can_handle and check in an Agent Reach channel?
The can_handle method determines whether a given URL belongs to the platform (e.g., checking if the domain contains "instagram.com"), while the check method verifies that the external tool or API (the backend) is actually installed and functional on the system. can_handle runs during URL routing; check runs during health verification or initial setup.
How do I specify which backend my channel should prioritize?
Users can override the default backend priority via a configuration file key named <channel>_backend (e.g., instagram_backend: opencli) or an environment variable like INSTAGRAM_BACKEND. The base class method ordered_backends(config) automatically moves the specified backend to the front of the candidate list before probing begins.
What should my check method return if the backend tool is not installed?
If the backend is not installed, your probe should return None, which signals to the channel to exclude that backend from the candidate list. The parent check method will then iterate through remaining backends, ultimately returning ("warn", "message") if no installations are found, or ("error", "message") if installations exist but are broken.
Do I need to modify the core routing logic to support a new platform?
No. Agent Reach uses a registry pattern in agent_reach/channels/__init__.py. Simply adding your channel class to the ALL_CHANNELS list is sufficient to make it visible to the CLI doctor command, the get_channel() factory function, and the core routing engine without touching any files outside the channels/ directory.
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 →