mcpField
C
callwright

callwright

本地服务
github.com/topness-msft通信协作115 周前更新

关于 callwright

Callwright 是可自托管的 MCP 语音 Agent,通过 Retell 拨打电话,并按助手整理且经用户确认的指示执行。它支持受约束的多语言通话,并返回通话结果。

主要功能

  1. 01经用户确认回读后拨打电话
  2. 02查询通话结果和转录
  3. 03管理通话配置与设置
  4. 04添加并验证通话语言
  5. 05根据通话学习资料
  6. 06未接通时默认重拨一次

适用场景

  1. 01致电确认已安排的预约
  2. 02在获批时间范围内预订座位
  3. 03向商家询问信息但不预订
  4. 04使用已保存的资料更改预约

MCP 相关

Callwright 向 MCP 客户端提供拨打电话、查询结果、管理资料和设置、语言及学习功能。拨号前会先回读内容,并要求明确确认。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"topness-msft-callwright": {
"command": "npx",
"args": [
"-y",
"callwright"
],
"env": {
"RETELL_API_KEY": "<RETELL_API_KEY>",
"MCP_AUTH_TOKEN": "<MCP_AUTH_TOKEN>",
"PORT": "<PORT>"
}
}
}
}
启动命令npx -y callwright
需要配置的环境变量
RETELL_API_KEY密钥Your Retell secret API key (stays server-side)
MCP_AUTH_TOKEN密钥Bearer token clients must send; required when exposed beyond localhost
PORTPort the HTTP MCP server listens on (default 8787)

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmcallwright1.0.3

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Callwright

一个可代你拨打电话的语音 Agent,处理预订、预约、确认和一般咨询,由大模型的指引和上下文信息塑造。它会说明自己是 AI,在你设定的范围内协商,绝不捏造信息,并汇报结果。

基于 Retell 构建。它以 MCP 服务的形式提供,因此任何兼容 MCP 的助手(Claude、ChatGPT、Cursor、Copilot)都能替你拨打电话——将 callwright(执行器)与其他 MCP(WorkIQ、Gmail、calendar——传感器)结合起来获取上下文。

只需开口询问

你无需填写表单——只要用日常语言询问助手,它就会收集上下文(来自日历、邮件或聊天),安排通话内容,先读给你听,并在你同意后拨打:

“在我的日历里找到维修预约,然后打电话给承包商,确认周四是否仍按计划进行。”

“打电话给 Sakura Sushi,预订本周五晚上 7 点的 4 人桌——6:30 到 8 点之间都可以。”

“打电话给我的牙医,把洗牙预约改到下周的某个时间;我的会员 ID 在个人资料里。”

“電話して、東京の美容院に明日の午後カットの予約を取って.” — (用日语拨打电话)

“打电话给京都这家酒店,询问他们到机场的租车价格——只收集信息,不要预订。”

助手只会提取每通电话所需的最少信息,先与你确认计划,再以无需等待的方式拨打;你询问时,它会获取通话结果。

工作原理

You (chat) --> Host LLM --gathers context from other MCPs--> shapes a place_call
                  |
                  v
            callwright MCP  --validate + profile + compose + guard--> Retell --> phone
                  |                                                     |
                  +-- get_call_outcome / learn_from_call <-- outcome --+
  • 通用 Agent,而非针对每种场景单独定制。 一个 Agent 提示词 = 固定护栏(说明 AI 身份、绝不付款、绝不捏造、尽量减少 PII)+ 注入的单次通话指引。可处理任何场景和语言。
  • 支持多种语言,可在运行时扩展。 初始支持英语和日语;通过 add_language,完全在聊天中即可新增一种通话语言(翻译后的提示词 + 原生语音 + 专属 Agent),无需重新部署。所有语言措辞都作为数据存放于 lang-phrases.json,而非代码中。
  • 以目的为先的身份说明。 开场先说明目标(“我是 AI 助手。我打电话是为了确认……”),而不是报姓名。只有在商家需要时才会透露你的姓名。
  • 尽量减少数据,只在需要时补充。 PII 存放在 principal.facts 中(仅在被询问时共享);每通电话只携带最少的相关信息,并会在回读时明确列出将提供哪些类型的数据。当通话用到你尚未保存的长期有效信息时,它会询问是否要记住这些信息——因此个人资料会在使用过程中逐步完善,而非一开始就通过访谈收集。
  • 从每次通话中学习。 如果通话因缺少信息而暂缓,个人资料会得到补充,下次便可提前收集这些信息——既可手动操作(learn_from_call),也可通过经过签名验证的 Retell webhook 自动完成。遇到真正的新场景时,会先暂存并提议(绝不会静默创建),同时通过护栏避免过度细分。
  • 有限重试。 无人接听或占线时会重新拨打——默认恰好重拨一次,未经明确要求绝不多拨(防止骚扰)。

工具

设置与配置

工具用途
get_setup_status查看已配置 / 缺少的内容
configure保存你的姓名、回拨信息、固定事实(+ 可选的资源配置)
list_scenarios已知的场景配置(+ 待处理候选项)

拨打电话

工具用途
place_call默认仅试运行(返回回读信息);设置 confirm:true 后才会拨号。支持 lang 和 overrides.retry
get_call_outcome根据 call_id 获取结果 + 分析 + 转录
list_recent_calls最近的通话
list_retries最近自动重拨的无人接听通话

语言

工具用途
list_voices浏览 Retell 语音(用于添加语言)
list_languages此服务支持拨打电话的语言
add_language在运行时添加新的通话语言(翻译 → Agent)
verify_language对新语言进行质量把关(审核卡片 + 可选的实时测试通话)
update_language / remove_language更改 / 移除已添加的语言

学习

工具用途
learn_from_call丰富配置,或暂存新场景候选项
list_candidates已暂存的场景候选项(待创建的新配置)
create_profile创建新的场景配置(先提议再确认,并有保护措施)
add_scenario_alias将一种通话类型合并到现有配置中
reject_candidate丢弃噪声 / 一次性候选项

place_call 是即发即忘的,并且有门控:首次调用会返回回读信息(包括 PII 涉及范围);只有通过 confirm:true 确认后才会拨号。

get_call_outcome 会返回规范的 outcome 对象。当 Retell 的内置 call_successful 信号与之不一致时,自定义分析优先的状态具有权威性;两个原始信号仍可用于诊断。成功的信息咨询通话使用 completed,而 booked 仅用于实际的预订、预约或承诺。


Retell 设置(前置条件)

Callwright 通过 Retell 拨打电话,因此你需要拥有一个已启用外拨功能的 Retell 账户才能开始使用。在 Retell 控制面板中:

  1. 创建账户并添加付款方式(Stripe)。通话和电话号码按需付费;Callwright 不会额外收费。
  2. 完成 KYC 验证。 要启用外拨功能和购买电话号码,这一步是必需的;未完成验证时,通话会被拦截。(这是一次性身份 / 企业验证,通常很快就能获批。)
  3. 购买电话号码。 这会成为你的来电显示号码(from 号码)。美国本地号码最便宜;Callwright 会在 configure run_provisioning 期间自动选择该号码。
  4. 创建 API 密钥(Settings → API Keys)。这是你的 RETELL_API_KEY,它会保留在服务端,绝不能放入浏览器或聊天中。

可选,建议启用:

  • 已验证电话号码 / 品牌呼叫(控制面板 → Telephony)——注册你的号码,降低运营商将其标记为 "Spam Likely" 的可能性,从而显著提高外拨电话的接听率。

不需要(目前在此处未启用):

  • A2P 10DLC 注册——仅在需要发送 SMS 时才需要,须经过多个步骤:企业资料 → 品牌 → 活动审批,并产生周期性费用。Callwright 的 SMS 通知功能已构建完成,但目前搁置,因此拨打电话时完全可以跳过此项。

费用按分钟计费,并取决于目的地(美国大约为每分钟 ~$0.015,国际通话费用更高),此外还需支付每月的号码租用费。


安装

在 npm 上发布为 callwright。全局安装后即可使用 callwright(服务端)和 callwright-init(设置向导)命令:

npm install -g callwright

或者克隆此仓库并运行 npm install,从源码运行(node server.js、node init.js)。

无论采用哪种方式,callwright 都是一个可自托管的单用户 HTTP MCP 服务:你运行自己的实例,并使用自己的 Retell 凭据(参见上文的 Retell 设置)。数据不会共享,也不支持多租户。

本地运行

使用全局安装:

callwright-init                     # one-time setup wizard (number, agent, your identity)
export RETELL_API_KEY=key_xxx       # [Environment]::SetEnvironmentVariable on Windows
callwright                          # MCP server on :8787 (POST /mcp)

如果是从克隆的仓库运行,请改用 node init.js 和 node server.js。

随时检查设置状态:callwright-init status(或 node init.js status)。 从命令行发起通话(绕过 MCP):node dispatch.js <job.json> --go。

用于本地场景时,MCP_AUTH_TOKEN 是可选的——未设置时,服务仅接受环回连接。当你将服务暴露到 localhost 之外时再设置(参见部署为托管服务)。


部署为托管服务(单用户)

目标:部署一个只有你能使用的远程 MCP URL。适用于 Web 客户端(claude.ai、chatgpt.com)和本地客户端。

1. 选择具有持久磁盘的主机

config.json 和 scenario-profiles.json 会在运行时写入(由 configure 和 learn_from_call 写入),因此请避免使用临时或无服务器文件系统。适用选项包括:Fly.io(卷)、Railway(卷)、Render(磁盘)。小型常驻实例即可——通话量很少。

2. 设置环境变量(主机控制面板)
RETELL_API_KEY = key_xxx            # your Retell secret - stays server-side
MCP_AUTH_TOKEN = <long random>      # the bearer token only you hold
PORT           = 8787               # or whatever the host injects
CALLWRIGHT_DATA_DIR = /data         # persistent volume for runtime state
CALLWRIGHT_PUBLIC_URL = https://your-host.example.com   # optional: enables the auto-learn webhook (Retell posts call_analyzed back here)
CLAUDE_ROUTINE_URL = https://api.anthropic.com/v1/claude_code/routines/trig_xxx/fire   # optional immediate call completion wake-up
CLAUDE_ROUTINE_TOKEN = <routine trigger token>   # dedicated token generated by the Claude Routine

参见 .env.example。切勿在浏览器或聊天中填写 Retell 密钥。

当通话来自 TickTick 任务时,发起通话的助手可以将 tracking.ticktick_task_id 传递给 place_call。Callwright 会将该不透明 ID 存储在 Retell 仅用于存储的元数据中,在自动重试时保留该 ID,并通过最终的 call_analyzed webhook 唤醒已配置的 Claude Routine。 Routine URL 和令牌为可选项;每小时轮询仍是备用方案。

3. 部署

提供了 Docker:

docker build -t callwright .
docker run -p 8787:8787 --env-file .env callwright

或者将主机指向此仓库(它会自动检测 Dockerfile)。在应用目录挂载一个卷,使 config.json / scenario-profiles.json 能在重启后保留。

无需 Docker 的替代方案:在主机上通过 npm 安装并直接运行二进制文件(将 CALLWRIGHT_DATA_DIR 指向持久卷,使运行时状态在重启后保留):

npm install -g callwright
CALLWRIGHT_DATA_DIR=/data callwright     # reads RETELL_API_KEY / MCP_AUTH_TOKEN from env
4. 通过 MCP 完成首次运行设置(无需网页)

在聊天中完成设置:

  1. 连接服务(见下文)。
  2. 请求助手调用 configure,并设置 run_provisioning: true,同时提供你的姓名和回拨号码。此操作会验证密钥、选择你的 Retell 号码、创建通用 Agent 并保存你的个人资料。
  3. 此时 get_setup_status 应返回 ready: true。

(如果你更愿意,也可以在主机 shell 中运行一次 node init.js。)


连接客户端

将 URL 替换为你部署的主机地址,并将令牌替换为你的 MCP_AUTH_TOKEN。服务支持通过两种方式传递令牌:Authorization: Bearer 请求头(Desktop/Code/Cursor),或 ?key= URL 查询参数(连接器表单没有请求头字段的 Web 客户端)。

Claude.ai(Web)

Web 连接器表单只接受 URL,因此请将令牌放入 URL:

  1. 设置 → 连接器 → 添加自定义连接器(或浏览连接器 → 添加自定义连接器)。
  2. 名称: Callwright
  3. URL: 粘贴你的主机地址 + /mcp,并通过 ?key= 添加令牌:
    https://your-host.example.com/mcp?key=<MCP_AUTH_TOKEN>
    
  4. 保存,然后在聊天中启用该连接器(🔌/工具菜单)。询问 “你有哪些 callwright 工具?” 以确认连接成功。

由于令牌位于 URL 中,请将该连接器 URL 视同密码——任何拥有该 URL 的人都可以使用你的 Retell 账户拨打电话。更换 MCP_AUTH_TOKEN 并更新连接器即可轮换令牌。

Claude Desktop / Cursor
{
  "mcpServers": {
    "callwright": {
      "url": "https://your-host.example.com/mcp",
      "headers": { "Authorization": "Bearer <MCP_AUTH_TOKEN>" }
    }
  }
}
Claude Code
claude mcp add --transport http callwright https://your-host.example.com/mcp \
  --header "Authorization: Bearer <MCP_AUTH_TOKEN>"
ChatGPT(Developer mode / connectors)

使用相同的 URL 添加自定义 MCP connector——请求头和 ?key= 两种方式均可。

请保持开启 “运行工具前确认”。place_call 默认已采用试运行模式,但对于会花钱并联系真实人员的执行工具,工具确认是很好的第二道关卡。


安全注意事项

  • **单个 bearer token 就是你的锁。**任何拥有该 token 的人都可以拨打电话,费用记入你的 Retell 账户。请像对待密码一样保管它;修改 MCP_AUTH_TOKEN 即可轮换。
  • **Retell 密钥遵循最小权限原则。**如果不需要完整的管理员权限,请使用受限密钥。
  • **PII。**固定信息存储在主机上的 config.json 中。拨打电话时仅发送最少的信息,且只在商家提出要求时才分享;每次都会在回读内容中显示所涉及的信息。
  • 如果未设置 MCP_AUTH_TOKEN,服务仅接受 loopback 连接(本地开发)。

关键文件

文件用途
server.jsMCP 服务(Streamable HTTP、bearer 身份验证)+ 自动学习 / 重试 webhook
dispatch-core.js验证 → 配置档案 → 组合变量 → 分派(共享核心)
dispatch.js基于 dispatch-core 的 CLI
setup-core.js配置资源 + config + 状态 + 延迟保存辅助函数(由 init 和 MCP 共享)
lang-core.js运行时语言管理(添加/验证/更新/移除、语音)
lang-phrases.json按语言整理的措辞(数据,非代码)
learn-core.js配置档案补充 + 新场景候选项暂存(防止场景碎片化)
retry-core.js无人接听重试策略 + 有限的重新拨号决策
routine-core.js幂等处理 Retell 通话完成事件 → 触发 Claude Routine
init.js终端配置向导(node init.js / node init.js status)
update-prompt.js将提示词 + 工具 + 礼仪规范 + webhook 推送到现有 Agent
place_call.schema.jsonLLM 填写的任务约定
generic-prompt.md / .ja.md通用 Agent 提示词(防护规则 + {{variables}})
scenario-profiles.json学习配置档案(按场景推荐的详细信息)
learn.js / get-call.jsCLI:补充配置档案 / 获取通话结果
paths.js解析可变状态路径(遵循 CALLWRIGHT_DATA_DIR)
scripts/release.ps1一键发布:提升版本号 + 测试 + 推送 + 发布到 npm 和 MCP 注册表
docs/设计规范(add-language、profile-learning)
webhook/可选的无服务器 Retell→Resend 邮件通知器(独立于 MCP)

每位用户的运行时文件——config.json、agents.json、.retell-ids.json、job.*.json、 grounding.*.json——均已加入 git 忽略规则。它们会在运行时创建(由 init/configure 创建),或包含个人通话数据;切勿提交。请从 config.example.json 和 examples/ 开始。

关于信息披露与合法性的说明

Agent 每次通话开始时都会说明自己是 AI——这是不可移除的固定行为。在某些司法辖区(例如加利福尼亚州的 B.O.T. Act),法律要求披露 AI 通话信息;在其他地方这样做也是良好实践。Agent 也绝不会捏造信息,且只会在商家提出要求时分享个人数据。若用于商业用途或大规模使用,请咨询法律顾问,确认所在司法辖区的相关要求。

可选:每次通话后主动发送邮件

参见 webhook/——一个无服务器 Retell→Resend 通知器,会通过邮件向你发送每次通话的结果。 它独立于 MCP(MCP 会通过 get_call_outcome 按需检索通话结果),且默认不会部署或接入。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。