18 Commits

Author SHA1 Message Date
Pnant 84b474c79b chore: bump version to 1.4.1 (#341)
ci / test (3.10) (push) Has been cancelled
ci / test (3.11) (push) Has been cancelled
ci / test (3.12) (push) Has been cancelled
ci / test (3.13) (push) Has been cancelled
ci / wheel-gate (push) Has been cancelled
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 11:47:32 +08:00
Pnant b6241e8e67 ci: add wheel-build gate (duplicate-entry check + clean-venv smoke install) (#340)
Editable installs in CI never exercise wheel packaging, which let the
force-include duplication ship broken source installs while tests stayed
green (#308 #315 #328 #332 #334). This gate builds the real wheel, fails
on any duplicate archive entry, asserts SKILL.md/guides/scripts ship,
and smoke-installs into a clean venv.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 11:45:08 +08:00
nyxst4ck 607f0d2c56 fix(build): drop duplicate force-include that breaks source installs (#329)
Removes the [tool.hatch.build.targets.wheel.force-include] block that duplicated files already included via packages=["agent_reach"], which made modern hatchling fail source installs with 'ValueError: A second file is being added to the wheel archive at the same path'.

Verified before merge: wheel builds clean (48 entries, no duplicates), SKILL.md / guides / scripts all ship in site-packages, 85 tests pass on Python 3.11.

Fixes #334, fixes #332, fixes #328, fixes #315, fixes #308.
2026-06-10 11:41:46 +08:00
Pnant 17624268a0 docs: update Reddit auth requirement and fix architecture diagrams across all READMEs
Reddit requires authentication since 2024 (all API requests return 403
without a valid session cookie). Updated all 4 language versions (zh, en,
ja, ko) to reflect this: platform tables, tool choice tables, architecture
diagrams, and FAQ sections.

Also fixed Chinese README architecture diagram: reddit.py backend corrected
from Exa to rdt-cli, wechat.py backend corrected from camoufox+miku to Exa.
Fixed Japanese README reddit.py swap suggestions (removed outdated PRAW/Pushshift).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 17:45:43 +08:00
Hak Lee 575cd3b479 docs: add Korean README translation (docs/README_ko.md) (#251)
docs: add Korean README translation (closes #250)
2026-04-13 17:17:28 +08:00
Always lucky 0e21545bc5 Add English skill locale support (#223)
feat: add English skill locale support with SKILL_en.md
2026-04-13 17:17:20 +08:00
Sri Sowmya Nemani 28e6f07f8e Create SECURITY.md (#254)
docs: add SECURITY.md with responsible disclosure process
2026-04-13 17:17:16 +08:00
Thomas Lau 0aee897ef4 fix(reddit): detect auth status in doctor check (#261)
fix(reddit): detect auth status in doctor check, show recovery paths
2026-04-13 17:16:19 +08:00
Harshit Anand e36f737bb6 docs: fix Douyin MCP installation and configuration instructions (#256) (#257)
docs: fix Douyin MCP installation instructions
2026-04-13 17:16:11 +08:00
Pgooone a45147c53d fix(wechat): Windows 系统上 doctor 误判微信公众号渠道不可用 (#263)
fix(wechat): Windows GBK encoding causes false negative in doctor check
2026-04-13 17:16:05 +08:00
Pnant def2ce932e docs: update all remaining files for v1.4.0 upstream migrations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:27:32 +08:00
Pnant a1cc229239 docs: update README for v1.4.0 upstream migrations
Update all tool references across both Chinese and English READMEs:
- bird CLI → twitter-cli
- Exa Reddit → rdt-cli
- Docker xiaohongshu-mcp → xhs-cli (pipx)
- miku_ai → Exa (WeChat)
- Add bili-cli to Bilibili
- Update stars counts, install commands, FAQ answers, credits

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:13:38 +08:00
Pnant e178470320 fix(twitter): support both twitter-cli and bird CLI, never uninstall user tools
CRITICAL FIX: update.md was telling agents to uninstall bird CLI,
which broke users who had working bird installations. Now:

- twitter.py: prefers twitter-cli, falls back to bird/birdx if installed
- update.md: removed "clean up deprecated tools" step entirely
- Added explicit rule: "Never uninstall any existing tools the user already has"
- Tests cover twitter-cli primary + bird fallback + preference order

78 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:01:09 +08:00
Pnant 7acf3c1367 docs(skill): add Twitter upstream caveats (search instability, IP risk, cookie issues)
Based on investigation of public-clis/twitter-cli 47 issues:
- search may 404 when Twitter changes GraphQL endpoints
- followers command has account ban risk on datacenter IPs
- Cookie auto-extraction fragile (macOS Keychain, Windows DPAPI)
- Recommend Cookie-Editor export + env vars over auto-extraction
- Ensure v0.8.5+ for Windows pipe fix

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 19:13:31 +08:00
Pnant 04fd645966 docs(skill): add upstream caveats for Reddit, B站, YouTube
Based on upstream issue investigation:
- Reddit (rdt-cli): ensure v0.4.2+, note login-required features
- B站: 412 is overseas-IP + no-cookie, add bili-cli commands
- YouTube: --write-comments is best-effort, auto-subs may duplicate

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 19:12:44 +08:00
Pnant d877c09cd1 docs(skill): add XHS upstream caveats (xsec_token, rate limits, unstable commands)
Based on investigation of jackwener/xiaohongshu-cli issues:
- xsec_token: can't read by bare note_id, must search/feed first
- Rate limiting: high-freq requests trigger CAPTCHA
- v0.6.4: user/user-posts/favorites may return API error
- POST operations: may 406 due to signature issues in v0.6.x

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 19:10:36 +08:00
Pnant 65ff8d69d0 docs: rewrite update.md for v1.4.0 upstream migrations
update.md now handles the full update lifecycle autonomously:
- Installs new CLI tools (twitter-cli, rdt-cli, xhs-cli, bili-cli)
- Removes deprecated bird CLI
- Updates SKILL.md + references/ with fallback
- Reports changes to user

install.md: update tool references (bird→twitter-cli, Exa→rdt-cli).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 18:36:43 +08:00
Pnant 0f9cfe66ec fix(web): add read() via Jina Reader + skill install fallback (#238)
- WebChannel.read(): reads any URL via Jina Reader (r.jina.ai), returns Markdown
- _install_skill(): add fallback from importlib.resources to Path(__file__) for editable installs
- Explicit UTF-8 encoding on all file read/write operations

Inspired by PR #215, implemented correctly (Jina instead of raw requests).

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 18:31:48 +08:00
29 changed files with 1450 additions and 285 deletions
+40
View File
@@ -28,3 +28,43 @@ jobs:
- name: Run tests - name: Run tests
run: | run: |
pytest -q pytest -q
# Editable installs (-e) never exercise wheel packaging, so a broken wheel
# can pass tests and still fail every real `pip install` from source.
# This job builds the actual wheel and installs it into a clean venv.
wheel-gate:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Build wheel
run: |
python -m pip install --upgrade pip build
python -m build
- name: Verify wheel has no duplicate entries and ships data files
run: |
python - <<'PY'
import glob, zipfile, collections
whl = glob.glob("dist/*.whl")[0]
names = zipfile.ZipFile(whl).namelist()
dupes = [n for n, c in collections.Counter(names).items() if c > 1]
assert not dupes, f"duplicate entries in wheel: {dupes}"
assert "agent_reach/skill/SKILL.md" in names, "SKILL.md missing from wheel"
for prefix in ("agent_reach/guides/", "agent_reach/scripts/", "agent_reach/skill/references/"):
assert any(n.startswith(prefix) for n in names), f"{prefix} missing from wheel"
print(f"wheel OK: {len(names)} entries, no duplicates, data files present")
PY
- name: Smoke-install wheel into clean venv
run: |
python -m venv /tmp/smoke
/tmp/smoke/bin/pip install --quiet dist/*.whl
/tmp/smoke/bin/agent-reach version
cd /tmp && /tmp/smoke/bin/python -c "import agent_reach; from importlib.resources import files; assert (files('agent_reach')/'skill'/'SKILL.md').is_file(); print('SKILL.md ships in site-packages OK')"
+1 -1
View File
@@ -3,7 +3,7 @@
## Project ## Project
Agent Reach — Python CLI + library that gives AI agents read/search access to 14+ internet platforms. Agent Reach — Python CLI + library that gives AI agents read/search access to 14+ internet platforms.
Positioning: installer + doctor + config tool. NOT a wrapper — after install, agents call upstream tools directly. Positioning: installer + doctor + config tool. NOT a wrapper — after install, agents call upstream tools directly.
Repo: github.com/Panniantong/Agent-Reach | License: MIT | Version: 1.3.0 Repo: github.com/Panniantong/Agent-Reach | License: MIT | Version: 1.4.1
## Commands ## Commands
- `pip install -e .` — Dev install - `pip install -e .` — Dev install
+24 -22
View File
@@ -11,7 +11,7 @@
</p> </p>
<p align="center"> <p align="center">
<a href="#快速上手">快速开始</a> · <a href="docs/README_en.md">English</a> · <a href="docs/README_ja.md">日本語</a> · <a href="#支持的平台">支持平台</a> · <a href="#设计理念">设计理念</a> <a href="#快速上手">快速开始</a> · <a href="docs/README_en.md">English</a> · <a href="docs/README_ja.md">日本語</a> · <a href="docs/README_ko.md">한국어</a> · <a href="#支持的平台">支持平台</a> · <a href="#设计理念">设计理念</a>
</p> </p>
--- ---
@@ -56,7 +56,7 @@ AI Agent 已经能帮你写代码、改文档、管项目——但你让它去
|---|---| |---|---|
| 💰 **完全免费** | 所有工具开源、所有 API 免费。唯一可能花钱的是服务器代理($1/月),本地电脑不需要 | | 💰 **完全免费** | 所有工具开源、所有 API 免费。唯一可能花钱的是服务器代理($1/月),本地电脑不需要 |
| 🔒 **隐私安全** | Cookie 只存在你本地,不上传不外传。代码完全开源,随时可审查 | | 🔒 **隐私安全** | Cookie 只存在你本地,不上传不外传。代码完全开源,随时可审查 |
| 🔄 **持续更新** | 底层工具(yt-dlp、bird、Jina Reader 等)定期追踪更新到最新版,你不用自己盯 | | 🔄 **持续更新** | 底层工具(yt-dlp、twitter-cli、rdt-cli、Jina Reader 等)定期追踪更新到最新版,你不用自己盯 |
| 🤖 **兼容所有 Agent** | Claude Code、OpenClaw、Cursor、Windsurf……任何能跑命令行的 Agent 都能用 | | 🤖 **兼容所有 Agent** | Claude Code、OpenClaw、Cursor、Windsurf……任何能跑命令行的 Agent 都能用 |
| 🩺 **自带诊断** | `agent-reach doctor` 一条命令告诉你哪个通、哪个不通、怎么修 | | 🩺 **自带诊断** | `agent-reach doctor` 一条命令告诉你哪个通、哪个不通、怎么修 |
@@ -73,7 +73,7 @@ AI Agent 已经能帮你写代码、改文档、管项目——但你让它去
| 📦 **GitHub** | 读公开仓库 + 搜索 | 私有仓库、提 Issue/PR、Fork | 告诉 Agent「帮我登录 GitHub」 | | 📦 **GitHub** | 读公开仓库 + 搜索 | 私有仓库、提 Issue/PR、Fork | 告诉 Agent「帮我登录 GitHub」 |
| 🐦 **Twitter/X** | 读单条推文 | 搜索推文、浏览时间线、发推 | 告诉 Agent「帮我配 Twitter」 | | 🐦 **Twitter/X** | 读单条推文 | 搜索推文、浏览时间线、发推 | 告诉 Agent「帮我配 Twitter」 |
| 📺 **B站** | 本地:字幕提取 + 搜索 | 服务器也能用 | 告诉 Agent「帮我配代理」 | | 📺 **B站** | 本地:字幕提取 + 搜索 | 服务器也能用 | 告诉 Agent「帮我配代理」 |
| 📖 **Reddit** | 搜索 + 读帖子和评论(通过 Exa) | — | 无需配置(自动通过 Exa) | | 📖 **Reddit** | 搜索 + 读帖子和评论(通过 rdt-cli | Cookie | 需要登录认证(`rdt login`),详见 [rdt-cli](https://github.com/public-clis/rdt-cli) |
| 📕 **小红书** | — | 阅读、搜索、发帖、评论、点赞 | 告诉 Agent「帮我配小红书」 | | 📕 **小红书** | — | 阅读、搜索、发帖、评论、点赞 | 告诉 Agent「帮我配小红书」 |
| 🎵 **抖音** | — | 视频解析、无水印下载链接获取 | 告诉 Agent「帮我配抖音」 | | 🎵 **抖音** | — | 视频解析、无水印下载链接获取 | 告诉 Agent「帮我配抖音」 |
| 💼 **LinkedIn** | Jina Reader 读公开页面 | Profile 详情、公司页面、职位搜索 | 告诉 Agent「帮我配 LinkedIn」 | | 💼 **LinkedIn** | Jina Reader 读公开页面 | Profile 详情、公司页面、职位搜索 | 告诉 Agent「帮我配 LinkedIn」 |
@@ -96,7 +96,7 @@ AI Agent 已经能帮你写代码、改文档、管项目——但你让它去
> ⚠️ **OpenClaw 用户请先确认 exec 权限已开启** > ⚠️ **OpenClaw 用户请先确认 exec 权限已开启**
> >
> Agent Reach 依赖 Agent 执行 shell 命令(`pip install`、`mcporter`、`bird` 等)。如果你的 OpenClaw 使用了默认的 `messaging` 工具配置,Agent 将无法执行命令。**安装前请先开启 exec 权限**: > Agent Reach 依赖 Agent 执行 shell 命令(`pip install`、`mcporter`、`twitter` 等)。如果你的 OpenClaw 使用了默认的 `messaging` 工具配置,Agent 将无法执行命令。**安装前请先开启 exec 权限**:
> >
> ```bash > ```bash
> openclaw config set tools.profile "coding" > openclaw config set tools.profile "coding"
@@ -127,7 +127,7 @@ AI Agent 已经能帮你写代码、改文档、管项目——但你让它去
<summary>它会做什么?(点击展开)</summary> <summary>它会做什么?(点击展开)</summary>
1. **安装 CLI 工具**`pip install` 装好 `agent-reach` 命令行 1. **安装 CLI 工具**`pip install` 装好 `agent-reach` 命令行
2. **安装系统依赖** — 自动检测并安装 Node.js、gh CLI、mcporter、bird 2. **安装系统依赖** — 自动检测并安装 Node.js、gh CLI、mcporter、twitter-cli、rdt-cli
3. **配置搜索引擎** — 通过 MCP 接入 Exa(免费,无需 API Key 3. **配置搜索引擎** — 通过 MCP 接入 Exa(免费,无需 API Key
4. **检测环境** — 判断是本地电脑还是服务器,给出对应的配置建议 4. **检测环境** — 判断是本地电脑还是服务器,给出对应的配置建议
5. **注册 SKILL.md** — 在 Agent 的 skills 目录安装使用指南,以后 Agent 遇到"搜推特"、"看视频"这类需求,会自动知道该调哪个上游工具 5. **注册 SKILL.md** — 在 Agent 的 skills 目录安装使用指南,以后 Agent 遇到"搜推特"、"看视频"这类需求,会自动知道该调哪个上游工具
@@ -144,7 +144,7 @@ AI Agent 已经能帮你写代码、改文档、管项目——但你让它去
- "帮我看看这个链接" → `curl https://r.jina.ai/URL` 读任意网页 - "帮我看看这个链接" → `curl https://r.jina.ai/URL` 读任意网页
- "这个 GitHub 仓库是做什么的" → `gh repo view owner/repo` - "这个 GitHub 仓库是做什么的" → `gh repo view owner/repo`
- "这个视频讲了什么" → `yt-dlp --dump-json URL` 提取字幕 - "这个视频讲了什么" → `yt-dlp --dump-json URL` 提取字幕
- "帮我看看这条推文" → `bird read URL` - "帮我看看这条推文" → `twitter tweet URL`
- "订阅这个 RSS" → `feedparser` 解析 - "订阅这个 RSS" → `feedparser` 解析
- "搜一下 GitHub 上有什么 LLM 框架" → `gh search repos "LLM framework"` - "搜一下 GitHub 上有什么 LLM 框架" → `gh search repos "LLM framework"`
@@ -160,7 +160,7 @@ AI Agent 已经能帮你写代码、改文档、管项目——但你让它去
Agent Reach 做的事情很简单:**帮你把这些选型和配置的活儿做完了。** Agent Reach 做的事情很简单:**帮你把这些选型和配置的活儿做完了。**
安装完成后,Agent 直接调用上游工具(bird CLI、yt-dlp、mcporter、gh CLI 等),不需要经过 Agent Reach 的包装层。 安装完成后,Agent 直接调用上游工具(twitter-cli、rdt-cli、xhs-cli、yt-dlp、mcporter、gh CLI 等),不需要经过 Agent Reach 的包装层。
### 🔌 每个渠道都是可插拔的 ### 🔌 每个渠道都是可插拔的
@@ -169,15 +169,15 @@ Agent Reach 做的事情很简单:**帮你把这些选型和配置的活儿做
``` ```
channels/ channels/
├── web.py → Jina Reader ← 可以换成 Firecrawl、Crawl4AI…… ├── web.py → Jina Reader ← 可以换成 Firecrawl、Crawl4AI……
├── twitter.py → bird ← 可以换成 Nitter、官方 API…… ├── twitter.py → twitter-cli ← 可以换成官方 API……
├── youtube.py → yt-dlp ← 可以换成 YouTube API、Whisper…… ├── youtube.py → yt-dlp ← 可以换成 YouTube API、Whisper……
├── github.py → gh CLI ← 可以换成 REST API、PyGithub…… ├── github.py → gh CLI ← 可以换成 REST API、PyGithub……
├── bilibili.py → yt-dlp ← 可以换成 bilibili-api…… ├── bilibili.py → yt-dlp ← 可以换成 bilibili-api……
├── reddit.py → Exa ← 搜索+阅读,无需代理 ├── reddit.py → rdt-cli ← 搜索+阅读,需 Cookie 认证
├── xiaohongshu.py → mcporter MCP ← 可以换成其他 XHS 工具…… ├── xiaohongshu.py → mcporter MCP ← 可以换成其他 XHS 工具……
├── douyin.py → mcporter MCP ← 可以换成其他抖音工具…… ├── douyin.py → mcporter MCP ← 可以换成其他抖音工具……
├── linkedin.py → linkedin-mcp ← 可以换成 LinkedIn API…… ├── linkedin.py → linkedin-mcp ← 可以换成 LinkedIn API……
├── wechat.py → camoufox+miku ← 搜索+阅读微信公众号文章 ├── wechat.py → Exa (+ Camoufox) ← 搜索+阅读微信公众号文章
├── rss.py → feedparser ← 可以换成 atoma…… ├── rss.py → feedparser ← 可以换成 atoma……
├── exa_search.py → mcporter MCP ← 可以换成 Tavily、SerpAPI…… ├── exa_search.py → mcporter MCP ← 可以换成 Tavily、SerpAPI……
└── __init__.py → 渠道注册(doctor 检测用) └── __init__.py → 渠道注册(doctor 检测用)
@@ -190,15 +190,17 @@ channels/
| 场景 | 选型 | 为什么选它 | | 场景 | 选型 | 为什么选它 |
|------|------|-----------| |------|------|-----------|
| 读网页 | [Jina Reader](https://github.com/jina-ai/reader) | 9.8K Star,免费,不需要 API Key | | 读网页 | [Jina Reader](https://github.com/jina-ai/reader) | 9.8K Star,免费,不需要 API Key |
| 读推特 | [bird](https://www.npmjs.com/package/@steipete/bird) | Cookie 登录,免费。官方 API 按量付费(读一条 $0.005) | | 读推特 | [twitter-cli](https://github.com/public-clis/twitter-cli) | 2.1K StarCookie 登录,搜索/读推文/时间线/长文 |
| 视频字幕 + 搜索 | [yt-dlp](https://github.com/yt-dlp/yt-dlp) | 148K StarYouTube + B站 + 1800 站通吃 | | Reddit | [rdt-cli](https://github.com/public-clis/rdt-cli) | 304 StarCookie 认证,搜索+全文+评论 |
| 搜全网 | [Exa](https://exa.ai) via [mcporter](https://github.com/steipete/mcporter) | AI 语义搜索,MCP 接入免 Key | | 视频字幕 + 搜索 | [yt-dlp](https://github.com/yt-dlp/yt-dlp) | 154K StarYouTube + B站 + 1800 站通吃 |
| B站增强 | [bili-cli](https://github.com/public-clis/bilibili-cli) | 590 Star,热门/排行/搜索/动态 |
| 搜全网 | [Exa](https://exa.ai) via [mcporter](https://github.com/nicobailon/mcporter) | AI 语义搜索,MCP 接入免 Key |
| GitHub | [gh CLI](https://cli.github.com) | 官方工具,认证后完整 API 能力 | | GitHub | [gh CLI](https://cli.github.com) | 官方工具,认证后完整 API 能力 |
| 读 RSS | [feedparser](https://github.com/kurtmckee/feedparser) | Python 生态标准选择,2.3K Star | | 读 RSS | [feedparser](https://github.com/kurtmckee/feedparser) | Python 生态标准选择,2.3K Star |
| 小红书 | [xiaohongshu-mcp](https://github.com/xpzouying/xiaohongshu-mcp) | ⭐9K+Go 语言,Docker 一键部署 | | 小红书 | [xhs-cli](https://github.com/jackwener/xiaohongshu-cli) | 1.5K Starpipx 一行安装,搜索/阅读/评论/发帖 |
| 抖音 | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) | MCP 服务,无需登录,视频解析 + 无水印下载 | | 抖音 | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) | MCP 服务,无需登录,视频解析 + 无水印下载 |
| LinkedIn | [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) | ⭐900+MCP 服务,浏览器自动化 | | LinkedIn | [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) | ⭐1.2KMCP 服务,浏览器自动化 |
| 微信公众号 | [wechat-article-for-ai](https://github.com/Panniantong/wechat-article-for-ai) + [miku_ai](https://github.com/GobinFan/Miku_Spider) | Camoufox 隐身浏览器读全文 + 搜狗搜索 | | 微信公众号 | [Exa](https://exa.ai)(搜索+阅读)+ [Camoufox](https://github.com/daijro/camoufox)(可选) | 零配置搜索+全文阅读,Camoufox 可选增强 |
> 📌 这些都是「当前选型」。不满意?换掉对应文件就行。这正是脚手架的意义。 > 📌 这些都是「当前选型」。不满意?换掉对应文件就行。这正是脚手架的意义。
@@ -309,19 +311,19 @@ Star 一下,下次需要的时候能找到。⭐
<details> <details>
<summary><strong>AI Agent 怎么搜索 Twitter / X?不想付 API 费用</strong></summary> <summary><strong>AI Agent 怎么搜索 Twitter / X?不想付 API 费用</strong></summary>
Agent Reach 使用 [bird CLI](https://www.npmjs.com/package/@steipete/bird) 通过 Cookie 认证访问 Twitter,完全免费。安装 Agent Reach 后,用 Cookie-Editor 导出你的 Twitter Cookie,运行 `agent-reach configure twitter-cookies "your_cookies"` 即可。之后 Agent 就可以用 `bird search "关键词"` 搜索推文了。 Agent Reach 使用 [twitter-cli](https://github.com/public-clis/twitter-cli) 通过 Cookie 认证访问 Twitter,完全免费。安装:`pipx install twitter-cli`,确保浏览器已登录 x.comAgent 就可以用 `twitter search "关键词"` 搜索`twitter tweet URL`推文了。
</details> </details>
<details> <details>
<summary><strong>How to search Twitter/X with AI agent for free (no API)?</strong></summary> <summary><strong>How to search Twitter/X with AI agent for free (no API)?</strong></summary>
Agent Reach uses the bird CLI with cookie auth — zero API fees. After installing, export your Twitter cookies with the Cookie-Editor extension, run `agent-reach configure twitter-cookies "your_cookies"`, then your agent can search with `bird search "query"`. Agent Reach uses twitter-cli with cookie auth — zero API fees. Install with `pipx install twitter-cli`, make sure you're logged into x.com in your browser, then your agent can search with `twitter search "query"` and read tweets with `twitter tweet URL`.
</details> </details>
<details> <details>
<summary><strong>Reddit 返回 403 怎么办?</strong></summary> <summary><strong>Reddit 返回 403 怎么办?</strong></summary>
Agent Reach 已改为通过 Exa 搜索和阅读 Reddit 内容,完全绕过 Reddit API 的 IP 封锁。无需代理,无需额外配置。运行 `agent-reach install --env=auto` 自动安装 Exa Agent Reach 使用 [rdt-cli](https://github.com/public-clis/rdt-cli) 访问 Reddit。Reddit 自 2024 年起要求认证,安装后需运行 `rdt login` 登录。安装:`pipx install rdt-cli`,然后 `rdt login`(自动从浏览器提取 Cookie)。之后 Agent 可以用 `rdt search "关键词"` 搜索、`rdt read POST_ID` 读帖子全文和评论
</details> </details>
<details> <details>
@@ -333,7 +335,7 @@ Agent Reach 已改为通过 Exa 搜索和阅读 Reddit 内容,完全绕过 Red
<details> <details>
<summary><strong>怎么让 AI Agent 读小红书?</strong></summary> <summary><strong>怎么让 AI Agent 读小红书?</strong></summary>
小红书需要通过 Docker 运行一个 MCP 服务。安装 Docker 后,运行 `agent-reach install` 会自动配置。之后 Agent 就能用 `mcporter call 'xiaohongshu.get_feed_detail(...)'` 读取笔记或 `mcporter call 'xiaohongshu.search_feeds(keyword: "关键词")'` 搜索了 安装 `pipx install xiaohongshu-cli`,然后 `xhs login`(自动从浏览器提取 Cookie)。之后 Agent 就能用 `xhs search "关键词"` 搜索笔记、`xhs read NOTE_ID` 阅读详情、`xhs comments NOTE_ID` 查看评论了。不需要 Docker
</details> </details>
<details> <details>
@@ -353,14 +355,14 @@ Yes! Agent Reach is an installer + configuration tool — any AI coding agent th
<details> <details>
<summary><strong>Is this free? Any API costs?</strong></summary> <summary><strong>Is this free? Any API costs?</strong></summary>
100% free. All backends are open-source tools (bird CLI, yt-dlp, Jina Reader, Exa, etc.) that don't require paid API keys. The only optional cost is a residential proxy (~$1/month) if you need Bilibili access from a server. Reddit now works free via Exa without any proxy. 100% free. All backends are open-source tools (twitter-cli, rdt-cli, xhs-cli, yt-dlp, Jina Reader, Exa, etc.) that don't require paid API keys. The only optional cost is a residential proxy (~$1/month) if you need Bilibili access from an overseas server.
</details> </details>
--- ---
## 致谢 ## 致谢
[Jina Reader](https://github.com/jina-ai/reader) · [yt-dlp](https://github.com/yt-dlp/yt-dlp) · [bird](https://www.npmjs.com/package/@steipete/bird) · [Exa](https://exa.ai) · [mcporter](https://github.com/steipete/mcporter) · [feedparser](https://github.com/kurtmckee/feedparser) · [xiaohongshu-mcp](https://github.com/xpzouying/xiaohongshu-mcp) · [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) · [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) [twitter-cli](https://github.com/public-clis/twitter-cli) · [rdt-cli](https://github.com/public-clis/rdt-cli) · [xhs-cli](https://github.com/jackwener/xiaohongshu-cli) · [bili-cli](https://github.com/public-clis/bilibili-cli) · [yt-dlp](https://github.com/yt-dlp/yt-dlp) · [Jina Reader](https://github.com/jina-ai/reader) · [Exa](https://exa.ai) · [mcporter](https://github.com/nicobailon/mcporter) · [feedparser](https://github.com/kurtmckee/feedparser) · [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) · [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server)
## 联系 ## 联系
+51
View File
@@ -0,0 +1,51 @@
# Security Policy
## Supported Versions
| Version | Supported |
|---------|-----------|
| Latest | ✅ Yes |
## Reporting a Vulnerability
If you discover a security vulnerability in Agent-Reach, please report
it responsibly by using GitHub's private security advisory feature:
👉 **[Report a vulnerability](https://github.com/Panniantong/Agent-Reach/security/advisories/new)**
Please do NOT open a public GitHub issue for security vulnerabilities.
## What to Include
- Description of the vulnerability
- Steps to reproduce
- Affected versions
- Potential impact
- Suggested fix (if any)
## Response Timeline
- Acknowledgement within **48 hours**
- Status update within **7 days**
- Fix timeline communicated within **14 days**
## Scope
The following are considered in scope:
- Authentication and authorization bypass
- Remote code execution
- Path traversal / arbitrary file read
- Server-Side Request Forgery (SSRF)
- Injection vulnerabilities (SQL, command, prompt)
- Sensitive data exposure
## Out of Scope
- Vulnerabilities in dependencies (report to the dependency maintainer)
- Social engineering attacks
- Denial of service via resource exhaustion
## Credits
We appreciate responsible disclosure and will credit researchers
in our release notes unless anonymity is requested.
+1 -1
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Agent Reach — Give your AI Agent eyes to see the entire internet.""" """Agent Reach — Give your AI Agent eyes to see the entire internet."""
__version__ = "1.4.0" __version__ = "1.4.1"
__author__ = "Neo Reid" __author__ = "Neo Reid"
from agent_reach.core import AgentReach from agent_reach.core import AgentReach
+53 -8
View File
@@ -1,10 +1,19 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Reddit — search and read via rdt-cli (public-clis/rdt-cli).""" """Reddit — search and read via rdt-cli (public-clis/rdt-cli).
NOTE: Reddit requires authentication since 2024. All API requests
(including public subreddit reads) return HTTP 403 without a valid
session cookie. Run `rdt login` after installation to authenticate.
"""
import json
import shutil import shutil
import subprocess import subprocess
from .base import Channel from .base import Channel
_CREDENTIAL_FILE = "~/.config/rdt-cli/credential.json"
class RedditChannel(Channel): class RedditChannel(Channel):
name = "reddit" name = "reddit"
@@ -14,18 +23,54 @@ class RedditChannel(Channel):
def can_handle(self, url: str) -> bool: def can_handle(self, url: str) -> bool:
from urllib.parse import urlparse from urllib.parse import urlparse
d = urlparse(url).netloc.lower() d = urlparse(url).netloc.lower()
return "reddit.com" in d or "redd.it" in d return "reddit.com" in d or "redd.it" in d
def check(self, config=None): def check(self, config=None):
rdt = shutil.which("rdt") rdt = shutil.which("rdt")
if rdt: if not rdt:
return "ok", (
"rdt-cli 可用(搜索帖子、阅读全文、查看评论,无需登录)"
)
return "off", ( return "off", (
"需要安装 rdt-cli\n" "需要安装 rdt-cli(推荐使用最新版 v0.4.2+\n"
" pipx install rdt-cli\n" " pip install 'rdt-cli>=0.4.2'\n"
"或:\n" "或:\n"
" uv tool install rdt-cli" " uv tool install rdt-cli\n"
"最新源码:https://github.com/public-clis/rdt-cli\n"
"安装后运行 `rdt login` 登录(需先在浏览器登录 reddit.com)"
) )
try:
r = subprocess.run(
[rdt, "status", "--json"],
capture_output=True,
encoding="utf-8",
errors="replace",
timeout=10,
)
data = json.loads(r.stdout or "{}")
authenticated = data.get("data", {}).get("authenticated", False)
username = data.get("data", {}).get("username") or ""
if authenticated:
suffix = f"(已登录:{username}" if username else ""
return "ok", (f"rdt-cli 可用{suffix}(搜索帖子、阅读全文、查看评论)")
return "warn", (
"rdt-cli 已安装但未登录。Reddit 自 2024 年起要求认证,"
"未登录时所有请求均返回 403。\n\n"
"方法一(自动):运行 `rdt login`\n"
" 先在浏览器登录 reddit.com,再运行此命令自动提取 Cookie。\n\n"
"方法二(手动,适用于 Chrome/Edge 127+ 无法自动提取时):\n"
" 1. Chrome 应用商店安装 Cookie-Editor 扩展:\n"
" https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm\n"
" 2. 在浏览器打开 reddit.com(确保已登录)\n"
" 3. 点击 Cookie-Editor 图标,找到 `reddit_session`,复制其 Value\n"
f" 4. 将以下内容写入 {_CREDENTIAL_FILE}\n"
' {"cookies": {"reddit_session": "<粘贴 Value>"}, '
'"source": "manual", "username": "<你的用户名>", '
'"modhash": null, "saved_at": 0, "last_verified_at": null}\n\n'
"验证:`rdt status --json` 确认 authenticated: true"
)
except (json.JSONDecodeError, FileNotFoundError, subprocess.TimeoutExpired):
return "warn", "rdt-cli 已安装但状态检查失败,运行 `rdt status` 查看详情"
+35 -6
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Twitter/X — check if twitter-cli (public-clis/twitter-cli) is available.""" """Twitter/X — check if twitter-cli or bird CLI is available."""
import shutil import shutil
import subprocess import subprocess
@@ -9,7 +9,7 @@ from .base import Channel
class TwitterChannel(Channel): class TwitterChannel(Channel):
name = "twitter" name = "twitter"
description = "Twitter/X 推文" description = "Twitter/X 推文"
backends = ["twitter-cli"] backends = ["twitter-cli", "bird CLI (legacy)"]
tier = 1 tier = 1
def can_handle(self, url: str) -> bool: def can_handle(self, url: str) -> bool:
@@ -18,24 +18,32 @@ class TwitterChannel(Channel):
return "x.com" in d or "twitter.com" in d return "x.com" in d or "twitter.com" in d
def check(self, config=None): def check(self, config=None):
# Prefer twitter-cli, fallback to bird/birdx
twitter = shutil.which("twitter") twitter = shutil.which("twitter")
if not twitter: bird = shutil.which("bird") or shutil.which("birdx")
if twitter:
return self._check_twitter_cli(twitter)
elif bird:
return self._check_bird(bird)
else:
return "warn", ( return "warn", (
"twitter-cli 未安装。安装方式:\n" "Twitter CLI 未安装。安装方式:\n"
" pipx install twitter-cli\n" " pipx install twitter-cli\n"
"或:\n" "或:\n"
" uv tool install twitter-cli" " uv tool install twitter-cli"
) )
def _check_twitter_cli(self, binary: str):
try: try:
r = subprocess.run( r = subprocess.run(
[twitter, "status"], capture_output=True, [binary, "status"], capture_output=True,
encoding="utf-8", errors="replace", timeout=10 encoding="utf-8", errors="replace", timeout=10
) )
output = (r.stdout or "") + (r.stderr or "") output = (r.stdout or "") + (r.stderr or "")
if r.returncode == 0 and "ok: true" in output: if r.returncode == 0 and "ok: true" in output:
return "ok", ( return "ok", (
"完整可用(搜索、读推文、时间线、长文/Article、" "twitter-cli 完整可用(搜索、读推文、时间线、长文/Article、"
"用户查询、Thread" "用户查询、Thread"
) )
if "not_authenticated" in output: if "not_authenticated" in output:
@@ -51,3 +59,24 @@ class TwitterChannel(Channel):
) )
except Exception: except Exception:
return "warn", "twitter-cli 已安装但连接失败" return "warn", "twitter-cli 已安装但连接失败"
def _check_bird(self, binary: str):
try:
r = subprocess.run(
[binary, "check"], capture_output=True,
encoding="utf-8", errors="replace", timeout=10
)
output = (r.stdout or "") + (r.stderr or "")
if r.returncode == 0:
return "ok", "bird CLI 可用(读取、搜索推文,含长文/X Article)"
if "Missing credentials" in output or "missing" in output.lower():
return "warn", (
"bird CLI 已安装但未配置认证。设置环境变量:\n"
" export AUTH_TOKEN=\"xxx\"\n"
" export CT0=\"yyy\""
)
return "warn", (
"bird CLI 已安装但认证检查失败。"
)
except Exception:
return "warn", "bird CLI 已安装但连接失败"
+15
View File
@@ -1,8 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Web — any URL via Jina Reader. Always available.""" """Web — any URL via Jina Reader. Always available."""
import urllib.request
from .base import Channel from .base import Channel
_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
class WebChannel(Channel): class WebChannel(Channel):
name = "web" name = "web"
@@ -15,3 +18,15 @@ class WebChannel(Channel):
def check(self, config=None): def check(self, config=None):
return "ok", "通过 Jina Reader 读取任意网页(curl https://r.jina.ai/URL" return "ok", "通过 Jina Reader 读取任意网页(curl https://r.jina.ai/URL"
def read(self, url: str) -> str:
"""通过 Jina Reader 读取网页,返回 Markdown 全文。"""
if not url.startswith(("http://", "https://")):
url = "https://" + url
jina_url = f"https://r.jina.ai/{url}"
req = urllib.request.Request(
jina_url,
headers={"User-Agent": _UA, "Accept": "text/plain"},
)
with urllib.request.urlopen(req, timeout=30) as resp:
return resp.read().decode("utf-8")
+1 -1
View File
@@ -17,7 +17,7 @@ def _exa_available() -> bool:
try: try:
r = subprocess.run( r = subprocess.run(
[mcporter, "config", "list"], [mcporter, "config", "list"],
capture_output=True, text=True, timeout=5, capture_output=True, encoding="utf-8", errors="replace", timeout=5,
) )
return "exa" in r.stdout.lower() return "exa" in r.stdout.lower()
except Exception: except Exception:
+36 -8
View File
@@ -326,20 +326,47 @@ def _install_skill():
import shutil import shutil
import importlib.resources import importlib.resources
def _is_english_locale(value: str) -> bool:
normalized = value.strip().lower()
return normalized.startswith("en") or normalized.startswith("english")
def _skill_resource_name() -> str:
locale_candidates = (
os.environ.get("AGENT_REACH_LANG", ""),
os.environ.get("LC_ALL", ""),
os.environ.get("LC_MESSAGES", ""),
os.environ.get("LANG", ""),
)
if any(_is_english_locale(candidate) for candidate in locale_candidates):
return "SKILL_en.md"
return "SKILL.md"
def _read_skill_markdown(skill_pkg):
resource_name = _skill_resource_name()
try:
return skill_pkg.joinpath(resource_name).read_text(encoding="utf-8")
except FileNotFoundError:
return skill_pkg.joinpath("SKILL.md").read_text(encoding="utf-8")
def _copy_skill_dir(target: str) -> bool: def _copy_skill_dir(target: str) -> bool:
"""Copy entire skill directory (SKILL.md + references/).""" """Copy entire skill directory (locale-specific SKILL.md + references/)."""
try: try:
# Clear existing installation # Clear existing installation
if os.path.exists(target): if os.path.exists(target):
shutil.rmtree(target) shutil.rmtree(target)
os.makedirs(target, exist_ok=True) os.makedirs(target, exist_ok=True)
# Get skill directory from package # Get skill directory from package (with fallback for editable installs)
try:
skill_pkg = importlib.resources.files("agent_reach").joinpath("skill") skill_pkg = importlib.resources.files("agent_reach").joinpath("skill")
skill_md = _read_skill_markdown(skill_pkg)
except Exception:
from pathlib import Path
skill_pkg = Path(__file__).resolve().parent / "skill"
skill_md = _read_skill_markdown(skill_pkg)
# Copy SKILL.md # Copy SKILL.md using the selected locale file
skill_md = skill_pkg.joinpath("SKILL.md").read_text() with open(os.path.join(target, "SKILL.md"), "w", encoding="utf-8") as f:
with open(os.path.join(target, "SKILL.md"), "w") as f:
f.write(skill_md) f.write(skill_md)
# Copy references/ directory # Copy references/ directory
@@ -348,9 +375,10 @@ def _install_skill():
os.makedirs(refs_target, exist_ok=True) os.makedirs(refs_target, exist_ok=True)
for ref_file in refs_pkg.iterdir(): for ref_file in refs_pkg.iterdir():
if ref_file.suffix == ".md": name = ref_file.name if hasattr(ref_file, 'name') else str(ref_file).split('/')[-1]
content = ref_file.read_text() if name.endswith(".md"):
with open(os.path.join(refs_target, ref_file.name), "w") as f: content = ref_file.read_text(encoding="utf-8") if hasattr(ref_file, 'read_text') else ref_file.read_text()
with open(os.path.join(refs_target, name), "w", encoding="utf-8") as f:
f.write(content) f.write(content)
return True return True
+1 -1
View File
@@ -3,7 +3,7 @@
AgentReach — installer, doctor, and configuration tool. AgentReach — installer, doctor, and configuration tool.
Agent Reach helps AI agents install and configure upstream platform tools Agent Reach helps AI agents install and configure upstream platform tools
(bird CLI, yt-dlp, mcporter, gh CLI, etc.). After installation, agents (twitter-cli, yt-dlp, mcporter, gh CLI, etc.). After installation, agents
call the upstream tools directly — no wrapper layer needed. call the upstream tools directly — no wrapper layer needed.
Usage: Usage:
+22 -13
View File
@@ -4,42 +4,51 @@
Reddit 封锁了几乎所有非浏览器的直接访问(包括数据中心和 ISP 代理 IP),JSON API 返回 403。 Reddit 封锁了几乎所有非浏览器的直接访问(包括数据中心和 ISP 代理 IP),JSON API 返回 403。
Agent Reach 通过 **Exa** 实现 Reddit 的搜索和阅读功能: Agent Reach 通过 **rdt-cli** 实现 Reddit 的搜索和阅读功能:
- **搜索**`web_search_exa` + `includeDomains: ["reddit.com"]` - **搜索**`rdt search "关键词"`
- **阅读完整帖子+评论**`crawling_exa` 读取 Reddit URL 的缓存内容 - **阅读完整帖子+评论**`rdt read POST_ID`
免费,无需代理,无需 API Key。 免费,无需代理,无需 API Key,无需登录
## Agent 可自动完成的步骤 ## Agent 可自动完成的步骤
1. 检查 Exa 是否可用: 1. 检查 rdt-cli 是否可用:
```bash ```bash
agent-reach doctor | grep -E "Reddit|Exa" which rdt && echo "installed" || echo "not installed"
``` ```
2. 如果 Exa 未安装,自动安装: 2. 如果未安装,自动安装:
```bash ```bash
npm install -g mcporter pipx install rdt-cli
mcporter config add exa https://mcp.exa.ai/mcp
``` ```
或一键安装: 或一键安装:
```bash ```bash
agent-reach install --env=auto agent-reach install --env=auto --channels=reddit
``` ```
## 使用示例 ## 使用示例
搜索 Reddit 内容: 搜索 Reddit 内容:
```bash ```bash
mcporter call 'exa.web_search_exa(query: "python best practices", numResults: 5, includeDomains: ["reddit.com"])' rdt search "python best practices" -n 5
``` ```
阅读完整帖子和评论: 阅读完整帖子和评论:
```bash ```bash
mcporter call 'exa.crawling_exa(urls: ["https://www.reddit.com/r/python/comments/xxx/"], maxCharacters: 10000)' rdt read POST_ID
``` ```
## 需要用户手动做的步骤 ## 需要用户手动做的步骤
无。Exa 通过 `agent-reach install --env=auto` 自动配置 无。rdt-cli 通过 `agent-reach install --env=auto` 自动安装
## FallbackExa 搜索
如果你已经配置了 Exa(通过 mcporter),也可以通过 Exa 搜索 Reddit 内容:
```bash
mcporter call 'exa.web_search_exa(query: "python best practices", numResults: 5, includeDomains: ["reddit.com"])'
```
rdt-cli 是当前推荐方案,无需额外配置即可使用。
+21 -18
View File
@@ -1,35 +1,34 @@
# Twitter 高级功能配置指南(bird CLI # Twitter 高级功能配置指南(twitter-cli
Twitter 基础阅读通过 Jina Reader 免费可用,无需配置。 Twitter 基础阅读通过 Jina Reader 免费可用,无需配置。
高级功能需要 bird CLI@steipete/bird): 高级功能需要 twitter-cli@public-clis/twitter-cli):
- 搜索推文(`bird search` - 搜索推文(`twitter search`
- 读取完整推文和对话链(`bird read``bird thread` - 读取完整推文和对话链(`twitter tweet``twitter thread`
- 用户时间线(`bird user-tweets` - 用户时间线(`twitter timeline`
- 长文阅读(`twitter article`
bird 是免费开源工具(npm 包 @steipete/bird),但需要你的 Twitter 账号 cookie。 twitter-cli 是免费开源工具(pipx 安装),但需要你的 Twitter 账号 cookie。
## 快速配置 ## 快速配置
1. 检查 bird 是否安装: 1. 检查 twitter-cli 是否安装:
```bash ```bash
which bird && echo "installed" || echo "not installed" which twitter && echo "installed" || echo "not installed"
``` ```
2. 安装 bird 2. 安装 twitter-cli
```bash ```bash
npm install -g @steipete/bird pipx install twitter-cli
``` ```
> 备选包:`npm install -g @connormartin/bird`
3. 测试是否配置好: 3. 测试是否配置好:
```bash ```bash
AUTH_TOKEN="xxx" CT0="yyy" bird search "test" -n 1 twitter search "test" -n 1
``` ```
## 获取 CookieCookie-Editor 方式,推荐) ## 获取 CookieCookie-Editor 方式,推荐)
@@ -49,7 +48,7 @@ agent-reach configure twitter-cookies "粘贴的 cookie JSON"
如果你已经知道 `auth_token``ct0` 如果你已经知道 `auth_token``ct0`
1. 安装 bird(如果没装):`npm install -g @steipete/bird` 1. 安装 twitter-cli(如果没装):`pipx install twitter-cli`
2. 设置环境变量: 2. 设置环境变量:
@@ -61,21 +60,25 @@ export CT0="你的ct0"
3. 测试: 3. 测试:
```bash ```bash
bird search "test" -n 1 twitter search "test" -n 1
``` ```
## 代理配置 ## 代理配置
> bird CLI 支持通过环境变量设置代理: > twitter-cli 支持通过环境变量设置代理:
```bash ```bash
export HTTP_PROXY="http://user:pass@host:port" export HTTP_PROXY="http://user:pass@host:port"
export HTTPS_PROXY="http://user:pass@host:port" export HTTPS_PROXY="http://user:pass@host:port"
bird search "test" -n 1 twitter search "test" -n 1
``` ```
也可以使用全局代理工具: 也可以使用全局代理工具:
```bash ```bash
proxychains bird search "test" -n 1 proxychains twitter search "test" -n 1
``` ```
## Fallbackbird CLI
如果你已经安装了 [bird CLI](https://www.npmjs.com/package/@steipete/bird)`npm install -g @steipete/bird`),它也能正常工作。Agent Reach 会自动检测并使用已安装的 bird。两者功能类似,twitter-cli 是当前推荐方案。
+45 -56
View File
@@ -1,51 +1,36 @@
# 小红书配置指南 # 小红书配置指南
## 功能说明 ## 功能说明
读取和搜索小红书笔记。通过 [xiaohongshu-mcp](https://github.com/xpzouying/xiaohongshu-mcp) 实现(⭐9K+,Go 语言,内置 Chrome 浏览器) 读取和搜索小红书笔记。通过 [xhs-cli](https://github.com/jackwener/xiaohongshu-cli)(⭐1.5K,pipx 一行安装)实现
## 前置条件 ## 前置条件
- Docker(用来运行 xiaohongshu-mcp 服务 - Python 3.10+pipx 安装
- mcporter CLIMCP 协议桥接工具 - 浏览器已登录 xiaohongshu.com(用于导出 Cookie
## Agent 可自动完成的步骤 ## Agent 可自动完成的步骤
### 1. 安装 mcporter ### 1. 安装 xhs-cli
```bash ```bash
npm install -g mcporter pipx install xiaohongshu-cli
``` ```
### 2. 启动 xiaohongshu-mcp 服务 ### 2. 登录(从浏览器提取 Cookie
```bash ```bash
docker run -d \ xhs login
--name xiaohongshu-mcp \
-p 18060:18060 \
xpzouying/xiaohongshu-mcp
``` ```
> 如需代理(服务器部署推荐): > 这会自动从浏览器提取 Cookie。如果自动提取失败,可以手动导入(见下方)。
> ```bash
> docker run -d \
> --name xiaohongshu-mcp \
> -p 18060:18060 \
> -e XHS_PROXY=http://user:pass@ip:port \
> xpzouying/xiaohongshu-mcp
> ```
### 3. 注册到 mcporter ### 3. 验证
```bash
mcporter config add xiaohongshu http://localhost:18060/mcp
```
### 4. 验证
```bash ```bash
agent-reach doctor agent-reach doctor
``` ```
应该看到小红书显示为 ✅ 或 ⚠️MCP 已连接但未登录) 应该看到小红书显示为 ✅。
## 需要用户手动做的步骤 ## 需要用户手动做的步骤
如果 doctor 显示"MCP 已连接但未登录",需要导入 cookies 如果 `xhs login` 自动提取失败,需要手动导入 cookies
> **推荐方式:Cookie-Editor 浏览器导出(最可靠)** > **推荐方式:Cookie-Editor 浏览器导出(最可靠)**
> >
@@ -54,43 +39,47 @@ agent-reach doctor
> 3. 点击 Cookie-Editor 图标 → Export → Header String > 3. 点击 Cookie-Editor 图标 → Export → Header String
> 4. 把导出的字符串发给 Agent,运行:`agent-reach configure xhs-cookies "导出的cookie字符串"` > 4. 把导出的字符串发给 Agent,运行:`agent-reach configure xhs-cookies "导出的cookie字符串"`
> >
> **注意**`http://localhost:18060` 根路径可能返回 404,这是正常的——MCP 服务在 `/mcp` 路径 > **注意**不要依赖 QR 扫码登录,Cookie-Editor 导出方式最简单可靠
> 不要依赖 QR 扫码登录,Docker 容器内的 QR 登录页面不一定可用,且 cookies 不会自动共享到 MCP 服务。
## 使用示例
搜索笔记:
```bash
xhs search "关键词"
```
阅读笔记详情:
```bash
xhs read NOTE_ID
```
查看评论:
```bash
xhs comments NOTE_ID
```
## 常见问题 ## 常见问题
**Q: Docker 容器重启后 cookie 了?** **Q: Cookie 过期了?**
A: 挂载数据卷持久化: A: 重新运行 `xhs login` 或通过 Cookie-Editor 重新导出。
**Q: 小红书提示 IP 风险?**
A: 推荐使用住宅代理:`export HTTP_PROXY="http://user:pass@ip:port"`
**Q: xhs-cli 不支持我的系统?**
A: 确保 Python 3.10+ 和 pipx 已安装。运行 `pipx install xiaohongshu-cli` 即可。
## 备选方案:Docker MCP
如果你已经在使用 [xiaohongshu-mcp](https://github.com/xpzouying/xiaohongshu-mcp) Docker 方案,它也能正常工作:
```bash ```bash
docker run -d \ docker run -d \
--name xiaohongshu-mcp \ --name xiaohongshu-mcp \
-p 18060:18060 \ -p 18060:18060 \
-v xhs-data:/app/data \
xpzouying/xiaohongshu-mcp xpzouying/xiaohongshu-mcp
mcporter config add xiaohongshu http://localhost:18060/mcp
``` ```
**Q: 服务器上小红书提示 IP 风险?** xhs-cli 是当前推荐方案,不需要 Docker,安装更简单。
A: 加代理参数 `-e XHS_PROXY=http://user:pass@ip:port`,推荐住宅代理。
**Q: Docker 镜像不支持 ARM64 / Apple Silicon**
A: 上游镜像暂无 ARM64 版本,两种解决办法:
方法一:使用 Rosetta 模拟运行(推荐,最简单)
```bash
docker run -d \
--name xiaohongshu-mcp \
-p 18060:18060 \
--platform linux/amd64 \
xpzouying/xiaohongshu-mcp
```
方法二:从源码编译原生 ARM64 版本
```bash
git clone https://github.com/xpzouying/xiaohongshu-mcp
cd xiaohongshu-mcp
docker build -t xiaohongshu-mcp .
docker run -d --name xiaohongshu-mcp -p 18060:18060 xiaohongshu-mcp
```
**Q: 我不想用 Docker**
A: 可以从源码编译:https://github.com/xpzouying/xiaohongshu-mcp
+1 -1
View File
@@ -5,7 +5,7 @@ Agent Reach MCP Server — expose doctor/status as MCP tool.
Run: python -m agent_reach.integrations.mcp_server Run: python -m agent_reach.integrations.mcp_server
Agent Reach is an installer + doctor tool. For actual reading/searching, Agent Reach is an installer + doctor tool. For actual reading/searching,
agents should call upstream tools directly (bird, yt-dlp, mcporter, etc.). agents should call upstream tools directly (twitter-cli, yt-dlp, mcporter, etc.).
""" """
import asyncio import asyncio
+312
View File
@@ -0,0 +1,312 @@
---
name: agent-reach
description: >
Give your AI agent eyes to see the entire internet.
Search and read 17 platforms: Twitter/X, Reddit, YouTube, GitHub, Bilibili,
XiaoHongShu, Douyin, Weibo, WeChat Articles, Xiaoyuzhou Podcast, LinkedIn,
V2EX, Xueqiu, RSS, Exa web search, and any web page.
Zero config for 8 channels. Use when the user asks to search, read, or interact
on any supported platform, shares a URL, or asks to search the web.
Triggers: "search twitter", "search xiaohongshu", "watch this video",
"search the web", "look this up", "research", "youtube transcript",
"search reddit", "read this link", "bilibili", "douyin video",
"wechat article", "wechat official account", "weibo", "V2EX",
"xiaoyuzhou", "podcast", "xueqiu", "stock quote",
"install agent reach".
metadata:
openclaw:
homepage: https://github.com/Panniantong/Agent-Reach
---
# Agent Reach — Usage Guide
Upstream tools for 17 platforms. Call them directly.
Run `agent-reach doctor` to check which channels are available.
## ⚠️ Workspace Rules
**Never create files in the agent workspace.** Use `/tmp/` for temporary output and `~/.agent-reach/` for persistent data.
## Web — Any URL
```bash
curl -s "https://r.jina.ai/URL"
```
## Web Search (Exa)
```bash
mcporter call 'exa.web_search_exa(query: "query", numResults: 5)'
mcporter call 'exa.get_code_context_exa(query: "code question", tokensNum: 3000)'
```
## Twitter/X (bird)
```bash
bird search "query" -n 10 # search
bird read URL_OR_ID # read tweet (supports /status/ and /article/ URLs)
bird user-tweets @username -n 20 # user timeline
bird thread URL_OR_ID # full thread
```
## YouTube (yt-dlp)
```bash
yt-dlp --dump-json "URL" # video metadata
yt-dlp --write-sub --write-auto-sub --sub-lang "zh-Hans,zh,en" --skip-download -o "/tmp/%(id)s" "URL"
# download subtitles, then read the .vtt file
yt-dlp --dump-json "ytsearch5:query" # search
```
## Bilibili (yt-dlp)
```bash
yt-dlp --dump-json "https://www.bilibili.com/video/BVxxx"
yt-dlp --write-sub --write-auto-sub --sub-lang "zh-Hans,zh,en" --convert-subs vtt --skip-download -o "/tmp/%(id)s" "URL"
```
> Server IPs may get 412. Use `--cookies-from-browser chrome` or configure a proxy.
## Reddit
```bash
curl -s "https://www.reddit.com/r/SUBREDDIT/hot.json?limit=10" -H "User-Agent: agent-reach/1.0"
curl -s "https://www.reddit.com/search.json?q=QUERY&limit=10" -H "User-Agent: agent-reach/1.0"
```
> Server IPs may get 403. Search via Exa instead, or configure a proxy.
## GitHub (gh CLI)
```bash
gh search repos "query" --sort stars --limit 10
gh repo view owner/repo
gh search code "query" --language python
gh issue list -R owner/repo --state open
gh issue view 123 -R owner/repo
```
## XiaoHongShu (mcporter)
```bash
mcporter call 'xiaohongshu.search_feeds(keyword: "query")'
mcporter call 'xiaohongshu.get_feed_detail(feed_id: "xxx", xsec_token: "yyy")'
mcporter call 'xiaohongshu.get_feed_detail(feed_id: "xxx", xsec_token: "yyy", load_all_comments: true)'
mcporter call 'xiaohongshu.publish_content(title: "Title", content: "Body text", images: ["/path/img.jpg"], tags: ["tag"])'
```
> Requires login. Use Cookie-Editor to import cookies.
> **Tip: Clean bloated output.** The XHS API returns large JSON with many unused fields.
> Pipe through the formatter to save context:
> ```bash
> mcporter call 'xiaohongshu.search_feeds(keyword: "query")' | agent-reach format xhs
> ```
> This keeps only: title, content, author, engagement counts, image URLs, and tags.
## Douyin (mcporter)
```bash
mcporter call 'douyin.parse_douyin_video_info(share_link: "https://v.douyin.com/xxx/")'
mcporter call 'douyin.get_douyin_download_link(share_link: "https://v.douyin.com/xxx/")'
```
> No login needed.
## WeChat Articles
**Search** (`miku_ai`):
```bash
# miku_ai is installed inside the agent-reach Python environment.
# Use the same interpreter that runs agent-reach (handles pipx / venv installs):
AGENT_REACH_PYTHON=$(python3 -c "import agent_reach, sys; print(sys.executable)" 2>/dev/null || echo python3)
$AGENT_REACH_PYTHON -c "
import asyncio
from miku_ai import get_wexin_article
async def s():
for a in await get_wexin_article('query', 5):
print(f'{a[\"title\"]} | {a[\"url\"]}')
asyncio.run(s())
"
```
**Read** (Camoufox — bypasses WeChat anti-bot):
```bash
cd ~/.agent-reach/tools/wechat-article-for-ai && python3 main.py "https://mp.weixin.qq.com/s/ARTICLE_ID"
```
> WeChat articles cannot be read with Jina Reader or curl. Use Camoufox.
## Weibo (mcporter)
```bash
# Trending topics
mcporter call 'weibo.get_trendings(limit: 20)'
# Search users
mcporter call 'weibo.search_users(keyword: "Lei Jun", limit: 10)'
# Get a user profile
mcporter call 'weibo.get_profile(uid: "1195230310")'
# Get a user's feed
mcporter call 'weibo.get_feeds(uid: "1195230310", limit: 20)'
# Get a user's hot posts
mcporter call 'weibo.get_hot_feeds(uid: "1195230310", limit: 10)'
# Search post content
mcporter call 'weibo.search_content(keyword: "artificial intelligence", limit: 20)'
# Search topics
mcporter call 'weibo.search_topics(keyword: "AI", limit: 10)'
# Get post comments
mcporter call 'weibo.get_comments(mid: "5099916367123456", limit: 50)'
# Get fans
mcporter call 'weibo.get_fans(uid: "1195230310", limit: 20)'
# Get followings
mcporter call 'weibo.get_followers(uid: "1195230310", limit: 20)'
```
> Zero config. No login needed. Uses the mobile API with auto-generated visitor cookies.
## Xiaoyuzhou Podcast (groq-whisper + ffmpeg)
```bash
# Transcribe a single podcast episode (outputs text to /tmp/)
~/.agent-reach/tools/xiaoyuzhou/transcribe.sh "https://www.xiaoyuzhoufm.com/episode/EPISODE_ID"
```
> Requires `ffmpeg` and a Groq API key (free).
> Configure the key with `agent-reach configure groq-key YOUR_KEY`.
> On first run, install the tools with `agent-reach install --env=auto`.
> Run `agent-reach doctor` to check status.
> Output Markdown files are saved to `/tmp/` by default.
## LinkedIn (mcporter)
```bash
mcporter call 'linkedin.get_person_profile(linkedin_url: "https://linkedin.com/in/username")'
mcporter call 'linkedin.search_people(keyword: "AI engineer", limit: 10)'
```
Fallback: `curl -s "https://r.jina.ai/https://linkedin.com/in/username"`
## V2EX (public API)
```bash
# Hot topics
curl -s "https://www.v2ex.com/api/topics/hot.json" -H "User-Agent: agent-reach/1.0"
# Topics in a node (node_name examples: python, tech, jobs, qna)
curl -s "https://www.v2ex.com/api/topics/show.json?node_name=python&page=1" -H "User-Agent: agent-reach/1.0"
# Topic details (extract topic_id from URLs like https://www.v2ex.com/t/1234567)
curl -s "https://www.v2ex.com/api/topics/show.json?id=TOPIC_ID" -H "User-Agent: agent-reach/1.0"
# Topic replies
curl -s "https://www.v2ex.com/api/replies/show.json?topic_id=TOPIC_ID&page=1" -H "User-Agent: agent-reach/1.0"
# User profile
curl -s "https://www.v2ex.com/api/members/show.json?username=USERNAME" -H "User-Agent: agent-reach/1.0"
```
Python example (`V2EXChannel`):
```python
from agent_reach.channels.v2ex import V2EXChannel
ch = V2EXChannel()
# Get hot topics (default 20 items)
# Returned fields: id, title, url, replies, node_name, node_title, content(first 200 chars), created
topics = ch.get_hot_topics(limit=10)
for t in topics:
print(f"[{t['node_title']}] {t['title']} ({t['replies']} replies) {t['url']}")
print(f" id={t['id']} created={t['created']}")
# Get latest topics for a specific node
# Returned fields: id, title, url, replies, node_name, node_title, content(first 200 chars), created
node_topics = ch.get_node_topics("python", limit=5)
for t in node_topics:
print(t["id"], t["title"], t["url"])
# Get one topic plus replies
# Returned fields: id, title, url, content, replies_count, node_name, node_title,
# author, created, replies (list of {author, content, created})
topic = ch.get_topic(1234567)
print(topic["title"], "", topic["author"])
for r in topic["replies"]:
print(f" {r['author']}: {r['content'][:80]}")
# Get user info
# Returned fields: id, username, url, website, twitter, psn, github, btc, location, bio, avatar, created
user = ch.get_user("Livid")
print(user["username"], user["bio"], user["github"])
# Search (not supported by the public V2EX API; returns guidance instead)
result = ch.search("asyncio")
print(result[0]["error"]) # Use built-in site search or the Exa channel instead
```
> No auth required. Results are public JSON. V2EX node names are listed at https://www.v2ex.com/planes
## Xueqiu (public API)
```python
from agent_reach.channels.xueqiu import XueqiuChannel
ch = XueqiuChannel()
# Get stock quotes (symbol examples: SH600519 mainland China, SZ000858 Shenzhen, AAPL US, 00700 HK)
# Returned fields: symbol, name, current, percent, chg, high, low, open, last_close,
# volume, amount, market_capital, turnover_rate, pe_ttm, timestamp
quote = ch.get_stock_quote("AAPL")
print(f"{quote['name']} ({quote['symbol']}): {quote['current']} ({quote['percent']}%)")
# Search stocks
# Returned fields: symbol, name, exchange
stocks = ch.search_stock("Apple", limit=5)
for s in stocks:
print(f"{s['name']} ({s['symbol']}) - {s['exchange']}")
# Hot posts
# Returned fields: id, title, text(first 200 chars), author, likes, url
posts = ch.get_hot_posts(limit=10)
for p in posts:
print(f"{p['author']}: {p['text'][:50]}... ({p['likes']} likes)")
# Hot stocks (stock_type=10 popularity ranking, stock_type=12 watchlist ranking)
# Returned fields: symbol, name, current, percent, rank
hot = ch.get_hot_stocks(limit=10, stock_type=10)
for s in hot:
print(f"#{s['rank']} {s['name']} ({s['symbol']}): {s['current']} ({s['percent']}%)")
```
> No login required. Agent Reach auto-fetches session cookies, and all public APIs can be used directly.
## RSS (feedparser)
```python
python3 -c "
import feedparser
for e in feedparser.parse('FEED_URL').entries[:5]:
print(f'{e.title}{e.link}')
"
```
## Troubleshooting
- **Channel not working?** Run `agent-reach doctor` — it shows status and fix instructions.
- **Twitter fetch failed?** Ensure `undici` is installed: `npm install -g undici`. Configure a proxy if needed: `agent-reach configure proxy URL`.
## Setting Up a Channel ("help me configure XXX")
If a channel needs setup (cookies, Docker, etc.), fetch the install guide:
https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/install.md
The user only provides cookies. Everything else is your job.
+72 -20
View File
@@ -4,11 +4,13 @@
## 小红书 / XiaoHongShu (xhs-cli) ## 小红书 / XiaoHongShu (xhs-cli)
### 稳定可用的命令
```bash ```bash
# 搜索笔记 # 搜索笔记(推荐入口)
xhs search "query" xhs search "query"
# 阅读笔记详情 # 阅读笔记详情(必须用搜索结果中的 URL 或 ID,不能裸 note_id
xhs read NOTE_ID_OR_URL xhs read NOTE_ID_OR_URL
# 查看评论 # 查看评论
@@ -19,21 +21,50 @@ xhs hot
# 推荐 feed # 推荐 feed
xhs feed xhs feed
# 用户主页
xhs user USER_ID
xhs user-posts USER_ID
# 发帖/互动
xhs post --title "标题" --content "正文" --images img1.jpg img2.jpg
xhs like NOTE_ID
xhs comment NOTE_ID "评论内容"
``` ```
### 已知不稳定的命令(v0.6.4)
```bash
# 以下命令当前可能返回 API error,谨慎使用:
xhs user USER_ID # 可能返回 {code: -1}
xhs user-posts USER_ID # 可能返回 {code: -1}
xhs favorites # 可能返回 API error
```
### 重要注意事项
> **安装**: `pipx install xiaohongshu-cli`,然后 `xhs login`(自动从浏览器提取 Cookie)。 > **安装**: `pipx install xiaohongshu-cli`,然后 `xhs login`(自动从浏览器提取 Cookie)。
>
> **xsec_token 限制**: 小红书强制 xsec_token 机制,**不能直接用裸 note_id 去读**。正确流程是:先 `xhs search` 或 `xhs feed` 获取结果,再用结果中的 URL/ID 去 `xhs read`。直接构造 note_id 会被拦截。
>
> **频率控制**: 高频请求(批量搜索、深翻评论)会触发验证码,这是平台限制无法绕过。建议每次操作间隔 2-3 秒。
>
> **POST 操作风险**: 发帖(post)、评论(comment)、点赞(like) 等写操作在 v0.6.x 可能因签名问题返回 406。如需使用,建议降级到 v0.3.5 (`pipx install xiaohongshu-cli==0.3.5`)。
## 抖音 / Douyin ## 抖音 / Douyin
### 安装与配置
`douyin-mcp-server` 是 **stdio 模式**的 MCP server,需先安装再注册到 mcporter
```bash
# 1. 安装
pipx install douyin-mcp-server
# 2. 查找安装路径
pipx runpip douyin-mcp-server show -f 2>/dev/null | grep "Location" \
|| find ~/.local -name "douyin-mcp-server" 2>/dev/null | head -1
# 3. 注册到 mcporter(使用 stdio 模式,将路径替换为上一步的输出)
mcporter config add douyin --command "/path/to/douyin-mcp-server" --scope home
```
> **注意**`agent-reach install --channels douyin` 暂不支持抖音渠道(抖音在"可选渠道待解锁"列表)。
> HTTP 模式(`mcporter config add douyin http://localhost:18070/mcp`**无法正常工作**,请使用上方 stdio 方式。
### 用法
```bash ```bash
# 解析视频信息 # 解析视频信息
mcporter call 'douyin.parse_douyin_video_info(share_link: "https://v.douyin.com/xxx/")' mcporter call 'douyin.parse_douyin_video_info(share_link: "https://v.douyin.com/xxx/")'
@@ -49,9 +80,11 @@ mcporter call 'douyin.extract_douyin_text(share_link: "https://v.douyin.com/xxx/
## Twitter/X (twitter-cli) ## Twitter/X (twitter-cli)
### 稳定命令
```bash ```bash
# 搜索推文 # 首页时间线(最稳定)
twitter search "query" --limit 10 twitter feed -n 20
# 读取单条推文(含回复) # 读取单条推文(含回复)
twitter tweet URL_OR_ID twitter tweet URL_OR_ID
@@ -60,17 +93,34 @@ twitter tweet URL_OR_ID
twitter article URL_OR_ID twitter article URL_OR_ID
# 用户时间线 # 用户时间线
twitter user-posts @username --limit 20 twitter user-posts @username -n 20
# 用户资料 # 用户资料
twitter user @username twitter user @username
# 首页时间线
twitter feed --limit 20
``` ```
> **安装**: `pipx install twitter-cli` 或 `uv tool install twitter-cli` ### 可能不稳定的命令
> **认证**: 设置 `TWITTER_AUTH_TOKEN` + `TWITTER_CT0` 环境变量,或确保浏览器已登录 x.com。
```bash
# 搜索推文(Twitter 频繁改 GraphQL 端点,可能 404
twitter search "query" -n 10
# 如果 search 返回 404,升级 twitter-clipipx upgrade twitter-cli
# likes(2024 年后只能看自己的,平台限制)
twitter likes
```
### 重要注意事项
> **安装**: `pipx install twitter-cli`(确保 v0.8.5+
>
> **认证**: 推荐用 Cookie-Editor 导出后设置环境变量 `TWITTER_AUTH_TOKEN` + `TWITTER_CT0`。自动提取在 SSH/Docker/无头环境不可用。
>
> **IP 风控**: 不要在 VPS/数据中心 IP 上频繁调用,尤其是 followers/following,有封号风险。使用住宅代理或本地环境。
>
> **search 可能失效**: Twitter 频繁修改 GraphQL APIsearch 命令可能随时返回 404。如遇到,先 `pipx upgrade twitter-cli`。如果最新版仍不行,说明上游还没跟上 Twitter 的改动,用 `twitter feed` 替代。
>
> **输出格式**: 建议用 `--yaml` 或 `--json` 获得结构化输出,对 AI agent 更友好。
## 微博 / Weibo ## 微博 / Weibo
@@ -173,4 +223,6 @@ rdt popular --limit 10
rdt all --limit 10 rdt all --limit 10
``` ```
> **安装**: `pipx install rdt-cli`。无需登录即可搜索和阅读。 > **安装**: `pipx install rdt-cli`(确保 v0.4.2+。无需登录即可搜索和阅读。
> 需要登录的功能:`rdt feed --subs-only`(订阅列表)、`rdt saved`(收藏)。
> 建议使用 `--yaml` 输出,对 AI agent 更友好。
+31 -4
View File
@@ -20,27 +20,54 @@ yt-dlp --write-sub --write-auto-sub --sub-lang "zh-Hans,zh,en" --skip-download -
cat /tmp/VIDEO_ID.*.vtt cat /tmp/VIDEO_ID.*.vtt
``` ```
### 获取评论
```bash
# 提取评论(best-effort,不保证完整)
yt-dlp --write-comments --skip-download --write-info-json \
--extractor-args "youtube:max_comments=20" \
-o "/tmp/%(id)s" "URL"
# 评论在 .info.json 的 comments 字段中
```
### 搜索视频 ### 搜索视频
```bash ```bash
yt-dlp --dump-json "ytsearch5:query" yt-dlp --dump-json "ytsearch5:query"
``` ```
## B站 / Bilibili (yt-dlp) > **字幕注意**: 手动上传的字幕提取可靠;自动生成字幕可能存在行间重复,需后处理。
> **评论注意**: `--write-comments` 基于网页抓取(非 YouTube Data API),部分评论可能丢失。
### 获取视频元数据 ## B站 / Bilibili (yt-dlp + bili-cli)
### 视频元数据 (yt-dlp)
```bash ```bash
yt-dlp --dump-json "https://www.bilibili.com/video/BVxxx" yt-dlp --dump-json "https://www.bilibili.com/video/BVxxx"
``` ```
### 下载字幕 ### 字幕 (yt-dlp)
```bash ```bash
yt-dlp --write-sub --write-auto-sub --sub-lang "zh-Hans,zh,en" --convert-subs vtt --skip-download -o "/tmp/%(id)s" "URL" yt-dlp --write-sub --write-auto-sub --sub-lang "zh-Hans,zh,en" --convert-subs vtt --skip-download -o "/tmp/%(id)s" "URL"
``` ```
> **注意**: 服务器 IP 可能遇到 412 错误。使用 `--cookies-from-browser chrome` 或配置代理。 ### 搜索/热门/排行 (bili-cli)
```bash
# 搜索视频
bili search "query" --type video -n 5
# 热门视频
bili hot -n 10
# 排行榜
bili rank -n 10
```
> **412 风控**: 海外 IP 必须提供 Cookie`--cookies-from-browser chrome` 或 `--cookies /path/to/cookies.txt`),国内 IP 一般不受影响。
> **安装 bili-cli**: `pipx install bilibili-cli`,然后 `bili login` 扫码登录。
## 小宇宙播客 / Xiaoyuzhou Podcast ## 小宇宙播客 / Xiaoyuzhou Podcast
+31 -24
View File
@@ -11,7 +11,7 @@
</p> </p>
<p align="center"> <p align="center">
<a href="#quick-start">Quick Start</a> · <a href="../README.md">中文</a> · <a href="README_ja.md">日本語</a> · <a href="#supported-platforms">Platforms</a> · <a href="#design-philosophy">Philosophy</a> <a href="#quick-start">Quick Start</a> · <a href="../README.md">中文</a> · <a href="README_ja.md">日本語</a> · <a href="README_ko.md">한국어</a> · <a href="#supported-platforms">Platforms</a> · <a href="#design-philosophy">Philosophy</a>
</p> </p>
--- ---
@@ -51,7 +51,7 @@ Update Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/ma
|---|---| |---|---|
| 💰 **Completely free** | All tools are open source, all APIs are free. The only possible cost is a server proxy ($1/month) — local computers don't need one | | 💰 **Completely free** | All tools are open source, all APIs are free. The only possible cost is a server proxy ($1/month) — local computers don't need one |
| 🔒 **Privacy safe** | Cookies stay local. Never uploaded. Fully open source — audit anytime | | 🔒 **Privacy safe** | Cookies stay local. Never uploaded. Fully open source — audit anytime |
| 🔄 **Kept up to date** | Upstream tools (yt-dlp, bird, Jina Reader, etc.) are tracked and updated regularly | | 🔄 **Kept up to date** | Upstream tools (yt-dlp, twitter-cli, rdt-cli, Jina Reader, etc.) are tracked and updated regularly |
| 🤖 **Works with any Agent** | Claude Code, OpenClaw, Cursor, Windsurf… any Agent that can run commands | | 🤖 **Works with any Agent** | Claude Code, OpenClaw, Cursor, Windsurf… any Agent that can run commands |
| 🩺 **Built-in diagnostics** | `agent-reach doctor` — one command shows what works, what doesn't, and how to fix it | | 🩺 **Built-in diagnostics** | `agent-reach doctor` — one command shows what works, what doesn't, and how to fix it |
@@ -62,11 +62,11 @@ Update Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/ma
| Platform | Capabilities | Setup | Notes | | Platform | Capabilities | Setup | Notes |
|----------|-------------|:-----:|-------| |----------|-------------|:-----:|-------|
| 🌐 **Web** | Read | Zero config | Any URL → clean Markdown ([Jina Reader](https://github.com/jina-ai/reader) ⭐9.8K) | | 🌐 **Web** | Read | Zero config | Any URL → clean Markdown ([Jina Reader](https://github.com/jina-ai/reader) ⭐9.8K) |
| 🐦 **Twitter/X** | Read · Search | Zero config / Cookie | Single tweets readable out of the box. Cookie unlocks search, timeline, posting ([bird](https://www.npmjs.com/package/@steipete/bird)) | | 🐦 **Twitter/X** | Read · Search | Cookie | Cookie unlocks search, timeline, tweet reading, articles ([twitter-cli](https://github.com/public-clis/twitter-cli)) |
| 📕 **XiaoHongShu** | Read · Search · **Post · Comment · Like** | mcporter | Via [xiaohongshu-mcp](https://github.com/user/xiaohongshu-mcp) internal API, install and go | | 📕 **XiaoHongShu** | Read · Search · **Post · Comment · Like** | Cookie | `pipx install xiaohongshu-cli` + `xhs login` ([xhs-cli](https://github.com/jackwener/xiaohongshu-cli)) |
| 🎵 **Douyin** | Video parsing · Watermark-free download | mcporter | Via [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server), no login needed | | 🎵 **Douyin** | Video parsing · Watermark-free download | mcporter | Via [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server), no login needed |
| 💼 **LinkedIn** | Jina Reader (public pages) | Full profiles, companies, job search | Tell your Agent "help me set up LinkedIn" | | 💼 **LinkedIn** | Jina Reader (public pages) | Full profiles, companies, job search | Tell your Agent "help me set up LinkedIn" |
| 💬 **WeChat Articles** | Search + Read | Zero config | Search + read WeChat Official Account articles (full Markdown) ([wechat-article-for-ai](https://github.com/Panniantong/wechat-article-for-ai) + [miku_ai](https://github.com/GobinFan/Miku_Spider)) | | 💬 **WeChat Articles** | Search + Read | Zero config | Search + read WeChat Official Account articles via Exa (zero config) + optional [Camoufox](https://github.com/daijro/camoufox) |
| 📰 **Weibo** | Trending · Search · Feeds · Comments | Zero config | Hot search, content/user/topic search, feeds, comments ([mcp-server-weibo](https://github.com/Panniantong/mcp-server-weibo)) | | 📰 **Weibo** | Trending · Search · Feeds · Comments | Zero config | Hot search, content/user/topic search, feeds, comments ([mcp-server-weibo](https://github.com/Panniantong/mcp-server-weibo)) |
| 💻 **V2EX** | Hot topics · Node topics · Topic detail + replies · User profile | Zero config | Public JSON API, no auth required. Great for tech community content | | 💻 **V2EX** | Hot topics · Node topics · Topic detail + replies · User profile | Zero config | Public JSON API, no auth required. Great for tech community content |
| 📈 **Xueqiu (雪球)** | Stock quotes · Search · Hot posts · Hot stocks | Browser cookie | Tell your Agent "help me set up Xueqiu" | | 📈 **Xueqiu (雪球)** | Stock quotes · Search · Hot posts · Hot stocks | Browser cookie | Tell your Agent "help me set up Xueqiu" |
@@ -76,7 +76,7 @@ Update Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/ma
| 📺 **YouTube** | Read · **Search** | Zero config | Subtitles + search across 1800+ video sites ([yt-dlp](https://github.com/yt-dlp/yt-dlp) ⭐148K) | | 📺 **YouTube** | Read · **Search** | Zero config | Subtitles + search across 1800+ video sites ([yt-dlp](https://github.com/yt-dlp/yt-dlp) ⭐148K) |
| 📺 **Bilibili** | Read · **Search** | Zero config / Proxy | Video info + subtitles + search. Local works directly, servers need a proxy ([yt-dlp](https://github.com/yt-dlp/yt-dlp)) | | 📺 **Bilibili** | Read · **Search** | Zero config / Proxy | Video info + subtitles + search. Local works directly, servers need a proxy ([yt-dlp](https://github.com/yt-dlp/yt-dlp)) |
| 📡 **RSS** | Read | Zero config | Any RSS/Atom feed ([feedparser](https://github.com/kurtmckee/feedparser) ⭐2.3K) | | 📡 **RSS** | Read | Zero config | Any RSS/Atom feed ([feedparser](https://github.com/kurtmckee/feedparser) ⭐2.3K) |
| 📖 **Reddit** | Search · Read | Zero config | Search and read via Exa (free, no proxy needed) | | 📖 **Reddit** | Search · Read | Cookie | Requires auth since 2024 — `rdt login` after install ([rdt-cli](https://github.com/public-clis/rdt-cli)) |
> **Setup levels:** Zero config = install and go · Auto-configured = handled during install · mcporter = needs MCP service · Cookie = export from browser · Proxy = $1/month > **Setup levels:** Zero config = install and go · Auto-configured = handled during install · mcporter = needs MCP service · Cookie = export from browser · Proxy = $1/month
@@ -116,6 +116,11 @@ npx skills add Panniantong/Agent-Reach@agent-reach
After the Skill is installed, the Agent will auto-detect whether `agent-reach` CLI is available and install it if needed. After the Skill is installed, the Agent will auto-detect whether `agent-reach` CLI is available and install it if needed.
> If you install via `agent-reach install`, the skill is registered automatically — no extra steps needed. > If you install via `agent-reach install`, the skill is registered automatically — no extra steps needed.
>
> Prefer an English-only skill file? Set an English locale or export `AGENT_REACH_LANG=en`
> before running `agent-reach install --env=auto` or `agent-reach skill --install`.
> The installed file is always written as `SKILL.md`, so switching languages means rerunning
> the install command with the new locale and replacing the previously installed skill file.
</details> </details>
--- ---
@@ -127,7 +132,7 @@ No configuration needed — just tell your Agent:
- "Read this link" → `curl https://r.jina.ai/URL` for any web page - "Read this link" → `curl https://r.jina.ai/URL` for any web page
- "What's this GitHub repo about?" → `gh repo view owner/repo` - "What's this GitHub repo about?" → `gh repo view owner/repo`
- "What does this video cover?" → `yt-dlp --dump-json URL` for subtitles - "What does this video cover?" → `yt-dlp --dump-json URL` for subtitles
- "Read this tweet" → `bird read URL` - "Read this tweet" → `twitter tweet URL`
- "Subscribe to this RSS" → `feedparser` to parse feeds - "Subscribe to this RSS" → `feedparser` to parse feeds
- "Search GitHub for LLM frameworks" → `gh search repos "LLM framework"` - "Search GitHub for LLM frameworks" → `gh search repos "LLM framework"`
@@ -147,7 +152,7 @@ Tell your Agent "help me configure Twitter cookies" — it'll guide you through
Bilibili blocks server IPs. Get a proxy ([Webshare](https://webshare.io) recommended, $1/month) and send the address to your Agent. Bilibili blocks server IPs. Get a proxy ([Webshare](https://webshare.io) recommended, $1/month) and send the address to your Agent.
> Reddit now works free via Exa without any proxy. Local computers don't need a proxy for Bilibili either. > Reddit now works free via rdt-cli without any proxy. Local computers don't need a proxy for Bilibili either.
--- ---
@@ -171,7 +176,7 @@ $ agent-reach doctor
⬜ Web semantic search — sign up at exa.ai for free key ⬜ Web semantic search — sign up at exa.ai for free key
🔧 Configurable: 🔧 Configurable:
✅ Reddit posts and comments — search and read via Exa (free, no proxy) ✅ Reddit posts and comments — search and read via rdt-cli (free, no proxy)
⬜ XiaoHongShu notes — needs cookie. Export from browser ⬜ XiaoHongShu notes — needs cookie. Export from browser
Status: 6/9 channels available Status: 6/9 channels available
@@ -187,7 +192,7 @@ Every time you spin up a new Agent, you spend time finding tools, installing dep
Agent Reach does one simple thing: **it makes those tool selection and configuration decisions for you.** Agent Reach does one simple thing: **it makes those tool selection and configuration decisions for you.**
After installation, your Agent calls the upstream tools directly (bird CLI, yt-dlp, mcporter, gh CLI, etc.) — no wrapper layer in between. After installation, your Agent calls the upstream tools directly (twitter-cli, rdt-cli, xhs-cli, yt-dlp, mcporter, gh CLI, etc.) — no wrapper layer in between.
### 🔌 Every Channel is Pluggable ### 🔌 Every Channel is Pluggable
@@ -196,11 +201,11 @@ Each platform maps to an upstream tool. **Don't like one? Swap it out.**
``` ```
channels/ channels/
├── web.py → Jina Reader ← swap to Firecrawl, Crawl4AI… ├── web.py → Jina Reader ← swap to Firecrawl, Crawl4AI…
├── twitter.py → bird CLI ← swap to Nitter, official API… ├── twitter.py → twitter-cli ← swap to official API…
├── youtube.py → yt-dlp ← swap to YouTube API, Whisper… ├── youtube.py → yt-dlp ← swap to YouTube API, Whisper…
├── github.py → gh CLI ← swap to REST API, PyGithub… ├── github.py → gh CLI ← swap to REST API, PyGithub…
├── bilibili.py → yt-dlp ← swap to bilibili-api… ├── bilibili.py → yt-dlp ← swap to bilibili-api…
├── reddit.py → Exa ← search + read, no proxy needed ├── reddit.py → rdt-cli ← search + read, cookie auth required
├── xiaohongshu.py → mcporter MCP ← swap to other XHS tools… ├── xiaohongshu.py → mcporter MCP ← swap to other XHS tools…
├── douyin.py → mcporter MCP ← swap to other Douyin tools… ├── douyin.py → mcporter MCP ← swap to other Douyin tools…
├── linkedin.py → linkedin-mcp ← swap to LinkedIn API… ├── linkedin.py → linkedin-mcp ← swap to LinkedIn API…
@@ -216,15 +221,17 @@ Each channel file only checks whether its upstream tool is installed and working
| Scenario | Tool | Why | | Scenario | Tool | Why |
|----------|------|-----| |----------|------|-----|
| Read web pages | [Jina Reader](https://github.com/jina-ai/reader) | 9.8K stars, free, no API key needed | | Read web pages | [Jina Reader](https://github.com/jina-ai/reader) | 9.8K stars, free, no API key needed |
| Read tweets | [bird](https://www.npmjs.com/package/@steipete/bird) | Cookie auth, free. Official API is pay-per-use ($0.005/post read) | | Read tweets | [twitter-cli](https://github.com/public-clis/twitter-cli) | 2.1K stars, cookie auth, search/read/timeline/articles |
| Video subtitles + search | [yt-dlp](https://github.com/yt-dlp/yt-dlp) | 148K stars, YouTube + Bilibili + 1800 sites | | Reddit | [rdt-cli](https://github.com/public-clis/rdt-cli) | 304 stars, cookie auth, search + full posts + comments |
| Search the web | [Exa](https://exa.ai) via [mcporter](https://github.com/nicepkg/mcporter) | AI semantic search, MCP integration, no API key | | Video subtitles + search | [yt-dlp](https://github.com/yt-dlp/yt-dlp) | 154K stars, YouTube + Bilibili + 1800 sites |
| Bilibili enhanced | [bili-cli](https://github.com/public-clis/bilibili-cli) | 590 stars, hot/rank/search/feed |
| Search the web | [Exa](https://exa.ai) via [mcporter](https://github.com/nicobailon/mcporter) | AI semantic search, MCP integration, no API key |
| GitHub | [gh CLI](https://cli.github.com) | Official tool, full API after auth | | GitHub | [gh CLI](https://cli.github.com) | Official tool, full API after auth |
| Read RSS | [feedparser](https://github.com/kurtmckee/feedparser) | Python ecosystem standard, 2.3K stars | | Read RSS | [feedparser](https://github.com/kurtmckee/feedparser) | Python ecosystem standard, 2.3K stars |
| XiaoHongShu | [xiaohongshu-mcp](https://github.com/user/xiaohongshu-mcp) | Internal API, bypasses anti-bot | | XiaoHongShu | [xhs-cli](https://github.com/jackwener/xiaohongshu-cli) | 1.5K stars, pipx install, search/read/comment/post |
| Douyin | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) | MCP server, no login needed, video parsing + watermark-free download | | Douyin | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) | MCP server, no login needed, video parsing + watermark-free download |
| LinkedIn | [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) | 900+ stars, MCP server, browser automation | | LinkedIn | [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) | 1.2K stars, MCP server, browser automation |
| WeChat Articles | [wechat-article-for-ai](https://github.com/Panniantong/wechat-article-for-ai) + [miku_ai](https://github.com/GobinFan/Miku_Spider) | Stealth browser for full article reading + Sogou search | | WeChat Articles | [Exa](https://exa.ai) (search + read) + [Camoufox](https://github.com/daijro/camoufox) (optional) | Zero-config search + full article reading |
| Weibo | `mcporter` | `mcporter call 'weibo.get_trendings(limit: 10)'` | | Weibo | `mcporter` | `mcporter call 'weibo.get_trendings(limit: 10)'` |
| Xiaoyuzhou Podcast | `transcribe.sh` | `bash ~/.agent-reach/tools/xiaoyuzhou/transcribe.sh <URL>` | | Xiaoyuzhou Podcast | `transcribe.sh` | `bash ~/.agent-reach/tools/xiaoyuzhou/transcribe.sh <URL>` |
@@ -249,7 +256,7 @@ This project was entirely vibe-coded 🎸 There might be rough edges here and th
<details> <details>
<summary><strong>How to search Twitter/X with AI agent without paying for API?</strong></summary> <summary><strong>How to search Twitter/X with AI agent without paying for API?</strong></summary>
Agent Reach uses the [bird CLI](https://www.npmjs.com/package/@steipete/bird) with cookie-based authentication — completely free, no Twitter API subscription needed. After installing Agent Reach, export your Twitter cookies using the Cookie-Editor Chrome extension, run `agent-reach configure twitter-cookies "your_cookies"`, and your agent can search with `bird search "query" -n 10`. Agent Reach uses [twitter-cli](https://github.com/public-clis/twitter-cli) with cookie-based authentication — completely free, no Twitter API subscription needed. Install with `pipx install twitter-cli`, make sure you're logged into x.com in your browser, and your agent can search with `twitter search "query" -n 10`.
</details> </details>
<details> <details>
@@ -261,7 +268,7 @@ Agent Reach uses the [bird CLI](https://www.npmjs.com/package/@steipete/bird) wi
<details> <details>
<summary><strong>Reddit returns 403 from server / datacenter IP blocked?</strong></summary> <summary><strong>Reddit returns 403 from server / datacenter IP blocked?</strong></summary>
Agent Reach now uses Exa to search and read Reddit content, completely bypassing Reddit's IP blocks. No proxy needed. Run `agent-reach install --env=auto` to set up Exa automatically. Agent Reach uses [rdt-cli](https://github.com/public-clis/rdt-cli) for Reddit. Since 2024, Reddit requires authentication for all API requests. Install with `pipx install rdt-cli`, then run `rdt login` (auto-extracts cookies from your browser). Your agent can then search with `rdt search "query"` and read full posts + comments with `rdt read POST_ID`.
</details> </details>
<details> <details>
@@ -273,19 +280,19 @@ Yes! Agent Reach is an installer + configuration tool. Any AI coding agent that
<details> <details>
<summary><strong>Is Agent Reach free? Any API costs?</strong></summary> <summary><strong>Is Agent Reach free? Any API costs?</strong></summary>
100% free and open source. All backends (bird CLI, yt-dlp, Jina Reader, Exa) are free tools that don't require paid API keys. The only optional cost is a residential proxy (~$1/month) if you need Bilibili access from a server. Reddit works free via Exa without any proxy. 100% free and open source. All backends (twitter-cli, rdt-cli, xhs-cli, yt-dlp, Jina Reader, Exa) are free tools that don't require paid API keys. The only optional cost is a residential proxy (~$1/month) if you need Bilibili access from a server. Reddit works free via rdt-cli without any proxy.
</details> </details>
<details> <details>
<summary><strong>Free alternative to Twitter API for web scraping?</strong></summary> <summary><strong>Free alternative to Twitter API for web scraping?</strong></summary>
Agent Reach uses bird CLI which accesses Twitter via cookie auth — same as your browser session. No API fees, no rate limit tiers, no developer account needed. Supports search, read tweets, read profiles, and timelines. Agent Reach uses twitter-cli which accesses Twitter via cookie auth — same as your browser session. No API fees, no rate limit tiers, no developer account needed. Supports search, read tweets, read profiles, and timelines.
</details> </details>
<details> <details>
<summary><strong>How to read XiaoHongShu / 小红书 content programmatically?</strong></summary> <summary><strong>How to read XiaoHongShu / 小红书 content programmatically?</strong></summary>
Agent Reach integrates with xiaohongshu-mcp (runs in Docker). After setup, use `mcporter call 'xiaohongshu.get_feed_detail(...)'` to read notes or `mcporter call 'xiaohongshu.search_feeds(keyword: "query")'` to search. Install `pipx install xiaohongshu-cli`, then `xhs login` (auto-extracts cookies from browser). Your agent can then use `xhs search "query"` to search notes, `xhs read NOTE_ID` to read details, `xhs comments NOTE_ID` to view comments. No Docker needed.
</details> </details>
<details> <details>
@@ -325,7 +332,7 @@ This is useful when your agent workflow is “paste a link, get a script file”
## Credits ## Credits
[Jina Reader](https://github.com/jina-ai/reader) · [yt-dlp](https://github.com/yt-dlp/yt-dlp) · [bird](https://www.npmjs.com/package/@steipete/bird) · [Exa](https://exa.ai) · [feedparser](https://github.com/kurtmckee/feedparser) · [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) · [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) [twitter-cli](https://github.com/public-clis/twitter-cli) · [rdt-cli](https://github.com/public-clis/rdt-cli) · [xhs-cli](https://github.com/jackwener/xiaohongshu-cli) · [bili-cli](https://github.com/public-clis/bilibili-cli) · [yt-dlp](https://github.com/yt-dlp/yt-dlp) · [Jina Reader](https://github.com/jina-ai/reader) · [Exa](https://exa.ai) · [mcporter](https://github.com/nicobailon/mcporter) · [feedparser](https://github.com/kurtmckee/feedparser) · [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) · [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server)
## Contact ## Contact
+22 -22
View File
@@ -11,7 +11,7 @@
</p> </p>
<p align="center"> <p align="center">
<a href="#クイックスタート">クイックスタート</a> · <a href="../README.md">中文</a> · <a href="README_en.md">English</a> · <a href="#対応プラットフォーム">プラットフォーム</a> · <a href="#設計思想">設計思想</a> <a href="#クイックスタート">クイックスタート</a> · <a href="../README.md">中文</a> · <a href="README_en.md">English</a> · <a href="README_ko.md">한국어</a> · <a href="#対応プラットフォーム">プラットフォーム</a> · <a href="#設計思想">設計思想</a>
</p> </p>
--- ---
@@ -51,7 +51,7 @@ Update Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/ma
|---|---| |---|---|
| 💰 **完全無料** | すべてのツールはオープンソース、すべてのAPIは無料。唯一のコストはサーバープロキシ(月額$1)の可能性のみ — ローカルPCでは不要 | | 💰 **完全無料** | すべてのツールはオープンソース、すべてのAPIは無料。唯一のコストはサーバープロキシ(月額$1)の可能性のみ — ローカルPCでは不要 |
| 🔒 **プライバシー安全** | Cookieはローカルに保存。アップロードされることはありません。完全オープンソース — いつでも監査可能 | | 🔒 **プライバシー安全** | Cookieはローカルに保存。アップロードされることはありません。完全オープンソース — いつでも監査可能 |
| 🔄 **常に最新** | 上流ツール(yt-dlp、bird、Jina Reader等)を定期的に追跡・更新 | | 🔄 **常に最新** | 上流ツール(yt-dlp、twitter-cli、rdt-cli、Jina Reader等)を定期的に追跡・更新 |
| 🤖 **あらゆるエージェントに対応** | Claude Code、OpenClaw、Cursor、Windsurf… コマンドを実行できるすべてのエージェント | | 🤖 **あらゆるエージェントに対応** | Claude Code、OpenClaw、Cursor、Windsurf… コマンドを実行できるすべてのエージェント |
| 🩺 **組み込み診断** | `agent-reach doctor` — 1コマンドで何が動き、何が動かないか、どう修正するかを表示 | | 🩺 **組み込み診断** | `agent-reach doctor` — 1コマンドで何が動き、何が動かないか、どう修正するかを表示 |
@@ -62,11 +62,11 @@ Update Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/ma
| プラットフォーム | 機能 | セットアップ | 備考 | | プラットフォーム | 機能 | セットアップ | 備考 |
|-----------------|------|:----------:|------| |-----------------|------|:----------:|------|
| 🌐 **Web** | 閲覧 | 設定不要 | 任意のURL → クリーンなMarkdown[Jina Reader](https://github.com/jina-ai/reader) ⭐9.8K | | 🌐 **Web** | 閲覧 | 設定不要 | 任意のURL → クリーンなMarkdown[Jina Reader](https://github.com/jina-ai/reader) ⭐9.8K |
| 🐦 **Twitter/X** | 閲覧・検索 | 設定不要 / Cookie | 単一ツイートはすぐに閲覧可能。Cookieで検索、タイムライン、投稿が解放([bird](https://www.npmjs.com/package/@steipete/bird) | | 🐦 **Twitter/X** | 閲覧・検索 | 設定不要 / Cookie | 単一ツイートはすぐに閲覧可能。Cookieで検索、タイムライン、投稿が解放([twitter-cli](https://github.com/public-clis/twitter-cli) |
| 📕 **小紅書** | 閲覧・検索・**投稿・コメント・いいね** | mcporter | [xiaohongshu-mcp](https://github.com/user/xiaohongshu-mcp) 内部APIで、インストールしてすぐ使える | | 📕 **小紅書** | 閲覧・検索・**投稿・コメント・いいね** | Cookie | `pipx install xiaohongshu-cli` + `xhs login`[xhs-cli](https://github.com/jackwener/xiaohongshu-cli) |
| 🎵 **抖音** | 動画解析・ウォーターマークなしダウンロード | mcporter | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server)、ログイン不要 | | 🎵 **抖音** | 動画解析・ウォーターマークなしダウンロード | mcporter | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server)、ログイン不要 |
| 💼 **LinkedIn** | Jina Reader(公開ページ) | プロフィール、企業、求人検索 | エージェントに「LinkedInの設定を手伝って」と伝えてください | | 💼 **LinkedIn** | Jina Reader(公開ページ) | プロフィール、企業、求人検索 | エージェントに「LinkedInの設定を手伝って」と伝えてください |
| 💬 **WeChat記事** | 検索 + 閲覧 | 設定不要 | WeChat公式アカウント記事の検索+閲覧(完全Markdown)([wechat-article-for-ai](https://github.com/Panniantong/wechat-article-for-ai) + [miku_ai](https://github.com/GobinFan/Miku_Spider) | | 💬 **WeChat記事** | 検索 + 閲覧 | 設定不要 | WeChat公式アカウント記事の検索+閲覧(完全Markdown)([Exa](https://exa.ai) + [Camoufox](https://github.com/daijro/camoufox)(オプション) |
| 📰 **Weibo** | トレンド・検索・フィード・コメント | 設定不要 | ホット検索、コンテンツ/ユーザー/トピック検索、フィード、コメント([mcp-server-weibo](https://github.com/Panniantong/mcp-server-weibo) | | 📰 **Weibo** | トレンド・検索・フィード・コメント | 設定不要 | ホット検索、コンテンツ/ユーザー/トピック検索、フィード、コメント([mcp-server-weibo](https://github.com/Panniantong/mcp-server-weibo) |
| 💻 **V2EX** | 人気トピック・ノードトピック・トピック詳細+返信・ユーザープロフィール | 設定不要 | 公開JSON API、認証不要。技術コミュニティのコンテンツに最適 | | 💻 **V2EX** | 人気トピック・ノードトピック・トピック詳細+返信・ユーザープロフィール | 設定不要 | 公開JSON API、認証不要。技術コミュニティのコンテンツに最適 |
| 📈 **雪球(Xueqiu** | 株価・検索・人気投稿・人気銘柄 | 設定不要 | 公開APIで自動セッションCookie、ログイン不要 | | 📈 **雪球(Xueqiu** | 株価・検索・人気投稿・人気銘柄 | 設定不要 | 公開APIで自動セッションCookie、ログイン不要 |
@@ -76,7 +76,7 @@ Update Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/ma
| 📺 **YouTube** | 閲覧・**検索** | 設定不要 | 字幕 + 1800以上の動画サイトでの検索([yt-dlp](https://github.com/yt-dlp/yt-dlp) ⭐148K | | 📺 **YouTube** | 閲覧・**検索** | 設定不要 | 字幕 + 1800以上の動画サイトでの検索([yt-dlp](https://github.com/yt-dlp/yt-dlp) ⭐148K |
| 📺 **Bilibili** | 閲覧・**検索** | 設定不要 / プロキシ | 動画情報 + 字幕 + 検索。ローカルはそのまま動作、サーバーはプロキシが必要([yt-dlp](https://github.com/yt-dlp/yt-dlp) | | 📺 **Bilibili** | 閲覧・**検索** | 設定不要 / プロキシ | 動画情報 + 字幕 + 検索。ローカルはそのまま動作、サーバーはプロキシが必要([yt-dlp](https://github.com/yt-dlp/yt-dlp) |
| 📡 **RSS** | 閲覧 | 設定不要 | 任意のRSS/Atomフィード([feedparser](https://github.com/kurtmckee/feedparser) ⭐2.3K | | 📡 **RSS** | 閲覧 | 設定不要 | 任意のRSS/Atomフィード([feedparser](https://github.com/kurtmckee/feedparser) ⭐2.3K |
| 📖 **Reddit** | 検索・閲覧 | 無料 / プロキシ | 検索はExa(無料)経由。投稿の閲覧はサーバーでプロキシが必要 | | 📖 **Reddit** | 検索・閲覧 | Cookie | 2024年以降認証が必要 — インストール後 `rdt login` を実行([rdt-cli](https://github.com/public-clis/rdt-cli) |
> **セットアップレベル:** 設定不要 = インストールしてすぐ使える · 自動設定 = インストール時に処理 · mcporter = MCPサービスが必要 · Cookie = ブラウザからエクスポート · プロキシ = 月額$1 > **セットアップレベル:** 設定不要 = インストールしてすぐ使える · 自動設定 = インストール時に処理 · mcporter = MCPサービスが必要 · Cookie = ブラウザからエクスポート · プロキシ = 月額$1
@@ -127,7 +127,7 @@ Skillインストール後、エージェントは`agent-reach` CLIが利用可
- 「このリンクを読んで」→ `curl https://r.jina.ai/URL` で任意のWebページ - 「このリンクを読んで」→ `curl https://r.jina.ai/URL` で任意のWebページ
- 「このGitHubリポジトリは何?」→ `gh repo view owner/repo` - 「このGitHubリポジトリは何?」→ `gh repo view owner/repo`
- 「この動画の内容は?」→ `yt-dlp --dump-json URL` で字幕取得 - 「この動画の内容は?」→ `yt-dlp --dump-json URL` で字幕取得
- 「このツイートを読んで」→ `bird read URL` - 「このツイートを読んで」→ `twitter tweet URL`
- 「このRSSを購読して」→ `feedparser` でフィード解析 - 「このRSSを購読して」→ `feedparser` でフィード解析
- 「GitHubでLLMフレームワークを検索して」→ `gh search repos "LLM framework"` - 「GitHubでLLMフレームワークを検索して」→ `gh search repos "LLM framework"`
@@ -147,7 +147,7 @@ Skillインストール後、エージェントは`agent-reach` CLIが利用可
RedditとBilibiliはサーバーIPをブロックします。プロキシを取得し([Webshare](https://webshare.io) 推奨、月額$1)、アドレスをエージェントに伝えてください。 RedditとBilibiliはサーバーIPをブロックします。プロキシを取得し([Webshare](https://webshare.io) 推奨、月額$1)、アドレスをエージェントに伝えてください。
> ローカルPCではプロキシは不要です。Reddit検索はプロキシなしでもExaで無料で動作します。 > ローカルPCではプロキシは不要です。Reddit検索はプロキシなしでもrdt-cliで無料で動作します。
--- ---
@@ -171,7 +171,7 @@ $ agent-reach doctor
⬜ Webセマンティック検索 — exa.aiで無料キーを取得 ⬜ Webセマンティック検索 — exa.aiで無料キーを取得
🔧 設定可能: 🔧 設定可能:
Reddit投稿とコメント — 検索はExa(無料)経由。閲覧にはプロキシが必要 Reddit投稿とコメント — rdt-cliで検索+閲覧(無料、プロキシ不要)
⬜ 小紅書ノート — Cookieが必要。ブラウザからエクスポート ⬜ 小紅書ノート — Cookieが必要。ブラウザからエクスポート
ステータス: 9チャンネル中6チャンネルが利用可能 ステータス: 9チャンネル中6チャンネルが利用可能
@@ -187,7 +187,7 @@ $ agent-reach doctor
Agent Reach はシンプルなことを1つだけ行います:**ツールの選定と設定の判断をあなたの代わりに行います。** Agent Reach はシンプルなことを1つだけ行います:**ツールの選定と設定の判断をあなたの代わりに行います。**
インストール後、エージェントは上流ツール(bird CLI、yt-dlp、mcporter、gh CLI等)を直接呼び出します — 間にラッパーレイヤーはありません。 インストール後、エージェントは上流ツール(twitter-cli、rdt-cli、xhs-cli、yt-dlp、mcporter、gh CLI等)を直接呼び出します — 間にラッパーレイヤーはありません。
### 🔌 すべてのチャンネルはプラグ可能 ### 🔌 すべてのチャンネルはプラグ可能
@@ -196,12 +196,12 @@ Agent Reach はシンプルなことを1つだけ行います:**ツールの
``` ```
channels/ channels/
├── web.py → Jina Reader ← Firecrawl、Crawl4AIなどに差し替え可能… ├── web.py → Jina Reader ← Firecrawl、Crawl4AIなどに差し替え可能…
├── twitter.py → bird CLI Nitter、公式APIなどに差し替え可能… ├── twitter.py → twitter-cli ← 公式APIなどに差し替え可能…
├── youtube.py → yt-dlp ← YouTube API、Whisperなどに差し替え可能… ├── youtube.py → yt-dlp ← YouTube API、Whisperなどに差し替え可能…
├── github.py → gh CLI ← REST API、PyGithubなどに差し替え可能… ├── github.py → gh CLI ← REST API、PyGithubなどに差し替え可能…
├── bilibili.py → yt-dlp ← bilibili-apiなどに差し替え可能… ├── bilibili.py → yt-dlp ← bilibili-apiなどに差し替え可能…
├── reddit.py → JSON API + Exa ← PRAW、Pushshiftなどに差し替え可能… ├── reddit.py → rdt-cli ← 検索+閲覧、Cookie認証が必要
├── xiaohongshu.py → mcporter MCP ← 他のXHSツールに差し替え可能… ├── xiaohongshu.py → xhs-cli ← 他のXHSツールに差し替え可能…
├── douyin.py → mcporter MCP ← 他の抖音ツールに差し替え可能… ├── douyin.py → mcporter MCP ← 他の抖音ツールに差し替え可能…
├── linkedin.py → linkedin-mcp ← LinkedIn APIに差し替え可能… ├── linkedin.py → linkedin-mcp ← LinkedIn APIに差し替え可能…
├── rss.py → feedparser ← atomaなどに差し替え可能… ├── rss.py → feedparser ← atomaなどに差し替え可能…
@@ -216,15 +216,15 @@ channels/
| シナリオ | ツール | 理由 | | シナリオ | ツール | 理由 |
|----------|--------|------| |----------|--------|------|
| Webページ閲覧 | [Jina Reader](https://github.com/jina-ai/reader) | ⭐9.8K、無料、APIキー不要 | | Webページ閲覧 | [Jina Reader](https://github.com/jina-ai/reader) | ⭐9.8K、無料、APIキー不要 |
| ツイート閲覧 | [bird](https://www.npmjs.com/package/@steipete/bird) | Cookie認証、無料。公式APIは従量課金(投稿閲覧1件$0.005) | | ツイート閲覧 | [twitter-cli](https://github.com/public-clis/twitter-cli) | 2.1K Star、Cookie認証、検索/閲覧/タイムライン/長文 |
| 動画字幕 + 検索 | [yt-dlp](https://github.com/yt-dlp/yt-dlp) | ⭐148K、YouTube + Bilibili + 1800サイト | | 動画字幕 + 検索 | [yt-dlp](https://github.com/yt-dlp/yt-dlp) | ⭐148K、YouTube + Bilibili + 1800サイト |
| Web検索 | [Exa](https://exa.ai)[mcporter](https://github.com/nicepkg/mcporter)経由) | AIセマンティック検索、MCP統合、APIキー不要 | | Web検索 | [Exa](https://exa.ai)[mcporter](https://github.com/nicepkg/mcporter)経由) | AIセマンティック検索、MCP統合、APIキー不要 |
| GitHub | [gh CLI](https://cli.github.com) | 公式ツール、認証後フルAPI | | GitHub | [gh CLI](https://cli.github.com) | 公式ツール、認証後フルAPI |
| RSS閲覧 | [feedparser](https://github.com/kurtmckee/feedparser) | Pythonエコシステムの標準、⭐2.3K | | RSS閲覧 | [feedparser](https://github.com/kurtmckee/feedparser) | Pythonエコシステムの標準、⭐2.3K |
| 小紅書 | [xiaohongshu-mcp](https://github.com/user/xiaohongshu-mcp) | 内部API、アンチボット回避 | | 小紅書 | [xhs-cli](https://github.com/jackwener/xiaohongshu-cli) | 1.5K Star、pipxインストール、検索/閲覧/コメント/投稿 |
| 抖音 | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) | MCPサーバー、ログイン不要、動画解析 + ウォーターマークなしダウンロード | | 抖音 | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) | MCPサーバー、ログイン不要、動画解析 + ウォーターマークなしダウンロード |
| LinkedIn | [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) | ⭐900+、MCPサーバー、ブラウザ自動化 | | LinkedIn | [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) | ⭐900+、MCPサーバー、ブラウザ自動化 |
| WeChat記事 | [wechat-article-for-ai](https://github.com/Panniantong/wechat-article-for-ai) + [miku_ai](https://github.com/GobinFan/Miku_Spider) | ステルスブラウザで記事全文閲覧 + Sogou検索 | | WeChat記事 | [Exa](https://exa.ai)(検索+閲覧)+ [Camoufox](https://github.com/daijro/camoufox)(オプション) | ゼロ設定で検索+全文閲覧、Camoufoxでオプション強化 |
| Weibo | `mcporter` | `mcporter call 'weibo.get_trendings(limit: 10)'` | | Weibo | `mcporter` | `mcporter call 'weibo.get_trendings(limit: 10)'` |
| 小宇宙Podcast | `transcribe.sh` | `bash ~/.agent-reach/tools/xiaoyuzhou/transcribe.sh <URL>` | | 小宇宙Podcast | `transcribe.sh` | `bash ~/.agent-reach/tools/xiaoyuzhou/transcribe.sh <URL>` |
@@ -249,7 +249,7 @@ channels/
<details> <details>
<summary><strong>Twitter/X APIに課金せずにAIエージェントで検索するには?</strong></summary> <summary><strong>Twitter/X APIに課金せずにAIエージェントで検索するには?</strong></summary>
Agent Reach は [bird CLI](https://www.npmjs.com/package/@steipete/bird) をCookie認証で使用します — 完全無料、Twitter APIのサブスクリプションは不要です。Agent Reach インストール後、Cookie-Editor Chrome拡張機能でTwitterのCookieをエクスポートし、`agent-reach configure twitter-cookies "your_cookies"` を実行すれば、`bird search "query" -n 10` でエージェントが検索できるようになります。 Agent Reach は [twitter-cli](https://github.com/public-clis/twitter-cli) をCookie認証で使用します — 完全無料、Twitter APIのサブスクリプションは不要です。`pipx install twitter-cli`インストール後、Cookie-Editor Chrome拡張機能でTwitterのCookieをエクスポートし、`agent-reach configure twitter-cookies "your_cookies"` を実行すれば、`twitter search "query" -n 10` でエージェントが検索できるようになります。
</details> </details>
<details> <details>
@@ -261,7 +261,7 @@ Agent Reach は [bird CLI](https://www.npmjs.com/package/@steipete/bird) をCook
<details> <details>
<summary><strong>サーバー/データセンターIPからRedditが403を返す?</strong></summary> <summary><strong>サーバー/データセンターIPからRedditが403を返す?</strong></summary>
Redditはデータセンター IPをブロックします。レジデンシャルプロキシを設定してください:`agent-reach configure proxy http://user:pass@ip:port`。推奨:Webshare(月額約$1)。ローカルマシンでは通常この問題は発生しません Agent Reach は [rdt-cli](https://github.com/public-clis/rdt-cli) でRedditにアクセスします。2024年以降、RedditはすべてのAPIリクエストに認証を要求しています。`pipx install rdt-cli` でインストール後、`rdt login`(ブラウザからCookieを自動抽出)を実行してください。その後 `rdt search "query"` で検索、`rdt read POST_ID` で投稿+コメントの閲覧ができます
</details> </details>
<details> <details>
@@ -273,19 +273,19 @@ Redditはデータセンター IPをブロックします。レジデンシャ
<details> <details>
<summary><strong>Agent Reach は無料?APIのコストは?</strong></summary> <summary><strong>Agent Reach は無料?APIのコストは?</strong></summary>
100%無料でオープンソース。すべてのバックエンド(bird CLI、yt-dlp、Jina Reader、Exa)は有料APIキーが不要な無料ツールです。唯一のオプションコストは、サーバーからReddit/Bilibiliにアクセスする場合のレジデンシャルプロキシ(月額約$1)です。 100%無料でオープンソース。すべてのバックエンド(twitter-cli、rdt-cli、xhs-cli、yt-dlp、Jina Reader、Exa)は有料APIキーが不要な無料ツールです。唯一のオプションコストは、サーバーからBilibiliにアクセスする場合のレジデンシャルプロキシ(月額約$1)です。
</details> </details>
<details> <details>
<summary><strong>Twitter APIの無料代替 — Webスクレイピング用</strong></summary> <summary><strong>Twitter APIの無料代替 — Webスクレイピング用</strong></summary>
Agent Reach はbird CLIを使用し、Cookie認証でTwitterにアクセスします — ブラウザセッションと同じです。API料金なし、レート制限のティアなし、開発者アカウント不要。検索、ツイート閲覧、プロフィール閲覧、タイムラインに対応。 Agent Reach はtwitter-cliを使用し、Cookie認証でTwitterにアクセスします — ブラウザセッションと同じです。API料金なし、レート制限のティアなし、開発者アカウント不要。検索、ツイート閲覧、プロフィール閲覧、タイムラインに対応。
</details> </details>
<details> <details>
<summary><strong>小紅書のコンテンツをプログラムで読むには?</strong></summary> <summary><strong>小紅書のコンテンツをプログラムで読むには?</strong></summary>
Agent Reach は xiaohongshu-mcpDockerで実行)と統合されています。セットアップ後、`mcporter call 'xiaohongshu.get_feed_detail(...)'` でノートを閲覧`mcporter call 'xiaohongshu.search_feeds(keyword: "query")'` で検索できます。 `pipx install xiaohongshu-cli` でインストール後、`xhs login`(ブラウザからCookieを自動抽出)。エージェントは `xhs search "query"` でノートを検索`xhs read NOTE_ID` で詳細を閲覧、`xhs comments NOTE_ID` でコメントを表示できます。Dockerは不要です。
</details> </details>
<details> <details>
@@ -298,7 +298,7 @@ douyin-mcp-serverをインストールすれば、`mcporter call 'douyin.parse_d
## クレジット ## クレジット
[Jina Reader](https://github.com/jina-ai/reader) · [yt-dlp](https://github.com/yt-dlp/yt-dlp) · [bird](https://www.npmjs.com/package/@steipete/bird) · [Exa](https://exa.ai) · [feedparser](https://github.com/kurtmckee/feedparser) · [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) · [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) [twitter-cli](https://github.com/public-clis/twitter-cli) · [rdt-cli](https://github.com/public-clis/rdt-cli) · [xhs-cli](https://github.com/jackwener/xiaohongshu-cli) · [Jina Reader](https://github.com/jina-ai/reader) · [yt-dlp](https://github.com/yt-dlp/yt-dlp) · [Exa](https://exa.ai) · [feedparser](https://github.com/kurtmckee/feedparser) · [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) · [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server)
## お問い合わせ ## お問い合わせ
+359
View File
@@ -0,0 +1,359 @@
<h1 align="center">👁️ Agent Reach</h1>
<p align="center">
<strong>AI 에이전트가 인터넷 전체에 접근할 수 있도록 한 번에 설정해 드립니다</strong>
</p>
<p align="center">
<a href="../LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge" alt="MIT License"></a>
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/Python-3.10+-green.svg?style=for-the-badge&logo=python&logoColor=white" alt="Python 3.10+"></a>
<a href="https://github.com/Panniantong/agent-reach/stargazers"><img src="https://img.shields.io/github/stars/Panniantong/agent-reach?style=for-the-badge" alt="GitHub Stars"></a>
</p>
<p align="center">
<a href="#빠른-시작">빠른 시작</a> · 한국어 · <a href="../README.md">中文</a> · <a href="README_en.md">English</a> · <a href="README_ja.md">日本語</a> · <a href="#지원-플랫폼">지원 플랫폼</a> · <a href="#설계-철학">설계 철학</a>
</p>
---
## Agent Reach가 필요한 이유
AI 에이전트는 이미 인터넷에 접근할 수 있습니다 — 하지만 "인터넷에 접속할 수 있다"는 것은 시작에 불과합니다.
가장 가치 있는 정보는 소셜 미디어와 특화된 플랫폼에 분포되어 있습니다: Twitter 토론, Reddit 피드백, YouTube 튜토리얼, XiaoHongShu 리뷰, Bilibili 비디오, GitHub 활동... **여기가 정보 밀도가 가장 높은 곳**이지만, 각 플랫폼은 고유한 진입장벽이 있습니다:
| 문제점 | 현실 |
|------------|---------|
| Twitter API | 유료 사용, 중간 정도 사용량 ~월 $215 |
| Reddit | 서버 IP가 403 오류 발생 |
| XiaoHongShu | 둘러보기 위해 로그인 필요 |
| Bilibili | 해외/서버 IP 차단 |
에이전트를 이 플랫폼에 연결하려면 도구를 찾고, 의존성을 설치하고, 설정을 디버깅해야 합니다 — 하나씩 직접.
**Agent Reach는 이를 하나의 명령으로 바꿉니다:**
```
Install Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/install.md
```
이 명령을 에이전트에 복사해서 붙여넣으세요. 몇 분 뒤에는 트윗을 읽고, Reddit을 검색하고, Bilibili를 볼 수 있게 됩니다.
**이미 설치하셨나요? 한 번에 업데이트하세요:**
```
Update Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/update.md
```
### ✅ 시작하기 전에 알면 좋은 것들
| | |
|---|---|
| 💰 **완전 무료** | 모든 도구는 오픈 소스, 모든 API는 무료입니다. 유일한 비용은 서버 프록시(월 $1)일 수 있습니다 — 로컬 컴퓨터에서는 불필요 |
| 🔒 **프라이버시 안전** | Cookie는 로컬에 유지됩니다. 업로드되지 않습니다. 완전 오픈 소스 — 언제든지 감사 가능 |
| 🔄 **최신 상태 유지** | 업스트림 도구(yt-dlp, twitter-cli, rdt-cli, Jina Reader 등)를 추적하고 정기적으로 업데이트 |
| 🤖 **모든 에이전트와 호환** | Claude Code, OpenClaw, Cursor, Windsurf... 명령을 실행할 수 있는 모든 에이전트 |
| 🩺 **내장 진단 도구** | `agent-reach doctor` — 하나의 명령으로 작동 항목, 작동하지 않는 항목, 수정 방법 표시 |
---
## 지원 플랫폼
| 플랫폼 | 기능 | 설정 | 참고 |
|----------|-------------|:-----:|-------|
| 🌐 **Web** | 읽기 | 없음 | 모든 URL → 깨끗한 Markdown ([Jina Reader](https://github.com/jina-ai/reader) ⭐9.8K) |
| 🐦 **Twitter/X** | 읽기 · 검색 | Cookie | Cookie로 검색, 타임라인, 트윗 읽기, 아티클 읽기 가능 ([twitter-cli](https://github.com/public-clis/twitter-cli)) |
| 📕 **XiaoHongShu** | 읽기 · 검색 · **게시글 작성 · 댓글 · 좋아요** | Cookie | `pipx install xiaohongshu-cli` + `xhs login` ([xhs-cli](https://github.com/jackwener/xiaohongshu-cli)) |
| 🎵 **Douyin** | 비디오 파싱 · 워터마크 없는 다운로드 | mcporter | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) 통해, 로그인 불필요 |
| 💼 **LinkedIn** | Jina Reader (공개 페이지) | Cookie | 전체 프로필, 회사, 채용 공고 검색 가능. 에이전트에 "LinkedIn 설정 도와줘"라고 말하세요 |
| 💬 **WeChat Articles** | 검색 + 읽기 | 없음 | Exa를 통한 WeChat 공식 계정 게시글 검색 + 읽기 (설정 없음) + 선택적 [Camoufox](https://github.com/daijro/camoufox) |
| 📰 **Weibo** | 인기 · 검색 · 피드 · 댓글 | 없음 | 핫 검색, 콘텐츠/사용자/주제 검색, 피드, 댓글 ([mcp-server-weibo](https://github.com/Panniantong/mcp-server-weibo)) |
| 💻 **V2EX** | 인기 주제 · 노드 주제 · 주제 상세 + 답글 · 사용자 프로필 | 없음 | 공개 JSON API, 인증 없음. 기술 커뮤니티 콘텐츠에 적합 |
| 📈 **Xueqiu (雪球)** | 주식 시세 · 검색 · 인기 글 · 인기 종목 | 브라우저 Cookie | 에이전트에 "Xueqiu 설정 도와줘"라고 말하세요 |
| 🎙️ **Xiaoyuzhou Podcast** | 음성 변환 | 무료 API key | Groq Whisper를 통한 팟캐스트 오디오 → 전체 텍스트 변환 (무료) |
| 🔍 **Web Search** | 검색 | 자동 설정 | 설치 시 자동 설정, 무료, API key 불필요 ([Exa](https://exa.ai) via [mcporter](https://github.com/nicepkg/mcporter)) |
| 📦 **GitHub** | 읽기 · 검색 | 없음 | [gh CLI](https://cli.github.com) 기반. 공개 저장소는 즉시 사용 가능. `gh auth login`으로 Fork, Issue, PR 기능 활성화 |
| 📺 **YouTube** | 읽기 · **검색** | 없음 | 자막 + 1800+ 비디오 사이트 검색 ([yt-dlp](https://github.com/yt-dlp/yt-dlp) ⭐148K) |
| 📺 **Bilibili** | 읽기 · **검색** | 없음 / 프록시 | 비디오 정보 + 자막 + 검색. 로컬은 바로 작동, 서버는 프록시 필요 ([yt-dlp](https://github.com/yt-dlp/yt-dlp)) |
| 📡 **RSS** | 읽기 | 없음 | 모든 RSS/Atom 피드 ([feedparser](https://github.com/kurtmckee/feedparser) ⭐2.3K) |
| 📖 **Reddit** | 검색 · 읽기 | Cookie | 2024년부터 인증 필요 — 설치 후 `rdt login` 실행 ([rdt-cli](https://github.com/public-clis/rdt-cli)) |
> **설정 단계:** 없음 = 설치 후 바로 사용 · 자동 = 설치 시 처리 · mcporter = MCP 서비스 필요 · Cookie = 브라우저에서 내보내기 · 프록시 = 월 $1
---
## 빠른 시작
이 명령을 AI 에이전트(Claude Code, OpenClaw, Cursor 등)에 입력하세요:
```
Install Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/install.md
```
에이전트가 자동으로 설치하고, 환경을 감지하고, 준비된 항목을 알려줍니다.
> 🔄 **이미 설치하셨나요?** 한 번에 업데이트:
> ```
> Update Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/update.md
> ```
<details>
<summary>수동 설치</summary>
```bash
pip install https://github.com/Panniantong/agent-reach/archive/main.zip
agent-reach install --env=auto
```
</details>
<details>
<summary>Skill로 설치 (Claude Code / OpenClaw / Skill을 지원하는 모든 에이전트)</summary>
```bash
npx skills add Panniantong/Agent-Reach@agent-reach
```
Skill이 설치된 후, 에이전트는 `agent-reach` CLI 사용 가능 여부를 자동 감지하고 필요한 경우 설치합니다.
> `agent-reach install`을 통해 설치하면 Skill이 자동으로 등록됩니다 — 추가 단계 불필요.
</details>
---
## 별도 설정 없이 바로 사용
별도의 설정이 필요 없습니다. 에이전트에게 요청하기만 하면 됩니다:
- "이 링크 읽어줘" → 모든 웹 페이지에 대해 `curl https://r.jina.ai/URL`
- "이 GitHub 저장소는 무엇인가요?" → `gh repo view owner/repo`
- "이 비디오는 무엇을 다루나요?" → 자막을 위해 `yt-dlp --dump-json URL`
- "이 트윗 읽어줘" → `twitter tweet URL`
- "이 RSS 구독해줘" → 피드 파싱을 위해 `feedparser`
- "GitHub에서 LLM 프레임워크 검색" → `gh search repos "LLM framework"`
**기억할 명령이 없습니다.** 에이전트가 SKILL.md를 읽고 무엇을 호출할지 알고 있습니다.
---
## 필요할 때 설정
사용하지 않나요? 설정하지 마세요. 모든 단계는 선택 사항입니다.
### 🍪 Cookies — 무료, 2분
에이전트에 "Twitter 쿠키 설정 도와줘"라고 말하세요 — 브라우저에서 내보내는 과정을 안내해 줍니다. 로컬 컴퓨터는 자동으로 가져올 수 있습니다.
### 🌐 Proxy — 월 $1, 서버 전용
Bilibili은 서버 IP를 차단합니다. 프록시를 가져오세요([Webshare](https://webshare.io) 추천, 월 $1)하고 주소를 에이전트에 보내세요.
> Reddit은 이제 프록시 없이 rdt-cli를 통해 무료로 작동합니다. 로컬 컴퓨터는 Bilibili에도 프록시가 필요 없습니다.
---
## 한눈에 보는 상태
```
$ agent-reach doctor
👁️ Agent Reach 상태
========================================
✅ 사용 가능:
✅ GitHub 저장소 및 코드 — 공개 저장소 읽기 및 검색 가능
✅ Twitter/X 트윗 — 읽기 가능. Cookie로 검색 및 게시 가능
✅ YouTube 비디오 자막 — yt-dlp
⚠️ Bilibili 비디오 정보 — 서버 IP가 차단될 수 있음, 프록시 설정
✅ RSS/Atom 피드 — feedparser
✅ 웹 페이지 (모든 URL) — Jina Reader API
🔍 검색 (무료 Exa key로 잠금 해제):
⬜ 웹 시맨틱 검색 — exa.ai에서 무료 key 발급
🔧 설정 가능:
✅ Reddit 글 및 댓글 — rdt-cli를 통한 검색 및 읽기 (무료, 프록시 없음)
⬜ XiaoHongShu 노트 — 쿠키 필요. 브라우저에서 내보내기
상태: 6/9 채널 사용 가능
```
---
## 설계 철학
**Agent Reach는 스캐폴딩(scaffolding) 도구이지, 프레임워크가 아닙니다.**
새 에이전트를 실행할 때마다 도구를 찾고, 의존성을 설치하고, 설정을 디버깅하는 데 시간을 보내게 됩니다 — Twitter는 무엇으로 읽나요? Reddit 차단을 어떻게 우회하나요? YouTube 자막은 어떻게 추출하나요? 매번 동일한 작업을 반복해야 합니다.
Agent Reach는 한 가지 간단한 작업을 수행합니다: **도구 선택 및 설정 결정을 대신 해줍니다.**
설치 후, 에이전트는 업스트림 도구(twitter-cli, rdt-cli, xhs-cli, yt-dlp, mcporter, gh CLI 등)를 직접 호출합니다 — 중간에 래퍼 계층이 없습니다.
### 🔌 모든 채널은 플러그인 가능
각 플랫폼은 업스트림 도구에 매핑됩니다. **마음에 안 드나요? 교체하세요.**
```
channels/
├── web.py → Jina Reader ← Firecrawl, Crawl4AI로 교체...
├── twitter.py → twitter-cli ← 공식 API로 교체...
├── youtube.py → yt-dlp ← YouTube API, Whisper로 교체...
├── github.py → gh CLI → REST API, PyGithub로 교체...
├── bilibili.py → yt-dlp → bilibili-api로 교체...
├── reddit.py → rdt-cli → 검색 + 읽기, cookie 인증 필요
├── xiaohongshu.py → mcporter MCP ← 다른 XHS 도구로 교체...
├── douyin.py → mcporter MCP ← 다른 Douyin 도구로 교체...
├── linkedin.py → linkedin-mcp ← LinkedIn API로 교체...
├── rss.py → feedparser ← atoma로 교체...
├── exa_search.py → mcporter MCP ← Tavily, SerpAPI로 교체...
└── __init__.py → 채널 레지스트리 (doctor 검사용)
```
각 채널 파일은 업스트림 도구가 설치되어 작동하는지만 확인합니다(`agent-reach doctor``check()` 메서드). 실제 읽기 및 검색은 업스트림 도구를 직접 호출하여 수행합니다.
### 현재 도구 선택
| 시나리오 | 도구 | 이유 |
|----------|------|-----|
| 웹 페이지 읽기 | [Jina Reader](https://github.com/jina-ai/reader) | 9.8K stars, 무료, API key 불필요 |
| 트윗 읽기 | [twitter-cli](https://github.com/public-clis/twitter-cli) | 2.1K stars, cookie 인증, 검색/읽기/타임라인/글 |
| Reddit | [rdt-cli](https://github.com/public-clis/rdt-cli) | 304 stars, cookie 인증, 검색 + 전체 글 + 댓글 |
| 비디오 자막 + 검색 | [yt-dlp](https://github.com/yt-dlp/yt-dlp) | 154K stars, YouTube + Bilibili + 1800 사이트 |
| Bilibili 향상 | [bili-cli](https://github.com/public-clis/bilibili-cli) | 590 stars, 인기/순위/검색/피드 |
| 웹 검색 | [Exa](https://exa.ai) via [mcporter](https://github.com/nicobailon/mcporter) | AI 시맨틱 검색, MCP 통합, API key 불필요 |
| GitHub | [gh CLI](https://cli.github.com) | 공식 도구, 인증 후 전체 API |
| RSS 읽기 | [feedparser](https://github.com/kurtmckee/feedparser) | Python 생태계 표준, 2.3K stars |
| XiaoHongShu | [xhs-cli](https://github.com/jackwener/xiaohongshu-cli) | 1.5K stars, pipx 설치, 검색/읽기/댓글/게시 |
| Douyin | [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) | MCP 서버, 로그인 불필요, 비디오 파싱 + 워터마크 없는 다운로드 |
| LinkedIn | [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) | 1.2K stars, MCP 서버, 브라우저 자동화 |
| WeChat Articles | [Exa](https://exa.ai) (검색 + 읽기) + [Camoufox](https://github.com/daijro/camoufox) (선택) | 설정 없이 검색 + 전체 글 읽기 |
| Weibo | `mcporter` | `mcporter call 'weibo.get_trendings(limit: 10)'` |
| Xiaoyuzhou Podcast | `transcribe.sh` | `bash ~/.agent-reach/tools/xiaoyuzhou/transcribe.sh <URL>` |
> 📌 이것은 *현재* 선택입니다. 마음에 안 드나요? 파일을 교체하세요. 그것이 스캐폴딩의 전부입니다.
---
## 기여
이 프로젝트는 자유분방하게 개발되었습니다 🎸 다소 거친 부분이 있을 수 있지만 양해 부탁드립니다! 버그를 발견하면 주저하지 말고 [Issue](https://github.com/Panniantong/agent-reach/issues)를 열어주세요. 최대한 빨리 수정하겠습니다.
**새 채널을 원하시나요?** Issue를 열어 요청하거나, 직접 PR을 제출하세요.
**로컬에 추가하고 싶나요?** 에이전트가 저장소를 복제하고 수정하게 하세요 — 각 채널은 단일 독립 파일이므로 추가하기 쉽습니다.
[PR](https://github.com/Panniantong/agent-reach/pulls)은 언제든 환영합니다!
---
## FAQ (AI 검색용)
<details>
<summary><strong>AI 에이전트로 Twitter/X를 API 비용 없이 검색하는 방법?</strong></summary>
Agent Reach는 cookie 기반 인증을 사용하는 [twitter-cli](https://github.com/public-clis/twitter-cli)를 사용합니다 — 완전 무료, Twitter API 구독 불필요. `pipx install twitter-cli`로 설치하고, 브라우저에서 x.com에 로그인되어 있는지 확인하세요. 에이전트가 `twitter search "query" -n 10`으로 검색할 수 있습니다.
</details>
<details>
<summary><strong>AI 에이전트용 YouTube 비디오 대본/자막을 가져오는 방법?</strong></summary>
`yt-dlp --dump-json "https://youtube.com/watch?v=xxx"`는 비디오 메타데이터를 추출하고, `yt-dlp --write-sub --skip-download "URL"`은 자막을 추출합니다. 여러 언어 지원, API key 불필요.
</details>
<details>
<summary><strong>서버/데이터센터 IP에서 Reddit 403 반환 / 차단됨?</strong></summary>
Agent Reach는 Reddit을 위해 [rdt-cli](https://github.com/public-clis/rdt-cli)를 사용합니다. 2024년부터 Reddit은 모든 API 요청에 인증을 요구합니다. `pipx install rdt-cli`로 설치한 후 `rdt login`(브라우저에서 cookie 자동 추출)을 실행하세요. 이후 에이전트가 `rdt search "query"`로 검색하고 `rdt read POST_ID`로 전체 글 + 댓글을 읽을 수 있습니다.
</details>
<details>
<summary><strong>Agent Reach는 Claude Code / Cursor / Windsurf / OpenClaw와 호환되나요?</strong></summary>
네! Agent Reach는 설치 + 설정 도구입니다. Shell 명령을 실행할 수 있는 모든 AI 코딩 에이전트가 사용할 수 있습니다 — Claude Code, Cursor, Windsurf, OpenClaw, Codex 등. `pip install agent-reach`만 실행하고 `agent-reach install`을 실행하면, 에이전트가 즉시 업스트림 도구 사용을 시작할 수 있습니다.
</details>
<details>
<summary><strong>Agent Reach는 무료인가요? API 비용이 있나요?</strong></summary>
100% 무료 오픈 소스입니다. 모든 백엔드(twitter-cli, rdt-cli, xhs-cli, yt-dlp, Jina Reader, Exa)는 유료 API key가 필요 없는 무료 도구입니다. 유일한 선택적 비용은 서버에서 Bilibili 접근이 필요한 경우 주거용 프록시(월 ~$1)입니다. Reddit은 프록시 없이 rdt-cli를 통해 무료로 작동합니다.
</details>
<details>
<summary><strong>웹 스크래핑용 Twitter API의 무료 대안?</strong></summary>
Agent Reach는 cookie 인증을 통해 Twitter에 접근하는 twitter-cli를 사용합니다 — 브라우저 세션과 동일. API 요금 없음, 속도 제한 등급 없음, 개발자 계정 불필요. 검색, 트윗 읽기, 프로필 읽기, 타임라인 지원.
</details>
<details>
<summary><strong>XiaoHongShu / 小红书 콘텐츠를 프로그래밍 방식으로 읽는 방법?</strong></summary>
`pipx install xiaohongshu-cli`를 설치한 다음 `xhs login`(브라우저에서 cookie 자동 추출)을 실행하세요. 에이전트가 `xhs search "query"`로 노트를 검색하고, `xhs read NOTE_ID`로 상세 정보를 읽고, `xhs comments NOTE_ID`로 댓글을 볼 수 있습니다. Docker 불필요.
</details>
<details>
<summary><strong>AI 에이전트로 Douyin / 抖音 비디오를 파싱하는 방법?</strong></summary>
douyin-mcp-server를 설치한 다음, 에이전트가 `mcporter call 'douyin.parse_douyin_video_info(share_link: "share_url")'`를 사용하여 비디오 정보를 파싱하고 워터마크 없는 다운로드 링크를 가져올 수 있습니다. 로그인 불필요 — Douyin 링크를 공유하기만 하면 됩니다. https://github.com/yzfly/douyin-mcp-server 참조
</details>
<details>
<summary><strong>하나의 MCP로 Douyin과 XiaoHongShu 모두에서 대본을 추출하는 방법?</strong></summary>
다음을 처리할 수 있는 하나의 MCP 서버가 필요한 경우:
- Douyin 비디오
- XiaoHongShu 비디오 노트
- XiaoHongShu 이미지 노트
그리고 직접 `script.md` + `info.json`을 작성하려면, 기존 `douyin` mcporter 별칭을 다음으로 변경할 수 있습니다:
- https://github.com/JNHFlow21/social-post-extractor-mcp
다음과 호환성을 유지합니다:
- `parse_douyin_video_info`
- `get_douyin_download_link`
- `extract_douyin_text`
그리고 통합 도구를 추가합니다:
- `parse_social_post_info`
- `extract_social_post_script`
이것은 에이전트 워크플로우가 "링크를 붙여넣고, 스크립트 파일을 받음"일 때 유용합니다.
</details>
---
## 크레딧
[twitter-cli](https://github.com/public-clis/twitter-cli) · [rdt-cli](https://github.com/public-clis/rdt-cli) · [xhs-cli](https://github.com/jackwener/xiaohongshu-cli) · [bili-cli](https://github.com/public-clis/bilibili-cli) · [yt-dlp](https://github.com/yt-dlp/yt-dlp) · [Jina Reader](https://github.com/jina-ai/reader) · [Exa](https://exa.ai) · [mcporter](https://github.com/nicobailon/mcporter) · [feedparser](https://github.com/kurtmckee/feedparser) · [douyin-mcp-server](https://github.com/yzfly/douyin-mcp-server) · [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server)
## 연락처
- 📧 **이메일:** pnt01@foxmail.com
- 🐦 **Twitter/X:** [@Neo_Reidlab](https://x.com/Neo_Reidlab)
협력이나 질문은 WeChat에 추가해주세요 — 커뮤니티 그룹에 초대해 드리겠습니다:
<p align="center">
<img src="wechat-group-qr.jpg" width="280" alt="WeChat QR">
</p>
> 버그 보고 및 기능 요청은 [GitHub Issues](https://github.com/Panniantong/Agent-Reach/issues)를 이용해주세요 — 추적이 더 수월합니다.
## 라이선스
[MIT](../LICENSE)
## 관련 프로젝트
[FluxNode](https://fluxnode.org) — 저비용 AI API 게이트웨이, 공식 가격의 90% 할인, 종량제 또는 구독. OpenClaw, Claude Code 및 모든 에이전트와 호환.
[OpenClaw for Enterprise](https://github.com/littleben/openclaw-for-enterprise) — 엔터프라이즈급 다중 사용자 OpenClaw 배포, Feishu/Lark에서 AI 직접 사용, 컨테이너 격리, 원 명령어 관리.
[OpenClaw on Tencent Cloud](https://www.tencentcloud.com/act/pro/intl-openclaw?referral_code=G76Y819A&lang=en&pg=) — Tencent Cloud에서 원클릭 OpenClaw: 채팅으로 Agent Reach를 연결하고 인터넷 기능을 활성화하세요.
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=Panniantong/Agent-Reach&type=Date&v=20260309)](https://star-history.com/#Panniantong/Agent-Reach&Date)
+19 -14
View File
@@ -20,7 +20,7 @@ Copy this to your AI Agent:
### Goal ### Goal
Install Agent Reach and all upstream tools so your user's agent has full internet access. After installation, you'll use the upstream tools directly (bird CLI, yt-dlp, mcporter, gh CLI, etc.) — Agent Reach is just the installer and health checker. Install Agent Reach and all upstream tools so your user's agent has full internet access. After installation, you'll use the upstream tools directly (twitter-cli, rdt-cli, xhs-cli, yt-dlp, mcporter, gh CLI, etc.) — Agent Reach is just the installer and health checker.
### ⚠️ Boundaries ### ⚠️ Boundaries
@@ -140,8 +140,7 @@ agent-reach configure twitter-cookies "PASTED_STRING"
> **代理说明(中国大陆等需要翻墙的网络环境):** > **代理说明(中国大陆等需要翻墙的网络环境):**
> >
> bird CLI 使用 Node.js,在需要代理的网络环境下可通过环境变量配置代理。 > twitter-cli 和 rdt-cli 使用 Python,在需要代理的网络环境下可通过环境变量配置代理。
> Agent Reach 安装时会自动安装 `undici``npm install -g undici`)以提供代理支持。
> >
> **你(Agent)需要做的:** > **你(Agent)需要做的:**
> 1. 确认用户配了代理:`agent-reach configure proxy http://user:pass@ip:port` > 1. 确认用户配了代理:`agent-reach configure proxy http://user:pass@ip:port`
@@ -157,18 +156,17 @@ agent-reach configure twitter-cookies "PASTED_STRING"
agent-reach configure proxy http://user:pass@ip:port agent-reach configure proxy http://user:pass@ip:port
``` ```
**XiaoHongShu / 小红书 (需要 Docker):** **XiaoHongShu / 小红书 (xhs-cli):**
> "小红书需要一个 MCP 服务。需要你的机器上有 Docker。安装好 Docker 后我来搞定剩下的。" > "小红书通过 xhs-cli 访问,pipx 一行安装,不需要 Docker。"
```bash ```bash
docker run -d --name xiaohongshu-mcp -p 18060:18060 xpzouying/xiaohongshu-mcp pipx install xiaohongshu-cli
mcporter config add xiaohongshu http://localhost:18060/mcp xhs login
``` ```
> 如果在服务器上,建议加代理避免 IP 风控 > `xhs login` 会自动从浏览器提取 Cookie。如果自动提取失败,可以手动导入
> `docker run -d --name xiaohongshu-mcp -p 18060:18060 -e XHS_PROXY=http://user:pass@ip:port xpzouying/xiaohongshu-mcp`
> >
> **登录方式(优先用 Cookie-Editor,最简单):** > **手动导入 CookieCookie-Editor 方式):**
> 1. 用户在自己的浏览器登录小红书 (xiaohongshu.com) > 1. 用户在自己的浏览器登录小红书 (xiaohongshu.com)
> 2. 用 [Cookie-Editor](https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm) 插件导出 CookieJSON 或 Header String 格式均可) > 2. 用 [Cookie-Editor](https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm) 插件导出 CookieJSON 或 Header String 格式均可)
> 3. 把 Cookie 字符串发给 Agent > 3. 把 Cookie 字符串发给 Agent
@@ -182,7 +180,14 @@ mcporter config add xiaohongshu http://localhost:18060/mcp
> agent-reach configure xhs-cookies "key1=val1; key2=val2; ..." > agent-reach configure xhs-cookies "key1=val1; key2=val2; ..."
> ``` > ```
> >
> **注意:** `http://localhost:18060` 根路径可能返回 404MCP 服务在 `/mcp` 路径。推荐使用 Cookie-Editor 导出方式,不要依赖 Docker 容器内的 QR 扫码登录。 > **注意:** 推荐使用 Cookie-Editor 导出方式,不要依赖 QR 扫码登录。
>
> **备选方案:Docker MCP**
> 如果你已经在使用 [xiaohongshu-mcp](https://github.com/xpzouying/xiaohongshu-mcp) Docker 方案,它也能正常工作:
> ```bash
> docker run -d --name xiaohongshu-mcp -p 18060:18060 xpzouying/xiaohongshu-mcp
> mcporter config add xiaohongshu http://localhost:18060/mcp
> ```
**微博 / Weibo (mcp-server-weibo):** **微博 / Weibo (mcp-server-weibo):**
> "微博已默认安装,装好即用。可搜索微博内容、查看热搜、获取用户动态和评论。" > "微博已默认安装,装好即用。可搜索微博内容、查看热搜、获取用户动态和评论。"
@@ -385,10 +390,10 @@ After installation, use upstream tools directly. See SKILL.md for the full comma
| Platform | Upstream Tool | Example | | Platform | Upstream Tool | Example |
|----------|--------------|---------| |----------|--------------|---------|
| Twitter/X | `bird` | `bird search "query" -n 10` | | Twitter/X | `twitter` | `twitter search "query" -n 10` |
| YouTube | `yt-dlp` | `yt-dlp --dump-json URL` | | YouTube | `yt-dlp` | `yt-dlp --dump-json URL` |
| Bilibili | `yt-dlp` | `yt-dlp --dump-json URL` | | Bilibili | `yt-dlp` + `bili` | `bili hot` / `bili search "query" --type video` |
| Reddit | `mcporter` (Exa) | `mcporter call 'exa.web_search_exa(query: "...", includeDomains: ["reddit.com"])'` | | Reddit | `rdt` | `rdt search "query"` / `rdt read POST_ID` |
| GitHub | `gh` | `gh search repos "query"` | | GitHub | `gh` | `gh search repos "query"` |
| Web | `curl` + Jina | `curl -s "https://r.jina.ai/URL"` | | Web | `curl` + Jina | `curl -s "https://r.jina.ai/URL"` |
| Exa Search | `mcporter` | `mcporter call 'exa.web_search_exa(...)'` | | Exa Search | `mcporter` | `mcporter call 'exa.web_search_exa(...)'` |
+11 -9
View File
@@ -16,11 +16,11 @@ agent-reach configure --from-browser chrome
--- ---
## Twitter/X: bird CLI 连接失败 ## Twitter/X: twitter-cli 连接失败
**症状:** `bird search` 或其他命令返回错误 **症状:** `twitter search` 或其他命令返回错误
**原因:** bird CLI 需要 AUTH_TOKEN 和 CT0 环境变量才能访问 Twitter API。如果你的网络环境需要代理才能访问 x.com,需要配置代理。 **原因:** twitter-cli 需要 AUTH_TOKEN 和 CT0 环境变量才能访问 Twitter API。如果你的网络环境需要代理才能访问 x.com,需要配置代理。
**解决方案:** **解决方案:**
@@ -29,22 +29,22 @@ agent-reach configure --from-browser chrome
```bash ```bash
export HTTP_PROXY="http://user:pass@host:port" export HTTP_PROXY="http://user:pass@host:port"
export HTTPS_PROXY="http://user:pass@host:port" export HTTPS_PROXY="http://user:pass@host:port"
bird search "test" -n 1 twitter search "test" -n 1
``` ```
### 方案 2:使用全局代理工具 ### 方案 2:使用全局代理工具
让代理工具接管所有网络流量,这样 bird 的请求也会走代理: 让代理工具接管所有网络流量,这样 twitter-cli 的请求也会走代理:
```bash ```bash
# macOS — ClashX / Surge 开启"增强模式" # macOS — ClashX / Surge 开启"增强模式"
# Linux — proxychains 或 tun2socks # Linux — proxychains 或 tun2socks
proxychains bird search "test" -n 1 proxychains twitter search "test" -n 1
``` ```
### 方案 3:不用 bird,用 Exa 搜索替代 ### 方案 3:不用 twitter-cli,用 Exa 搜索替代
bird 不可用时,可以直接用 Exa 搜索 Twitter 内容: twitter-cli 不可用时,可以直接用 Exa 搜索 Twitter 内容:
```bash ```bash
mcporter call 'exa.web_search_exa(query: "site:x.com 搜索词", numResults: 5)' mcporter call 'exa.web_search_exa(query: "site:x.com 搜索词", numResults: 5)'
@@ -53,7 +53,9 @@ mcporter call 'exa.web_search_exa(query: "site:x.com 搜索词", numResults: 5)'
### 方案 4:检查认证 ### 方案 4:检查认证
```bash ```bash
bird check twitter check
``` ```
> 如果返回 "Missing credentials",需要设置 AUTH_TOKEN 和 CT0 环境变量。 > 如果返回 "Missing credentials",需要设置 AUTH_TOKEN 和 CT0 环境变量。
>
> **Fallback** 如果你已经安装了 bird CLI`npm install -g @steipete/bird`),它也能正常工作。Agent Reach 会自动检测已安装的工具。
+79 -22
View File
@@ -24,7 +24,7 @@ Update Agent Reach: https://raw.githubusercontent.com/Panniantong/agent-reach/ma
### Goal ### Goal
Update Agent Reach to the latest version, then verify everything still works. Update Agent Reach to the latest version, install any new upstream tools, migrate from deprecated tools, and verify everything works. The user should not need to do anything manually.
### Step 1: Check current version ### Step 1: Check current version
@@ -32,44 +32,101 @@ Update Agent Reach to the latest version, then verify everything still works.
agent-reach check-update agent-reach check-update
``` ```
If it says "已是最新版本", you're done — tell the user. If it says "已是最新版本", skip to Step 5 (verify). Otherwise continue.
### Step 2: Update ### Step 2: Update Agent Reach package
```bash ```bash
pip install --upgrade https://github.com/Panniantong/agent-reach/archive/main.zip pip install --upgrade https://github.com/Panniantong/agent-reach/archive/main.zip
``` ```
### Step 3: Verify ### Step 3: Install / migrate upstream tools
Run these commands to ensure all upstream CLI tools are installed. Skip any that are already installed.
```bash
# === Required tools (core functionality) ===
# Twitter/X — twitter-cli (replaces deprecated bird CLI)
which twitter >/dev/null 2>&1 || pipx install twitter-cli 2>/dev/null || uv tool install twitter-cli 2>/dev/null
# Reddit — rdt-cli (replaces Exa-based approach)
which rdt >/dev/null 2>&1 || pipx install rdt-cli 2>/dev/null || uv tool install rdt-cli 2>/dev/null
# XiaoHongShu — xhs-cli (replaces Docker MCP)
which xhs >/dev/null 2>&1 || pipx install xiaohongshu-cli 2>/dev/null || uv tool install xiaohongshu-cli 2>/dev/null
# === Optional enhancements ===
# Bilibili — bili-cli (adds hot/rank/search on top of yt-dlp)
which bili >/dev/null 2>&1 || pipx install bilibili-cli 2>/dev/null || uv tool install bilibili-cli 2>/dev/null
# mcporter + Exa (for WeChat, web search)
which mcporter >/dev/null 2>&1 || npm install -g mcporter 2>/dev/null
# yt-dlp (YouTube + Bilibili video)
which yt-dlp >/dev/null 2>&1 || pip install yt-dlp 2>/dev/null
# gh CLI (GitHub)
which gh >/dev/null 2>&1 || echo "GitHub CLI not installed — see https://cli.github.com"
```
### Step 4: Coexistence (DO NOT uninstall old tools)
**IMPORTANT: Never uninstall any existing tools the user already has installed.** Old tools (bird, browser_cookie3, miku_ai, etc.) may still be working on the user's machine even if their upstream repos are archived or deleted. Agent Reach supports both old and new tools as fallback. Only install new tools alongside existing ones.
### Step 5: Verify
```bash ```bash
agent-reach version agent-reach version
agent-reach doctor agent-reach doctor
``` ```
Report the new version and channel status to the user. If any channel changed status (was ✅ now ❌), investigate and fix. Check the doctor output:
- All channels should show ✅ or ⚠️ (with clear instructions)
- If any channel that was working before now shows ❌, investigate:
- Twitter: needs `twitter-cli` + browser cookies (run `xhs login` pattern)
- Reddit: needs `rdt-cli` (should be installed in Step 3)
- XiaoHongShu: needs `xhs-cli` + login (run `xhs login`)
- WeChat: should work via Exa (zero config)
### Step 4: Update SKILL.md (if installed) ### Step 6: Update SKILL.md (if installed)
If the user has the Agent Reach skill installed, update it too:
```bash ```bash
agent-reach install --skill-only agent-reach install --skill-only 2>/dev/null || python3 -c "
``` import importlib.resources, os
try:
skill_pkg = importlib.resources.files('agent_reach').joinpath('skill')
except Exception:
from pathlib import Path
skill_pkg = Path(os.path.dirname(os.path.abspath(__file__))).parent / 'agent_reach' / 'skill'
If the `--skill-only` flag is not available, manually copy the latest SKILL.md: skill_md = skill_pkg.joinpath('SKILL.md').read_text(encoding='utf-8')
refs_pkg = skill_pkg.joinpath('references')
```bash for base in [os.path.expanduser('~/.openclaw/skills/agent-reach'),
python3 -c " os.path.expanduser('~/.claude/skills/agent-reach'),
import importlib.resources, shutil, os os.path.expanduser('~/.agents/skills/agent-reach')]:
skill = importlib.resources.files('agent_reach').joinpath('skill', 'SKILL.md').read_text() if os.path.isdir(base):
for d in [os.path.expanduser('~/.openclaw/skills/agent-reach'), with open(os.path.join(base, 'SKILL.md'), 'w', encoding='utf-8') as f:
os.path.expanduser('~/.claude/skills/agent-reach')]: f.write(skill_md)
if os.path.isdir(d): refs_dir = os.path.join(base, 'references')
with open(os.path.join(d, 'SKILL.md'), 'w') as f: os.makedirs(refs_dir, exist_ok=True)
f.write(skill) for ref in refs_pkg.iterdir():
print(f'✅ Updated: {d}') name = ref.name if hasattr(ref, 'name') else str(ref).split('/')[-1]
if name.endswith('.md'):
with open(os.path.join(refs_dir, name), 'w', encoding='utf-8') as f:
f.write(ref.read_text(encoding='utf-8'))
print(f'✅ Updated skill: {base}')
" "
``` ```
Done. Tell the user what version they're now on and how many channels are available. ### Step 7: Report to user
Tell the user:
1. What version they're now on (`agent-reach version`)
2. How many channels are available (count ✅ in doctor output)
3. Any channels that need their action (e.g., `xhs login` for XiaoHongShu, browser cookies for Twitter)
4. What changed in this update (major: Twitter/Reddit/XiaoHongShu upstream tools migrated for better stability)
Done.
+1 -6
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "agent-reach" name = "agent-reach"
version = "1.4.0" version = "1.4.1"
description = "Give your AI Agent eyes to see the entire internet. Search + Read 10+ platforms." description = "Give your AI Agent eyes to see the entire internet. Search + Read 10+ platforms."
readme = "README.md" readme = "README.md"
license = {text = "MIT"} license = {text = "MIT"}
@@ -64,11 +64,6 @@ build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel] [tool.hatch.build.targets.wheel]
packages = ["agent_reach"] packages = ["agent_reach"]
[tool.hatch.build.targets.wheel.force-include]
"agent_reach/guides" = "agent_reach/guides"
"agent_reach/skill" = "agent_reach/skill"
"agent_reach/scripts" = "agent_reach/scripts"
[tool.ruff] [tool.ruff]
target-version = "py310" target-version = "py310"
line-length = 100 line-length = 100
+67 -3
View File
@@ -7,9 +7,9 @@ import subprocess
from urllib.error import URLError from urllib.error import URLError
from agent_reach.channels import get_all_channels, get_channel from agent_reach.channels import get_all_channels, get_channel
from agent_reach.channels.v2ex import V2EXChannel
from agent_reach.channels.xiaohongshu import XiaoHongShuChannel from agent_reach.channels.xiaohongshu import XiaoHongShuChannel
from agent_reach.channels.xueqiu import XueqiuChannel from agent_reach.channels.xueqiu import XueqiuChannel
from agent_reach.channels.v2ex import V2EXChannel
class TestChannelRegistry: class TestChannelRegistry:
@@ -223,8 +223,6 @@ class TestV2EXChannel:
}, },
] ]
call_count = {"n": 0}
class FakeResponse: class FakeResponse:
def __init__(self, payload): def __init__(self, payload):
self._payload = payload self._payload = payload
@@ -648,6 +646,72 @@ class TestXueqiuChannel:
assert "agent-reach" not in captured["ua"] assert "agent-reach" not in captured["ua"]
class TestRedditChannel:
def test_reports_off_when_not_installed(self, monkeypatch):
monkeypatch.setattr(shutil, "which", lambda _: None)
from agent_reach.channels.reddit import RedditChannel
status, msg = RedditChannel().check()
assert status == "off"
assert "rdt-cli" in msg
assert "public-clis/rdt-cli" in msg
def test_reports_ok_when_authenticated(self, monkeypatch):
monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/rdt")
fake_output = json.dumps({
"ok": True,
"schema_version": "1",
"data": {"authenticated": True, "username": "testuser", "cookie_count": 1},
})
def fake_run(cmd, **kwargs):
return subprocess.CompletedProcess(cmd, 0, fake_output, "")
monkeypatch.setattr(subprocess, "run", fake_run)
from agent_reach.channels.reddit import RedditChannel
status, msg = RedditChannel().check()
assert status == "ok"
assert "testuser" in msg
def test_reports_warn_when_not_authenticated(self, monkeypatch):
monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/rdt")
fake_output = json.dumps({
"ok": True,
"schema_version": "1",
"data": {"authenticated": False, "username": None, "cookie_count": 0},
})
def fake_run(cmd, **kwargs):
return subprocess.CompletedProcess(cmd, 0, fake_output, "")
monkeypatch.setattr(subprocess, "run", fake_run)
from agent_reach.channels.reddit import RedditChannel
status, msg = RedditChannel().check()
assert status == "warn"
assert "403" in msg
assert "rdt login" in msg
assert "Cookie-Editor" in msg
assert "chromewebstore.google.com" in msg
def test_reports_warn_when_status_check_fails(self, monkeypatch):
monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/rdt")
def fake_run(cmd, **kwargs):
return subprocess.CompletedProcess(cmd, 1, "not valid json{{{", "")
monkeypatch.setattr(subprocess, "run", fake_run)
from agent_reach.channels.reddit import RedditChannel
status, msg = RedditChannel().check()
assert status == "warn"
def test_can_handle_reddit_urls(self):
from agent_reach.channels.reddit import RedditChannel
ch = RedditChannel()
assert ch.can_handle("https://www.reddit.com/r/python/comments/abc123/")
assert ch.can_handle("https://redd.it/abc123")
assert not ch.can_handle("https://github.com/user/repo")
assert not ch.can_handle("https://v2ex.com/t/123")
class TestXiaoHongShuChannel: class TestXiaoHongShuChannel:
def test_reports_ok_when_cli_authenticated(self, monkeypatch): def test_reports_ok_when_cli_authenticated(self, monkeypatch):
monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/xhs") monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/xhs")
+1 -1
View File
@@ -89,7 +89,7 @@ class TestCheckUpdateRetry:
sequence = [ sequence = [
R(429, headers={"Retry-After": "3"}), R(429, headers={"Retry-After": "3"}),
R(200, payload={"tag_name": "v1.4.0"}), R(200, payload={"tag_name": "v1.4.1"}),
] ]
with patch("requests.get", side_effect=sequence): with patch("requests.get", side_effect=sequence):
+38
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Tests for 'agent-reach skill' command and _install_skill / _uninstall_skill.""" """Tests for 'agent-reach skill' command and _install_skill / _uninstall_skill."""
import importlib.resources
import os import os
import tempfile import tempfile
import unittest import unittest
@@ -12,6 +13,16 @@ from agent_reach.cli import _install_skill, _uninstall_skill
class TestSkillCommand(unittest.TestCase): class TestSkillCommand(unittest.TestCase):
"""Test skill install and uninstall via CLI helpers.""" """Test skill install and uninstall via CLI helpers."""
def test_skill_resources_include_both_locales(self):
"""Package resources should expose both default and English skill markdown files."""
skill_dir = importlib.resources.files("agent_reach").joinpath("skill")
default_skill = skill_dir.joinpath("SKILL.md").read_text(encoding="utf-8")
english_skill = skill_dir.joinpath("SKILL_en.md").read_text(encoding="utf-8")
self.assertTrue(default_skill.strip())
self.assertTrue(english_skill.strip())
def test_install_skill_creates_skill_md(self): def test_install_skill_creates_skill_md(self):
"""_install_skill should create SKILL.md in the first available skill dir.""" """_install_skill should create SKILL.md in the first available skill dir."""
with tempfile.TemporaryDirectory() as tmpdir: with tempfile.TemporaryDirectory() as tmpdir:
@@ -85,6 +96,33 @@ class TestSkillCommand(unittest.TestCase):
content = f.read() content = f.read()
self.assertIn("Agent Reach", content) self.assertIn("Agent Reach", content)
def test_install_uses_english_skill_for_english_locale(self):
"""_install_skill should install the English skill file for English locales."""
with tempfile.TemporaryDirectory() as tmpdir:
skill_parent = os.path.join(tmpdir, ".openclaw", "skills")
os.makedirs(skill_parent)
with patch(
"agent_reach.cli.os.path.expanduser",
side_effect=lambda p: p.replace("~", tmpdir),
):
env = os.environ.copy()
env.pop("OPENCLAW_HOME", None)
env["LANG"] = "en_US.UTF-8"
with patch.dict(os.environ, env, clear=True):
_install_skill()
target = os.path.join(skill_parent, "agent-reach", "SKILL.md")
self.assertTrue(os.path.exists(target))
with open(target) as f:
content = f.read()
self.assertTrue(content.strip())
self.assertIn("Give your AI agent eyes to see the entire internet.", content)
self.assertNotIn("搜推特", content)
self.assertTrue(
os.path.exists(os.path.join(skill_parent, "agent-reach", "references"))
)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
+57 -21
View File
@@ -13,22 +13,25 @@ def _cp(stdout="", stderr="", returncode=0):
return m return m
# --- twitter-cli tests ---
def test_check_twitter_cli_found_and_auth_ok(): def test_check_twitter_cli_found_and_auth_ok():
"""twitter-cli found + twitter status ok → ok.""" """twitter-cli found + twitter status ok → ok."""
channel = TwitterChannel() channel = TwitterChannel()
with patch("shutil.which", return_value="/usr/local/bin/twitter"), patch( with patch("shutil.which", side_effect=lambda name: "/usr/local/bin/twitter" if name == "twitter" else None), patch(
"subprocess.run", "subprocess.run",
return_value=_cp(stdout="ok: true\nusername: testuser\n", returncode=0), return_value=_cp(stdout="ok: true\nusername: testuser\n", returncode=0),
): ):
status, message = channel.check() status, message = channel.check()
assert status == "ok" assert status == "ok"
assert "twitter-cli" in message
assert "完整可用" in message assert "完整可用" in message
def test_check_twitter_cli_found_auth_missing(): def test_check_twitter_cli_found_auth_missing():
"""twitter-cli found + not_authenticated → warn about auth.""" """twitter-cli found + not_authenticated → warn about auth."""
channel = TwitterChannel() channel = TwitterChannel()
with patch("shutil.which", return_value="/usr/local/bin/twitter"), patch( with patch("shutil.which", side_effect=lambda name: "/usr/local/bin/twitter" if name == "twitter" else None), patch(
"subprocess.run", "subprocess.run",
return_value=_cp( return_value=_cp(
stderr="ok: false\nerror:\n code: not_authenticated\n", stderr="ok: false\nerror:\n code: not_authenticated\n",
@@ -40,8 +43,44 @@ def test_check_twitter_cli_found_auth_missing():
assert "未认证" in message assert "未认证" in message
def test_check_twitter_cli_not_found(): # --- bird CLI fallback tests ---
"""twitter-cli not found → warn with install hint."""
def test_check_bird_fallback_auth_ok():
"""No twitter-cli, but bird found + bird check ok → ok."""
channel = TwitterChannel()
def which_side_effect(name):
if name == "bird":
return "/usr/local/bin/bird"
return None
with patch("shutil.which", side_effect=which_side_effect), patch(
"subprocess.run",
return_value=_cp(stdout="Authenticated as @user\n", returncode=0),
):
status, message = channel.check()
assert status == "ok"
assert "bird" in message
def test_check_bird_fallback_auth_missing():
"""No twitter-cli, bird found but Missing credentials → warn."""
channel = TwitterChannel()
def which_side_effect(name):
if name == "bird":
return "/usr/local/bin/bird"
return None
with patch("shutil.which", side_effect=which_side_effect), patch(
"subprocess.run",
return_value=_cp(stderr="Missing credentials\n", returncode=1),
):
status, message = channel.check()
assert status == "warn"
assert "未配置认证" in message
# --- neither installed ---
def test_check_nothing_installed():
"""Neither twitter-cli nor bird → warn with install hint."""
channel = TwitterChannel() channel = TwitterChannel()
with patch("shutil.which", return_value=None): with patch("shutil.which", return_value=None):
status, message = channel.check() status, message = channel.check()
@@ -49,24 +88,21 @@ def test_check_twitter_cli_not_found():
assert "twitter-cli" in message assert "twitter-cli" in message
def test_check_twitter_cli_generic_failure(): # --- twitter-cli preferred over bird ---
"""twitter status returns 1 without not_authenticated → generic warn."""
def test_twitter_cli_preferred_over_bird():
"""When both are installed, twitter-cli is used."""
channel = TwitterChannel() channel = TwitterChannel()
with patch("shutil.which", return_value="/usr/local/bin/twitter"), patch( def which_side_effect(name):
if name == "twitter":
return "/usr/local/bin/twitter"
if name == "bird":
return "/usr/local/bin/bird"
return None
with patch("shutil.which", side_effect=which_side_effect), patch(
"subprocess.run", "subprocess.run",
return_value=_cp(stderr="some error\n", returncode=1), return_value=_cp(stdout="ok: true\n", returncode=0),
): ):
status, message = channel.check() status, message = channel.check()
assert status == "warn" assert status == "ok"
assert "认证检查失败" in message assert "twitter-cli" in message
def test_check_twitter_cli_exception():
"""twitter status throws exception → warn."""
channel = TwitterChannel()
with patch("shutil.which", return_value="/usr/local/bin/twitter"), patch(
"subprocess.run", side_effect=Exception("timeout"),
):
status, message = channel.check()
assert status == "warn"
assert "连接失败" in message