关于 Signal Messaging (via signal-cli)
这是一个通过现有 signal-cli 守护进程收发 Signal 消息的非官方 MCP 服务。它为 Agent 提供状态通知、提问和权限请求,并由独立订阅程序收集回复。
主要功能
- 01发送消息、问题和权限请求
- 02收集并筛选文本回复
- 03检查发送与接收状态
- 04使用现有 signal-cli 守护进程
适用场景
- 01发送任务完成通知
- 02任务受阻时询问问题
- 03执行不可逆操作前请求批准
MCP 相关
它通过 stdio 提供 MCP 服务,包含发送 Signal 消息、检查回复和健康状态的工具。可选订阅程序从现有 signal-cli 守护进程接收通知。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm -e SIGNAL_SENDER -e SIGNAL_DEFAULT_RECIPIENT -e SIGNAL_RPC_URL -e SIGNAL_TCP_HOST -e SIGNAL_TCP_PORT -e SIGNAL_INBOX_PATH -e SIGNAL_POLL_INTERVAL -e SIGNAL_INBOX_RETENTION_DAYS ghcr.io/joshuawowk/signal-mcp:1.0.1SIGNAL_SENDERE.164 number of the account registered in signal-cli (e.g. +15555550100)SIGNAL_DEFAULT_RECIPIENTE.164 number messaged by default; tools accept a per-call recipient overrideSIGNAL_RPC_URLsignal-cli HTTP JSON-RPC endpoint as seen from the container. The server's built-in default is http://127.0.0.1:8080/api/v1/rpc (use with --network host on Linux); this listing defaults to the Docker host alias.SIGNAL_TCP_HOSTsignal-cli daemon TCP host, used only for the receive-path health checkSIGNAL_TCP_PORTsignal-cli daemon TCP port (daemon started with --tcp), used only for the receive-path health checkSIGNAL_INBOX_PATHPath of the replies inbox file inside the container (populated only by the subscriber process)SIGNAL_POLL_INTERVALSubscriber poll cadence in secondsSIGNAL_INBOX_RETENTION_DAYSDays of replies kept in the inbox file本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/joshuawowk/signal-mcp:1.0.1stdio工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
signal-mcp
通过 signal-cli 使用 Signal 的非官方 MCP 集成。它可以让 MCP 客户端向你发送 Signal 消息(任务完成提醒、阻塞问题、权限请求),并读取你的回复。
要求: 一个正在运行的 signal-cli JSON-RPC 守护进程(signal-cli daemon --http ...,如果需要回复,还需添加 --tcp ...),以及一个已在 signal-cli 中注册的 Signal 电话号码。本项目不会注册号码、运行守护进程,也不会自行连接 Signal 服务器;它只是你守护进程的客户端。本项目与 Signal Messenger 和 Signal Foundation 无关,也未获得其认可。
它由一个 MCP 服务(app/server.py)和一个可选的回复订阅器(app/subscriber.py)组成,后者连接现有的 signal-cli 守护进程,无需重新注册或绑定挂载其数据目录。
安装
此镜像发布于 ghcr.io/joshuawowk/signal-mcp,并已列入 MCP Registry,名称为 io.github.joshuawowk/signal-mcp。不带参数运行时,容器会启动回复订阅器(即下方 Compose 部署使用的长期运行模式);MCP 服务需要显式启动。
通过 stdio 使用 MCP 客户端(仅发送)
docker run -i --rm \
--add-host host.docker.internal:host-gateway \
-e SIGNAL_SENDER=+15555550100 \
-e SIGNAL_DEFAULT_RECIPIENT=+15555550101 \
-e SIGNAL_RPC_URL=http://host.docker.internal:8080/api/v1/rpc \
ghcr.io/joshuawowk/signal-mcp:latest python3 /app/server.py --stdio
说明:
- 在 Linux 上,也可以使用
--network host,并省略--add-host和SIGNAL_RPC_URL设置(此时默认的127.0.0.1:8080可以连接到你的守护进程)。 - 使用桥接网络时,容器必须能够访问该守护进程。仅绑定到
127.0.0.1的守护进程无法访问。signal-cli HTTP 端点未经身份验证:请勿将其暴露在不受信任的接口上。 - 独立的 stdio 容器没有订阅器,因此不会收集回复:
signal_check_replies不会返回任何内容,且signal_health会报告接收路径处于关闭状态。如需接收回复,请使用下方的 Compose 部署。
Compose 部署(发送并接收回复)
参见设置。
架构
MCP client ──stdio──> docker exec ──> python3 /app/server.py ─┐
│ HTTP JSON-RPC
host: signal-cli-daemon.service ◀── 127.0.0.1:8080 (synchronous)─┤ (send, version)
◀── 127.0.0.1:7583 (TCP stream)─┤ (receive notifications)
│
docker container (signal-mcp, restart=unless-stopped) │
PID 1: subscriber.py ── persistent TCP socket ─────────────┘
└─> append /data/inbox.jsonl ◀── signal_check_replies reads
- 不会绑定挂载 signal-cli 数据。 容器只是主机守护进程的客户端。Signal 身份密钥不会进入容器。
- 无需重新注册。 Signal 身份保留在主机上。
- 双通道守护进程。 同步调用(发送、版本、健康状态)通过
:8080上的 HTTP 进行。收到的消息通知通过持久 TCP 套接字(:7583)流式传输。signal-cli 的内部自动接收循环会永久锁定 HTTP 守护进程的receive方法,因此 TCP 是唯一可用于接收回复的路径。 - 仅添加一个守护进程标志。 在现有的
signal-cli-daemon.serviceExecStart 中添加了--tcp 127.0.0.1:7583参数(见下方“守护进程配置”)。其他使用方的 HTTP 行为保持不变。
设置
git clone https://github.com/joshuawowk/signal-mcp && cd signal-mcp
cp .env.example .env # set SIGNAL_SENDER and SIGNAL_DEFAULT_RECIPIENT
docker compose build
docker compose up -d
docker compose logs -f signal-mcp # watch the subscriber start up
验证容器能否访问该守护进程:
docker exec signal-mcp python3 -c \
"import rpc; print(rpc.ping())"
# expected: 0.14.3
在 Claude Desktop 中注册 MCP 服务
将 claude_desktop_config.snippet.json 合并到 ~/.config/Claude/claude_desktop_config.json 的 mcpServers 下:
"signal": {
"command": "sg",
"args": ["docker", "-c", "exec docker exec -i signal-mcp python3 /app/server.py"]
}
重启 Claude Desktop。
为什么需要 sg 包装器
sg docker -c "…" 会在 docker 附加组下运行命令。当 Claude Desktop 进程是在将你的用户添加到 docker 组之前启动时,就需要这样做——现有会话会继承过期的附加组列表,导致 docker exec 返回 permission denied while trying to connect to the docker API at unix:///var/run/docker.sock,并在 Claude Desktop 的日志中显示为
write EPIPE / Server transport closed unexpectedly。
-c 字符串中的 exec 会将 sg 启动的临时 bash 替换为 docker exec 进程,因此连接关闭时,来自 Claude Desktop 的 SIGTERM/SIGPIPE 能正常传递到 MCP 服务。
如果你注销后重新登录(或重启),所有新进程都会继承 docker 组,因此严格来说不再需要这个包装器——但保留它也无妨,还能让配置在组配置可能不同的主机之间保持可移植。signal 服务会出现在 MCP 服务列表中,其工具(signal_send_message、
signal_send_question、signal_send_permission_request、
signal_check_replies、signal_health)可供任何会话使用。
安装配套技能
示例 Agent 技能位于 skill/SKILL.md(根据某个人的配置编写;请按需调整名称和措辞)。将它复制或符号链接到 Agent 的技能目录中,例如:
mkdir -p <your-skills-dir>/signal
ln -sf "$PWD/skill/SKILL.md" <your-skills-dir>/signal/SKILL.md
在 Claude 会话中进行端到端测试
Use signal_health to confirm the daemon is up, then signal_send_message
with text="signal-mcp end-to-end test from session XYZ" and
session_id="signal-mcp-test-001". Then wait 30 seconds and call
signal_check_replies with session_id="signal-mcp-test-001".
用手机回复任意内容;下一次调用 signal_check_replies 时应该会返回你的消息。
工具
| 工具 | 何时调用 |
|---|---|
signal_send_message(text, recipient?, session_id?) | 任务完成通知、供参考的更新。无需回复。 |
signal_send_question(question, options?, recipient?, session_id?) | 遇到阻碍,需要答案时。options 接受列表 ["A","B"]、JSON 数组字符串 '["A","B"]',或以换行符/逗号分隔的文本——服务器端会统一规范化。响应会回显 options_parsed。 |
signal_send_permission_request(action, context, recipient?, session_id?) | 即将执行不可逆操作时。请等待明确的 YES。 |
signal_check_replies(since?, from_recipient?, session_id?, limit?) | 轮询回复。按 session_id 筛选。 |
signal_health() | 完整健康状况:发送路径(daemon HTTP)、接收路径(TCP 端口 + 订阅进程存活状态)以及收件箱状态。只有发送和接收均正常时,ok 才为 true。收件箱为空是正常情况。出现任何故障时,先运行此工具。 |
可靠性说明(2026 年 6 月)
- 收件箱文件(
/data/inbox.jsonl)会在订阅进程启动时创建,并且不会被保留期清理删除——即使收件箱为空,也会保留为 0 字节文件。此前,当所有记录都超过保留期(14 天)后,清理会彻底删除该文件,导致signal_check_replies/signal_health看起来像是订阅进程已停止。每次调用signal_check_replies和signal_health时,也会确保文件存在。 signal_health和signal_check_replies会报告subscriber_running(扫描/proc查找subscriber.py)和receive_channel_ok(连接到 daemon 的:7583端口),以便新会话区分“尚无回复”和“接收路径故障”。signal_send_question能兼容将options列表序列化为字符串的客户端(参见工具表)。
配置(.env)
| 变量 | 含义 |
|---|---|
SIGNAL_SENDER | 已注册 signal-cli 账号的 E.164 号码。必填。 |
SIGNAL_DEFAULT_RECIPIENT | 默认发送通知的 E.164 号码。必填。 |
SIGNAL_RPC_URL | 容器中可见的 daemon 端点。默认值为 http://127.0.0.1:8080/api/v1/rpc;使用 network_mode: host 时,该地址可用。 |
SIGNAL_TCP_HOST / SIGNAL_TCP_PORT | 用于接收通知的 daemon TCP 流。默认值为 127.0.0.1 / 7583。 |
SIGNAL_POLL_INTERVAL | 订阅进程的轮询间隔(秒)。 |
SIGNAL_INBOX_RETENTION_DAYS | 在 inbox.jsonl 中保留回复的天数。 |
SIGNAL_INBOX_PATH | 容器内的收件箱文件路径。 |
运行
docker compose ps # status
docker compose logs -f signal-mcp # subscriber output
docker exec signal-mcp tail -f /data/inbox.jsonl # raw replies
docker compose restart signal-mcp # bounce the container
docker compose down # stop
如果主机守护进程重启,订阅器会在下一次轮询时重新连接(发生错误时,重试间隔最多会延长至 60 s)。
备注和限制
- 仅支持 Linux 主机。 在 macOS/Windows 的 Docker Desktop 上,
network_mode: host不起作用。要迁移到其他环境:切换到桥接网络,设置SIGNAL_RPC_URL=http://host.docker.internal:8080/api/v1/rpc,并添加extra_hosts: ["host.docker.internal:host-gateway"]。 - 通过 HTTP 守护进程轮询。 signal-cli 的 HTTP 模式不会流式传输接收事件,因此我们采用轮询。使用 WebSocket 订阅的 TCP 模式守护进程延迟会更低,但需要更改现有的守护进程服务。
- 跳过附件。 订阅器只会保存文本内容。表情回应、输入状态指示和已读回执会被忽略。
- 不会记住电话号码。 电话号码仅保存在
.env和注册代码片段中,两者都位于此项目内。
守护进程配置
此项目要求主机上的 signal-cli-daemon.service 同时提供 HTTP(用于同步调用)和 TCP(用于流式接收通知)。~/.config/systemd/user/signal-cli-daemon.service 中的单元文件应包含:
ExecStart=/usr/local/bin/signal-cli -a +15555550100 daemon --http 127.0.0.1:8080 --tcp 127.0.0.1:7583 --receive-mode on-start
应用更改:
systemctl --user daemon-reload
systemctl --user restart signal-cli-daemon.service
首次设置 signal-mcp 时,原始单元文件的备份会写在当前文件旁边,文件名后缀为 .bak.YYYYMMDD-HHMMSS。
为什么接收消息时不直接使用 HTTP?
signal-cli 的 HTTP 守护进程模式仅支持同步操作。通过 HTTP 执行 receive 总会报错 "Receive command cannot be used if messages are already being received",因为守护进程内部的接收循环拥有该队列,而 HTTP 无法传递推送事件。TCP 模式会打开一个持久的、以换行符分隔的 JSON-RPC 流,并在收到通知时推送 receive 通知;subscriber.py 使用的就是这种方式。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。