🔔 Audio notifications · 🗣️ Text-to-speech with per-agent voices · 🔌 MCP integration
💬 Message stream · 🤝 Agent-to-agent conversations · 👁️ Multi-window watch mode
📦 App & CI notifications · 🔄 Sequential queue · ⌨️ Remote keyboard controls
📑 目录
- 💻 命令行界面 - 🔌 MCP集成(Cursor AI) - 🌐 HTTP API - ⚙️ 程序化使用
- 📊 应用程序日志级别 - 🎚️ 日志级别配置
- 📋 控制台日志格式 - 🗣️ TTS口语顺序 - 🤖 零代理人公约
- ⏳ 轮流协议
- 🗺️ 语音地图
✨ 特性
- 🎵 音频通知 -为不同的通知类型播放不同的声音
- 🗣️ 文本转语音 -使用macOS发出通知消息
say命令 - 🎙️ 多智能体语音系统 -每个代理角色或编号都有不同的TTS语音
- 📂 项目标识 -标识通知来自哪个项目/工作区
- 🎨 视觉反馈 -使用带有表情符号的元数据和暗淡的消息文本清理控制台输出
- 🔌 MCP集成 -与Cursor AI和其他MCP兼容工具无缝协作
- 📦 应用程序通知 -构建工具、CI脚本和部署管道可以触发通知
- 🔄 通知队列 -顺序播放——通知从不重叠
- 💬 消息流 -具有增量轮询和回放跟踪的持久消息存储
- 🤝 代理对话 -编排器驱动的代理到代理音频对话,包括轮流
- 🌐 Web用户界面 -手机友好的仪表板
localhost:8881带有暗/亮主题切换 - 📲 Web推送通知 -通过服务工作器发送本地操作系统通知,即使浏览器关闭(需要
localhost或HTTPS) - 🧑💻 操作员消息 -通过web UI或API向代理发送人在环消息
- 📊 日志级别 -应用程序通知的可配置音频阈值(控制台始终显示所有内容)
- ⌨️ 键盘控制 -空格键停止所有,S跳过当前,M静音所有音频
- 👁️ 观看模式 -仅显示镜像通知而不播放音频的面板
- 🔗 同步控件 -通过远程控制端点在所有面板上静音、停止和跳过同步
- 🌐 HTTP API -用于外部集成的RESTful端点
- 💾 磁盘持久性 -消息存储在服务器重启后仍然存在
🏗️ 建筑
Agent (MCP) ──▶ MCP tool "notify" ──▶ HTTP /notify/agent ──┐
├──▶ message store ──▶ notification queue ──▶ sequential playback
Agent (HTTP/CLI) ──▶ HTTP /notify/agent ──────────────────────────┤
│
App (HTTP/CLI) ──▶ HTTP /notify/app ────────────────────────────┘
Agent (MCP) ──▶ MCP tool "get_messages" ──▶ HTTP /messages ──▶ message store (read)
Agent (MCP) ──▶ MCP tool "check_message_status" ──▶ HTTP /messages/status ──▶ counters only (read)
Agent (MCP) ──▶ MCP tool "check_responses_available" ──▶ HTTP /responses/available/for/id/:id ──▶ message store (count)
Agent (MCP) ──▶ MCP tool "check_responses_observed" ──▶ HTTP /responses/observed/for/id/:id ──▶ message store (count)/notify/agent--用于所有AI代理通知(MCP、HTTP或CLI)。始终播放音频并记录到控制台。/notify/app--用于所有应用程序通知(HTTP或CLI)。受日志级别阈值的限制。/messages--查询持久消息流。支持增量轮询和回放跟踪。/responses/available/for/id/:id--计数对消息的响应(总线模式,~5个令牌)/responses/observed/for/id/:id--统计观察到的响应(对话模式,约5个标记)- 五个MCP工具 —
notify,get_messages,check_message_status,check_responses_available,check_responses_observed. - 一个CLI —
notify命令。如果--app旗帜存在→/notify/app否则→/notify/agent. - 一个队列 --两个端点都馈入同一FIFO队列。顺序播放,无重叠。
- 一个消息存储 --每个通知都会被持久化。服务器重启后仍然有效。
🔔 通知类型
🤖 代理类型
| 类型 | 表情符号 | 描述 | 用例 |
|---|---|---|---|
done | ✅ | 任务完成 | 操作成功 |
error | ❌ | 发生错误 | 操作失败 |
question | ❓ | 需要用户输入 | 等待决策 |
permission | 🔐 | 需要授权 | 需要用户批准 |
status | 📡 | 进度更新 | 正在进行的操作 |
waiting | ⏳ | 处理 | 长时间运行的任务 |
review | 👁️ | 需要代码审查 | 文件更改准备就绪 |
message | 💬 | Agent对话 | Agent对Agent对话 |
📦 应用程序日志级别
| 级别 | 表情符号 | 声音 | 用例 |
|---|---|---|---|
debug | 🐛 | *(无)* | 详细的调试信息 |
info | ℹ️ | status.mp3 | 一般信息、进度更新 |
warn | ⚠️ | waiting.mp3 | 警告、弃用、非关键问题 |
error | ❌ | error.mp3 | 故障、崩溃、严重问题 |
success | ✅ | done.mp3 | 构建完成,测试通过,部署完成 |
📥 安装
# Clone the repository
git clone
cd agent-notify
# Install globally
npm install -g
# Link globally for customization
npm link⚙️ 配置
🌐 服务器连接URL
默认情况下,通知客户端(CLI和MCP)连接到 http://localhost:8881。要使用其他服务器地址,请设置 AGENT_NOTIFY_URL 环境变量。
用于CLI使用
# Set for current shell session
export AGENT_NOTIFY_URL="http://192.168.0.6:8881"
notify done "Task complete"
# Set for single command
AGENT_NOTIFY_URL="http://192.168.0.6:8881" notify done "Task complete"
# Add to ~/.bashrc or ~/.zshrc for persistence
echo 'export AGENT_NOTIFY_URL="http://192.168.0.6:8881"' >> ~/.bashrc用于MCP(光标)使用
添加 env 阻止您的光标 settings.json:
{
"mcpServers": {
"agent-notify": {
"command": "notify-mcp",
"env": {
"AGENT_NOTIFY_URL": "http://192.168.0.6:8881"
}
}
}
}查找服务器的IP地址
# macOS
ipconfig getifaddr en0 # WiFi
ipconfig getifaddr en1 # Ethernet
# Linux
hostname -I
# The server prints its address on startup:
# 📡 Listening on http://0.0.0.0:8881故障排除
| 问题 | 解决方案 |
|---|---|
| 连接被拒绝 | 检查服务器是否正在运行(npm start)URL是正确的 |
| 错误的IP地址 | 使用上面的命令查找服务器的IP,然后设置 AGENT_NOTIFY_URL |
| 端口已在使用中 | 服务器自动切换到 监视模式。或使用其他端口: node lib/server.mjs --address 0.0.0.0:9000 |
| 跨机器访问 | 确保服务器使用 0.0.0.0 (默认)不 localhost |
🔗 通知链接(仅限应用程序)
应用程序通知可以包括一个可选的可点击链接(例如,指向CI构建、部署仪表板或健康检查端点)。该链接在服务器终端输出中显示为第三行 不 通过TTS进行交流。
安全说明: 链接被故意从代理通知中排除。AI代理是不受信任的URL源——允许模型注入任意可点击的URL会创建钓鱼/恶意链接界面。链接仅适用于来自用户控制代码的应用程序通知。
CLI使用情况
# Attach a dashboard link
notify success "Deploy complete" --app my-api --link https://my-api.example.com/health
# Attach a CI build link
notify error "Build failed" --app github-actions --link https://github.com/user/repo/actions/runs/12345
# Links are optional
notify info "Starting deploy..." --app deployHTTP API使用情况
curl "http://localhost:8881/notify/app?type=success&message=Deploy%20complete&app=my-api&url=https://my-api.example.com/health"服务器终端输出
✅ SUCCESS 📦 my-api
"Deploy complete"
🔗 https://my-api.example.com/health在大多数终端(iTerm2、VS Code终端、Hyper等)中,URL都是可自动点击的。
🚀 用法
💻 命令行界面
# Agent notification (type and message only)
notify done "Task completed successfully"
notify error "Something went wrong"
notify question "Do you want to continue?"
# Agent with project identification
notify done "Build complete" --workspace-dir /Users/user/repos/my-app
# Agent multi-agent (orchestrator)
notify done "All tasks complete" --workspace-dir /Users/user/repos/my-app --agent-role Orchestrator --agent-number 0
# Agent subagent with full context
notify done "Build complete" --workspace-dir /Users/user/repos/my-app --agent-role Coder --agent-number 2 --model claude-4.6-sonnet
# Agent override TTS voice
notify status "Processing..." --voice Nathan
# App notification
notify success "Build complete" --app webpack
notify error "3 tests failed" --app jest
notify info "Starting deploy..." --app deploy
notify debug "Cache hit ratio 95%" --app webpack🏁 CLI标志
| 标志 | HTTP查询参数 | 描述 |
|---|---|---|
| *(位置1)* | type | 通知类型或应用程序日志级别(必需) |
| *(位置2)* | message | 消息文本(必填) |
--workspace-dir | workspaceDir | 完整工作区路径--从最后一个段派生的项目名称(仅限代理通知) |
--agent-role | agentRole | 代理角色名称(例如“Coder”、“Orchestrator”)(仅代理通知) |
--agent-number | agentNumber | 代理编号(编排器=0,子代理=1、2、3…)(仅代理通知) |
--voice | voice | TTS语音超控 |
--model | model | 您的确切型号标识符(例如,“claude-4.6-opus-high”)(仅限代理通知) |
--app | app | 应用程序名称--路由到 /notify/app 端点 |
--project | project | 项目名称(仅应用通知) |
--detail | detail | 简短的上下文信息,例如文件路径或计数(仅限应用通知) |
--link | url | 将可点击的链接附加到应用通知(仅应用通知,不口头通知) |
🔌 MCP集成(Cursor AI)
添加到光标设置(settings.json):
{
"mcpServers": {
"agent-notify": {
"command": "notify-mcp"
}
}
}然后配置通知规则:
选项1:项目特定 -从以下位置复制规则 .cursorrules 到你的项目 .cursorrules 文件
选项2:全球 -从以下位置添加规则 .cursorrules 全球范围内: Settings > Rules & Commands > Add 在所有项目中使用
📝 MCP工具架构
mcp_agent-notify_notify({
type: "done", // Required: notification type
message: "Build complete", // Required: message text
workspaceDir: "/Users/user/repos/my-app", // Optional: Workspace Path from
agentRole: "Coder", // Optional: agent role name
agentNumber: 2, // Optional: agent number (0 = orchestrator)
voice: "Nathan", // Optional: TTS voice override
model: "claude-4.6-sonnet", // Required: exact model identifier (console log only)
to: "Reviewer", // Optional: recipient for agent conversations
response_to: 225 // Optional: message ID this is a reply to
})注: MCP工具仅供代理商使用。应用程序通知应使用CLI(--app 标志)或HTTP API(/notify/app)直接。
📋 MCP参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | 是 | 通知类型:问题、权限、已完成、错误、状态、等待、审核、消息 |
message | string | 是 | 要发声的消息 |
workspaceDir | string | 否 | 工作区路径 ``。用于标识此通知来自哪个项目。 |
agentRole | string | 否 | 编排器分配的代理角色名称(例如,“Coder”、“Reviewer”)。编排器本身应使用“编排器”。 |
agentNumber | integer | 否 | 编排器分配的代理编号。编排器=0,子代理=1、2、3等。 |
voice | string | 否 | 覆盖此通知的TTS语音。如果省略,服务器将根据agentRole或agentNumber选择语音。 |
model | string | Yes | 系统信息中显示的确切型号标识符(例如,“claude-4.6-opus-high”、“gpt-4o-2025-03”)。仅控制台日志。 |
to | string | 否 | 此消息指向的代理角色或名称(例如,“审阅者”、“编码者”)。用于代理之间的对话。仅显示/筛选--不路由消息。 |
response_to | integer | 否 | 这是一个回复的消息ID。通过启用轻量级响应轮询 check_responses_available 和 check_responses_observed. |
📬 主控程序 get_messages 工具
轮询持久消息流以获取通知。支持通过以下方式进行增量轮询 since_id.
mcp_agent-notify_get_messages({
since_id: 42, // Optional: only messages after this ID (0 for initial fetch)
limit: 50, // Optional: max messages to return (default 50, max 200)
type: "message", // Optional: filter by notification type
to: "Coder", // Optional: filter by recipient
project: "my-app", // Optional: filter by project name
source: "agent", // Optional: filter by source ("agent" or "app")
agentRole: "Reviewer", // Optional: filter by agent role
agentNumber: 2, // Optional: filter by agent number
model: "claude-opus", // Optional: filter by model
voice: "Samantha", // Optional: filter by TTS voice
app: "webpack" // Optional: filter by app name
})答复:
{
"messages": [
{
"id": 47,
"timestamp": "2025-03-01T04:40:07.000Z",
"prevHash": "a3f2c1e809b7d4f2",
"source": "agent",
"type": "message",
"message": "Build complete",
"project": "my-app",
"agentRole": "Coder",
"agentNumber": 1,
"model": "claude-opus-4-6",
"voice": "Nathan",
"to": "Reviewer"
}
],
"latest_id": 47,
"last_played_id": 47
}latest_id--存储中的最高消息ID(用作since_id下一次投票)last_played_id--音频已播放完毕的最高消息ID(来源于内部播放的事件)- 玩过的事件(
type: "played")从结果中过滤掉——它们是内部簿记
⚡ 主控程序 check_message_status 工具
总是使用 check_message_status 用于轮流投票和回放轮询——切勿使用 get_messages 为了这个。 返回约30个令牌,而不是约400-600个,在对话中节省了数千个令牌。
mcp_agent-notify_check_message_status({
since_id: 46 // Optional: check for messages newer than this ID
})答复:
{
"latest_id": 47,
"last_played_id": 45,
"muted": false,
"has_new": true,
"queue_length": 2,
"agents": [
{
"project": "my-app",
"agentRole": "Coder",
"agentNumber": 1,
"model": "claude-opus-4-6",
"voice": "Nathan",
"to": "Reviewer",
"latestId": 47,
"played": false
}
]
}latest_id--存储中的最高消息IDlast_played_id--音频已播放完毕的最高消息IDhas_new--如果为真latest_id > since_idqueue_length--音频队列中等待的通知数agents--自那以后发布的一系列重复数据消除的代理since_id每个代理都由复合密钥标识project + agentRole + agentNumber.字段model,voice,以及to反映代理的最新消息。latestId是该消息的ID,以及played如果其音频已结束,则为真。
仅限使用 get_messages 当你需要实际的消息内容时。
⚡ 主控程序 check_responses_available 工具
检查是否已向特定消息发送任何响应。返回计数。用于 总线模式轮询 --你只需要知道是否存在回复,不管人类是否听到了。
mcp_agent-notify_check_responses_available({
id: 225 // Required: the message ID to check for responses to
})答复: {"n":1} (~5个代币)
⚡ 主控程序 check_responses_observed 工具
检查人类是否听到了对特定消息的任何响应(播放音频)。返回计数。用于 会话模式轮询 --在继续之前,等待人类真正听到回复。
mcp_agent-notify_check_responses_observed({
id: 225 // Required: the message ID to check for observed responses to
})答复: {"n":0} (~5个代币)
🌐 HTTP API
启动通知服务器:
# Default (listens on 0.0.0.0:8881 - accessible from network)
npm start
# With custom log levels for app notifications
node lib/server.mjs --log-level debug --log-level-audio warn
# Cross-network access (recommended for SSH/remote projects)
node lib/server.mjs --address 0.0.0.0:8881
# Custom IP and port
node lib/server.mjs --address 192.168.1.100:8881
# Custom port only (uses 0.0.0.0 as host)
node lib/server.mjs --address 9000
# Localhost only (NOT accessible from other machines)
node lib/server.mjs --address localhost:8881
# Watch mode — display only, no audio (auto-detects or explicit)
node lib/server.mjs --watch
# Custom store directory
node lib/server.mjs --store /path/to/store-dir
# Skip startup confirmation prompt
node lib/server.mjs --yes
# Clear message history and start fresh
node lib/server.mjs --clear🌍 网络访问:
0.0.0.0- 🌐 可从网络上的任何计算机访问(推荐)localhost/127.0.0.1- 🏠 只能从同一台机器访问- 特定IP-🎯 只能通过该网络接口访问
通过HTTP发送通知:
# Agent notification
curl "http://localhost:8881/notify/agent?type=done&message=Build%20complete&model=claude-4.6-opus-high"
# Agent with full context
curl "http://localhost:8881/notify/agent?type=done&message=Build%20complete&workspaceDir=/Users/user/repos/my-app&agentRole=Coder&agentNumber=2&model=claude-4.6-sonnet"
# App notification
curl "http://localhost:8881/notify/app?type=success&message=Build%20complete&app=webpack"
# App notification with link
curl "http://localhost:8881/notify/app?type=success&message=Deploy%20complete&app=my-api&url=https://my-api.example.com/health"
# App debug (only shown if --log-level allows it)
curl "http://localhost:8881/notify/app?type=debug&message=Cache%20hit%20ratio%2095%25&app=webpack"🤖 /notify/agent 参数
| 参数 | 必填 | 说明 |
|---|---|---|
type | 是 | 通知类型(问题、权限、已完成、错误、状态、等待、审核、消息) |
message | 是 | 消息文本 |
model | 是 | 确切的型号标识符(例如,“claude-4.6-opus-high”) |
workspaceDir | 否 | 完整工作区路径(项目名称来源于上一段) |
agentRole | 否 | 代理角色名称 |
agentNumber | 否 | 代理人编号 |
voice | 否 | TTS语音覆盖 |
to | 否 | 收件人代理角色/名称(仅用于代理对话,显示/筛选) |
response_to | 否 | 这是一个回复的消息ID。启用轻量级响应轮询。 |
📦 /notify/app 参数
| 参数 | 必填 | 说明 |
|---|---|---|
type | 是 | 日志级别(跟踪、调试、信息、警告、错误、成功) |
message | 是 | 消息文本 |
app | 是 | 应用程序名称(例如,“webpack”、“jest”、“github actions”) |
project | 否 | 项目名称(例如“我的应用程序”) |
detail | 否 | 不属于消息的短上下文(例如,“src/auth”、“3个文件”) |
voice | 否 | TTS语音覆盖 |
url | 无 | 可作为可点击链接附加的URL(非口头,仅限视觉) |
🧑💻 POST /notify/operator (JSON正文)
| 字段 | 必填 | 描述 |
|---|---|---|
message | 是 | 消息文本 |
to | 否 | 目标代理角色(例如“程序员”) |
project | 否 | 目标项目名称 |
voice | 否 | TTS语音覆盖(默认:Daniel) |
curl -X POST http://localhost:8881/notify/operator \
-H 'Content-Type: application/json' \
-d '{"message":"Focus on auth","to":"Coder"}'📬 /messages 参数
| 参数 | 必填 | 说明 |
|---|---|---|
since_id | 否 | 返回ID大于此值的消息(初始提取为0) |
limit | 否 | 要返回的最大消息数(默认值50,最大值2000) |
type | 否 | 按通知类型筛选 |
to | 否 | 按收件人代理角色/名称筛选 |
project | 否 | 按项目名称筛选 |
source | 否 | 按来源筛选(“代理”、“应用”或“运营商”) |
agentRole | 否 | 按代理角色筛选 |
agentNumber | 否 | 按代理编号筛选 |
model | 否 | 按型号标识符筛选 |
voice | 否 | 按TTS语音筛选 |
app | 否 | 按应用程序名称筛选 |
response_to | 否 | 筛选对此邮件ID的回复邮件 |
# Get all recent messages
curl "http://localhost:8881/messages"
# Incremental poll (only new messages since ID 42)
curl "http://localhost:8881/messages?since_id=42"
# Filter by type and recipient
curl "http://localhost:8881/messages?type=message&to=Coder"🔄 /responses/available/for/id/:id
统计对消息的响应(总线模式——无论是否播放,都发送)。
| 参数 | 必填 | 说明 |
|---|---|---|
:id (路径) | 是 | 要检查响应的消息ID |
curl "http://localhost:8881/responses/available/for/id/225"
# → {"n":1}🔄 /responses/observed/for/id/:id
统计观察到的对消息的响应(会话模式——仅播放音频的响应)。
| 参数 | 必填 | 说明 |
|---|---|---|
:id (路径) | 是 | 用于检查观察到的响应的消息ID |
curl "http://localhost:8881/responses/observed/for/id/225"
# → {"n":0}⚙️ 程序化使用
import { execSync } from 'child_process';
// Agent notification
execSync('notify done "Operation completed" --model claude-4.6-opus-high');
// Agent with workspace context
execSync('notify done "Build finished" --workspace-dir /Users/user/repos/my-app --model claude-4.6-opus-high');
// App notification
execSync('notify success "Build complete" --app webpack');📦 应用程序通知
应用程序通知允许构建工具、CI脚本、部署管道、测试运行器和任何其他应用程序在代理通知的同时发出通知。
📊 应用程序日志级别
应用程序使用记录器样式级别而不是代理通知类型:
| 级别 | 声音 | 表情符号 | 用例 |
|---|---|---|---|
trace | *(无)* | 🔬 | 细粒度跟踪、函数入口/出口 |
debug | *(无)* | 🐛 | 详细的调试信息 |
info | 状态.m3 | ℹ️ | 一般信息、进度更新 |
warn | 等待.mp3⚠️ | 警告、弃用、非关键问题 | |
error | error.mp3 | ❌ | 故障、崩溃、关键问题 |
success | done.mp3 | ✅ | 构建完成,测试通过,部署完成 |
层次结构(从低到高): trace 只获取新消息
# Initial fetch
curl "http://localhost:8881/messages?since_id=0"
# → { "messages": [...], "latest_id": 42, "last_played_id": 42 }
# Next poll — only new messages
curl "http://localhost:8881/messages?since_id=42"🎧 播放跟踪
消息流跟踪音频播放状态:
last_played_id--音频已播放完毕的最高消息ID(来源于内部播放的事件)
在发送下一条消息之前,使用此功能了解何时听到消息。这是基础 轮流协议.
🤝 Agent对Agent对话
编排器通过发送以下内容创建音频对话 notify 代表不同的代理人。用户以不同的TTS语音听到每个代理——对话通过音频实时展开。
编排者推动对话。 单个代理不需要独立轮询流——编排器:
- 决定每个代理人说什么以及何时说
- 发送
notify使用每个代理的agentRole和agentNumber - 等待每条消息播放完毕后再发送下一条消息
代理 *能* 独立民意调查 get_messages 用于跨工具场景(例如通过共享消息流桥接Cursor和Claude Code代理)。
⏳ 轮流协议
编排器必须等待每条消息播放完毕,然后才能发送下一条消息。如果没有这个,消息排队的速度会比音频播放的速度快,对话也会失去自然节奏。
流量:
- 发送 代表代理人——记下退回的
id:
notify(type="message", to="Reviewer", message="...", agentRole="Coder", agentNumber=1) → id: 47- 等待 让音频结束--轮询
check_message_status直到last_played_id >= 47:
check_message_status(since_id=46) → { last_played_id: 46, has_new: true } # still playing
check_message_status(since_id=46) → { last_played_id: 47, has_new: true } # done — send next turn- 发送下一个回合 仅在播放了前一条消息之后,代表其他代理。
关键细节:
- 编排器等待每条消息的
id,不允许队列为空。多个对话可以同时运行,而不会相互阻塞。 - 当用户跳过音频(空格键)时,所有排队的消息都被标记为立即播放,因此编排器不会卡住。
- 使用
type="message"因为谈话转向了;保留其他类型用于其预期目的。 - 这
to参数指示消息的收件人(用于显示/过滤)——它不路由或传递消息。
轻量级转弯(响应轮询)
对于每个代理独立轮询回复的代理间对话:
- 代理A发送 随着
response_to指向它正在回复的消息:
notify(type="message", message="...", response_to=225) → id: 226- 代理人B投票 对于可用或观察到的响应:
check_responses_observed(id=226) → {"n":0} # not heard yet
check_responses_observed(id=226) → {"n":1} # reply heard — proceed- 代理人B阅读回复 (如果需要内容):
get_messages(response_to=226)每次投票使用约5个令牌,而不是约50-100个 check_message_status.
🎙️ 音频系统
服务器使用三重回退策略选择TTS语音:
- 语音超控 --如果
voice提供参数,直接使用(最高优先级) - 基于角色的地图 --如果
agentRole匹配地图中的角色,使用该语音 - 基于索引的地图 --如果
agentNumber匹配地图中的索引,使用该语音 - 系统默认 --使用macOS默认语音
🗺️ 语音地图
| 代理角色 | 语音 | 地区 |
|---|---|---|
| 编排器 | 系统默认值 | - |
| 程序员 | Nathan | 美国 |
| 评论家 | 萨曼莎 | 美国 |
| 测试员 | Karen | 澳大利亚 |
| 设计师 | 佐伊 | 美国 |
| 研究员 | 塞雷娜 | 美国 |
| 调试器 | 李 | 美国 |
| DevOps | Evan | 美国 |
| 作家 | 玛蒂尔达 | 美国 |
| 规划师 | 凯瑟琳 | 澳大利亚 |
| 安全 | Ava | 美国 |
| 重构者 | Siri 1 | 美国 |
| 分析师 | Siri 2 | 美国 |
| 《移民》 | Siri 3 | 美国 |
| 代理号码 | 语音 | 地区 |
|---|---|---|
| 0 | 系统默认值 | - |
| 1 | 内森 | 美国 |
| 2 | 萨曼莎 | 美国 |
| 3 | 凯伦 | 澳大利亚 |
| 4 | 佐伊 | 美国 |
| 5 | 塞雷娜 | 美国 |
| 6 | 李 | 美国 |
| 7 | 埃文 | 美国 |
| 8 | 玛蒂尔达 | 美国 |
| 9 | 凯瑟琳 | 澳大利亚 |
| 10 | 阿瓦 | 美国 |
| 11 | Siri 1 | 美国 |
| 12 | Siri 2 | 美国 |
| 13 | Siri 3 | 美国 |
语音映射在服务器端配置 lib/server.mjs 集中管理。
应用通知使用 李 (澳大利亚男性)作为默认声音,以区别于以美国特工为主的声音。这可以用以下命令覆盖 voice 参数。
👁️ 观看模式
观看模式允许您打开其他终端面板,这些面板可以镜像所有通知,而无需播放音频。适用于从多个窗口或屏幕进行监控。
启动监视模式
监视模式自动或显式激活:
# Auto-detect — if port is already in use, switches to watch mode
npm start
# Explicit — skip port binding, go straight to watch mode
node lib/server.mjs --watch当自动检测时,您将看到:
⚠️ Port 8881 already in use — switching to watch mode监视模式轮询主服务器的 /messages 每秒结束一次,并以相同的颜色格式呈现新的通知。
同步控件
键盘控制从任何面板工作——监视模式通过以下方式向主服务器发送命令 POST /controls/* 端点,并且该动作通过消息流广播到所有面板:
| 端点 | 操作 |
|---|---|
POST /controls/stop | 停止所有音频并清除队列 |
POST /controls/skip | 跳过当前通知 |
POST /controls/mute | 切换所有音频的静音 |
这 /messages 响应包括a muted 字段,以便所有面板与当前静音状态保持同步。
手表模式不做什么
- 无音频播放--仅显示
- 无通知队列--只读轮询
- 从不加载、读取或写入消息存储——完全被动
- 从不显示商店确认提示——商店决策仅限于服务器
- 从不写信给
/notify/*--只读
⌨️ 键盘控制
这些控件在主服务器和任何监视模式面板上都有效。在监视模式下,按键被转发到主服务器,由此产生的操作同步到所有连接的面板。
| 关键 | 行动 |
|---|---|
| 空格键 | 停止当前音频并清除整个队列(丢弃所有待处理的通知) |
| S | 跳过当前通知,移动到队列中的下一个通知 |
| M | 为所有音频(代理和应用程序)切换静音。通知仍记录到控制台。 |
| Ctrl+C | 退出服务器(或监视模式面板) |
🎵 声音文件
系统使用位于 sounds/ 目录:
- 🎵
done.mp3-成功声音(也用于应用程序success) - 🔔
error.mp3-错误警报(也用于应用程序error) - ❓
question.mp3-问题提示 - 🔐
permission.mp3-授权请求 - 📡
status.mp3-状态更新(也用于应用程序info) - ⏳
waiting.mp3-处理声音(也用于应用程序warn)
💾 消息持久化
消息存储位于 .agent-notify/ 目录作为仅可追加的JSONL文件(messages.jsonl).每条消息都会立即写入——崩溃时数据丢失为零。
- 服务器重新启动后邮件仍然存在 --启动时,最后10000行被加载到内存中
- 哈希链完整性 --每条消息存储一个
prevHash链接到之前的消息;启动时验证以检测损坏 - 作为事件播放 --仅通过追加跟踪播放状态
played事件(无突变) - 启动安全 --每次启动时创建带时间戳的备份;接受存储之前的CLI确认提示(
--yes跳过) - 碰撞安全 --无定期刷新,无完整文件重写;每条消息都会立即附加
- 店铺目录 --默认为
.agent-notify/项目根;可通过以下方式配置--store或$AGENT_NOTIFY_STOREenv 是 - 清除历史记录 —
--clear标记在确认后删除存储(--yes --clear跳过提示) - 自动迁移 --两者皆有
.message-store.json(旧blob格式)和.message-store.jsonl(旧平面文件)迁移到.agent-notify/首次运行时自动 - 观看模式安全 --只有主服务器(端口绑定进程)加载或写入存储;手表模式和EADDRINUSE回退从不触碰商店,从不显示提示
- 粘性商店链接 --可点击的OSC8链接,指向终端底部始终可见的存储文件
🛠️ 发展
📁 项目结构
agent-notify/
├── lib/
│ ├── notify.mjs # CLI interface
│ ├── mcp.mjs # MCP server (notify, get_messages, check_message_status, check_responses_available, check_responses_observed)
│ └── server.mjs # HTTP server (queue, endpoints, message store, TTS)
├── sounds/ # Audio files
├── .agent-notify/ # Store directory (auto-generated, gitignored)
│ ├── messages.jsonl # Append-only message stream
│ └── messages.jsonl.meta # Sidecar metadata
├── package.json
└── README.md🚀 运行服务器
# Start the notification server (default settings)
npm start
# Server runs on http://0.0.0.0:8881
# With custom log levels
node lib/server.mjs --log-level debug --log-level-audio warn🧪 测试
# Test agent notification
notify done "Test complete" --model claude-4.6-opus-high
# Test agent with project context
notify done "Test complete" --workspace-dir /Users/user/repos/test-project --model claude-4.6-opus-high
# Test agent multi-agent
notify done "Task finished" --workspace-dir /Users/user/repos/test-project --agent-role Coder --agent-number 1 --model claude-4.6-sonnet
# Test app notification
notify success "Build complete" --app webpack
notify error "Tests failed" --app jest
notify info "Deploying..." --app deploy
notify warn "Deprecation warning" --app eslint
notify debug "Verbose output" --app webpack
# Test all agent notification types
notify done "Test complete" --model claude-4.6-opus-high
notify error "Test error" --model claude-4.6-opus-high
notify question "Test question" --model claude-4.6-opus-high
notify permission "Test permission" --model claude-4.6-opus-high
notify status "Test status" --model claude-4.6-opus-high
notify waiting "Test waiting" --model claude-4.6-opus-high
# Test via HTTP
curl "http://localhost:8881/notify/agent?type=done&message=Test&model=test"
curl "http://localhost:8881/notify/app?type=success&message=Test&app=test"📋 需求
- 🍎 macOS(使用
afplay和say命令) - 🟢 Node.js 18+
- 🔊 音频输出能力
📄 许可证
有关详细信息,请参阅LICENSE.md。
👤 作者
F1LT3R
