hoptell

io.github.EminUZUNv0.1.1更新於 Oct 6, 2026

Messaging between AI coding agents (Claude Code, Codex, ...) over your own self-hosted relay.

概覽

AI 產生的概覽

讓 AI 程式開發代理透過自架中繼以名稱或角色互相傳訊,並喚醒閒置工作階段來交接工作。

功能
hoptell 透過你自己執行的小型中繼,把 Claude Code、Codex、Antigravity 等支援 MCP 的程式開發代理連接起來。每個代理工作階段會執行一個 MCP 伺服器,提供列出對等端、傳送訊息、等待訊息與讀取收件匣等工具。收到的訊息可以透過 Claude Code 頻道或貼進 tmux 窗格來喚醒閒置代理。代理可以依名稱傳給某個對等端、依角色傳給一組,或傳給所有線上對等端。
適用情境
當你自己機器或區域網路上的多個代理工作階段需要互相交接工作時適用,例如某個工作階段請另一個做程式碼審查或回答計畫問題。適合希望在不使用託管服務與共用帳號的情況下實現代理間通訊的團隊。
執行需求
需要 Node.js 20 或更新版本,喚醒終端代理還需要 tmux 3.2 或更新版本;支援 macOS 與 Linux,Windows 僅支援中繼與輪詢工具。由一部機器執行中繼。對等端需要 HOPTELL_RELAY 與必要的密鑰 HOPTELL_TOKEN,可選 HOPTELL_NAME 與 HOPTELL_ROLES。中繼需要監聽位址與權杖,可選成員檔案。
安裝前請注意
任何持有有效 HOPTELL_TOKEN 的人都能對你的代理傳訊,而以寬鬆權限執行的代理可能會據此行動。請保管好權杖,多人情境使用依成員權杖,並只在私有網路或 VPN 中執行中繼;中繼使用明文 ws://,沒有 TLS。tmux 注入會對使用中的終端輸入內容,該窗格中已輸入一半的內容會隨訊息一起送出。訊息會被標示為來自其他代理而非使用者,但這只是提示,不是沙箱。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 hoptell,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

[hoptell icon] hoptell

Let AI coding agents talk to each other: across sessions, machines, accounts and tools.

hoptell connects Claude Code, Codex, Antigravity (agy) and other MCP-capable agents through one small relay that you run yourself on your LAN or VPN. Agents get tools to list peers and send messages, and incoming messages wake idle agents up, so a Claude session on your laptop can hand a review to a Codex session on a colleague's workstation and get the answer back without anyone typing.

[Sam's Claude Code sends the contents of greet.js to Alex's Codex, which wakes up and suggests a corrected line]

Sam's Claude Code on a MacBook sends the contents of greet.js to Alex's Codex in a Linux container. Codex wakes up and returns a one-line suggested fix. Real session, played at 2.5× speed with idle pauses shortened.

 laptop:   Claude Code ──┐                        ┌── Codex        :workstation laptop:   Codex       ──┼── hoptell relay (LAN) ─┼── Claude Code  :workstation CI box:   Claude Code ──┘    one tiny process    └── ...
  • Self-hosted, no accounts. One Node process. Agents can use different Claude or OpenAI accounts. Messages between agents travel only through your relay; each agent still talks to its own AI provider as usual.
  • Wakes agents up. Claude Code with channels enabled gets a notice and reads the message; Codex (or any terminal agent) gets it pasted in through tmux; anything else can poll.
  • Teams and swarms. Agents announce roles (reviewer, backend, ...). Send to one agent by name, to every agent with a role (@reviewer), or to everyone (@all).
  • Small and auditable. About 1,200 lines of JavaScript, two dependencies (ws and the MCP SDK).

Agents can also answer questions about plans, not only code:

[Sam's Claude Code asks @pm about the demo app's 2.4 release; Dana's agent answers from planning/roadmap.md]

Sam's Claude Code asks @pm about the demo app's 2.4 release, and Dana's agent answers from planning/roadmap.md in its Linux container. Real session, played at 2.5× speed with idle pauses shortened.

hoptell moves plain text between agents that may act on it. Read Security before connecting agents that run with relaxed permissions.

How it works

PartWhat it does
hoptell relayWebSocket hub on one machine: authenticates peers, routes messages, queues messages for offline peers (in memory).
hoptell mcpMCP server each agent session runs: tools list_peers, send_message, wait_for_message, read_inbox.
hoptell tmuxRuns a terminal agent in tmux and pastes incoming messages into it, so it wakes up.
hoptell send / list / wait / listenCLI for scripts, CI jobs and agents without MCP.

How an incoming message reaches the agent:

AgentStart it withIncoming message
Claude Code (push)claude --dangerously-load-development-channels server:hoptella channel notice wakes the agent, which calls read_inbox to read the message
Claude Code (plain)claudethe MCP server asks Claude to keep a background hoptell listen running; Claude wakes when it returns
Antigravity (agy)agybackground hoptell listen, like plain Claude Code
Codex, Antigravity, or any terminal agenthoptell tmux <name> -- codexpasted into the agent's prompt
Anything else—wait_for_message / read_inbox tools, or hoptell wait

Push uses Claude Code's channels (research preview). Custom channels need the --dangerously-load-development-channels flag, and Claude Code asks you to confirm a "development channels" warning each time it starts with it. hoptell detects the flag and adapts. Set HOPTELL_PUSH=channel|listener to override the detection. Without the flag, the background listener starts after your first prompt in the session.

Quick start

Requirements: Node.js 20+, plus tmux 3.2+ to wake Codex/terminal agents. Supported on macOS and Linux; on Windows only the relay and polling tools work.

1. Install (every machine)

sh
npm install -g hoptell    # puts `hoptell` on your PATH

From source instead: git clone https://github.com/EminUZUN/hoptell && cd hoptell && npm install && npm link.

Claude Code clients can use the plugin instead of the manual MCP registration in step 4. It asks for the relay URL and token (stored in Claude Code's secure storage). The relay machine still needs the npm installation above or the Docker image. Anyone using the hoptell CLI or hoptell tmux needs the npm installation above.

Install the plugin and start Claude Code with push enabled:

/plugin marketplace add EminUZUN/hoptell/plugin install hoptell@hoptellclaude --dangerously-load-development-channels plugin:hoptell@hoptell   # with push

The relay image is ghcr.io/eminuzun/hoptell, and the server is listed in the MCP Registry as io.github.EminUZUN/hoptell.

2. Start a relay (one machine)

sh
mkdir -p ~/.config/hoptellcat > ~/.config/hoptell/.env <<EOFHOPTELL_TOKEN=$(openssl rand -hex 32)HOPTELL_HOST=192.0.2.10EOFchmod 600 ~/.config/hoptell/.envhoptell relay

Replace 192.0.2.10 with this machine's LAN or VPN address in the relay settings above. For Docker, use the same address and replace ... with your generated token: docker run -d -p 192.0.2.10:7777:7777 -e HOPTELL_TOKEN=... ghcr.io/eminuzun/hoptell. Publish the port on that address only. Without a host address, -p 7777:7777 publishes on all host addresses by default. See examples/. Health check: GET /healthz.

3. Configure each machine

Add these settings to ~/.config/hoptell/.env (chmod 600). On the relay machine, add them to the file from step 2 and keep its HOPTELL_HOST and token:

sh
HOPTELL_RELAY=ws://192.0.2.10:7777HOPTELL_TOKEN=<the same token>

Check: hoptell list should connect and print the peers (none yet).

4. Connect your agents

Claude Code: register the MCP server once (user scope, all projects):

sh
claude mcp add --scope user hoptell -- hoptell mcp

If an agent cannot find hoptell (for example with nvm), use the full path that command -v hoptell prints, here and in the configs below.

Then start Claude with push enabled:

sh
HOPTELL_NAME=laptop-claude claude --dangerously-load-development-channels server:hoptell

Inside a clone of this repo, .mcp.json registers the server for you.

Codex: add to ~/.codex/config.toml:

toml
[mcp_servers.hoptell]command = "hoptell"args = ["mcp"]tool_timeout_sec = 1800                  # wait_for_message can block up to 1500sdefault_tools_approval_mode = "approve"  # optional: no approval prompt per hoptell tool call

Then start Codex through tmux so messages wake it:

sh
hoptell tmux laptop-codex -- codex

The launcher passes the peer name to Codex as a -c override, because interactive Codex starts MCP servers from a shared daemon that does not inherit your shell's environment. Detach with Ctrl-b d, reattach with tmux attach -t hoptell-laptop-codex.

Antigravity (agy): register the MCP server once:

sh
agy mcp add hoptell hoptell mcpHOPTELL_NAME=laptop-agy agy                      # listener mode, after your first prompthoptell tmux laptop-agy --roles gemini -- agy    # or: woken through tmux

5. Try it

Ask either agent: "list hoptell peers and say hi to laptop-codex".

For organizations

hoptell has no central service: every organization runs its own relay, and agents connect from their users' machines.

  1. Run a relay inside your network: the Docker image (examples/docker-compose.yml), or the systemd unit (examples/hoptell-relay.service), behind your VPN or a TLS proxy.

  2. Issue per-member tokens with a members file (see Teams and swarms), so people cannot use each other's agent names.

  3. Roll out the client: the Claude Code plugin, or npm install -g hoptell plus the MCP config for Codex and Antigravity.

  4. Allowlist the channel (Claude Code): with managed settings your users can start claude --channels plugin:hoptell@hoptell, without the development flag and its prompt:

    json
    {  "channelsEnabled": true,  "allowedChannelPlugins": [{ "marketplace": "hoptell", "plugin": "hoptell" }]}

Teams and swarms

Names. Each agent has a peer name (HOPTELL_NAME; default <hostname>-<pid>): letters, digits, _ and -. A new connection with a name already in use replaces the old one.

Roles. HOPTELL_ROLES=reviewer,backend (or hoptell tmux <name> --roles reviewer -- codex). list_peers shows them. Sending to @reviewer reaches every online peer with that role, and @all reaches every online peer. A busy peer gets it queued behind its unconfirmed messages. Fan-out is not queued for offline peers. A direct message to a name is queued while that peer is offline (up to 50 per peer, in relay memory). Roles are labels that agents choose for themselves to route work. They are not permissions.

Many people. Give each person their own token so nobody can impersonate anyone else's agents. Create a members file on the relay (chmod 600):

json
{ "members": [    { "name": "alice", "token": "<openssl rand -hex 32>" },    { "name": "bob",   "token": "sha256:<hex sha256 of bob's token>" } ] }

Run hoptell relay --members members.json or set HOPTELL_MEMBERS. A member may only use the name <member> or names starting with <member>- (alice-claude, alice-codex-2). The relay refuses member names that overlap, such as alice and alice-bob. You can combine a members file with a shared HOPTELL_TOKEN; token holders can use any name. For separate teams, run separate relays. A relay is a single small process.

Example swarm on one machine:

sh
hoptell tmux alice-planner  --roles planner  -- claudehoptell tmux alice-codex-1  --roles backend  -- codexhoptell tmux alice-codex-2  --roles backend  -- codexhoptell tmux alice-reviewer --roles reviewer -- claude

Then tell the planner: "split the task, send backend work to @backend, and send the result to @reviewer".

Guard rails. Each connection may send at most 30 messages per 10 seconds, so two agents that keep replying to each other hit the limit instead of flooding everyone. Messages are plain text up to 100,000 characters.

CLI

hoptell relay --host <ip> [--port 7777] [--members file.json]hoptell mcphoptell tmux <name> [--roles a,b] -- <agent command...>hoptell listhoptell send <to> <message...>        # to: name, @role or @all; sends as $HOPTELL_NAME without going onlinehoptell wait [seconds]                # goes online as $HOPTELL_NAME and prints the next messagehoptell listen <name> [seconds]       # waits on <name>'s local inbox (no relay connection)

Settings come from environment variables, otherwise from the first existing file of $HOPTELL_ENV, ~/.config/hoptell/.env, <package>/.env. See .env.example. In settings files, double-quoted values decode JSON-style escapes (\", \\, \n), single-quoted values are literal, and an empty value counts as unset.

VariableUsed byMeaning
HOPTELL_RELAYpeersrelay URL, ws://host:7777 or wss:// behind TLS
HOPTELL_TOKENbothshared secret, or a member's own token
HOPTELL_NAMEpeersthis agent's peer name
HOPTELL_ROLESpeerscomma-separated roles
HOPTELL_PUSHpeerschannel or listener, overrides detection
HOPTELL_HOMEpeerslocal state directory (default ~/.hoptell)
HOPTELL_HOST, HOPTELL_PORTrelaylisten address (required) and port (default 7777)
HOPTELL_MEMBERSrelaymembers file with per-member tokens

Security

hoptell's job is to put text from one agent in front of another agent. Plan for that:

  • Anyone who holds a valid token can message your agents, and agents running with relaxed permissions (--dangerously-skip-permissions, auto-approve) may act on it. Keep tokens secret, use per-member tokens for groups, and run the relay on a private network or VPN only.
  • Messages are labeled, not trusted. Agents are told that hoptell messages come from other agents, not from their user. Message text cannot close the channel tag or forge a message boundary. That is guidance for the model, not a sandbox.
  • Use TLS outside a trusted network. The relay speaks plain ws://. Put it behind a VPN (WireGuard, Tailscale) or a TLS proxy, for example Caddy: caddy reverse-proxy --from relay.example.com --to 127.0.0.1:7777, then use HOPTELL_RELAY=wss://relay.example.com.
  • tmux injection types into a live terminal. The injector pastes only into the pane where it started the agent, never into another pane, and holds back while it recognizes an approval prompt on screen. That is best effort, based on what the screen shows; prefer agents that ask before risky actions over auto-approve modes. A message that itself looks like a prompt is never typed: the agent gets a short notice to fetch it with read_inbox. Detection errs on the side of waiting: text on screen that merely looks like a prompt (for example a quoted question the agent just printed) also holds later messages until it scrolls away. Held messages stay in the inbox; nothing is lost. Anything you have half-typed in that pane is submitted together with the message.
  • Local inboxes live in ~/.hoptell/inbox/<name>/ (0700/0600). Every message holds the sender name the relay verified.

What the hoptell MCP server does on your machine

  • Runs a local MCP server over standard input/output, hoptell mcp. The Claude Code plugin starts node ${CLAUDE_PLUGIN_ROOT}/bin/hoptell.js mcp.
  • Uses two direct runtime dependencies, ws and @modelcontextprotocol/sdk. package-lock.json records resolved dependency versions. Installing from a checkout with npm ci uses that lockfile and can download packages from the configured npm registry. The MCP server does not install dependencies at startup.
  • Loads settings from environment variables and a local settings file, when present: an explicit HOPTELL_ENV file, otherwise the first existing file of $XDG_CONFIG_HOME/hoptell/.env (default ~/.config/hoptell/.env) and <package>/.env. It also reads its package's package.json for the version.
  • Connects by WebSocket to the relay you configure. Its hello frame sends the token, peer name, roles, sanitized host name, protocol version and connection mode. It sends message destinations and text, peer-list requests and receipt acknowledgements; it receives addressed messages, peer-list metadata and protocol responses.
  • Stores incoming MCP messages before acknowledging receipt. It creates private inbox directories (0700) and message files (0600) under ~/.hoptell/inbox/<name>/ by default, or $HOPTELL_HOME/inbox/<name>/ when configured. Files are consumed and deleted by read_inbox, wait_for_message, hoptell listen or the tmux injector. Recovering abandoned inbox claims checks whether the claiming process exists with process.kill(pid, 0).
  • Inspects up to five ancestor processes with ps -o ppid=,args= -p <pid> to detect Claude Code's channel flags. This check is skipped on Windows or when HOPTELL_PUSH overrides detection.
  • In listener mode, instructs the receiving agent to run node <package>/bin/hoptell.js listen <name> as a background command when supported. That command polls and consumes the local inbox. Launching it remains subject to the receiving agent's permissions.
  • At runtime, the MCP server opens outbound WebSocket connections only to its configured relay. It has no telemetry and does not change the agent's permission settings. Dependency installation is separate from runtime; each agent still communicates with its own AI provider.

To report a vulnerability, see SECURITY.md. How hoptell handles data is described in PRIVACY.md.

Limitations

  • The relay keeps offline queues in memory; restarting the relay drops them.
  • Delivery is at least once. "Delivered" means the receiving machine stored the message in the agent's inbox or pushed it into the session, not that the agent has acted on it. A message that was not confirmed is redelivered after the receiver reconnects, so in rare cases it arrives twice. A receiver gets at most 50 unconfirmed messages; more wait in its queue.
  • Push depends on Claude Code channels (research preview); the flag name may change.
  • No built-in TLS, persistence, message history or web UI, by design: the relay stays small.

Roadmap

Ideas that fit the small-relay design, roughly in order:

  • hoptell doctor: check settings source, relay reachability, identity, delivery mode, inbox and injector
  • message expiry (TTL) and reply-to ids for request/response automation
  • token revocation and reload without restarting the relay; optional per-member send rules
  • optional on-disk queue so a relay restart keeps undelivered messages

Development

sh
npm installnpm test        # starts its own relay on a random port; tmux tests run when tmux is installed

npm run test:e2e is an opt-in end-to-end test with real agents. It starts a relay and two Docker "machines" running Claude Code, Codex and Antigravity, then checks a roll call (@all) and a baton passed through every agent across both machines. It needs Docker and agent logins (--use-local-logins copies this machine's logins into the test containers for the run; CLAUDE_CODE_OAUTH_TOKEN / OPENAI_API_KEY also work; see test/e2e/run.mjs), uses your model subscriptions, and takes a few minutes. It runs only on your machine, never in CI.

See CONTRIBUTING.md. Licensed under the Apache License 2.0.

來源:README.md,提交 45f4dda

工具

0
工具後設資料尚未被收錄。

版本歷史

1
  1. v0.1.1最新Oct 6, 2026