feat: 持久对话 MCP 插件 v1.6.37 · Hub + Panel + MCP 三形态部署
- src/: server.js (MCP 4 工具) + hub.js (HTTP Hub) + cursor-title.js - web/: panel.html (主面板) + panel.remote.html (远端 1637) - scripts/: ensure-hub.sh (stdio→http 桥) + mongo_sync.py - mcp-config/: trae.mcp.json + cursor.mcp.json - docs/: INSTALL / DEPLOY / MCP_SETUP / ARCHITECTURE / QUICKSTART - ZIP 原始安装包备查 关键机制: - 4 MCP 工具:init / select / wait / merge - 垂直绑定:workspace::cursorTitle@hostIp 三件指纹 - 真挂起:关闭 timedReply 后 wait 真正阻塞,agent turn 不结束 - 双 Hub 部署:远端 NAS 24×7 + 本地 launchd 守护备份 - 三形态组合:远端 + 本地 + Trae 插件,可同时跑
This commit is contained in:
294
docs/MCP_SETUP.md
Normal file
294
docs/MCP_SETUP.md
Normal file
@@ -0,0 +1,294 @@
|
||||
# MCP 配置(MCP_SETUP.md)
|
||||
|
||||
> Trae / Cursor 接入持久对话 MCP 插件的完整配置
|
||||
|
||||
---
|
||||
|
||||
## 1. Trae CN(macOS)
|
||||
|
||||
### 配置文件位置
|
||||
|
||||
```
|
||||
~/.trae/mcp.json
|
||||
```
|
||||
|
||||
### 完整配置
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"persistent-chat": {
|
||||
"type": "stdio",
|
||||
"command": "/Users/karuo/.persistent-chat-local/ensure-hub.sh",
|
||||
"args": [
|
||||
"--workspace=${workspaceFolder}"
|
||||
],
|
||||
"env": {
|
||||
"PCHAT_HTTP_PORT": "13458",
|
||||
"PCHAT_NODE": "/usr/local/opt/node@22/bin/node",
|
||||
"PCHAT_HUB_HOST": "192.168.110.101",
|
||||
"NO_PROXY": "192.168.110.101,127.0.0.1,localhost"
|
||||
},
|
||||
"disabled": false,
|
||||
"autoApprove": [
|
||||
"wait_for_user_input",
|
||||
"init_conversation",
|
||||
"merge_conversation",
|
||||
"select_conversation"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 关键字段
|
||||
|
||||
| 字段 | 值 | 说明 |
|
||||
|:---|:---|:---|
|
||||
| `command` | `~/.persistent-chat-local/ensure-hub.sh` | 启动器,桥接 stdio ↔ HTTP |
|
||||
| `PCHAT_HUB_HOST` | `192.168.110.101` | 远端 NAS IP(主) |
|
||||
| `PCHAT_HTTP_PORT` | `13458` | Hub 端口 |
|
||||
| `PCHAT_NODE` | `/usr/local/opt/node@22/bin/node` | Node 22 路径 |
|
||||
| `NO_PROXY` | `192.168.110.101,127.0.0.1,localhost` | 绕过代理直连 |
|
||||
| `autoApprove` | 4 个工具全开 | 不弹确认框 |
|
||||
|
||||
### 加载步骤
|
||||
|
||||
1. 写入 `~/.trae/mcp.json`
|
||||
2. **Trae 必须 `Cmd+Q` 完全退出**(不是关窗)
|
||||
3. 重新打开 Trae
|
||||
4. 看 SOLO Agent 窗口的工具列表 → 出现 `persistent-chat` 4 个工具
|
||||
|
||||
### 验证
|
||||
|
||||
```bash
|
||||
# 1. 看 Trae 进程里是否有 server.js
|
||||
ps aux | grep "persistent-chat-local/server.js" | grep -v grep
|
||||
# 期望:看到 1 个进程,env 含 PCHAT_HUB_HOST=192.168.110.101
|
||||
|
||||
# 2. 在 Trae 里发:"开始测试"
|
||||
# 期望:4 工具出现 + 拿到 ct_ 开头的 token
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Cursor
|
||||
|
||||
### 配置文件位置
|
||||
|
||||
```
|
||||
~/Documents/个人/.cursor/mcp.json
|
||||
```
|
||||
|
||||
### 完整配置(与 Trae 相同)
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"persistent-chat": {
|
||||
"type": "stdio",
|
||||
"command": "/Users/karuo/.persistent-chat-local/ensure-hub.sh",
|
||||
"args": ["--workspace=${workspaceFolder}"],
|
||||
"env": {
|
||||
"PCHAT_HTTP_PORT": "13458",
|
||||
"PCHAT_NODE": "/usr/local/opt/node@22/bin/node",
|
||||
"PCHAT_HUB_HOST": "192.168.110.101",
|
||||
"NO_PROXY": "192.168.110.101,127.0.0.1,localhost"
|
||||
},
|
||||
"disabled": false,
|
||||
"autoApprove": [
|
||||
"wait_for_user_input",
|
||||
"init_conversation",
|
||||
"merge_conversation",
|
||||
"select_conversation"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 加载步骤
|
||||
|
||||
1. 写入 `~/Documents/个人/.cursor/mcp.json`
|
||||
2. Cursor → 设置 → MCP → Refresh
|
||||
3. 看 `persistent-chat` 是否绿色点
|
||||
4. 面板访问:Ctrl+L → 输入 `/mcp`
|
||||
|
||||
---
|
||||
|
||||
## 3. 多 IDE 共存
|
||||
|
||||
### 场景
|
||||
- 同时开 Trae 和 Cursor,都想用持久对话
|
||||
- 共享同一个 Hub(远端 NAS)
|
||||
|
||||
### 配置要点
|
||||
|
||||
**两边的 mcp.json 保持一致**,都指向同一个 Hub:
|
||||
|
||||
```json
|
||||
"PCHAT_HUB_HOST": "192.168.110.101"
|
||||
```
|
||||
|
||||
**垂直绑定隔离**:
|
||||
- 不同工作区 → 不同 session
|
||||
- 不同 Cursor 标签 → 不同 session
|
||||
- 同工作区 + 同标签 → 复用 session
|
||||
|
||||
**冲突场景**:
|
||||
- Trae 标签 = "学习" + Cursor 标签 = "学习" → 互窜(不推荐)
|
||||
- 建议:Trae 用 "Trae_xxx",Cursor 用 "Cursor_xxx"
|
||||
|
||||
---
|
||||
|
||||
## 4. 双 Hub 配置(远端 + 本地)
|
||||
|
||||
### 场景
|
||||
- 远端 NAS 24×7 在
|
||||
- 本地 launchd 守护备份
|
||||
- 远端挂时自动 fallback
|
||||
|
||||
### 方案:脚本切换
|
||||
|
||||
**ensure-hub.sh 增强版**(可加 fallback):
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# /Users/karuo/.persistent-chat-local/ensure-hub.sh
|
||||
HUB_HOST="${PCHAT_HUB_HOST:-127.0.0.1}"
|
||||
# 测试主 Hub
|
||||
if ! curl -sf "http://${HUB_HOST}:13458/api/health" -m 2 > /dev/null; then
|
||||
# 失败,fallback 到本地
|
||||
HUB_HOST="127.0.0.1"
|
||||
fi
|
||||
export PCHAT_HUB_HOST="$HUB_HOST"
|
||||
exec /usr/local/opt/node@22/bin/node \
|
||||
/Users/karuo/.persistent-chat-local/server.js \
|
||||
--workspace="${1#--workspace=}"
|
||||
```
|
||||
|
||||
这样远端挂时自动回退到本地(launchd 守护一直跑)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 工具参数详解
|
||||
|
||||
### 5.1 init_conversation
|
||||
|
||||
```typescript
|
||||
{
|
||||
token?: string; // 已有 token(merge 用)
|
||||
cursorTitle: string; // 必填:Cursor 标签
|
||||
newPlan?: boolean; // true=换计划,归档旧 ct_
|
||||
planLabel?: string; // 计划名(newPlan 时必填)
|
||||
workspace?: string; // 工作区路径
|
||||
}
|
||||
```
|
||||
|
||||
**返回**:
|
||||
```json
|
||||
{
|
||||
"Conversation initialized. pchat-token: ct_xxxx"
|
||||
"🆕 新计划线程:ct_xxxx"
|
||||
"[BINDING_AUTO_NEW] 新对话已自动绑定"
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 select_conversation
|
||||
|
||||
```typescript
|
||||
{
|
||||
token: string; // 必填:要复用的 ct_
|
||||
cursorTitle: string; // 必填:当前 Cursor 标签
|
||||
}
|
||||
```
|
||||
|
||||
**返回**:
|
||||
```json
|
||||
{
|
||||
"[BINDING_REUSE]"
|
||||
"🔄 恢复对话: ct_xxxx"
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 wait_for_user_input
|
||||
|
||||
```typescript
|
||||
{
|
||||
token: string; // 必填
|
||||
message: string; // 提示用户的话
|
||||
timeout?: number; // 最长等多久(ms),默认 60000
|
||||
renewalOnly?: boolean; // true=只续约不等消息
|
||||
}
|
||||
```
|
||||
|
||||
**返回**:
|
||||
```json
|
||||
{
|
||||
"<用户发的消息 或 '保活续跑' 默认文本>"
|
||||
"[pchat-token: ct_xxxx]"
|
||||
"校验#N"
|
||||
}
|
||||
```
|
||||
|
||||
### 5.4 merge_conversation
|
||||
|
||||
```typescript
|
||||
{
|
||||
fromToken: string; // 源 token
|
||||
toToken: string; // 目标 token
|
||||
cursorTitle: string; // 当前标签
|
||||
}
|
||||
```
|
||||
|
||||
**用途**:把两个 plan 的上下文合并。
|
||||
|
||||
---
|
||||
|
||||
## 6. 完整对话循环示例
|
||||
|
||||
```javascript
|
||||
// 1. 起新计划
|
||||
const init = await mcp.call('init_conversation', {
|
||||
cursorTitle: '持久对话永久续跑-20260626',
|
||||
newPlan: true,
|
||||
planLabel: '永久续跑三段式',
|
||||
});
|
||||
const token = extractToken(init); // ct_xxxx
|
||||
|
||||
// 2. 干活(可任意调用其他工具)
|
||||
// ...
|
||||
|
||||
// 3. 真挂起等用户
|
||||
const reply = await mcp.call('wait_for_user_input', {
|
||||
token,
|
||||
message: '【真挂起】请发任务或"继续"',
|
||||
timeout: 1800000, // 30 分钟
|
||||
});
|
||||
// 收到用户消息 → reply.text
|
||||
|
||||
// 4. 复用旧 session
|
||||
await mcp.call('select_conversation', {
|
||||
token,
|
||||
cursorTitle: '持久对话永久续跑-20260626',
|
||||
});
|
||||
|
||||
// 5. 循环到用户说"结束持久对话"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 常见配置错误
|
||||
|
||||
| 错误 | 现象 | 修复 |
|
||||
|:---|:---|:---|
|
||||
| `PCHAT_NODE` 路径错 | `node not found` | `which node` 改 |
|
||||
| `PCHAT_HUB_HOST` 用 0.0.0.0 | 端口冲突 | 改成具体 IP |
|
||||
| `NO_PROXY` 缺 | 代理拦截 | 加 `192.168.110.101` |
|
||||
| `autoApprove` 缺 | 每次弹窗 | 加 4 个工具名 |
|
||||
| Trae 没重启 | MCP 不加载 | `Cmd+Q` 退出 |
|
||||
| Cursor 没 refresh | 看不到 | 设置 → MCP → Refresh |
|
||||
|
||||
---
|
||||
|
||||
> 最后更新:2026-06-26 · 卡若AI
|
||||
Reference in New Issue
Block a user