关于 signal-tools
signal-tools 为编码 Agent 提供访问 Signal 聊天、联系人、消息、文件及消息操作的能力。它支持多种 Agent 宿主,并将读取操作与需要确认的写入操作分开。
主要功能
- 01读取聊天并搜索消息
- 02列出联系人并检查号码
- 03保存收到的文件和压缩包
- 04发送文本消息和文件
- 05编辑、删除消息及添加回应
适用场景
- 01在 Signal 对话中搜索消息
- 02保存聊天收到的文件
- 03向聊天发送已批准的文件
- 04查看或修改自己发送的消息
MCP 相关
它向 MCP 宿主提供 Signal 工具,包括 Claude Code、Codex 和其他 MCP 客户端。部分宿主也可将其作为原生插件安装。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
4收录的工具列表 · 更新于 今天
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| account | string | 否 | 账户标签;省略时列出所有标签。 |
详细介绍
signal-tools
面向编码 Agent 的 Signal 工具:聊天、消息、联系人、接收的文件和发送功能。
| Harness | 交付方式 | 固定版本依据 |
|---|---|---|
| OpenCode V2 | 原生插件(npm 包,含技能) | 包中的版本 |
| OpenCode V1 | 原生插件(npm 包,不含技能) | 包中的版本 |
| Claude Code | 插件:MCP 服务和技能 | 发布标签,作为 ref |
| Codex | 插件:MCP 服务和技能 | 发布标签,作为 ref |
| Grok Build | 插件:MCP 服务和技能 | 发布标签,作为 @ref |
| Antigravity | 插件:MCP 服务和技能 | 发布标签的树 URL |
| Hermes Agent | 原生插件(Python,调用命令行) | 发布提交,作为 SHA |
| other MCP host | 来自 npm 的 MCP 服务 | 包中的版本 |
这些工具需要 Node.js 24 或更高版本。
docs/conventions.md 介绍工具的命名方式
及其行为。
安装
请从发布版本安装,切勿从默认分支安装:发布版本是一个包含构建后的 dist/ 的提交所对应的标签,而默认分支不包含该目录。在
以下命令中,<version> 是发布版本号(1.2.3),<sha> 是该标签指向的
提交:
gh api repos/craft-agent/signal-tools/commits/v<version> --jq .sha
OpenCode
OpenCode V2 在 opencode.json 中接收包及其选项:
{
"plugins": [{ "package": "@craftsamo/signal-tools@<version>", "options": { "read_only": false } }],
"permissions": [{ "action": "signal_*", "resource": "*", "effect": "ask" }]
}
OpenCode V1 接收作为字符串的包,或与其选项组成的一对:
{
"plugin": [["@craftsamo/signal-tools@<version>", { "read_only": false }]],
"permission": { "signal_*": "ask" }
}
OpenCode 允许任何不带规则名称的操作,因此除非规则设置为 ask,否则会静默批准插件的请求。
读取工具不会询问,因此 signal_* 通配符是安全的。
V1 不会注册技能。解压该包,并将其中的 skills/* 文件夹复制到
~/.config/opencode/skills/:
npm pack @craftsamo/signal-tools@<version>
tar -xzf craftsamo-signal-tools-<version>.tgz
mkdir -p ~/.config/opencode/skills
cp -r package/skills/* ~/.config/opencode/skills/
rm -rf package craftsamo-signal-tools-<version>.tgz
Claude Code
claude plugin marketplace add craft-agent/signal-tools#v<version>
claude plugin install signal-tools@craft-agent
Codex
codex plugin marketplace add craft-agent/signal-tools --ref v<version>
codex plugin add signal-tools@craft-agent
Codex 会将服务名称中的 - 转为 _,因此工具会显示为
mcp__signal_tools__signal_*。它会在插件的安装目录中启动 MCP 服务,而不是调用方的工作树目录。
Grok Build
grok plugin install craft-agent/signal-tools@v<version> --trust
Grok 会在会话的工作目录中启动 MCP 服务。
Antigravity
请从发布标签对应的树安装,切勿从默认分支安装,因为默认分支没有构建后的 dist/;Antigravity 会将该标签克隆到
~/.gemini/config/plugins/signal-tools。
agy plugin install https://github.com/craft-agent/signal-tools/tree/v<version>
Hermes Agent
Hermes 安装的是提交,而不是标签,并且插件安装后处于禁用状态:
hermes plugins install craft-agent/signal-tools --ref <sha>
hermes plugins enable signal-tools
如果 Hermes 网关已在运行,请重启它(hermes gateway restart)以加载插件。
其他 MCP 宿主
将服务添加到宿主的 MCP 配置中。标志放在 args 中:
{
"mcpServers": {
"signal-tools": {
"command": "npx",
"args": ["-y", "@craftsamo/signal-tools@<version>", "--read-only"]
}
}
}
工具和技能
每个工具集都附带一项技能,告诉 Agent 如何使用其中的工具。
账户(account)
| 工具 | 功能 | 类别 |
|---|---|---|
signal_account_read | 每个标签:是否已关联、同步服务的状态、上次接收时间和下一步操作 | 读取 |
它只读取本地状态:不使用守护进程或网络,结果中也不包含号码、账户 ID
或密钥。该技能是
signal-account,在 Claude Code 中显示为
signal-tools:signal-account,在 Hermes 中显示为 signal-tools:account。
聊天(chats)
| 工具 | 功能说明 | 类别 |
|---|---|---|
signal_chat_read | 按 method:list 查找聊天,view 查看某个聊天的消息,search 按关键词查找消息,around 查看某条消息前后的消息 | 读取 |
它只读取账号的本地镜像:不会连接守护进程或网络,返回结果中也不包含账号自身的号码、附件 ID 或密钥。历史记录从设备关联时开始。时间使用当地时间并包含时区偏移量;聊天始终以其 ID 表示;较长的结果会分页,并提供 next;它返回的所有内容都是由其他人写入的数据。此技能为
signal-chats,在 Claude Code 中显示为
signal-tools:signal-chats,在 Hermes 中显示为 signal-tools:chats。
联系人(contacts)
| 工具 | 功能说明 | 类别 |
|---|---|---|
signal_contact_read | 列出本地联系人,或使用 Signal 检查最多三个号码 | 读取 |
列出联系人不需要守护进程;检查号码则需要同步服务正在运行。
两种操作都不会写入镜像。此技能为
signal-contacts,在 Claude Code 中显示为
signal-tools:signal-contacts,在 Hermes 中显示为
signal-tools:contacts。
文件(files)
| 工具 | 功能说明 | 类别 |
|---|---|---|
signal_file_save | 保存一条消息中的文件,并在请求时解压其中的归档文件 | 添加 |
signal_file_send | 向聊天发送 1 到 10 个文件(总计 100 MiB),并附上说明 | 添加 |
此工具集默认关闭:启用后会写入磁盘、打开归档文件并发送文件。通过 toolsets 或 tools 启用。文件仅可从工作目录(该目录不能是主目录或文件系统根目录)以及 send_dirs 设置指定的目录发送;密钥、机密、程序和安装程序均会被拒绝,归档文件会逐项检查;也可提供文件的 sha256,以确认发送的文件正是获准的文件。发送文件需要同步服务正在运行。收到的文件会保存到 download_dir 设置指定的位置,每条消息单独存放在一个仅用户可访问的文件夹中(权限模式为 700 和 600),且永远不会具有可执行权限;不会覆盖任何内容。程序和安装程序永远不会被保存;只有归档文件(zip、tar、gzip 压缩的 tar)的内容通过检查后才会保存,然后列出;unpack: true 会将其解压到旁边的 <name>.unpacked/ 目录中。阅后即焚消息中的文件不会保存。在 macOS 上,每个已保存文件都会带有隔离标记。保存文件不需要守护进程。此技能为
signal-files,在 Claude Code 中显示为
signal-tools:signal-files,在 Hermes 中显示为 signal-tools:files。
发送(sends)
| 工具 | 功能说明 | 类别 |
|---|---|---|
signal_message_send | 向聊天发送一条不超过 4,000 个字符的文本,可选择引用一条消息 | add |
聊天始终以其 ID 标识;用户自己的账号 ID 对应“Note to Self”,而用户已退出的群组会被拒绝。结果表示 Signal 已接受消息;对于群组,结果会包含 reached 和 not_reached。请求发出后出现的任何其他失败都属于 uncertain:再次发送前请检查手机。消息会记录到镜像中,若记录失败,会列在 errors 下,但不会撤销发送。此工具需要同步服务正在运行。对应的技能是
signal-sends,在 Claude Code 中显示为
signal-tools:signal-sends,在 Hermes 中显示为 signal-tools:sends。
操作(actions)
| 工具 | 功能说明 | 类别 |
|---|---|---|
signal_message_edit | 替换用户自己一条消息的文本 | overwrite |
signal_message_delete | 为所有人删除用户自己的一条消息;此操作无法撤销 | administrative |
signal_message_react | 设置、替换或移除用户对一条消息的表情回应 | overwrite |
默认情况下,此工具集处于关闭状态:这些操作会更改其他人已读过的内容。使用 toolsets 或 tools 将其启用。编辑和删除仅适用于用户自己发送的消息,且须在发送后 24 小时内进行;一条消息最多可编辑 10 次,且只有文本消息可以编辑。回应可以针对任意消息,每人只能设置一个,因此新回应会替换用户之前的回应。操作结果与发送相同:结果表示 Signal 已接受操作;对于群组,结果会包含 reached 和 not_reached。请求发出后出现的任何其他失败都属于 uncertain:重复操作前请检查手机。每项操作都会记录到镜像中,就像同步服务从另一台设备记录该操作一样;若记录失败,会列在 errors 下。工具不会发送已读回执或正在输入提示。此工具需要同步服务正在运行。对应的技能是
signal-actions,在 Claude Code 中显示为 signal-tools:signal-actions,在 Hermes 中显示为 signal-tools:actions。
添加工具
- 使用
defineTool在src/core/<domain>/<verb>.ts中编写规范:包含 ID<prefix>_<domain>_<verb>、标题和描述、Zod 参数和输出架构、所属工具集和写入类别,以及execute(args, context)。 写入工具还需提供targets(args, context),用于指明调用会写入的目标,权限规则应以此目标命名。 - 在规范文件旁边编写测试(
<verb>.test.ts),像各入口点一样通过invoke调用工具。运行程序的工具需使用PATH中该程序的模拟版本进行测试;任何测试都不会访问真实服务。 - 在
src/tools.ts中列出该工具。新工具集需加入src/project.ts中的toolsets(若默认启用,也要加入defaultToolsets)。 - 添加或更新该工具集的技能文件:
skills/<prefix>-<toolset>/SKILL.md。 - 运行
pnpm run build && pnpm run manifests,将工具列入plugin.yaml,然后在“工具和技能”下对其进行介绍。
docs/conventions.md 列出了每个步骤所遵循的规则。
读取和写入
每个读取工具都命名为 <prefix>_<domain>_read。读取操作可以在未经询问的情况下运行;写入操作由执行环境确认。
| 执行环境 | 无需询问即可读取 |
|---|---|
| OpenCode | 始终如此;插件只会在写入前询问 |
| Claude Code | ~/.claude/settings.json 中 permissions.allow 里的规则 mcp__plugin_signal-tools_signal-tools__*_read |
| Codex | 始终如此;Codex 会在未经询问的情况下运行声明了 readOnlyHint 的工具,读取工具正是如此 |
| Grok Build | grok --allow 'MCPTool(signal-tools__*_read)' --allow 'MCPTool(signal_*_read)'(两条规则;见下文) |
| Antigravity | permissions.allow 中的规则 mcp(signal-tools_signal-tools/<tool id>),每个读取工具各一条 |
| Hermes | 始终如此;插件只会在写入前询问 |
关于何时会询问写入操作,以及何时不会:
- OpenCode 不使用规则名称就会批准任何操作,因此除非有规则要求确认,否则写入操作会在未经询问的情况下运行:添加 OpenCode 下所示的
signal_*规则。 - 在
codex exec下的 Codex 和grok -p下的 Grok Build,会拒绝无法询问用户的写入操作,除非事先已允许该操作。 - Grok Build 通过其
use_tool工具调用插件的工具,而且 Agent 往往会先报出不带服务端名称的工具名称。Grok 会根据给出的名称检查规则,因此仅有带服务端名称的规则无法匹配首次调用。第二条规则会匹配简短名称;写入操作仍不会匹配任何一条规则。 - Antigravity 会在任何不被规则允许的 MCP 工具运行前询问,包括读取工具;它将插件的服务端命名为
signal-tools_signal-tools(先是插件,再是服务端)。agy -p会拒绝无法询问用户的工具。 - Hermes
hermes chat -q会拒绝无法询问用户的写入操作;hermes -z和--yolo会跳过批准,因此写入操作会在未经询问的情况下运行。
设置
每个入口点都采用相同的设置。标志的优先级高于其环境变量,选项或设置的优先级也高于变量。
| 设置 | 标志 | 变量 | 含义 |
|---|---|---|---|
toolsets | --toolsets | SIGNAL_TOOLS_TOOLSETS | 启用的工具集,或 all;默认启用 src/project.ts 中列出的名称 |
read_only | --read-only | SIGNAL_TOOLS_READ_ONLY | 不注册任何会写入的工具;优先级高于所有其他设置 |
tools | --tools | SIGNAL_TOOLS_TOOLS | 按 ID 添加单个工具,无论它们属于哪个工具集 |
exclude_tools | --exclude-tools | SIGNAL_TOOLS_EXCLUDE_TOOLS | 按 ID 移除单个工具;优先级高于 tools 和 toolsets |
confirm | --confirm | SIGNAL_TOOLS_CONFIRM | 仅适用于 MCP 服务:按约定使用 harness(默认)或 elicitation |
state_dir | --state-dir | SIGNAL_TOOLS_STATE_DIR | 各标签的状态存放位置;默认值为 $XDG_STATE_HOME/signal-tools |
download_dir | --download-dir | SIGNAL_TOOLS_DOWNLOAD_DIR | 接收的文件保存位置;默认值为 ~/Downloads/signal-tools |
send_dirs | --send-dirs | SIGNAL_TOOLS_SEND_DIRS | 除工作目录外,允许发送文件的目录 |
标志或变量中的列表以逗号分隔。各个宿主如何读取这些设置:
-
OpenCode 使用上文所示的插件
options,列表采用数组,read_only采用布尔值,state_dir和download_dir采用路径,send_dirs采用路径数组;如果未设置,则回退到变量。V2 在后台服务中运行插件,该服务会保留启动时的环境:在opencode run启动时设置的变量,要等到在该环境中重启服务后才会生效(opencode service restart)。V1 在自己的进程中运行插件。 -
Hermes 在
config.yaml中使用plugins.entries.signal-tools.settings:plugins: entries: signal-tools: settings: read_only: false exclude_tools: []插件会将自己的环境传递给它运行的命令行,因此变量也有效。正在运行的网关会保留启动时的环境;更改变量后,请重启网关(
hermes gateway restart)。 -
Claude Code、Grok Build 和 Antigravity 启动插件的服务时不带标志,并传递客户端的环境,因此请在宿主运行时所处的环境中设置变量。
-
Codex 只会向插件的 MCP 服务传递少数基本变量(例如
PATH和HOME),以及插件清单中列出的变量,也就是上文的变量:请在 Codex 运行时所处的环境中设置它们。若要传递标志,或向服务提供所需的其他变量,请在 Codex 的config.toml中将服务添加到[mcp_servers],而不是使用插件:标志放在args中,env_vars用于指定要从 Codex 环境转发的变量名称,env用于设置固定值。[mcp_servers.signal-tools] command = "npx" args = ["-y", "@craftsamo/signal-tools@<version>", "--read-only"] env_vars = ["SIGNAL_TOOLS_STATE_DIR"]
账户和同步服务
这些工具通过 signal-cli 将 Signal 账户作为用户手机的关联设备使用,方式与 Signal Desktop 相同。你需要自行安装 signal-cli。它们绝不会读取其他客户端的数据。
- 每台关联设备都有一个标签,由 1 至 24 个小写字母、数字和
_组成(关联时未命名则为default)。工具的account参数用于选择标签;仅关联了一台设备时可省略。 - 每个标签将其状态保存在一个目录中,即
<state_dir>/<label>/(权限模式为 700):其中包含 signal-cli 的数据和密钥、守护进程的套接字、收到的消息镜像,以及正在发送的文件副本。state_dir默认为$XDG_STATE_HOME/signal-tools,或~/.local/state/signal-tools。请勿将其纳入你要共享的备份:其中的密钥可让工具以你的身份读取和发送消息。 - 同步服务会为每个标签接收消息并保存其镜像,读取工具只读取镜像。历史记录从设备关联时开始;服务停机期间收到的消息会暂存在 Signal 服务器上,保留时长取决于 Signal 对未送达消息的保留策略。
- Signal 会取消 45 天未使用设备的关联;如果手机离线 30 天,则会取消所有关联设备的关联。运行中的服务会让设备保持使用状态。标签取消关联后,可通过手机重新关联。
- signal-cli 发行版本会过期。 超过大约三个月的版本可能无法继续与 Signal 服务器通信,因此请及时更新。
关联设备并运行同步服务
这些工具已通过 signal-cli 0.14 测试。请先安装:macOS 上运行 brew install signal-cli;其他平台请使用发行版本(JVM 构建需要 Java 25 或更高版本)。支持 macOS 和 Linux;Windows 支持情况见 #11。
# Link: on the phone, Signal > Settings > Linked devices > Link new device,
# then scan the code this prints.
signal-tools-cli link --account work
# Start receiving at logon, and restart after a failure.
signal-tools-cli service install --account work
signal-tools-cli service status --account work
仅有一个标签时可省略 --account(link 会将新标签命名为 default),并且每条命令都像这些工具一样支持 --state-dir。
| 命令 | 功能 |
|---|---|
link [--account <label>] [--device-name <n>] | 将此机器关联为手机的一台设备,并显示要扫描的代码;--show-uri 还会打印该代码对应的地址 |
sync [--account <label>] | 在前台运行同步服务,将日志输出到标准错误,直到服务停止 |
service install | uninstall | status | 将同步服务注册为 launchd 代理(macOS)或 systemd 用户单元(Linux)、移除服务,或报告服务状态 |
remove --account <label> [--yes] | 卸载服务并删除该标签的密钥、signal-cli 数据、历史记录和服务日志;删除前需重新输入标签 |
- 服务会记录此软件包的路径,因此更新软件包后请再次运行
service install。在 macOS 上,日志位于~/Library/Logs/io.github.craft-agent.signal-tools/<label>.log;在 Linux 上,可通过service status查看journalctl --user -u <unit>,而loginctl enable-linger可使服务在你注销后继续运行。 - 一部手机最多可关联五台设备,每个标签对应其中一台设备。
- 移除标签不会在手机上取消关联:关联设备无法自行取消关联,因此还需前往“设置”>“关联设备”将其移除。
- Signal 取消标签关联后,可重新关联:再次运行
link,旧密钥会移至其他位置,历史记录则会保留,前提是手机仍使用同一个账户。不同账户需要使用各自的标签。 signal_account_read会告知 Agent 标签需要执行上述哪些步骤。
布局
src/project.ts— 软件包的名称、工具 ID 前缀、设置前缀和工具集。src/core/— 工具契约和工具,不依赖任何运行框架,也不包含项目名称。src/tools.ts— 每个入口点都会注册的所有工具列表。src/mcp/— MCP 服务,构建为dist/mcp.js,并由signal-tools运行。src/opencode/— OpenCode 插件,构建为dist/opencode.js。src/cli/— Hermes 插件调用的命令行程序,构建为dist/cli.js,并由signal-tools-cli运行。src/hermes/、plugin.yaml和__init__.py— Hermes 插件。skills/— 每个工具集对应一个技能,路径为skills/<name>/SKILL.md;所有支持技能的运行框架都会从软件包或插件根目录加载这些技能。.claude-plugin/、.codex-plugin/、.agents/plugins/、.mcp.json、.antigravity-plugin/和mcp_config.json— 其他运行框架的插件清单。Codex 会读取.codex-plugin/plugin.json;根目录中的plugin.json会使其将插件作为 Agent Plugin 加载,其工具数量限制会隐藏超出固定上限的工具。根目录中的.mcp.json是 Grok Build 读取的配置(其中的${CLAUDE_PLUGIN_ROOT}是 Grok Build 和 Claude Code 都会展开的变量);在 Claude Code 中处理此代码库时,请拒绝它根据该文件提供的项目 MCP 服务。
发布流程见 RELEASING.md。
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。