---
title: TOOLS管理
source:
author: shenwei
published:
created:
description:
tags: []
---


# TOOLS管理
## 统一SSH管理
- **所有服务器**: 包括macmini、ubuntu1、ubuntu2、NAS
- **管理方式**: 通过SSH统一管理，不存储sudo密码
- **权限原则**: 遵循最小权限原则
## 管理流程
1. 所有服务器操作都通过SSH进行
2. 不存储任何服务器的sudo密码
3. 需要sudo权限的操作通过SSH执行
4. 保持所有服务器的管理方式一致
## Docker命令路径
- **macmini**: `/usr/local/bin/docker` 或 `/opt/homebrew/bin/docker`（SSH时PATH不包含docker）
- **NAS**: `/usr/local/bin/docker`（使用 `docker-compose` 而非 `docker compose`）
- **ubuntu1/ubuntu2**: 直接用 `docker`

## 文件编辑注意事项
- **所有重要文件**: 使用 `exec + echo` 追加内容，避免 edit 工具在文件末尾无换行时失败
- **edit工具使用准则**: edit依赖精确文本匹配，任何空白字符差异都会导致失败。建议：先 read 文件确认内容，用 write 重写整个文件更可靠（特别是 memory、SOUL、IDENTITY 等重要文件）

## FRP (frpc 客户端) 管理
### 安装目录

| 服务器     | FRP目录                            |
| ------- | -------------------------------- |
| macmini | /opt/frp/frp_0.65.0_darwin_arm64 |
| ubuntu1 | /opt/frp/frp_0.65.0_linux_amd64  |
| ubuntu2 | /opt/frp/frp_0.65.0_linux_amd64  |

### 配置文件
- **文件名**: `frpc.toml`（在FRP目录下）
- **作用**: 定义所有通过frp反向代理的应用及端口映射 (localPort ↔ remotePort)
### 管理方式（通过tmux）
1. 切换到root用户: `sudo su`
2. 进入FRP目录: `cd /opt/frp/frp_xxx`
3. 连接到tmux会话: `tmux attach -t frpc`
4. 停止进程: `Ctrl+C`
5. 重启frpc: `./frpc -c frpc.toml`
6. 查看启动是否成功
### 查看配置
```bash
# 读取frpc.toml了解端口映射
cat /opt/frp/frp_0.65.0_xxx/frpc.toml
```

## FRP端口映射查询格式 (2026-03-14)

用户会这样提问:
- "ubuntu1上frp的列表"
- "macmini的frp配置"
- "查看ubuntu2的frpc.toml"
格式: 扫描frpc.toml文件，列出proxies相关配置
输出格式: 表格 (名称 | 类型 | localPort | remotePort)

查询示例: ssh到对应服务器 -> cat /opt/frp/frp_0.65.0_xxx/frpc.toml
## FRP状态检查 (2026-03-14)
用户可能说: "检查frp状态"
**检查方法**:
1. SSH到对应服务器
2. 切换root: `sudo su`
3. 进入FRP目录: `cd /opt/frp/frp_xxx`
4. 如果是macmini服务器连接tmux: `tmux attach -t frpc`
5. 如果是ubuntu服务器：`systemctl status frpc`
6. 查看日志输出

**正常状态标志**:
- 所有 proxy 启动成功时会显示: `[xxx] [name] start proxy success`
- 例如: `2026-03-14 20:49:36.007 [I] [client/control.go:172] [65f4a34a064fae9e] [transmission] start proxy success`

**重启命令** (如果需要):
1. 如果是macmini服务器：
- `Ctrl+C` 停止当前进程
- `./frpc -c frpc.toml` 重启
2. 如果是ubuntu服务器
- `systemctl stop frpc` `systemctl start frpc` `systemctl restart frpc`

## VPS2 (x-UI 科学上网)
- **IP**: 104.194.92.188
- **SSH**: `ssh vps2`
- **管理命令**: `x-ui`
- **用途**: x-UI 面板管理，用于科学上网
- 结果展示用列表方式，方便阅读

## 笔记系统
用户可能说: "请帮我记笔记"、"帮我把这篇文章保存在笔记目录"、"请读取知识库笔记目录下的这篇笔记"
使用obsidian skill 读取/保存/修改Markdown笔记
Macmini服务器上
- **Obsidian笔记目录**: `/Users/weishen/Workspace/nexus`
- **Openclaw笔记目录**: `/Users/weishen/Workspace/nexus/openclaw`
- **知识库笔记目录**: `/Users/weishen/Workspace/nexus/openclaw/knowledgebase`
- **云策专属笔记目录**: `/Users/weishen/Workspace/nexus/openclaw/yunce`

## 网络测试策略 (2026-03-15)
用户可能说: "网络测试"、"检查服务器科学上网"
**测试项目**:
1. 国内直连baidu (https://www.baidu.com)
2. 国外直连 Google (https://www.google.com)
3. 国外通过代理访问 Google (socks5://127.0.0.1:10808)

**测试命令模板**:
**国内访问直连**
```
curl -v https://www.baidu.com
```

**国外访问直连**
```
curl -v https://www.google.com
```

**国外访问通过代理连**
这是最快、最直接的方法。我们可以强制 `curl` 使用 SOCKS5 代理去访问 Google 的状态页。
**执行命令：**
```
curl -x socks5h://127.0.0.1:10808 -v https://www.google.com
```
- **参数解释：**
    - `-x socks5h://`：指定使用 SOCKS5 代理。注意加个 `h`，这表示让代理服务器去解析域名（防止本地 DNS 污染导致测试失败）。
    - `-v`：(Verbose) 显示详细连接过程。
- **判断标准：**    
    - 如果看到 `HTTP/2 200` 或者大量的 HTML 文本，说明**代理成功**。
    - 如果显示 `Connection refused` 或 `Timeout`，说明**端口未开放或 V2Ray 未运行**。

**服务器列表与代理端口**:

| 服务器 | IP | 代理端口 | 备注 |
|--------|-----|---------|------|
| MacMini | 192.168.3.189 | 10808 | V2RayN |
| Ubuntu1 | 192.168.3.47 | 10808 | 需SSH后测试 |
| Ubuntu2 | 192.168.3.45 | 10808 | 需SSH后测试 |
| NAS | 192.168.3.17 | 20170 | 仅监听127.0.0.1 |
| VPS1 | 192.227.222.142 | - | 直连正常 |
| VPS2 | 104.194.92.188 | - | 直连正常 |

**输出格式**: 列表方式，方便阅读

**网络测试输出格式**
用户要求格式示例:
• 服务器名
  • 国内访问直连: ✅/❌
  • 国外访问直连: ✅/❌
  • 国外访问通过代理XXX连: ✅/❌
  
## Telegram 配置注意事项 (2026-03-15)
- groupPolicy=allowlist 时必须配置 groupAllowFrom，否则群消息被静默丢弃
- 中国访问Telegram API需要配置代理 (proxy)
- 代理协议必须是 http:// 或 socks5://
- Bot 的 has_topics_enabled: false，不支持 Telegram Topics 功能
## OpenClaw 命令路径 (2026-03-27)

| 服务器      | OpenClaw 路径                              |
| -------- | ---------------------------------------- |
| Mac mini | `/opt/homebrew/bin/openclaw`             |
| Ubuntu1  | `/home/shenwei/.npm-global/bin/openclaw` |
| Ubuntu2  | `/home/shenwei/.npm-global/bin/openclaw` |

## NAS Docker 代理配置 (2026-03-27)
- **配置文件**: `/etc/systemd/system/pkg-ContainerManager-dockerd.service.d/http-proxy.conf`
- **用途**: Synology NAS 上 Docker 守护进程的代理设置
- **修改后需执行**: `sudo systemctl daemon-reload && sudo systemctl restart docker`
**使用方式**:
- SSH 到对应服务器后，使用完整路径执行命令
- 例如: `ssh ubuntu1 '/home/shenwei/.npm-global/bin/openclaw status'`
## sag (TTS 语音生成) (2026-03-27)
### 安装
```bash
brew install steipete/tap/sag
```

### API Key 配置
- 位置: `~/.openclaw/.env`
- 环境变量: `ELEVENLABS_API_KEY`
### 生成语音并发送到 Telegram
```bash
# 1. 生成 MP3 文件
source ~/.openclaw/.env
sag --api-key "$ELEVENLABS_API_KEY" -o /tmp/voice.mp3 "要转换的文字"

# 2. 发送到 Telegram (voice note)
message --account <telegram bot> --chatId <user_id> --filePath /tmp/voice.mp3 --message "文字" --buttons []
```
### 使用规则
- 所有用 sag 生成的语音都必须通过 Telegram voice note 发送给我
- 使用 当前agent对应的telegram bot 账号发送
- 文件临时保存在 /tmp/ 目录

### OpenCode
- **路径**: `/Users/weishen/.opencode/bin/opencode`
- **版本**: 1.2.27
- **用法**: 开发任务必须通过它执行

## Nexus Git 仓库配置
当用户说 "请帮我把这个笔记push到Git"
用于提交Obsidian笔记目录里的笔记，进行版本控制管理
- **Remote URL**: `ssh://git@192.168.3.189:2222/admin/nexus.git`
- **SSH认证**: 已配置（osxkeychain），无需输入用户名密码
- **可直接执行**: git add → git commit → git push
- **用户名**: weishen
- **邮箱**: ishenwei@gmail.com

## AgentMail (邮件收发与自动化) (2026-03-28)
### 安装
```
npm install -g @clawhub/agentmail
```
### API Key / 账号配置
- 位置: `~/.openclaw/.env`
- 环境变量:
AGENTMAIL_API_KEY=your_api_key  
AGENTMAIL_EMAIL=your_email@example.com  
AGENTMAIL_PROVIDER=imap_smtp   # 或 gmail / outlook  
AGENTMAIL_IMAP_HOST=imap.example.com  
AGENTMAIL_SMTP_HOST=smtp.example.com  
AGENTMAIL_PASSWORD=your_password_or_app_password
> ⚠️ 建议使用 **App Password**（如 Gmail / Outlook），避免主密码暴露
### 发送邮件
```
agentmail send \  
  --to "target@example.com" \  
  --subject "测试邮件" \  
  --body "这是一封由 Agent 自动发送的邮件"
```
#### 带附件发送
```
agentmail send \  
  --to "target@example.com" \  
  --subject "报告文件" \  
  --body "请查收附件" \  
  --attachments "/tmp/report.pdf,/tmp/log.txt"
```
### 收取邮件
```
agentmail fetch \  
  --limit 10 \  
  --unread true
```
#### 输出为 JSON（方便 Agent 处理）
```
agentmail fetch \  
  --limit 20 \  
  --format json > /tmp/mails.json
```
### 搜索邮件
```
agentmail search \  
  --query "from:boss@example.com subject:urgent" \  
  --limit 5
```
### 自动化处理（典型 Agent 场景）
#### 1️⃣ 拉取未读邮件并分类
```
agentmail fetch --unread true --format json > /tmp/unread.json
```
#### 2️⃣ 解析后自动回复
```
agentmail send \  
  --to "<extracted_email>" \  
  --subject "Re: <original_subject>" \  
  --body "已收到您的邮件，我们会尽快处理"
```
#### 3️⃣ 保存关键邮件到 Markdown（用于知识库 / Daily Notes）
```
agentmail fetch --limit 10 --format markdown > /tmp/mails.md
```
### 与 Telegram 联动（通知类）
```
agentmail fetch --unread true --format text > /tmp/mail.txt  
```

```
message \  
  --account <telegram bot> \  
  --chatId <user_id> \  
  --message "$(cat /tmp/mail.txt)"
```
### 使用规则
- 所有 **重要邮件（如告警 / 客户 / 商机）必须同步到 Telegram**
- 邮件正文必须经过摘要处理（避免噪音信息）
- 附件文件统一下载到 `/tmp/` 目录再处理
- 自动回复必须符合上下文语义，避免机械回复
- 对于批量邮件处理，优先输出 JSON 供 Agent 决策
- 敏感邮件（如包含凭证 / 密钥）禁止自动转发

## Obsidian笔记同步 (2026-03-28)
用户可能说: "请帮我同步一下Obsidian笔记"、"请帮我把这篇笔记push到Git"、"请同步iCloud Obsidian笔记目录"

### 使用规则
1. 打开Macmini上的终端
2. 先把Obsidian笔记目录(`/Users/weishen/Workspace/nexus`)里新增内容添加到Git, 并添加备注，并push到Git
3. 再做一次`git pull`把Git上最新的内容同步到Obsidian笔记目录(`/Users/weishen/Workspace/nexus`)
4. 进入iCloud Obsidian目录 `/Users/weishen/Library/Mobile\ Documents/iCloud~md~obsidian/Documents/nexus`
5. 再执行一次`git pull`
6. 如果push成功，可以把commit id告诉用户。
7. 如果pull成功，也可以告诉用户目录已经更新。

### 异常处理
如果在处理git命令过程中出现任何问题，请第一时间联系用户。并把错误消息贴给用户看。

## N8N 工作流管理 (2026-03-29)
用户可能说: "帮我看看n8n上的工作流"、"触发n8n工作流"、"查看n8n执行记录"

### 连接配置
| 配置项 | 值 |
|--------|-----|
| **Base URL** | `https://n8n.ishenwei.online` |
| **API Key** | `~/.openclaw/.env` 中的 `N8N_API_KEY` |
| **管理界面** | https://n8n.ishenwei.online |

### 核心脚本路径
- **技能位置**: `~/.openclaw/skills/n8n/`
- **n8n_api.py**: 工作流管理、触发执行、查看状态
- **n8n_tester.py**: 验证工作流、dry-run 测试
- **n8n_optimizer.py**: 性能分析与优化建议

### 环境变量（已在 `~/.openclaw/.env`）
```
N8N_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
N8N_BASE_URL=https://n8n.ishenwei.online
```

### 常用操作
```bash
# 查看工作流列表
python3 ~/.openclaw/skills/n8n/scripts/n8n_api.py list-workflows --pretty

# 查看执行记录
python3 ~/.openclaw/skills/n8n/scripts/n8n_api.py list-executions --id <workflow-id> --limit 20 --pretty

# 手动触发工作流
python3 ~/.openclaw/skills/n8n/scripts/n8n_api.py execute --id <workflow-id>

# 带数据触发
python3 ~/.openclaw/skills/n8n/scripts/n8n_api.py execute --id <workflow-id> --data '{"key": "value"}'

# 激活/停用
python3 ~/.openclaw/skills/n8n/scripts/n8n_api.py activate --id <workflow-id>
python3 ~/.openclaw/skills/n8n/scripts/n8n_api.py deactivate --id <workflow-id>
```

### 测试与验证
```bash
# 验证工作流结构
python3 ~/.openclaw/skills/n8n/scripts/n8n_tester.py validate --id <workflow-id> --pretty

# Dry Run 测试
python3 ~/.openclaw/skills/n8n/scripts/n8n_tester.py dry-run --id <workflow-id> --data '{}'
```

### 创建工作流
```bash
# 从 JSON 文件创建
python3 ~/.openclaw/skills/n8n/scripts/n8n_api.py create --from-file workflow.json

# 创建后激活
python3 ~/.openclaw/skills/n8n/scripts/n8n_api.py activate --id <new-workflow-id>
```

### 性能分析
```bash
# 分析性能
python3 ~/.openclaw/skills/n8n/scripts/n8n_optimizer.py analyze --id <workflow-id> --pretty

# 获取优化建议
python3 ~/.openclaw/skills/n8n/scripts/n8n_optimizer.py suggest --id <workflow-id> --pretty
```

### Webhook 触发
```bash
# 直接调用 Webhook
curl -X POST "https://n8n.ishenwei.online/webhook/<webhook-path>" \
  -H "Content-Type: application/json" \
  -d '{"key": "value"}'
```

---

## N8N 内容翻译流水线 (2026-03-29)

**用途**：英文文章 → 中文（公众号Markdown + HTML）+ Twitter文案 + 视频脚本

**架构说明**：
- n8n 只能读写容器内的 `/home/node/.n8n-files/` 目录
- OpenClaw 负责文件搬运：复制到 n8n → 触发 → 复制回 Obsidian
- 完整设计文档：`~/Obsidian/shenwei/openclaw/yunce/n8n-content-pipeline-workflow.md`

### 工作流版本
| 版本 | ID | 状态 | 说明 |
|------|-----|------|------|
| **v5（最新）** | `iOf32aOKvTjfTDSM` | 未激活 | 双输出：Markdown + HTML |
| v3 | `tOGMiC6qOJPOY89E` | 活跃 | 单输出（Markdown） |

### 调用前的文件准备
n8n 的 Read/Write File 节点使用 `/home/node/.n8n-files/` 目录，**不是** Obsidian 目录。

```
n8n 容器内路径:  /home/node/.n8n-files/
MacMini Obsidian:  /Users/weishen/Workspace/nexus/openclaw/
```

### OpenClaw 完整调用流程

#### 第一步：复制原文到 n8n-files
```bash
# SSH 到 MacMini，将源文件复制到 n8n 容器可访问的目录
scp /Users/weishen/Workspace/nexus/openclaw/content-queue/{文件名}.md \
    macmini:/home/node/.n8n-files/{文件名}.md
```

#### 第二步：触发 Webhook
```bash
# 注意：v5 使用 /content-translation-v5
# note_name = n8n-files 里的文件名
# output_name = 输出的文件名（不含扩展名）
# source_path = Obsidian 原文路径（用于记录溯源）

curl -X POST "https://n8n.ishenwei.online/webhook/content-translation-v5" \
  -H "Content-Type: application/json" \
  -d "{
    \"note_name\": \"{文件名}.md\",
    \"output_name\": \"{文件名}\",
    \"source_path\": \"/Users/weishen/Workspace/nexus/openclaw/content-queue/{文件名}.md\",
    \"callback_url\": \"http://192.168.3.189:18789/webhook/yunce\"
  }"
```

#### 第三步：等待 Telegram 通知
- Telegram Bot (`y1NdRSaJwl0LoY37`) 会发送完成消息
- 消息格式：`✅ 文章转换完成！📝 标题：xxx`

#### 第四步：复制输出回 Obsidian
```bash
# 复制 Markdown 成品
scp macmini:/home/node/.n8n-files/{output_name}_output.md \
    /Users/weishen/Workspace/nexus/openclaw/content-output/{output_name}.md

# 复制 HTML 成品（公众号用）
scp macmini:/home/node/.n8n-files/{output_name}_output.html \
    /Users/weishen/Workspace/nexus/openclaw/content-output/{output_name}.html
```

#### 第五步：清理 n8n-files 临时文件
```bash
ssh macmini "rm /home/node/.n8n-files/{文件名}.md \
                  /home/node/.n8n-files/{output_name}_output.md \
                  /home/node/.n8n-files/{output_name}_output.html"
```

### 完整 Python 调用示例
```python
import subprocess
import time
import json

def trigger_content_translation(source_note_name, source_path, output_name):
    """完整的内容翻译流水线调用"""
    
    n8n_files_dir = "/home/node/.n8n-files"
    obsidian_root = "/Users/weishen/Workspace/nexus/openclaw"
    
    # ========== 第一步：复制原文到 n8n ==========
    source_full_path = f"{obsidian_root}/content-queue/{source_note_name}"
    print(f"[1/5] 复制原文到 n8n-files: {source_note_name}")
    subprocess.run([
        'scp', source_full_path, 
        f'macmini:{n8n_files_dir}/{source_note_name}'
    ], check=True)
    
    # ========== 第二步：触发 Webhook ==========
    print(f"[2/5] 触发 n8n 工作流...")
    webhook_url = "https://n8n.ishenwei.online/webhook/content-translation-v5"
    payload = json.dumps({
        "note_name": source_note_name,
        "output_name": output_name,
        "source_path": source_path,
        "callback_url": "http://192.168.3.189:18789/webhook/yunce"
    })
    subprocess.run([
        'curl', '-X', 'POST', webhook_url,
        '-H', 'Content-Type: application/json',
        '-d', payload
    ], check=True)
    
    # ========== 第三步：等待处理 ==========
    print("[3/5] 等待 Telegram 完成通知...")
    # Agent 应等待 Telegram 消息后再继续
    time.sleep(5)  # 示意用，实际应监听 Telegram
    
    # ========== 第四步：复制输出回 Obsidian ==========
    print(f"[4/5] 复制输出到 content-output...")
    output_md = f"{n8n_files_dir}/{output_name}_output.md"
    output_html = f"{n8n_files_dir}/{output_name}_output.html"
    dest_root = f"{obsidian_root}/content-output"
    
    subprocess.run(['scp', f'macmini:{output_md}', f'{dest_root}/{output_name}.md'], check=True)
    subprocess.run(['scp', f'macmini:{output_html}', f'{dest_root}/{output_name}.html'], check=True)
    
    # ========== 第五步：清理 ==========
    print(f"[5/5] 清理 n8n-files...")
    subprocess.run(['ssh', 'macmini', f'rm {n8n_files_dir}/{source_note_name} {output_md} {output_html}'])
    
    print(f"✅ 完成！输出: {dest_root}/{output_name}.md + .html")

# 调用示例
trigger_content_translation(
    source_note_name="article-2026-03-29.md",
    source_path="/Users/weishen/Workspace/nexus/openclaw/content-queue/article-2026-03-29.md",
    output_name="article-2026-03-29"
)
```

### Obsidian 目录结构
```
~/Workspace/nexus/openclaw/
├── content-queue/                              # 原始英文文章
│   └── article-2026-03-29.md
│
└── content-output/                            # 翻译成品（Markdown + HTML）
    ├── article-2026-03-29.md                  # 中文 Markdown（留存溯源）
    └── article-2026-03-29.html               # 公众号 HTML（直接复制粘贴）
```

### 输出文件说明
| 文件 | 格式 | 用途 |
|------|------|------|
| `*.md` | 中文 Markdown | Obsidian 留存、溯源、可修改 |
| `*.html` | 带样式 HTML | 复制到公众号编辑器，几乎零调整 |

### 常见问题
**Q: n8n API 返回 401？**
A: 检查 `~/.openclaw/.env` 里的 `N8N_API_KEY` 是否完整（应为 3 段 JWT）

**Q: 文件复制到 n8n-files 失败？**
A: 确认 MacMini 上 `/home/node/.n8n-files/` 目录存在且有写权限

**Q: 如何查看工作流状态？**
A: 用 `n8n_api.py list-executions --id <workflow-id> --limit 10 --pretty` 查看最近执行