release: v1.1.0 — 新增 Instagram、LinkedIn、Boss直聘 三个渠道

🆕 新渠道:
- 📷 Instagram — instaloader 读取帖子和 Profile
- 💼 LinkedIn — linkedin-scraper-mcp 读取 Profile、公司、职位
- 🏢 Boss直聘 — mcp-bosszp 搜索职位、向 HR 打招呼

📈 改进:
- 渠道数量 9 → 12
- 新增 CHANGELOG.md
- CLI 新增 search-instagram / search-linkedin / search-bosszhipin
- 安装指南更新
- 致谢列表更新
This commit is contained in:
Panniantong 2026-02-25 14:14:30 +01:00
parent 31eb6db537
commit c642e18e1f
7 changed files with 278 additions and 29 deletions

65
CHANGELOG.md Normal file
View file

@ -0,0 +1,65 @@
# Changelog / 更新日志
All notable changes to this project will be documented in this file.
本项目的所有重要变更都会记录在此文件中。
---
## [1.1.0] - 2025-02-25
### 🆕 New Channels / 新增渠道
#### 📷 Instagram
- Read public posts and profiles via [instaloader](https://github.com/instaloader/instaloader)
- Search via Exa (free, no API key)
- Optional cookie login for private content
- 通过 instaloader 读取公开帖子和 Profile
- 搜索通过 Exa免费无需 API Key
- 可选 Cookie 登录解锁私密内容
#### 💼 LinkedIn
- Read person profiles, company pages, and job details via [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server)
- Search people and jobs via MCP, with Exa fallback
- Fallback to Jina Reader when MCP is not configured
- 通过 linkedin-scraper-mcp 读取个人 Profile、公司页面、职位详情
- 通过 MCP 搜索人才和职位Exa 兜底
- 未配置 MCP 时自动 fallback 到 Jina Reader
#### 🏢 Boss直聘
- QR code login via [mcp-bosszp](https://github.com/mucsbr/mcp-bosszp)
- Job search and recruiter greeting via MCP
- Fallback to Jina Reader for reading job pages
- 通过 mcp-bosszp 扫码登录
- MCP 搜索职位、向 HR 打招呼
- Jina Reader 兜底读取职位页面
### 📈 Improvements / 改进
- Channel count: 9 → 12
- `agent-reach doctor` now detects all 12 channels
- CLI: added `search-instagram`, `search-linkedin`, `search-bosszhipin` subcommands
- Updated install guide with setup instructions for new channels
- 渠道数量9 → 12
- `agent-reach doctor` 现在检测全部 12 个渠道
- CLI新增 `search-instagram``search-linkedin``search-bosszhipin` 子命令
- 安装指南新增三个渠道的配置说明
---
## [1.0.0] - 2025-02-24
### 🎉 Initial Release / 首次发布
- 9 channels: Web, Twitter/X, YouTube, Bilibili, GitHub, Reddit, XiaoHongShu, RSS, Exa Search
- CLI with `read`, `search`, `doctor`, `install` commands
- Unified channel interface — each platform is a single pluggable Python file
- Auto-detection of local vs server environments
- Built-in diagnostics via `agent-reach doctor`
- Skill registration for Claude Code / OpenClaw / Cursor
- 9 个渠道网页、Twitter/X、YouTube、B站、GitHub、Reddit、小红书、RSS、Exa 搜索
- CLI 支持 `read``search``doctor``install` 命令
- 统一渠道接口 — 每个平台一个独立可插拔的 Python 文件
- 自动检测本地/服务器环境
- 内置诊断 `agent-reach doctor`
- Skill 注册支持 Claude Code / OpenClaw / Cursor

View file

@ -92,6 +92,12 @@ AI Agent 已经能帮你写代码、改文档、管项目——但你让它去
就这一步。Agent 会自己完成剩下的所有事情。
> 🛡️ **担心安全?** 可以用安全模式——不会自动装系统包,只告诉你需要什么:
> ```
> 帮我安装 Agent Reach安全模式https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/install.md
> 安装时使用 --safe 参数
> ```
<details>
<summary>它会做什么?(点击展开)</summary>
@ -169,6 +175,32 @@ channels/
---
## 安全性
Agent Reach 在设计上重视安全:
| 措施 | 说明 |
|------|------|
| 🔒 **凭据本地存储** | Cookie、Token 只存在你本机 `~/.agent-reach/config.yaml`,文件权限 600仅所有者可读写不上传不外传 |
| 🛡️ **安全模式** | `agent-reach install --safe` 不会自动修改系统,只列出需要什么,由你决定装不装 |
| 👀 **完全开源** | 代码透明,随时可审查。所有依赖工具也是开源项目 |
| 🔍 **Dry Run** | `agent-reach install --dry-run` 预览所有操作,不做任何改动 |
| 🧩 **可插拔架构** | 不信任某个组件?换掉对应的 channel 文件即可,不影响其他 |
### 🍪 Cookie 安全建议
需要 Cookie 的平台Twitter、小红书、Instagram建议使用**专用小号**不要用主账号。Cookie 等同于完整登录权限,用小号可以在凭据泄露时限制影响范围。
### 📦 安装方式
| 方式 | 命令 | 适合场景 |
|------|------|---------|
| 一键全自动(默认) | `agent-reach install --env=auto` | 个人电脑、开发环境 |
| 安全模式 | `agent-reach install --env=auto --safe` | 生产服务器、多人共用机器 |
| 仅预览 | `agent-reach install --env=auto --dry-run` | 先看看会做什么 |
---
## 贡献
这个项目是纯 vibe coding 出来的 🎸 可能会有一些不完美的地方,如果遇到问题请多多包涵。有 bug 尽管提 [Issue](https://github.com/Panniantong/agent-reach/issues),我都会尽快修复。
@ -195,7 +227,7 @@ Star 一下,下次需要的时候能找到。⭐
## 致谢
[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)
[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) · [instaloader](https://github.com/instaloader/instaloader) · [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) · [mcp-bosszp](https://github.com/mucsbr/mcp-bosszp)
## License

View file

@ -113,6 +113,10 @@ def main():
help="Environment: local, server, or auto-detect")
p_install.add_argument("--proxy", default="",
help="Residential proxy for Reddit/Bilibili (http://user:pass@ip:port)")
p_install.add_argument("--safe", action="store_true",
help="Safe mode: skip automatic system changes, show what's needed instead")
p_install.add_argument("--dry-run", action="store_true",
help="Show what would be done without making any changes")
# ── configure ──
p_conf = sub.add_parser("configure", help="Set a config value or auto-extract from browser")
@ -178,11 +182,21 @@ def _cmd_install(args):
from agent_reach.config import Config
from agent_reach.doctor import check_all, format_report
safe_mode = args.safe
dry_run = args.dry_run
config = Config()
print()
print("👁️ Agent Reach Installer")
print("=" * 40)
if dry_run:
print("🔍 DRY RUN — showing what would be done (no changes)")
print()
if safe_mode:
print("🛡️ SAFE MODE — skipping automatic system changes")
print()
# Auto-detect environment
env = args.env
if env == "auto":
@ -195,20 +209,33 @@ def _cmd_install(args):
# Apply explicit flags
if args.proxy:
config.set("reddit_proxy", args.proxy)
config.set("bilibili_proxy", args.proxy)
print(f"✅ Proxy configured for Reddit + Bilibili")
if dry_run:
print(f"[dry-run] Would configure proxy for Reddit + Bilibili")
else:
config.set("reddit_proxy", args.proxy)
config.set("bilibili_proxy", args.proxy)
print(f"✅ Proxy configured for Reddit + Bilibili")
# ── Install system dependencies ──
print()
_install_system_deps()
if dry_run:
_install_system_deps_dryrun()
elif safe_mode:
_install_system_deps_safe()
else:
_install_system_deps()
# ── mcporter (for Exa search + XiaoHongShu) ──
print()
_install_mcporter()
if dry_run:
print("📦 [dry-run] Would install mcporter and configure Exa search")
elif safe_mode:
_install_mcporter_safe()
else:
_install_mcporter()
# Auto-import cookies on local computers
if env == "local":
if env == "local" and not safe_mode and not dry_run:
print()
print("🍪 Trying to import cookies from browser...")
try:
@ -230,6 +257,13 @@ def _cmd_install(args):
print(" ⬜ No cookies found (normal if you haven't logged into these sites)")
except Exception:
print(" ⬜ Could not read browser cookies (browser might be open)")
elif env == "local" and safe_mode:
print()
print("🍪 Skipped auto cookie import (safe mode).")
print(" To import manually: agent-reach configure --from-browser chrome")
elif env == "local" and dry_run:
print()
print("🍪 [dry-run] Would try to import cookies from Chrome/Firefox")
# Environment-specific advice
if env == "server":
@ -240,25 +274,29 @@ def _cmd_install(args):
print(" Cheap option: https://www.webshare.io ($1/month)")
# Test channels
print()
print("Testing channels...")
results = check_all(config)
ok = sum(1 for r in results.values() if r["status"] == "ok")
total = len(results)
# Final status
print()
print(format_report(results))
print()
# ── Install agent skill ──
_install_skill()
print(f"✅ Installation complete! {ok}/{total} channels active.")
if ok < total:
if not dry_run:
print()
print("🤖 Some channels are not active yet. If you're an AI Agent, try to fix them yourself — then run `agent-reach doctor` again.")
print("Testing channels...")
results = check_all(config)
ok = sum(1 for r in results.values() if r["status"] == "ok")
total = len(results)
# Final status
print()
print(format_report(results))
print()
# ── Install agent skill ──
_install_skill()
print(f"✅ Installation complete! {ok}/{total} channels active.")
if ok < total:
print()
print("🤖 Some channels are not active yet. If you're an AI Agent, try to fix them yourself — then run `agent-reach doctor` again.")
else:
print()
print("🔍 Dry run complete. No changes were made.")
def _install_skill():
@ -403,6 +441,58 @@ def _install_system_deps():
print(" ⬜ instaloader install failed (optional — try: pip install instaloader)")
def _install_system_deps_safe():
"""Safe mode: check what's installed, print instructions for what's missing."""
import shutil
print("🔧 Checking system dependencies (safe mode — no auto-install)...")
deps = [
("gh", ["gh"], "GitHub CLI", "https://cli.github.com — or: apt install gh / brew install gh"),
("node", ["node", "npm"], "Node.js", "https://nodejs.org — or: apt install nodejs npm"),
("bird", ["bird", "birdx"], "bird CLI (Twitter)", "npm install -g @steipete/bird"),
("instaloader", ["instaloader"], "instaloader (Instagram)", "pip install instaloader"),
]
missing = []
for name, binaries, label, install_hint in deps:
found = any(shutil.which(b) for b in binaries)
if found:
print(f"{label} already installed")
else:
print(f"{label} not found")
missing.append((label, install_hint))
if missing:
print()
print(" To install missing dependencies manually:")
for label, hint in missing:
print(f" {label}: {hint}")
else:
print(" All system dependencies are installed!")
def _install_system_deps_dryrun():
"""Dry-run: just show what would be checked/installed."""
import shutil
print("🔧 [dry-run] System dependency check:")
checks = [
("gh CLI", ["gh"], "apt install gh / brew install gh"),
("Node.js", ["node"], "curl NodeSource setup | bash + apt install nodejs"),
("bird CLI", ["bird", "birdx"], "npm install -g @steipete/bird"),
("instaloader", ["instaloader"], "pip install instaloader"),
]
for label, binaries, method in checks:
found = any(shutil.which(b) for b in binaries)
if found:
print(f"{label}: already installed, skip")
else:
print(f" 📥 {label}: would install via: {method}")
def _install_mcporter():
"""Install mcporter and configure Exa + XiaoHongShu MCP servers."""
import shutil
@ -474,6 +564,21 @@ def _install_mcporter():
pass
def _install_mcporter_safe():
"""Safe mode: check mcporter status, print instructions."""
import shutil
print("📦 Checking mcporter (safe mode)...")
if shutil.which("mcporter"):
print(" ✅ mcporter already installed")
print(" To configure Exa search: mcporter config add exa https://mcp.exa.ai/mcp")
else:
print(" ⬜ mcporter not installed")
print(" To install: npm install -g mcporter")
print(" Then configure Exa: mcporter config add exa https://mcp.exa.ai/mcp")
def _detect_environment():
"""Auto-detect if running on local computer or server."""
import os

View file

@ -51,6 +51,12 @@ class Config:
self._ensure_dir()
with open(self.config_path, "w") as f:
yaml.dump(self.data, f, default_flow_style=False, allow_unicode=True)
# Restrict permissions — config may contain credentials
try:
import stat
self.config_path.chmod(stat.S_IRUSR | stat.S_IWUSR) # 0o600
except OSError:
pass # Windows or permission edge cases
def get(self, key: str, default: Any = None) -> Any:
"""Get a config value. Also checks environment variables (uppercase)."""

View file

@ -224,7 +224,7 @@ This project was entirely vibe-coded 🎸 There might be rough edges here and th
## Credits
[Jina Reader](https://github.com/jina-ai/reader) · [yt-dlp](https://github.com/yt-dlp/yt-dlp) · [bird](https://github.com/steipete/bird) · [Exa](https://exa.ai) · [feedparser](https://github.com/kurtmckee/feedparser)
[Jina Reader](https://github.com/jina-ai/reader) · [yt-dlp](https://github.com/yt-dlp/yt-dlp) · [bird](https://github.com/steipete/bird) · [Exa](https://exa.ai) · [feedparser](https://github.com/kurtmckee/feedparser) · [instaloader](https://github.com/instaloader/instaloader) · [linkedin-scraper-mcp](https://github.com/stickerdaniel/linkedin-mcp-server) · [mcp-bosszp](https://github.com/mucsbr/mcp-bosszp)
## License

View file

@ -8,6 +8,12 @@ Copy this to your AI Agent:
帮我安装 Agent Reachhttps://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/install.md
```
> 🛡️ **Security-conscious?** Use safe mode — it won't auto-install system packages:
> ```
> 帮我安装 Agent Reach安全模式https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/install.md
> 安装时使用 --safe 参数
> ```
---
## For AI Agents
@ -16,8 +22,20 @@ Copy this to your AI Agent:
Install Agent Reach and make sure **all channels are working**. Your user expects you to have full internet access capabilities when this is done — reading tweets, searching Reddit, watching YouTube, browsing GitHub, and more.
### ⚠️ Boundaries
When fixing issues, stay within these limits:
- **DO NOT** run commands with `sudo` unless the user explicitly approved
- **DO NOT** modify system files outside `~/.agent-reach/`
- **DO NOT** install packages not listed in this guide
- **DO NOT** disable firewalls, security settings, or system protections
- If something requires elevated permissions, **tell the user** what's needed and let them decide
### Step 1: Install
**Default (fully automatic):**
```bash
pip install https://github.com/Panniantong/agent-reach/archive/main.zip
agent-reach install --env=auto
@ -25,6 +43,25 @@ agent-reach install --env=auto
This auto-installs system dependencies (gh CLI, Node.js, mcporter, bird), configures Exa search, detects environment, and tests all channels.
**Safe mode (no automatic system changes):**
If the user asked for safe mode, or you're on a production machine:
```bash
pip install https://github.com/Panniantong/agent-reach/archive/main.zip
agent-reach install --env=auto --safe
```
Safe mode checks what's installed and tells you what's missing, but doesn't auto-install system packages. You can then install each dependency manually.
**Dry run (preview only):**
```bash
agent-reach install --env=auto --dry-run
```
Shows what would be done without making any changes.
**Read the output carefully**, then run:
```bash
@ -35,14 +72,16 @@ agent-reach doctor
`agent-reach doctor` shows you which channels are active and which aren't.
**Your goal is to get as many channels to ✅ as possible.** If something failed during install or shows as ❌/⚠️ in doctor, fix it yourself. You're a capable AI Agent — diagnose the problem, try alternative approaches, and iterate until it works.
Try to get as many channels to ✅ as possible. If something failed during install or shows as ❌/⚠️ in doctor, diagnose the problem and try to fix it — but stay within the boundaries above. If a fix requires elevated permissions or system changes, ask the user first.
Only ask the user when you genuinely need their input (see below).
Only ask the user when you genuinely need their input (credentials, permissions, etc.).
### Step 3: Configure things that need user input
Some channels need credentials only the user can provide. Based on the doctor output, ask for what's missing:
> 🔒 **Security tip:** For platforms that need cookies (Twitter, XiaoHongShu, Instagram), we recommend using a **dedicated/secondary account** rather than your main account. Cookie-based auth grants full account access — using a separate account limits the blast radius if credentials are ever compromised.
**Twitter search & posting (server users):**
> "To unlock Twitter search, I need your Twitter cookies. Install the Cookie-Editor Chrome extension, go to x.com/twitter.com, click the extension → Export → Header String, and paste it to me."
> Extension: https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm
@ -183,6 +222,8 @@ If the user wants a different agent to handle it, let them choose.
| Command | What it does |
|---------|-------------|
| `agent-reach install --env=auto` | Full auto-setup (installs deps + configures) |
| `agent-reach install --env=auto --safe` | Safe setup (no auto system changes) |
| `agent-reach install --env=auto --dry-run` | Preview what would be done |
| `agent-reach doctor` | Show channel status |
| `agent-reach watch` | Quick health + update check (for scheduled tasks) |
| `agent-reach check-update` | Check for new versions |

View file

@ -1,6 +1,6 @@
[project]
name = "agent-reach"
version = "1.0.0"
version = "1.1.0"
description = "Give your AI Agent eyes to see the entire internet. Search + Read 10+ platforms."
readme = "README.md"
license = {text = "MIT"}