关于 Twilio Agent Payments MCP Server
Twilio Agent Payments MCP Server 通过 Twilio API 支持语音通话中的 Agent 辅助支付,适用于需要分步采集支付信息的支付流程。它提供支付提示词、异步回调资源和支付信息令牌化。
主要功能
- 01在语音通话中处理支付
- 02采集并令牌化银行卡信息
- 03通过 MCP 资源处理异步回调
- 04使用提示词引导支付步骤
- 05支持重新输入支付信息
适用场景
- 01引导通话中的客户完成支付信息采集
- 02通过令牌化处理支付凭据
- 03查看异步支付回调状态
- 04支付信息输入错误后重新录入
MCP 相关
作为 MCP 服务,它向客户端公开支付工具、回调资源和流程提示词,辅助完成分步支付流程。README 提及可与 Claude Desktop 等 MCP 客户端集成。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Twilio Agent Payments MCP 服务
一款 MCP(Model Context Protocol)服务,可通过 Twilio API 处理由 Agent 辅助的支付,并增强了异步回调和基于上下文提示词的引导式工作流功能。
功能
- 通过 Twilio 在语音通话过程中处理安全支付
- 收集支付信息(卡号、安全码、有效期)
- 对支付信息进行令牌化,以符合 PCI 标准
- 通过 MCP 资源处理异步回调
- 使用 MCP 提示词引导支付流程的每个步骤
- 支持重新输入支付信息
- 与 Claude Desktop 等 MCP 客户端集成
- 安全地处理凭据
- 使用 Twilio API Keys 提升安全性
- 基于事件的日志架构
安装
你可以直接通过 npx 使用此服务:
npx twilio-agent-payments-mcp-server <accountSid> <apiKey> <apiSecret>
也可以全局安装:
npm install -g twilio-agent-payments-mcp-server
twilio-agent-payments-mcp-server <accountSid> <apiKey> <apiSecret>
环境参数
安装服务时,需要提供以下参数:
-
命令行参数(必需):
accountSid:你的 Twilio Account SIDapiKey:你的 Twilio API KeyapiSecret:你的 Twilio API Secret
-
环境变量(运行服务前设置):
TOKEN_TYPE:支付所用令牌的类型(例如,'reusable'、'one-time')CURRENCY:支付所用货币(例如,'USD'、'EUR')PAYMENT_CONNECTOR:与 Twilio 配合使用的支付连接器NGROK_AUTH_TOKEN:你的 Ngrok 身份验证令牌(处理回调时必需)NGROK_CUSTOM_DOMAIN:Ngrok 的可选自定义域名
环境变量示例:
TOKEN_TYPE=reusable CURRENCY=USD PAYMENT_CONNECTOR=your_connector NGROK_AUTH_TOKEN=your_token npx twilio-agent-payments-mcp-server <accountSid> <apiKey> <apiSecret>
有关这些参数的更多详情,请参阅下方的配置部分。
配置
服务需要以下参数:
accountSid:你的 Twilio Account SID(必须以 'AC' 开头,并会进行验证)apiKey:你的 Twilio API Key(以 'SK' 开头)apiSecret:你的 Twilio API Secret
环境变量
以下环境变量用于配置:
TOKEN_TYPE:支付所用令牌的类型(例如,'reusable'、'one-time')CURRENCY:支付所用货币(例如,'USD'、'EUR')PAYMENT_CONNECTOR:与 Twilio 配合使用的支付连接器NGROK_AUTH_TOKEN:你的 Ngrok 身份验证令牌(处理回调时必需)NGROK_CUSTOM_DOMAIN:Ngrok 的可选自定义域名
注意:Twilio 凭据(accountSid、apiKey、apiSecret)通过命令行参数提供,而不是通过环境变量提供。
安全说明
此服务使用 API Keys 和 Secrets,而非 Auth Tokens,以提升安全性。这种方式能够提供更好的访问控制,并可在需要时撤销凭据。更多信息请参阅 Twilio API Keys 文档。
在 Claude Desktop 中使用
本地开发
进行本地开发时(即软件包尚未发布到 npm),请将以下内容添加到 Claude Desktop 配置文件中(macOS 上为 ~/Library/Application Support/Claude/claude_desktop_config.json,Windows 上为 %APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"twilio-agent-payments": {
"command": "node",
"args": [
"/PATHTONODE/twilio-agent-payments-mcp-server/build/index.js",
"your_account_sid_here",
"your_api_key_here",
"your_api_secret_here"
],
"env": {
"TOKEN_TYPE": "reusable",
"CURRENCY": "USD",
"PAYMENT_CONNECTOR": "your_connector_name",
"NGROK_AUTH_TOKEN": "your_ngrok_auth_token_here",
"NGROK_CUSTOM_DOMAIN": "your_custom_domain_here" // Optional
}
}
}
}
将这些值替换为你实际的 Twilio 凭据和配置。
发布到 npm 后
软件包发布到 npm 后,你可以使用以下配置:
{
"mcpServers": {
"twilio-agent-payments": {
"command": "npx",
"args": [
"-y",
"twilio-agent-payments-mcp-server",
"your_account_sid_here",
"your_api_key_here",
"your_api_secret_here"
],
"env": {
...process.env, // Include existing environment variables so child process has access to the path
"TOKEN_TYPE": "reusable",
"CURRENCY": "USD",
"PAYMENT_CONNECTOR": "your_connector_name",
"NGROK_AUTH_TOKEN": "your_ngrok_auth_token_here",
"NGROK_CUSTOM_DOMAIN": "your_custom_domain_here" // Optional
}
}
}
}
与宿主应用集成
Model Context Protocol(MCP)的一个关键优势是,它无需大量手动配置大模型上下文。MCP 服务会自动向大模型客户端提供所有必需的工具定义、资源模板和功能。
设置宿主应用程序
要将此 MCP 服务集成到您自己的宿主应用程序中:
-
实现 MCP 客户端:使用现有的 MCP 客户端库,或在应用程序中实现 MCP 客户端协议。
-
连接到 MCP 服务:将应用程序配置为连接到 Twilio Agent Payments MCP 服务。
-
让协议处理其余工作:MCP 服务会自动:
- 向客户端注册其工具和资源
- 为所有工具提供输入架构
- 提供上下文提示词,引导大模型完成支付流程
无需在大模型的上下文中手动定义工具或资源——MCP 协议会自动处理发现过程。
集成代码示例
以下是如何与 MCP 客户端集成的简化示例:
// Initialize your MCP client
const mcpClient = new McpClient();
// Connect to the Twilio Agent Payments MCP server
await mcpClient.connectToServer({
name: "twilio-agent-payments",
// Connection details depend on your specific MCP client implementation
// This could be a WebSocket URL, stdio connection, or other transport
});
// The client will automatically discover available tools and resources
// When the LLM wants to use a tool, your application can handle it like this:
function handleLlmToolRequest(toolRequest) {
// The toolRequest would contain:
// - server_name: "twilio-agent-payments"
// - tool_name: e.g., "startPaymentCapture"
// - arguments: e.g., { callSid: "CA1234567890abcdef" }
return mcpClient.callTool(toolRequest);
}
// Similarly for resources:
function handleLlmResourceRequest(resourceRequest) {
// The resourceRequest would contain:
// - server_name: "twilio-agent-payments"
// - uri: e.g., "payment://CA1234567890abcdef/PA9876543210abcdef/status"
return mcpClient.accessResource(resourceRequest);
}
所需的最少大模型上下文
大模型只需知道它可以使用 Twilio Agent Payments MCP 服务处理支付即可。在系统提示词中添加一条简单指令就足够了:
You have access to a Twilio Agent Payments MCP server that can help process secure payments during voice calls.
When a customer wants to make a payment, you can use the tools provided by this server to securely capture
payment information while maintaining PCI compliance.
The server will guide you through the payment process with contextual prompts at each step.
MCP 服务本身会提供所有详细的工具定义、输入架构和上下文提示词,引导大模型完成支付流程。
开发者实现说明
本节将说明 MCP 服务的实现在不同组件和文件中的组织方式,重点介绍所采用的架构模式。
组件组织
服务实现分布在多个目录中:
-
src/index.ts:主入口,负责:
- 初始化 MCP 服务
- 初始化 TwilioAgentPaymentServer 单例
- 通过自动发现查找所有组件,并将其注册到 MCP 服务
- 设置用于日志记录的事件监听器
- 将服务连接到传输层
-
src/tools/:包含各个工具的实现
- 每个工具都通过工厂函数实现,该函数返回一个包含 name、description、shape 和 execute 属性的对象
- 工具负责处理特定的支付操作(例如,StartPaymentCaptureTool、CaptureCardNumberTool)
- 每个工具都使用 Zod 定义其输入架构,并实现 execute 方法
- 工具通过 getInstance() 访问 TwilioAgentPaymentServer 单例
-
src/prompts/:包含提示词的实现
- 每个提示词都通过工厂函数实现,该函数返回一个包含 name、description 和 execute 属性的对象
- 提示词为支付流程的每个步骤提供上下文指导,帮助大模型完成流程
- 某些提示词接受可用于自定义提示词内容的参数
-
src/resources/:包含资源的实现
- 资源提供对数据的访问(例如,PaymentStatusResource)
- 每个资源都通过工厂函数实现,该函数返回一个包含 name、template、description 和 read 属性的对象
- 资源通过 getInstance() 访问 TwilioAgentPaymentServer 单例
-
src/api-servers/:包含 Twilio API 客户端的实现
- 将 TwilioAgentPaymentServer 实现为单例
- 处理与 Twilio API 的通信
- 管理支付会话状态
- 提供用于访问单例实例的静态方法
-
src/utils/:包含实用函数
- autoDiscovery.ts 文件负责自动发现并注册工具、提示词和资源
TwilioAgentPaymentServer 的单例模式
此代码库采用的一种关键架构模式是为 TwilioAgentPaymentServer 使用单例模式:
class TwilioAgentPaymentServer extends EventEmitter {
// Singleton instance
private static instance: TwilioAgentPaymentServer | null = null;
/**
* Static method to get the instance
*/
public static getInstance(): TwilioAgentPaymentServer {
if (!TwilioAgentPaymentServer.instance) {
throw new Error('TwilioAgentPaymentServer not initialized. Call initialize() first.');
}
return TwilioAgentPaymentServer.instance;
}
/**
* Static method to initialize the instance
*/
public static initialize(accountSid: string, apiKey: string, apiSecret: string): TwilioAgentPaymentServer {
if (!TwilioAgentPaymentServer.instance) {
TwilioAgentPaymentServer.instance = new TwilioAgentPaymentServer(accountSid, apiKey, apiSecret);
}
return TwilioAgentPaymentServer.instance;
}
// Private constructor to prevent direct instantiation
private constructor(accountSid: string, apiKey: string, apiSecret: string) {
// Initialization code...
}
}
这种方式的优点:
- 确保整个应用程序中只有一个 TwilioAgentPaymentServer 实例
- 无需通过多个函数传递该实例
- 提供更简洁的 API 和更简单的函数签名
- 更便于从代码库中的任何位置访问 TwilioAgentPaymentServer
工厂函数模式
工具、提示词和资源均使用工厂函数模式实现:
-
工具:
// Example from StartPaymentCaptureTool.ts export function startPaymentCaptureTool() { // Get the TwilioAgentPaymentServer instance const twilioAgentPaymentServer = TwilioAgentPaymentServer.getInstance(); // Create an event emitter for logging const emitter = new EventEmitter(); return { name: "startPaymentCapture", description: "Start a new payment capture session", shape: schema.shape, execute: async function execute(params: z.infer<typeof schema>, extra: any): Promise<ToolResult> { // Implementation that calls Twilio API and returns result }, emitter // For attaching event listeners } } -
资源:
// Example from PaymentStatusResource.ts export function paymentStatusResource() { // Get the TwilioAgentPaymentServer instance const twilioAgentPaymentServer = TwilioAgentPaymentServer.getInstance(); // Create an event emitter for logging const emitter = new EventEmitter(); return { name: "PaymentStatus", template: new ResourceTemplate("payment://{callSid}/{paymentSid}/status", { list: undefined }), description: "Get the current status of a payment session", read: async (uri: URL, variables: Record<string, string | string[]>, extra: any): Promise<ResourceReadResult> => { // Implementation that retrieves and formats payment status data }, emitter // For attaching event listeners }; } -
提示词:
// Example from a prompt factory function export function startCapturePrompt() { return { name: "StartCapture", description: "Prompt for starting the payment capture process", execute: (args: { callSid: string }, extra: RequestHandlerExtra): GetPromptResult | Promise<GetPromptResult> => { // Return prompt content } }; }
自动发现和注册
服务使用自动发现机制来查找并注册所有组件:
// In src/utils/autoDiscovery.ts
export async function discoverComponents(mcpServer: McpServer) {
// Get the current directory path
const basePath: string = path.dirname(fileURLToPath(import.meta.url));
await Promise.all([
discoverTools(mcpServer, path.join(basePath, '../tools')),
discoverPrompts(mcpServer, path.join(basePath, '../prompts')),
discoverResources(mcpServer, path.join(basePath, '../resources'))
]);
}
此方法:
- 自动查找各自目录中的所有工具、提示词和资源
- 动态导入这些组件并将其注册到 MCP 服务
- 无需修改主文件即可轻松添加新组件
- 减少样板代码并提高可维护性
提示词中的参数
某些提示词接受参数,可用于自定义提示词内容。StartCapturePrompt 就是一个很好的例子:
-
参数定义:
// In the prompt factory function return { name: "StartCapture", description: "Prompt for starting the payment capture process", schema: { callSid: z.string().describe("The Twilio Call SID") }, // Parameter schema execute: (args: { callSid: string }, extra: RequestHandlerExtra) => { // Implementation } };- schema 属性使用 Zod 定义参数架构
- 在此示例中,需要一个类型为 string 的
callSid参数
-
在提示词中使用参数:
execute: (args: { callSid: string }, extra: RequestHandlerExtra): GetPromptResult | Promise<GetPromptResult> => { const { callSid } = args; if (!callSid) { throw new Error("callSid parameter is required"); } return { messages: [ { role: "assistant", content: { type: "text", text: getStartCapturePromptText(callSid), // Use the parameter in the prompt text } } ] }; }- execute 方法将参数作为第一个参数接收
- 它可以验证参数,并用这些参数自定义提示词内容
- 在此示例中,callSid 会用于提示词文本中,以提供上下文
此模式可使提示词具有动态性和上下文感知能力,根据支付流程的当前状态提供量身定制的指导。
可用工具
startPaymentCapture
为正在进行的通话启动支付捕获流程。
参数:
callSid:正在进行的通话的 Twilio Call SID
重要:StartCapturePrompt.ts 要求用户从 MCP 客户端输入 Call SID。这是必填参数;如果未提供,提示词将抛出错误。
注意:处理 Twilio 通话时,需要了解当前使用的是哪个通话支路的 Call SID。Twilio Payments 必须关联到 PSTN 侧的通话支路。如果应用于 Twilio Client 侧,则不会捕获 DTMF 数字。因此,此 MCP 服务假设使用的是正确的通话支路。通常会按以下方式进行检查:
// Pseudo code: direction of the call
if (event.CallDirection === "toPSTN") {
theCallSid = event.CallSid;
}
if (event.CallDirection == "toSIP") {
theCallSid = event.ParentCallSid;
}
返回:
paymentSid:新支付会话的 Twilio Payment SID
captureCardNumber
开始捕获支付卡号。
参数:
callSid:正在进行的通话的 Twilio Call SIDpaymentSid:支付会话的 Twilio Payment SIDcaptureType:设置为 'payment-card-number'
返回:
- 卡号捕获操作的状态
captureSecurityCode
开始捕获卡片安全码。
参数:
callSid:正在进行的通话的 Twilio Call SIDpaymentSid:支付会话的 Twilio Payment SIDcaptureType:设置为 'security-code'
返回:
- 安全码捕获操作的状态
captureExpirationDate
开始捕获卡片有效期。
参数:
callSid:正在进行的通话的 Twilio Call SIDpaymentSid:支付会话的 Twilio Payment SIDcaptureType:设置为 'expiration-date'
返回:
- 有效期捕获操作的状态
completePaymentCapture
完成支付捕获会话。
参数:
callSid:正在进行的通话的 Twilio Call SIDpaymentSid:支付会话的 Twilio Payment SID
返回:
- 支付完成操作的状态
可用资源
payment://{callSid}/{paymentSid}/status
以 JSON 对象的形式获取支付会话的当前状态。此资源提供支付捕获流程当前状态的详细信息,包括:
- Payment SID
- 支付卡号(已屏蔽)
- 支付卡类型
- 安全码状态
- 有效期
- 支付确认码
- 支付结果
- 支付令牌
MCP 提示词
此服务提供上下文提示词,引导大模型完成支付流程的每个步骤:
StartCapture 提示词
提供如何启动支付捕获流程的指导,包括:
- 指示如何询问客户是否准备好提供支付信息
- 说明安全处理和令牌化
- 使用 startPaymentCapture 工具的步骤
- 重要:要求用户从 MCP 客户端一侧输入 Call SID,这是必填参数
CardNumber 提示词
指导大模型如何处理银行卡号捕获流程,包括:
- 指示如何向客户说明需要哪些信息
- 处理客户问题或顾虑的建议
- 使用 captureCardNumber 工具的步骤
SecurityCode 提示词
提供捕获银行卡安全码的指导,包括:
- 指示如何说明安全码是什么
- 处理客户问题或顾虑的建议
- 使用 captureSecurityCode 工具的步骤
ExpirationDate 提示词
指导大模型如何捕获银行卡有效期,包括:
- 指示如何说明所需格式(MM/YY)
- 处理客户问题或顾虑的建议
- 使用 captureExpirationDate 工具的步骤
FinishCapture 提示词
提供如何完成支付捕获流程的指导,包括:
- 指示如何确认已收集所有信息
- 使用 completePaymentCapture 工具的步骤
Completion 提示词
指导大模型在支付成功处理后该如何操作,包括:
- 指示如何确认支付成功
- 后续对话的建议
Error 提示词
提供处理支付捕获流程中错误的指导,包括:
- 指示如何向客户说明错误
- 排查常见问题的建议
- 重试支付捕获流程的步骤
架构
此 MCP 服务采用增强型架构来处理支付流程:
基于事件的架构
服务使用基于事件的架构,通过 EventEmitter 在组件之间进行通信:
- 每个工具、资源和服务组件都扩展自 EventEmitter
- 组件会发出事件,用于日志记录和回调
- 事件监听器会将日志转发到 MCP 服务的日志系统
回调处理
服务使用 @deshartman/mcp-status-callback 包处理来自 Twilio 的异步回调:
- 使用 Ngrok 创建安全隧道以接收回调
- 处理不同支付阶段的回调
- 根据回调数据更新状态存储
- 处理错误情况和重新进入场景
状态管理
支付状态通过基于 Map 的存储进行管理:
- statusCallbackMap 按支付 SID 索引存储支付会话数据
- 每次回调都会使用最新信息更新状态
- PaymentStatusResource 提供对这些状态数据的访问
MCP 集成
服务通过以下方式与 MCP 协议集成:
- 工具:使用 Zod 模式定义,以验证输入
- 资源:提供对支付状态数据的访问
- 提示词:为支付流程的每个步骤提供上下文指导
- 日志记录:基于事件的日志记录会转发到 MCP 服务
开发
构建项目:
npm install
npm run build
前置条件
- Node.js 18+
- Express(用于回调处理)
- Twilio SDK
- 带有身份验证令牌的 Ngrok 账户
手动运行服务
如需手动启动服务进行测试(在 Claude Desktop 之外):
# Run with actual credentials
node build/index.js "your_account_sid_here" "your_api_key_here" "your_api_secret"
# Or use the npm script (which uses ts-node for development)
npm run dev -- "your_account_sid_here" "your_api_key_here" "your_api_secret"
服务将启动并等待 MCP 客户端连接。
使用 Claude Desktop 时,Claude 加载配置文件后会自动启动服务。无需手动启动。
PCI 合规性
此服务通过对支付卡信息进行令牌化,帮助满足 PCI 合规要求。实际卡数据由 Twilio 处理,绝不会存储在您的系统中。有关 Twilio 的 PCI 合规性,详见 Twilio 关于安全支付的文档。
许可证
MIT
与 MCP Inspector 的兼容性
将此服务与 MCP Inspector 配合使用时,请注意,所有日志记录都通过 MCP 日志记录功能完成,而非使用 console.log()。这是有意为之,也是与 MCP 协议兼容所必需的,因为该协议使用 stdout 进行 JSON 通信。
如果您要扩展此服务或调试问题:
- 通过发出 LOG_EVENT 事件,使用基于事件的日志记录系统
- 避免使用
console.log(),因为这会干扰 stdout 上 MCP 协议的 JSON 消息 - 在 MCP 上下文之外调试时,可以使用
console.error(),它会将输出写入 stderr
基于事件的日志记录架构
此服务采用基于事件的日志记录架构:
-
事件发射器:所有工具和资源类都继承自 Node.js 的
EventEmitter,并发出包含级别和消息数据的 'log' 事件。 -
日志转发:这些事件由事件监听器捕获,并转发至 MCP 服务的日志记录系统:
// Set up event listeners for tool logs startPaymentCaptureTool.on(LOG_EVENT, logToMcp); captureCardNumberTool.on(LOG_EVENT, logToMcp); // ... other tools -
MCP 集成:
logToMcp函数会将这些事件转换为兼容 MCP 的日志消息:const logToMcp = (data: { level: string, message: string }) => { // Only use valid log levels: info, error, debug // If level is 'warn', treat it as 'info' const mcpLevel = data.level === 'warn' ? 'info' : data.level as "info" | "error" | "debug"; // Send the log message to the MCP server's underlying Server instance mcpServer.server.sendLoggingMessage({ level: mcpLevel, data: data.message, }); };
支持的日志级别
此服务支持以下日志级别:
info:一般信息消息error:错误消息和异常debug:详细的调试信息warn:警告消息(为兼容 MCP,会自动转换为 'info')
支付回调数据结构
此服务处理来自 Twilio 的两种主要回调数据:
初始连接器数据
首次创建支付会话时,Twilio 会发送连接器数据:
{
"PaymentConnector": "PGP_MOCK",
"DateCreated": "2021-08-10T03:55:53.408Z",
"PaymentMethod": "credit-card",
"CallSid": "CAzzzzz",
"ChargeAmount": "9.99",
"AccountSid": "ACxxxxx",
"Sid": "PKxxxx"
}
捕获数据
捕获支付信息时,Twilio 会发送更新后的数据:
{
"SecurityCode": "xxx",
"PaymentCardType": "visa",
"Sid": "PKxxxx",
"PaymentConfirmationCode": "ch_a9dc6297cd1a4fb095e61b1a9cf2dd1d",
"CallSid": "CAxxxxx",
"Result": "success",
"AccountSid": "AC75xxxxxx",
"ProfileId": "",
"DateUpdated": "2021-08-10T03:58:27.290Z",
"PaymentToken": "",
"PaymentMethod": "credit-card",
"PaymentCardNumber": "xxxxxxxxxxxx1111",
"ExpirationDate": "1225"
}
此服务会将这些数据按支付 SID 索引,存储在 statusCallbackMap 中,并通过 PaymentStatusResource 提供访问。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。