
Signal Messaging (via signal-cli)
io.github.joshuawowk由 GitHub 账号 joshuawowk 发布v1.0.1更新于 Oct 26, 2026
Send Signal messages and read replies through your own signal-cli JSON-RPC daemon (unofficial).
概览
非官方 MCP 服务器,通过自建的 signal-cli 守护进程发送 Signal 消息并读取回复,让助手能通知你或向你提问。
- 可以做什么
- 向指定收件人发送 Signal 消息,可带会话标识用于任务完成提醒和进度通知
- 发送带选项的问题并等待回复
- 在执行不可逆操作前发送授权请求,等待明确同意
- 按会话、发件人或时间筛选轮询回复收件箱
- 检查发送通道、接收通道和收件箱的健康状态
- 适用场景
- 适合希望在本机运行的助手通过 Signal 主动联系你的场景:长任务完成时通知、遇到阻塞时提问、或在执行不可逆操作前请求批准。适合已经用 signal-cli 注册了号码的用户。
- 运行要求
- 需要本地 Docker 容器(镜像发布在 ghcr.io)以及已运行且已注册号码的 signal-cli JSON-RPC 守护进程;本项目不负责注册号码或启动守护进程。必填环境变量 SIGNAL_SENDER 和 SIGNAL_DEFAULT_RECIPIENT;SIGNAL_RPC_URL、SIGNAL_TCP_HOST、SIGNAL_TCP_PORT 用于指向守护进程。接收回复需使用带订阅进程的 Compose 部署;README 说明主要面向 Linux 主机网络。
安装
在 SourceWeft 中
- 打开 控制台中的 Signal Messaging (via signal-cli),将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
signal-mcp
An unofficial MCP integration for Signal via signal-cli. It lets an MCP client send you Signal messages (task-done pings, blocking questions, permission requests) and read your replies.
Requirements: a running signal-cli JSON-RPC daemon (signal-cli daemon --http ..., plus --tcp ... if you want replies) and a Signal phone number
already registered with signal-cli. This project does not register numbers, run
the daemon, or talk to Signal's servers itself; it is only a client of your
daemon. It is not affiliated with or endorsed by Signal Messenger or the Signal
Foundation.
It consists of an MCP server (app/server.py) and an optional reply
subscriber (app/subscriber.py) that fronts the existing signal-cli daemon
without re-registering or bind-mounting its data directory.
Install
The image is published at ghcr.io/joshuawowk/signal-mcp and listed in the
MCP Registry as
io.github.joshuawowk/signal-mcp. Run with no arguments, the container starts
the reply subscriber (the long-running mode used by the Compose deployment
below); the MCP server is started explicitly.
MCP client over stdio (send-only)
Notes:
- On Linux you can instead use
--network hostand drop the--add-hostandSIGNAL_RPC_URLsettings (the default127.0.0.1:8080then reaches your daemon). - With a bridge network the daemon must be reachable from the container. A
daemon bound only to
127.0.0.1is not. The signal-cli HTTP endpoint is unauthenticated: do not expose it beyond a trusted interface. - A standalone stdio container has no subscriber, so replies are not collected:
signal_check_repliesreturns nothing andsignal_healthreports the receive path as down. For replies, use the Compose deployment below.
Compose deployment (send and receive replies)
See Setup.
Architecture
- No bind-mount of signal-cli data. The container is purely a client of the host daemon. Signal identity keys never enter the container.
- No re-registration. The Signal identity stays on the host.
- Two-channel daemon. Synchronous calls (send, version, health)
go over HTTP on
:8080. Incoming-message notifications stream over a persistent TCP socket on:7583. The HTTP daemon'sreceivemethod is permanently locked by signal-cli's internal auto-receive loop, so TCP is the only path that works for replies. - One daemon flag added. The
--tcp 127.0.0.1:7583arg was added to the existingsignal-cli-daemon.serviceExecStart (see "Daemon configuration" below). HTTP behavior for any other consumer is unchanged.
Setup
Verify the daemon is reachable from the container:
Register the MCP server with Claude Desktop
Merge claude_desktop_config.snippet.json into
~/.config/Claude/claude_desktop_config.json under mcpServers:
Restart Claude Desktop.
Why the sg wrapper
sg docker -c "…" runs the command under the docker supplementary
group. This is required when the Claude Desktop process was started
before your user was added to the docker group — existing sessions
inherit a stale supplementary-group list and docker exec returns
permission denied while trying to connect to the docker API at unix:///var/run/docker.sock, which surfaces in Claude Desktop's logs
as write EPIPE / Server transport closed unexpectedly.
The exec inside the -c string replaces the temporary bash spawned
by sg with the docker exec process, so SIGTERM/SIGPIPE from Claude
Desktop reach the MCP server cleanly when the connection closes.
If you log out + back in (or reboot), all new processes inherit the
docker group and the wrapper isn't strictly needed — but it's
harmless to keep, and it makes the config portable across hosts where
the group situation may vary. The signal server will appear in the
MCP server list and its tools (signal_send_message,
signal_send_question, signal_send_permission_request,
signal_check_replies, signal_health) become available to any
session.
Install the companion skill
An example agent skill lives in skill/SKILL.md (written for one person's
setup; adapt the name and wording). Copy or symlink it into your agent's
skills directory, for example:
End-to-end test from a Claude session
Reply with anything from your phone; the next signal_check_replies call
should return your message.
Tools
Reliability notes (Jun 2026)
- The inbox file (
/data/inbox.jsonl) is created at subscriber startup and is never deleted by retention pruning — an empty inbox stays as a 0-byte file. Previously, pruning removed the file entirely once all records aged out (14-day retention), which madesignal_check_replies/signal_healthlook like the subscriber was down.signal_check_repliesandsignal_healthalso ensure the file exists on every call. signal_healthandsignal_check_repliesreportsubscriber_running(scans/procforsubscriber.py) andreceive_channel_ok(TCP connect to the daemon's:7583), so a fresh session can distinguish "no replies yet" from "receive path broken".signal_send_questiontolerates clients that serialize theoptionslist into a string (see tools table).
Config (.env)
Operational
If the host daemon is restarted, the subscriber will reconnect on its next poll (errors back off up to 60 s).
Notes & limitations
- Linux host only.
network_mode: hostis a no-op on Docker Desktop for macOS/Windows. To move it: switch to a bridge network, setSIGNAL_RPC_URL=http://host.docker.internal:8080/api/v1/rpc, and addextra_hosts: ["host.docker.internal:host-gateway"]. - HTTP daemon polling. signal-cli's HTTP mode does not stream receive events; we poll. A TCP-mode daemon with WebSocket subscription would be lower-latency, but would require changing your existing daemon service.
- Attachments are skipped. The subscriber only persists text bodies. Reactions, typing indicators, and read receipts are ignored.
- The phone number is not memorized. It lives only in
.envand the registration snippet, both inside this project.
Daemon configuration
This project requires the host's signal-cli-daemon.service to expose
both HTTP (for synchronous calls) and TCP (for streaming receive
notifications). The unit file at
~/.config/systemd/user/signal-cli-daemon.service should have:
To apply changes:
A backup of the original unit file is written next to the live one
with a .bak.YYYYMMDD-HHMMSS suffix the first time signal-mcp is set
up.
Why not just use HTTP for receive?
signal-cli's HTTP daemon mode is synchronous-only. receive over
HTTP always errors with "Receive command cannot be used if messages are already being received" because the daemon's internal receive
loop owns the queue and HTTP has no way to deliver push events. TCP
mode opens a persistent newline-delimited JSON-RPC stream and pushes
receive notifications as they arrive — that's the path
subscriber.py uses.
来源:README.md,提交 7a77027
工具
0版本历史
1- v1.0.1最新Oct 20, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分