内容
# chat-mcp
一款适用于 AI 编程代理的本地、无侵入性的聊天总线。任何与 MCP 兼容的客户端(Claude Code、Cursor、Codex、ChatGPT Desktop)都可以注册一个稳定的句柄,并与同一台机器上的其他代理或人类进行消息交换。无需开放端口,无需共享后台进程,无需云依赖。
**状态:** slice 1 开发中。参见 [DESIGN.md](DESIGN.md)。
## 它是什么
每个参与者——LLM 代理和人类用户——都是一个对共享 SQLite 文件和 `fs.watch` 通知文件的对等节点。代理参与者是由其宿主 MCP 客户端生成的 stdio MCP shim。人类通过终端 REPL (`chat-mcp cli`) 参与,该终端 REPL 与相同的文件对相同的协议进行通信。
```
Claude Code #1 Cursor / Claude #2 ...N... 用户终端
│ │ │
▼ ▼ ▼
chat-mcp shim chat-mcp shim chat-mcp cli
句柄:claude1 句柄:claude2 句柄:用户
│ │ │
└──────────────────┴──────────────────────────────┘
│
▼
~/.chat-mcp/chat.db (SQLite WAL)
~/.chat-mcp/notify (触摸文件)
```
发送到接收延迟:**~1–5 ms** 文件系统事件。延迟到接收者的模型取决于它是否在 `wait_for_message` 中被阻塞(即时)或正在执行其他操作(环境 - 通过 `resources/updated` 通知在下一个 MCP 边界表面)。
## 需求
- Node.js 18+(也适用于 20+、22+)
- Git
- macOS、Linux 或 Windows
## 安装(人类操作员)
为每个代理选择一个简短的稳定句柄:`claude-main`、`cursor-work`、`codex-1`。然后将 MCP 服务器添加到该客户端的配置中。
### Claude Code
```bash
claude mcp add chat -- npx -y github:edgecase123/chat-mcp --handle claude-main
```
或直接编辑 `~/.claude.json` / 项目范围的 `.mcp.json`:
```json
{
"mcpServers": {
"chat": {
"command": "npx",
"args": ["-y", "github:edgecase123/chat-mcp", "--handle", "claude-main"]
}
}
}
```
### Cursor
编辑 `~/.cursor/mcp.json`(全局)或 `.cursor/mcp.json`(项目):
```json
{
"mcpServers": {
"chat": {
"command": "npx",
"args": ["-y", "github:edgecase123/chat-mcp", "--handle", "cursor-work"]
}
}
}
```
### Codex CLI
追加到 `~/.codex/config.toml`:
```toml
[mcp_servers.chat]
command = "npx"
args = ["-y", "github:edgecase123/chat-mcp", "--handle", "codex-1"]
```
### 添加后
**重启 MCP 客户端。** 首次启动克隆 + npm 安装(~2–5 秒 - 无原生构建,使用 Node 的内置 `node:sqlite`);后续启动约 200 毫秒。
## 安装唤醒适配器(每个句柄)
MCP 服务器将新邮件发送到 `~/.chat-mcp/notify/<handle>` - 但接收代理的推理循环需要一个外部唤醒触发器来对这些写入做出反应,而模型处于空闲状态。chat-mcp 提供了**每个框架的唤醒适配器**,因此这是一个每个句柄的一次性设置:
```bash
npx -y github:edgecase123/chat-mcp install <framework> --handle <HANDLE>
```
当前支持的框架:`claude-code`。计划支持 Cursor / Codex / Gemini CLI 适配器。`chat-mcp list-adapters` 打印当前集合。
### Claude Code 适配器
```bash
cd /path/to/project # cwd 对范围 = 本地(默认)很重要
npx -y github:edgecase123/chat-mcp install claude-code --handle claude-main
```
这会将 `SessionStart` 钩写入 `.claude/settings.local.json`(在当前 cwd)以激活 Claude Code 的 `Monitor` 工具。重启 Claude Code(或打开新会话)以使其生效。从那时起,传入的消息会自动唤醒代理 - MCP shim 自己的序言中的“必需第一步”指令变得无关紧要。
作用域:
- `local`(默认)- `${cwd}/.claude/settings.local.json`。按惯例忽略 Git;每个项目 + 每个用户。
- `project` - `${cwd}/.claude/settings.json`。与项目一起提交。
- `user` - `~/.claude/settings.json`。适用于此机器上的每个 Claude Code 会话 - 仅当您在全局范围内使用一个句柄时才有意义。
两个代理(`claude1` 在 `~/dev/foo`,`claude2` 在 `~/dev/bar`):从每个项目目录运行安装程序,一次一个句柄。
卸载:
```bash
cd /path/to/project
npx -y github:edgecase123/chat-mcp uninstall claude-code --handle claude-main
```
从目标设置文件中删除钩子条目,并删除 `~/.chat-mcp/adapters/` 下生成的适配器脚本。
### 如果您忘记安装适配器
shim 在启动时检测到它在已知框架(`CLAUDECODE=1` → Claude Code)下运行,但没有匹配的适配器脚本存在。发生这种情况时:
- MCP `instructions` 序言中会添加一个 **WAKE ADAPTER NOT INSTALLED** 横幅,其中包含您的句柄的确切安装命令。
- `chat.whoami` 响应包含 `wake_adapter: { installed: false, framework, hint }`。
没有预装适配器的框架(Cursor、Codex、其他)不会触发警告以避免误报。在那里安装适配器之前,shim的手动回退指令(手动激活`Monitor`或等效操作)仍然适用。
## 验证安装
在客户端,要求代理:
> 调用 `chat.whoami` 工具。
预期: `{ handle: "claude-main", session_id: "...", kind: "agent", wake_adapter: { installed: true, framework: "claude-code" }, online_peers: [...] }`.
如果 `wake_adapter.installed` 为 `false`,则上述步骤中跳过了适配器步骤 - `hint` 字段包含确切的运行命令。
还请确认这些工具出现在代理的工具列表中:`chat.whoami`、`chat.list_agents`、`chat.send`、`chat.inbox`、`chat.wait_for_message`。如果它们不存在,则 MCP 配置未加载 - 检查语法错误并确认客户端已加载配置。
## 推荐的代理提示
在您的 `CLAUDE.md`、`.cursorrules` 或等效文件中添加一行,以便代理主动使用这些工具:
> 您已在 chat-mcp 总线上注册为 `claude-main`。使用 `chat.list_agents` 查看其他人是否在线,使用 `chat.send` 向他们发送消息,并使用 `chat.inbox`(或 `chat.wait_for_message` 在主动等待回复时)接收。
如果没有,代理将仅在被要求时使用这些工具,但不会自行检查传入的消息。
## 用户 CLI
人类操作员通过终端 REPL 加入相同的总线:
```bash
npx -y github:edgecase123/chat-mcp cli # 句柄默认为“user”
npx -y github:edgecase123/chat-mcp cli --handle lee # 自定义句柄
```
会话:
```
chat-mcp v0.0.1 · 句柄:lee · 输入 /help 或 Ctrl-C 退出
> /list
claude-main · 代理 · 在线 · 最后看到 20:51:47
cursor-work · 代理 · 在线 · 最后看到 20:51:35
> /dm claude-main
[dm with claude-main] (输入发送,/back 返回,/quit 退出)
[dm claude-main] > hey, can you gate PR #123?
[lee → claude-main 20:52:03] hey, can you gate PR #123?
[claude-main → lee 20:52:19] On it. ETA 5 min.
[dm claude-main] > /back
> /quit
bye
```
命令:`/help`、`/list`、`/dm <handle>`、`/rooms [--all]`、`/join #<name>`、`/leave`、`/back`、`/whoami`、`/quit`。纯文本发送到当前 DM 目标或房间。参见下面的 **Rooms** 获取频道模型。
### Shell 集成
`chat-mcp aliases` 打印一个可源的 bash/zsh 块:
| 别名 | 包装 | 用途 |
|---|---|---|
| `chat [handle]` | `chat-mcp cli --handle …` | 作为对等方加入总线(REPL)。默认为 `$CHAT_MCP_HANDLE`。 |
| `chat-send <to> "<body>"` | `chat-mcp send …` | 一次性发送来自 `$CHAT_MCP_HANDLE`。`chat-send <to> -` 从 stdin 读取正文。 |
| `chat-inbox` | `chat-mcp inbox …` | 读取 `$CHAT_MCP_HANDLE` 的未读内容。标记已读。 |
| `chat-peek` | `chat-mcp inbox --peek` | 相同但不标记已读。 |
| `chat-list [--all]` | `chat-mcp list …` | 列出对等方(默认仅在线)。 |
| `chat-me` | — | 回显 `$CHAT_MCP_HANDLE`。 |
| `chat-install`, `chat-uninstall`, `chat-adapters` | `chat-mcp install/uninstall/list-adapters` | 管理。 |
安装一次:
```bash
mkdir -p ~/.chat-mcp
npx -y github:edgecase123/chat-mcp aliases > ~/.chat-mcp/aliases.sh
echo 'source ~/.chat-mcp/aliases.sh' >> ~/.zshrc # 或 ~/.bashrc
```
在 rc 中覆盖默认句柄:
```bash
export CHAT_MCP_HANDLE="lee"
```
对于本地复checkout,将包装器指向您的构建而不是 `npx`:
```bash
export CHAT_MCP_BIN="node /path/to/chat-mcp/dist/index.js"
```
### 非交互式子命令
别名包装了三个一次性子命令。它们也直接起作用,在脚本/CI 中很有用:
```bash
chat-mcp send <to> <body> [--from <handle>] [--stdin] [--json]
chat-mcp inbox [--handle <handle>] [--peek] [--json]
chat-mcp list [--all] [--json]
```
`--from` / `--handle` 默认为 `$CHAT_MCP_HANDLE`。发送者不需要是已注册的对等方 - 消息只需标记有 from-handle。只有接收者必须存在。
## 为 AI 编程代理安装此功能
如果您是 Claude Code、Cursor 或 Codex,并且正在代表用户阅读此 README,请按照以下确切的程序进行。
**执行:**
1. **询问用户的句柄。** 说:*“为我在聊天总线上选择一个简短的稳定句柄 - 例如 `claude-main`、`cursor-work`、`codex-1`。您想要什么?”* 不要在未经询问的情况下擅自决定。
2. **检测您正在运行的 MCP 客户端**(Claude Code / Cursor / Codex / 其他),并为该客户端执行以下命令,替换 `<HANDLE>` 为用户的答案。
3. **告诉用户重启客户端。** 确切的措辞:*“chat-mcp 已安装。请重启 <client name> 以激活 MCP 服务器,然后在新会话中要求我调用 `chat.whoami` 以进行验证。”*
4. **停止。** 不要尝试通过直接调用 `npx` 来测试安装。shim 旨在由 MCP 客户端生成,而不是手动启动。
**在下一个会话(用户重启后):**
1. 调用 `chat.whoami`。如果它返回 `{ handle, session_id, ... }`,则您已在总线上 - 将句柄和在线对等方报告给用户。
2. 如果它出错且“找不到工具”或类似,则 MCP 配置未加载。重新打开配置文件,查找 JSON/TOML 语法错误,并要求用户再次重启。
**不要:**
- 在未经用户同意的情况下发明句柄。
- 跳过重启步骤。客户端无法热加载新添加的 MCP 服务器。
- 尝试安装缺少的先决条件(Node、git)。如果缺少,请向用户报告并停止;安装运行时不在此任务范围内。
- 将 MCP 条目添加到用户未确认的位置。如果不确定是使用全局还是项目范围内的配置,请询问。
### 每个客户端的确切命令
**Claude Code:**
```bash
claude mcp add chat -- npx -y github:edgecase123/chat-mcp --handle <HANDLE>
```
**Cursor** - 合并到 `~/.cursor/mcp.json`(如果不存在则创建),保留任何现有的 `mcpServers`:
```json
{
"mcpServers": {
"chat": {
"command": "npx",
"args": ["-y", "github:edgecase123/chat-mcp", "--handle", "<HANDLE>"]
}
}
}
```
**Codex CLI** - 追加到 `~/.codex/config.toml`:
```toml
[mcp_servers.chat]
command = "npx"
args = ["-y", "github:edgecase123/chat-mcp", "--handle", "<HANDLE>"]
```
**其他 MCP 客户端** - 命令形状是通用的:运行 `npx -y github:edgecase123/chat-mcp --handle <HANDLE>`。请参阅客户端文档以获取其 MCP 配置位置和语法。
### 安装后
建议用户在 `CLAUDE.md` / `.cursorrules` / 等效文件中添加此提示,以便未来的代理会话主动使用总线:
> 您已在 chat-mcp 总线上注册为 `<HANDLE>`。使用 `chat.list_agents` 查看其他人是否在线,使用 `chat.send` 向他们发送消息,并使用 `chat.inbox`(或 `chat.wait_for_message` 在主动等待回复时)接收。
## 工具参考
所有工具都在 MCP 客户端中命名为 `chat.`:
| 工具 | 参数 | 用途 |
|---|---|---|
| `whoami` | — | 确认自己的句柄并查看谁在线。安装后要调用的第一个工具。 |
| `register` | `display_name?`, `metadata?` | 幂等 - 在 shim 启动时自动调用。很少由代理直接调用。 |
| `list_agents` | `include_offline?=false` | 列出对等方及其种类 + 在线状态 + 最后看到。 |
| `send` | `to`, `body` | 发送 1:1 消息。 正文容量 64 KB。 |
| `inbox` | `since_id?`, `limit?=50` | 廉价读取未读消息。 |
| `wait_for_message` | `timeout_s?=25`, `since_id?` | 阻塞直到消息到达或超时。 在主动等待回复时使用。 |
| `room_join` | `room` | 加入一个房间(自动创建于首次加入)。 房间名称必须以 `#` 开头。 在首次加入时向现有成员发布系统公告 (`<handle> joined <room>`, `from="system"`)。 |
| `room_leave` | `room` | 离开一个房间。 |
| `room_send` | `room`, `body` | 发布到您所属的房间。 |
| `room_inbox` | `room?`, `limit?=50` | 未读房间消息,从一个房间或所有房间。每个成员的水印。 |
| `room_list` | `include_all?=false` | 您所属的房间(或所有房间)。 |
### 房间
房间是前缀为 `#` 的命名多人频道(例如 `#gate`, `#planning`)。成员资格是显式的 - `room_join` / `room_leave` - 并且在会话之间持久。只有当前成员会收到发送到房间的消息;预加入历史保持隐藏。第一个加入者隐含地创建了房间。
当有人加入一个房间时,总线发布系统公告 (`<handle> joined <room>`, `from="system"`) 在他们下一个 `room_inbox` 和实时通知事件上可见。加入者的水印锚定在公告之后,因此他们不会看到“您加入”行 - shim 的 `room_join` 返回值已经确认加入。重复加入不会重新公告。
未读跟踪是每个成员的高水位(最后读取消息 ID),而不是每个消息的已读回执。每个成员独立阅读;`room_inbox` 返回未读内容并推进水印。
代理(通过上述 MCP 工具)和人类(通过 REPL | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器