监控并控制本机上运行的多个 Claude Code / qodercli 会话。一个轻量「信使 Agent」理解你的意图、决定读还是写、定位到哪个会话;变更操作必须你确认后才执行。配套 Web 控制台。 Monitor and control many Claude Code / qodercli sessions on your machine. A lightweight “messenger agent” reads your intent, decides read vs. write, and targets the right session — every mutation waits for your confirmation. Ships with a web console.
npm install -g @tengxiaohtx/agent-connect
维护「当前会话」指针(像 cwd)。只做意图识别+路由:切换/列出/只读咨询/转发/接管/退出。咨询走 fork 只读副本问 worker 本身,绝不臆测代答。任意 OpenAI/Anthropic 兼容模型。 Keeps a “current session” pointer (like cwd). Pure intent-routing: switch / list / read-only consult / forward / takeover / exit. Consults fork a read-only copy and ask the worker itself — never guesses. Any OpenAI/Anthropic-compatible model.
路由,不干活routes, doesn't do the work读(list/read)只读落盘的 sessions 注册表与 transcript,零副作用、不碰 worker 进程——手机上狂刷也不污染上下文。写(send/takeover/run)经 tmux。 Reads only touch on-disk session registries and transcripts — zero side effects, never the worker process. Writes (send/takeover/run) go through tmux.
零污染zero pollution任何变更 worker 的操作走「提议 → 人工确认 → 执行」状态机,带白名单、命令前缀与确认超时。信使永远无法擅自动手。 Every mutation runs a propose → confirm → execute state machine, with sender allowlist, command prefix, and TTL. The messenger can never act on its own.
人工确认human-in-the-loop
继续用 cc-connect 做钉钉 ↔ 本地传输。因 cc-connect 只能通过 acp 类型接入自定义程序,信使以一个 ACP 薄桥作为它的 agent,转发给 agent-connect serve 守护。
cc-connect stays the DingTalk ⇄ local transport. Since cc-connect only accepts custom programs via its acp agent type, the messenger plugs in as a thin ACP bridge that forwards to the agent-connect serve daemon.
钉钉DingTalk ─Stream─► cc-connect ─exec─► agent-connect acp ─HTTP─► agent-connect serve │ ┌──────────────────────────────────────────────────────┐ │ │ Web 控制台console + SSE + 配置页config 闸门gate (allow/prefix)│◄┘ │ │ 共享 conductor / pending / 信使上下文shared conductor / pending / ctx │ │ AgentConductor ( propose → confirm → execute ) │ │ Messenger Agent ( AI SDK, OpenAI-compatible ) │ │ │ read tools / propose tools │ │ ControlPlane: listSessions·getMessages · send·takeover·run │ └──┬─────────────────┬──────────────────┬───────────────┘ registry.js transcript.js tmux.js
如果让被绑定的 worker 自己理解钉钉消息,一句「那任务咋样了」(读)就会进入它的工作上下文——读污染了写。独立信使 + 读写分离 + 人工确认,既保留「发一句话就行」的体验,又守住安全与上下文纯净。 If the bound worker interpreted your chat itself, a “how’s that task going?” (a read) would land in its working context — reads polluting writes. A separate messenger + plane split + human confirm keeps the “just say it” UX while protecting safety and context.
直接读 ~/.claude/sessions/*.json 与 *.jsonl transcript,完全不碰 agent 进程。工具:list_sessions / read_session / get_status。Reads ~/.claude/sessions/*.json and *.jsonl transcripts directly, never the process. Tools: list_sessions / read_session / get_status.
经 tmux 注入/接管/新建,且只暂存为提议。工具:propose_send / propose_takeover / propose_run,确认后才落地。Injects / takes over / spawns via tmux, staged as proposals only. Tools: propose_send / propose_takeover / propose_run, applied after confirm.
信使维护「当前会话」(cwd)。咨询走只读 fork、需要改动才建议接管、执行前人工确认;回复分清「信使」与「worker」两层。 The messenger keeps a “current session” (cwd). Consults are read-only forks; edits prompt a takeover; writes need confirmation; replies separate messenger vs. worker.
你You ──"这个 bug 怎么改?how to fix this bug?"──► Messenger │ consult (read-only) ▼ fork plan/只读 ──► Worker (原会话不动)(original untouched) ◄── 用自身上下文作答answers from its context Messenger ──► 你You: > 🔁 来自from <worker>(只读read-only): … + 建议接管suggest takeover 你You ──"接管take over"──► propose_takeover ──确认/confirm──► kill+resume 进 tmuxkill+resume in tmux 你You ──"按方案改apply the fix"──► propose_forward ──确认/confirm──► Worker 执行executes
你 ▸ 切到 c233caaf 🧭 信使 ▸ 📍 已切到 agentmon(c233caaf) 你 ▸ 它最近完成了什么? # 咨询 → 只读 fork 🧭 信使 ▸ > 🔁 来自 agentmon·claude(只读):发布了 v0.6.0…… 你 ▸ 帮我把版本号改成 0.6.1 # 需要改动 → 建议接管 🧭 信使 ▸ 这需要编辑,建议先接管。要我提议接管吗?You ▸ switch to c233caaf 🧭 Messenger ▸ 📍 current = agentmon (c233caaf) You ▸ what did it finish recently? # consult → read-only fork 🧭 Messenger ▸ > 🔁 from agentmon·claude (read-only): shipped v0.6.0… You ▸ bump the version to 0.6.1 # needs an edit → suggest takeover 🧭 Messenger ▸ that needs editing — take it over first? (propose?)
通信层用 cc-connect,它支持多种 IM;信使以平台无关的 ACP agent 接入,从 CC_SESSION_KEY 解析平台名并套用对应闸门。信使、读写平面、确认闸在所有平台完全一致,只有传输层不同。
Transport is cc-connect, which supports many IMs; the messenger plugs in as a platform-agnostic ACP agent, reads the platform from CC_SESSION_KEY, and applies its gate. Messenger, planes, and the confirm gate are identical everywhere — only the transport differs.
接入新 IM:① 在配置里配好该平台的 cc-connect 段(凭证等,见 cc-connect 文档);② 可选加一段闸门 [im.platforms.<名>](前缀 / 白名单 / 确认词),不配则用默认(启用、空白名单=允许所有)。
Add an IM: ① configure that platform's cc-connect block (credentials, per cc-connect docs); ② optionally add a gate [im.platforms.<name>] (prefix / allowlist / confirm words) — omit for defaults (enabled, empty allowlist = allow all).
card_template_id(或 Web 设置页),回复即打字机式流式呈现;不填则回退普通消息,功能不受影响。card_template_id (or via the web settings) for typewriter-style streaming; otherwise replies fall back to normal messages.两者不是同一类东西:OpenClaw 是一个自己干活的通用 AI Agent 本体(有自己的 agent loop、工具、模型、记忆,直接拿着 shell / 浏览器 / 邮件的钥匙替你做事);agent-connect 是套在你已有 coding agent 之上的遥控 / 分派层——它自己不干活,只判断「读还是写 / 哪个会话 / 哪个动词」,真正的活仍由 worker(Claude Code / qoder…)用它自己的完整上下文去做。 They're not the same kind of thing. OpenClaw is a general-purpose AI agent that does the work itself — its own loop, tools, model, and memory, holding the keys to your shell / browser / email. agent-connect is a remote-control / dispatch layer over the coding agents you already run — it does no work itself; it only decides read vs. write / which session / which verb, while the task still runs in the worker (Claude Code / qoder…) with its own full context.
| 维度Dimension | agent-connect | OpenClaw |
|---|---|---|
| 本质What it is | 已有 agent 的控制 / 信使层A control / messenger layer over existing agents | Agent 本体(Gateway 就是整个系统)The agent itself (the Gateway is the whole system) |
| 谁执行任务Who executes | 你原来的 Claude Code / qoder,保留完整项目上下文与工具Your existing Claude Code / qoder, keeping full project context & tools | OpenClaw 自己(另起一个上下文较弱的 agent)OpenClaw itself (a fresh agent with weaker context) |
| 一对多One-to-many | 核心能力:监控 / 寻址多个并发会话Core feature: monitor / address many concurrent sessions | 单一网关助手A single gateway assistant |
| 安全模型Safety model | 读写分离 + 写操作逐条人工确认;仅监听本机;显式白名单Read/write split + per-mutation human confirm; localhost-only; explicit allowlist | 自主为默认 → 攻击面更大Autonomous by default → larger attack surface |
| 上下文Context | 信使独立上下文,永不进入 worker 上下文Messenger has its own context, never enters the worker's | 它本身就是那个上下文It is that context |
| 定位Scope | 窄而专:从手机遥控你的 dev 会话Narrow & focused: remote-control your dev sessions from a phone | 通用个人助理(日程 / 消息 / 代码都做)General personal assistant (calendar / chat / code) |
| 体量Footprint | 轻:一层 + ACP 薄桥,传输复用 cc-connectLight: one layer + a thin ACP bridge, transport reused from cc-connect | 一整套长驻运行时A whole long-lived runtime |
不重造轮子、保住强上下文:真正的编码能力在你原来的 Claude Code 会话里(完整项目上下文、权限、工具链),这里让它继续干,只是变得可从聊天里寻址 / 观察 / 注入。
安全是设计前提:改动 worker 要你回「确认」,读操作零副作用,Web 只听 127.0.0.1。
天生一对多:「切到哪个会话」是一等概念。
轻量可组合:只是一层,传输复用 cc-connect。
Don't reinvent the agent, keep the strong context — your real coding power lives in your existing Claude Code session (full project context, permissions, toolchain); it just becomes addressable / observable / injectable from chat.
Safety is the premise: every mutation waits for your “confirm”, reads have zero side effects, the web console binds 127.0.0.1 only.
One-to-many by design: “which session” is first-class.
Light & composable: just a layer, transport reused from cc-connect.
你要的是一个通用自主助理——处理日程、跨平台联络、后台盯 GitHub issue 等非编码杂务,且愿意接受「给它钥匙让它自己跑」的取舍。agent-connect 是刻意收窄的:只解决「从手机安全地遥控本机多个 coding agent」这一件事。 You want a general autonomous assistant for non-coding chores — calendar, cross-platform messaging, background GitHub-issue triage — and accept the “hand it the keys and let it run” tradeoff. agent-connect is deliberately narrow: it solves exactly one thing — safely remote-controlling multiple local coding agents from your phone.
一键安装(装好 CLI + cc-connect,检查 Node/tmux 并 init): One-click install (CLI + cc-connect, checks Node/tmux, runs init):
curl -fsSL https://raw.githubusercontent.com/xinyuehtx/agent-connect/main/scripts/install.sh | bash
或用 npm:npm install -g @tengxiaohtx/agent-connect;或到 Releases 下载 .tgz 离线安装。装好后:
Or via npm: npm install -g @tengxiaohtx/agent-connect; or grab a .tgz from Releases. Then:
生成默认配置Create default configagent-connect init
仅本机 · 无需登录Localhost-only, no loginagent-connect serve
Web 设置页填 LLM 与钉钉Set LLM + DingTalk in the UI
另开终端拉起 cc-connectStart cc-connectagent-connect start
或全用 CLI 配置(等价于 Web 配置页): Or configure entirely via CLI (equivalent to the settings page):
# 信使 LLM(任意 OpenAI 兼容端点)messenger LLM (any OpenAI-compatible endpoint) agent-connect config set messenger.base_url "https://your-gateway/v1" agent-connect config set messenger.api_key "sk-..." agent-connect config set messenger.model "gpt-4o-mini" # 钉钉凭证(Stream 模式)DingTalk credentials (Stream mode) agent-connect config set projects.0.platforms.0.options.client_id "..." agent-connect config set projects.0.platforms.0.options.client_secret "..."
/ai 才路由给信使(如 /ai 列出会话);待确认时直接回「确认 / 取消」。写平面需要 tmux(brew install tmux),读平面不需要。
💡 In DingTalk, messages need the /ai prefix to reach the messenger (e.g. /ai list sessions); reply “确认/取消” (yes/no) to a pending action. The write plane needs tmux (brew install tmux); reads don’t.
| 命令Command | 说明What it does |
|---|---|
agent-connect init | 初始化配置目录与默认配置Create config dir + default config |
agent-connect serve | 启动 Web 控制台 + 信使守护(读写平面 + 安全闸)Start web console + messenger daemon (planes + gate) |
agent-connect acp | ACP 薄桥,供 cc-connect 拉起(勿手动运行)ACP bridge for cc-connect (not run by hand) |
agent-connect start | 启动 cc-connect(钉钉 ↔ 本地)Start cc-connect (DingTalk ⇄ local) |
agent-connect config set <k> <v> | 修改配置(支持点号路径)Set a config value (dot path) |
agent-connect agent list | 列出运行中的 agent 会话List running agent sessions |
agent-connect agent read <id> | 只读查看状态与最新回复Read status + latest reply (read-only) |
agent-connect agent send <id> "…" | 向 tmux 会话注入指令Inject into a tmux session |
agent-connect agent takeover <id> | 接管非 tmux 会话Adopt a non-tmux session |
agent-connect agent run "…" | 在 tmux 中新建可远控会话Spawn a new remote-controllable session |