关于 Sinch MCP Server
Sinch MCP Server 将 Sinch 的消息、邮件、验证和语音 API 封装为工具,面向构建客户沟通型 AI 系统的开发者。它涵盖多渠道通信发送与管理,以及账户配置和投递查询。
主要功能
- 01发送文本、媒体、模板、选项和位置消息
- 02管理 Conversation 应用、渠道、模板和 Webhook
- 03发送邮件并查询投递分析
- 04发起并完成 SMS 验证
- 05拨打电话并查看会话和批次
适用场景
- 01通过支持的消息渠道发送客户通知
- 02发送模板或自定义内容邮件并检查投递
- 03使用 SMS 一次性密码验证电话号码
- 04发起语音提醒并查看通话结果
MCP 相关
向 MCP 客户端提供 Sinch API 工具,包括 Claude Desktop 和其他兼容客户端。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Sinch MCP 服务 — 开发者预览版
此仓库包含 Sinch MCP 服务的源代码,该服务提供了一组用于与 Sinch API 交互的工具。本 README 重点介绍如何在 Claude Desktop 客户端中使用 MCP 服务,但也可以与任何其他 MCP 客户端搭配使用。
工具概览
以下是 MCP 服务中提供的工具列表(所有电话号码都必须采用 E.164 格式,例如,法国的电话号码为 +33612345678)。
会话工具
| Tool | Description | Tags |
|---|---|---|
| send-text-message | 向受支持渠道上的收件人发送纯文本消息。 示例提示词:“通过 SMS 向电话号码 +33612345678 发送一条简短的动态。” | 对话、通知 |
| send-media-message | 通过媒体消息发送图片、视频或文档。 示例提示词:“通过 WhatsApp 向电话号码 +33612345678 发送产品宣传册 PDF。” | 对话、通知 |
| send-template-message | 使用预定义模板发送消息(仅限 omni-template)。 示例提示词:“通过 Messenger 向此用户发送西班牙语的预约提醒模板。” | 对话、通知 |
| send-whatsapp-template-message | 使用预定义的 WhatsApp 模板发送消息。 示例提示词:“通过 WhatsApp 使用模板 "appointment-reminder" 发送消息。” | 对话、通知 |
| send-choice-message | 发送包含交互式选项(按钮或快捷回复)的消息。 示例提示词:“通过 RCS 向 +33612345678 发送一份关于偏好冰淇淋口味的调查,并提供以下选项:香草、草莓、榛子。” | 对话、通知 |
| send-location-message | 向用户发送位置图钉或坐标。 示例提示词:“向电话号码 +33612345678 发送毕尔巴鄂古根海姆博物馆的位置图钉。” | 对话、通知 |
| list-conversation-apps | 列出 Sinch 账户中配置的所有 Conversation 应用。 示例提示词:“我的账户中设置了哪些消息应用?” | 对话、通知 |
| create-conversation-app | 创建新的 Conversation API 应用(创建时无需配置渠道)。 示例提示词:“在 EU 区域创建一个名为 My Support Bot 的 Conversation 应用。” | 对话、配置 |
| update-conversation-app | 更新 Conversation API 应用的显示名称。 示例提示词:“将 Conversation 应用 abc123 重命名为 My Support Bot。” | 对话、配置 |
| delete-conversation-app | 根据 ID 删除 Conversation 应用。 示例提示词:“删除 Conversation 应用 abc123。” | 对话、配置 |
| set-sms-channel-on-app | 在 Conversation 应用上设置(创建或替换)SMS 渠道。 示例提示词:“使用服务计划 XYZ 和 API 令牌 … 为应用 abc123 设置 SMS。” | 对话、配置 |
| set-rcs-channel-on-app | 在 Conversation 应用上设置(创建或替换)RCS 渠道。 示例提示词:“使用发送方 ID … 和 bearer 令牌 … 为应用 abc123 设置 RCS。” | 对话、配置 |
| set-whatsapp-channel-on-app | 在 Conversation 应用上设置(创建或替换)WhatsApp 渠道。 示例提示词:“使用发送方 ID … 和 bearer 令牌 … 为应用 abc123 设置 WhatsApp。” | 对话、配置 |
| list-messaging-templates | 列出为已配置区域管理的全渠道消息模板(由 Sinch 管理)。可使用 list-whatsapp-templates 工具获取 WhatsApp 专用模板。 示例提示词:“显示我账户中的所有消息模板。” | 对话、通知 |
| list-webhooks | 列出为 Conversation 应用配置的 webhook。 示例提示词:“列出我的 Conversation 应用的所有 webhook。” | 对话、配置 |
| get-webhook | 根据 ID 获取 webhook。 示例提示词:“显示 webhook ID abc123 的详细信息。” | 对话、配置 |
| create-webhook | 创建 webhook,将 Conversation API 事件发送到目标 URL。 示例提示词:“为 https://example.com/callback 上的入站消息创建 webhook。” | 对话、配置 |
| update-webhook | 更新 webhook 的目标 URL 和/或触发条件。 示例提示词:“更新 webhook abc123,使其也接收 MESSAGE_DELIVERY 事件。” | 对话、配置 |
| delete-webhook | 根据 ID 删除 webhook。 示例提示词:“删除 webhook abc123。” | 对话、配置 |
邮件工具(Mailgun)
| 工具 | 描述 | 标签 |
|---|---|---|
| send-email | 使用预定义的 HTML 模板或原始 HTML/文本内容发送邮件。 示例提示词:“使用我们的入门模板向 [email protected] 发送一封欢迎邮件。” | 邮件、通知 |
| list-email-templates | 列出特定域名下的所有可用邮件模板。 示例提示词:“我有哪些可用的邮件模板?” | 邮件、通知 |
| retrieve-email-info | 获取特定邮件的元数据、内容和投递状态。 示例提示词:“可以查一下 ID 为 的邮件投递状态吗?” | 邮件 |
| list-email-events | 获取并归类近期的邮件投递事件,例如退信、打开或点击。 示例提示词:“显示我账户近期的所有邮件活动。” | 邮件 |
| analytics-metrics | 获取邮件分析指标,例如打开率或点击率。 示例提示词:“上周的打开率是多少?” | 邮件 |
验证工具
| 工具 | 描述 | 标签 |
|---|---|---|
| number-lookup | 查询电话号码的状态和功能。 示例提示词:“查询以下电话号码的功能:+33501020304。” | 验证 |
| start-sms-verification | 向用户的电话号码发送 OTP,发起短信验证。 示例提示词:“开始验证电话号码 +33612345678。” | 验证 |
| report-sms-verification | 提交一次性密码(OTP)以完成短信验证。 示例提示词:“使用此验证码验证电话号码:1234。” | 验证 |
语音工具
| 工具 | 描述 | 标签 |
|---|---|---|
| tts-callout | 发起语音呼叫,并使用文本转语音朗读消息。 示例提示词:“呼叫电话号码 +33612345678,并说:‘您的预约在明天上午 10 点。’” | 语音、通知 |
| get-call-information | 使用呼叫 ID 获取呼叫信息。 示例提示词:“获取呼叫 ID abc123 的详细信息。” | 语音、通知 |
| list-calls | 按服务、端点、时间范围、类型、结果或原因列出并筛选呼叫。 示例提示词:“列出今天已完成的呼叫。” | 语音、通知 |
| get-session-information | 使用会话 ID 获取语音会话及其所有呼叫分支。 示例提示词:“获取会话 01BX5ZZKBKACTAV9WEVGEMMVRB 的详细信息。” | 语音、通知 |
| create-voice-service | 创建语音服务。 示例提示词:“创建名为 Customer Support 的默认语音服务。” | 语音 |
| set-voice-service-webhook | 为语音服务配置主 Webhook 和备用 URL。 示例提示词:“为服务 6e124178-c29d-46a5-943c-5c2ae544aade 配置 Webhook 和备用地址。” | 语音 |
| remove-voice-service-webhook | 移除语音服务的 Webhook 处理。 示例提示词:“移除服务 6e124178-c29d-46a5-943c-5c2ae544aade 的 Webhook。” | 语音 |
| assign-number-to-voice-service | 将一个已启用的 Sinch 号码分配给语音服务。 示例提示词:“将 +14155550100 分配给语音服务 6e124178-c29d-46a5-943c-5c2ae544aade。” | 语音 |
| tts-batch-callout | 发起一批出站呼叫,播放相同的文本转语音消息。 示例提示词:“批量呼叫这些号码,并朗读这条提醒。” | 语音、通知 |
| get-voice-batch-summary | 获取批次执行汇总,还可选择获取每个会话的状态。 示例提示词:“获取批次 01BX5ZZKBKACTAV9WEVGEMMVRB 的汇总和会话详细信息。” | 语音、通知 |
语音批次、会话和呼叫的层级关系
- 批次将发起多个目的地呼叫的异步请求归为一组。
tts-batch-callout会返回一个批次 ID,每个目的地都会生成自己的会话。 - 会话表示一个呼叫流程,其中包含一个或多个呼叫。
tts-callout会直接返回会话 ID;使用get-session-information可获取其呼叫分支。 - 呼叫是会话中的一个独立分支,由呼叫 ID 标识。需要查看该分支的状态或详细信息时,请使用
get-call-information。
要从上到下检查一个批次:使用 get-voice-batch-summary 并启用会话详细信息,将返回的会话 ID 传给 get-session-information,然后将任何返回的呼叫 ID 传给 get-call-information。
RCS 发件人工具
| 工具 | 描述 | 标签 |
|---|---|---|
| list-rcs-senders | 列出项目的所有 RCS 发件人,支持分页。 示例提示词:“显示我的所有 RCS 发件人。” | rcs, configuration |
| get-rcs-sender | 按 ID 获取完整的 RCS 发件人信息,包括凭据、状态、品牌详情、测试号码和国家/地区状态。 示例提示词:“获取我的 RCS 发件人 abc123 的详细信息。” | rcs, configuration |
| create-rcs-sender | 创建新的 RCS 发件人。可在创建时提供品牌详情、问卷和国家/地区,也可通过 update-rcs-sender 逐步添加。 示例提示词:“为欧盟区域创建一个计费类别为 CONVERSATIONAL 的 RCS 发件人。” | rcs, configuration |
| update-rcs-sender | 更新 RCS 发件人的品牌、国家/地区、测试号码或问卷。 示例提示词:“为我的 RCS 发件人 abc123 更新品牌徽标 URL。” | rcs, configuration |
| launch-rcs-sender | 提交 RCS 发件人,供 Google 和运营商审核。启动前必须填写完整的品牌详情、国家/地区和问卷各部分。 示例提示词:“启动我的 RCS 发件人 abc123。” | rcs, configuration |
| add-rcs-test-number | 向 RCS 发件人添加测试电话号码(每次请求最多 20 个,每个发件人总计最多 200 个)。 示例提示词:“将 +14155552671 添加为我的 RCS 发件人的测试号码。” | rcs, configuration |
| delete-rcs-test-number | 从 RCS 发件人中删除测试号码。 示例提示词:“从我的 RCS 发件人中移除测试号码 +14155552671。” | rcs, configuration |
| resend-rcs-test-number-invite | 当状态为 PENDING 或 UNVERIFIED 时,重新发送测试号码邀请。 示例提示词:“重新发送发件人 abc123 上测试号码 +14155552671 的邀请。” | rcs, configuration |
| get-rcs-test-number-state | 获取单个 RCS 测试号码的验证状态。 示例提示词:“发件人 abc123 上测试号码 +14155552671 的状态是什么?” | rcs, configuration |
| get-rcs-number-capabilities | 获取测试号码设备支持的 RCS 功能(操作、富卡片布局、撤销)。 示例提示词:“+14155552671 支持哪些 RCS 功能?” | rcs, configuration |
WhatsApp 工具
| 工具 | 描述 | 标签 |
|---|---|---|
| get-whatsapp-account | 获取项目的 WhatsApp Business Account(WABA):入驻状态、WABA ID、企业详情、封禁状态、每日消息上限和兼容地区。 示例提示词:“我的 WhatsApp Business Account 当前状态如何?” | whatsapp, configuration |
| list-whatsapp-templates | 列出 WhatsApp 渠道专属的消息模板(由 Meta 管理)。可使用 list-messaging-templates 工具获取全渠道模板。 示例提示词:“显示我的 WhatsApp 模板。” | whatsapp, configuration |
| create-whatsapp-template | 创建 WhatsApp 消息模板,可以保存为草稿,也可以提交审核。 示例提示词:“创建一个名为 order_confirmation 的英文 WhatsApp UTILITY 模板,正文为 ‘Your order {{1}} has shipped.’” | whatsapp, configuration |
| update-whatsapp-template | 按名称和语言更新 WhatsApp 消息模板草稿(或将 APPROVED/REJECTED/PAUSED/DISABLED 模板重置为草稿)。 示例提示词:“将 order_confirmation EN WhatsApp 模板的正文更新为 ‘Your order {{1}} has shipped today.’,并提交审核。” | whatsapp, configuration |
| delete-single-whatsapp-template-language | 按名称和语言删除 WhatsApp 消息模板的单个语言版本,不影响同名模板的其他语言版本。 示例提示词:“删除 order_confirmation EN WhatsApp 模板的草稿。” | whatsapp, configuration |
| delete-all-whatsapp-template-languages | 一次调用即可删除指定名称 WhatsApp 消息模板的所有语言版本。 示例提示词:“删除 order_confirmation WhatsApp 模板的所有语言版本。” | whatsapp, configuration |
Numbers 工具
| 工具 | 描述 | 标签 |
|---|---|---|
| list-available-regions | 列出项目中可用电话号码的所有地区。可按号码类型(MOBILE、LOCAL、TOLL_FREE)筛选。示例提示词:“哪些地区提供免费电话号码?” | numbers |
| list-rented-numbers | 列出项目中所有处于活动状态(已租用)的电话号码。可按地区、类型、号码模式和功能筛选。 示例提示词:“显示我在美国所有处于活动状态的电话号码。” | numbers |
| search-for-available-numbers | 搜索可租用的电话号码,并按地区、类型、号码模式和功能筛选。 示例提示词:“查找美国支持 SMS 的可用本地号码。” | numbers |
| rent-sinch-virtual-numbers | 提供 E.164 格式的一个或多个电话号码,以租用(激活)这些号码。 示例提示词:“租用电话号码 +12025551234。” | numbers |
| release-rented-number | 释放项目中已租用的电话号码。 示例提示词:“释放电话号码 +12025551234。” | numbers |
| get-rented-number-configuration | 获取一个已租用号码及其当前或计划中的服务配置。 示例提示词:“显示 +12025551234 的配置和开通状态。” | numbers, configuration |
Configuration 工具
| 工具 | 描述 | 标签 |
|---|---|---|
| sinch-mcp-configuration | 列出 Sinch MCP 服务中的所有可用工具及其状态。如果某个工具已禁用,还会显示原因。 示例提示词:“Sinch MCP 服务中有哪些可用工具?” |
入门
前提条件
- Node.js 20.x 或 22.x(LTS)
- 已开通的 Sinch Build 账户
- Claude Desktop(或任何其他 MCP 客户端)。本 README 以 Claude Desktop 为重点介绍,但该 MCP 服务可与任何 MCP 客户端搭配使用。
API 凭据
要使用 MCP 工具所调用的 API,您需要以下凭据:
-
RCS API 凭据:必须为您的 Sinch 项目启用 RCS。请联系 [email protected] 激活。启用后,RCS 使用与 Conversation API 相同的
PROJECT_ID、KEY_ID和KEY_SECRET(见下文)。 -
WhatsApp Template API 凭据:使用与 Conversation API 相同的
PROJECT_ID、KEY_ID和KEY_SECRET(见下文)。 -
Conversation / Numbers / Voice v2 API 凭据:
- (必需)
PROJECT_ID:从 Sinch Build 控制面板中选择要使用的项目(位于顶部工具栏左侧)
- (必需)
KEY_ID:在 Sinch Build 控制面板的 Access keys 部分中选择或创建新的访问密钥。 - (必需)
KEY_SECRET:这是与您在上一步选择或创建的Access Key关联的密钥。请注意,创建Access Key时,Access Key Secret只会显示一次。如果您丢失了它,则需要创建新的Access Key。 CONVERSATION_APP_ID:这是您要使用的 conversation app 的 ID。您可以在 Sinch Build 控制面板的 Conversation API / Apps 部分中找到它。如果不设置,则必须在提示词中指定。CONVERSATION_REGION:这是您的 conversation app 和模板所在的区域。可设置为us、eu或br。如果不设置,默认值为us(但在多租户模式下,该项为必需且不会设默认值)。- 使用 SMS 通道时,您还可以将
DEFAULT_SMS_ORIGINATOR环境变量设置为用作 SMS 消息发件人的电话号码。根据您所在的国家/地区,此设置可能是必需的。 - 如果要使用位置功能,您还可以将
GEOCODING_API_KEY环境变量设置为您的 Google Geocoding API 密钥。此密钥用于将地址转换为纬度/经度坐标对。
- (必需)
-
Verification API 凭据:前往 Sinch Build 控制面板的 Verification / Apps 部分,创建新应用或选择现有应用。您需要以下凭据:
- (必需)
APPLICATION_KEY - (必需)
APPLICATION_SECRET
- (必需)
-
Voice 服务、呼叫、会话和批处理工具使用上述项目凭据中的
PROJECT_ID、KEY_ID和KEY_SECRET。- 您可以选择将
CALLING_LINE_IDENTIFICATION设置为具有 Voice 功能的有效 Sinch 号码。它将用作tts-callout和tts-batch-callout的默认主叫号码;调用者也可以为任一工具提供主叫号码。如果两者都未设置,则发起的呼叫不会显示主叫号码。
- 您可以选择将
-
Mailgun API 凭据:前往 Mailgun 控制面板的 Mailgun / Domains 部分,创建新域名或选择现有域名。您需要以下凭据:
- (必需)
MAILGUN_API_KEY MAILGUN_DOMAINMAILGUN_SENDER_ADDRESS
- (必需)
MCP 服务配置
Sinch MCP 服务以 NPM 包的形式提供。以下介绍如何在 Claude Desktop 配置文件(claude_desktop_config.json)中进行设置。请记得填入您自己的凭据作为环境变量:
{
"mcpServers": {
"sinch": {
"command": "npx",
"args": ["-y", "@sinch/mcp"],
"env": {
"PROJECT_ID": "",
"KEY_ID": "",
"KEY_SECRET": "",
"CONVERSATION_APP_ID": "",
"CONVERSATION_REGION": "",
"DEFAULT_SMS_ORIGINATOR": "",
"GEOCODING_API_KEY": "",
"APPLICATION_KEY": "",
"APPLICATION_SECRET": "",
"CALLING_LINE_IDENTIFICATION": "",
"MAILGUN_API_KEY": "",
"MAILGUN_DOMAIN": "",
"MAILGUN_SENDER_ADDRESS": ""
}
}
}
}
在本地运行 MCP 服务
选项 1:使用 Claude Desktop 通过 stdio 启动 MCP 服务
要使用 Claude Desktop 在本地运行 MCP 服务,您需要克隆代码库并构建 MCP 服务。此选项适用于本地开发和测试。
步骤 1:克隆代码库
git clone https://github.com/sinch/sinch-mcp-server.git
步骤 2:构建 MCP 服务
cd sinch-mcp-server
npm install
npm run build
第 3 步:设置 Claude Desktop 配置
以下是如何在 Claude Desktop 配置文件(claude_desktop_config.json)中配置 MCP 服务的示例:
{
"mcpServers": {
"sinch": {
"command": "node",
"args": ["/your/path/to/sinch-mcp-server/dist/index.js"],
"env": {
"PROJECT_ID": "",
"KEY_ID": "",
"KEY_SECRET": "",
"CONVERSATION_APP_ID": "",
"CONVERSATION_REGION": "",
"DEFAULT_SMS_ORIGINATOR": "",
"GEOCODING_API_KEY": "",
"APPLICATION_KEY": "",
"APPLICATION_SECRET": "",
"CALLING_LINE_IDENTIFICATION": "",
"MAILGUN_API_KEY": "",
"MAILGUN_DOMAIN": "",
"MAILGUN_SENDER_ADDRESS": ""
}
}
}
}
第 4 步:(可选)筛选 MCP 服务中可用的工具
工具太多会占用更多上下文、增加 Token 用量,也会让大模型更难选择合适的工具。
你可以使用 tags 选项筛选 MCP 服务中可用的工具。例如,如果只想使用对话工具,可以在 args 数组中添加以下选项:
"args": [
"/your/path/to/sinch-mcp-server/dist/index.js",
"--tags",
"conversation"
],
你可以用逗号分隔多个标签来组合使用。例如,如果想同时使用对话和验证工具,可以使用以下命令:
"args": [
"/your/path/to/sinch-mcp-server/dist/index.js",
"--tags",
"conversation,verification"
],
可用标签:conversation、rcs、whatsapp、email、verification、voice、numbers、notification、configuration、all。
如果想使用所有工具,可以省略 --tags 选项,或使用标签 all:
"args": [
"/your/path/to/sinch-mcp-server/dist/index.js",
"--tags",
"all"
],
选项 2:远程启动 MCP 服务并通过 SSE 连接
使用此选项,你可以在远程机器上运行 MCP 服务,并通过服务器发送事件(SSE)连接。若要在云服务器或专用机器上运行 MCP 服务,此选项会很有用。 默认情况下,Claude Desktop 会使用 STDIO 连接 MCP 服务;我们将使用 supergateway library 通过 SSE 连接 MCP 服务。
第 1 步:构建 MCP 服务
cd sinch-mcp-server
npm install
npm run build
第 2 步:设置 MCP 服务配置
复制文件 .template.env 并将其重命名为 .env。然后将占位符替换为你自己的凭据,并删除不需要的任何密钥。环境变量会在服务启动时通过 T3 Env 解析并进行类型检查;只有在调用需要相应凭据的工具时,缺少凭据才会导致错误。.env 文件应如下所示 ():
# Conversation / Numbers / Voice v2 API tools related environment variables
PROJECT_ID=
KEY_ID=
KEY_SECRET=
## Optional but recommended: the App ID holding your channels integration configuration. If not set it must be present in the prompt
CONVERSATION_APP_ID=
## Optional, defaults to "us". Other possible values are "eu" and "br"
CONVERSATION_REGION=
## Needed only if you want to send SMS messages: it is the number that will be used as the sender for SMS messages
DEFAULT_SMS_ORIGINATOR=
## Needed only if you want to send location messages: it converts an address to a latitude/longitude pair
GEOCODING_API_KEY=
# Verification tools related environment variables
APPLICATION_KEY=
APPLICATION_SECRET=
# Voice tools related environment variables
## Optional default active Sinch Voice number used by tts-callout and tts-batch-callout
CALLING_LINE_IDENTIFICATION=
# Mailgun tools related environment variables
MAILGUN_DOMAIN=
MAILGUN_API_KEY=
MAILGUN_SENDER_ADDRESS=
第 3 步:启动 MCP 服务
npm run start:stdio
默认情况下,此命令会启动包含所有可用工具的 MCP 服务。如果想筛选 MCP 服务中可用的工具,可以使用 --tags 选项。例如,如果只想使用对话工具,可以按如下方式修改命令:
# Original command
"start:sse": "tsc --project tsconfig.build.json && (npx -y supergateway --stdio \"node dist/index.js\" --port 8000 --baseUrl http://localhost:8000 --ssePath /sse --messagePath /message)"
# Modified command to only use conversation tools
"start:sse": "tsc --project tsconfig.build.json && (npx -y supergateway --stdio \"node dist/index.js --tag conversation\" --port 8000 --baseUrl http://localhost:8000 --ssePath /sse --messagePath /message)"
你可以用逗号分隔多个标签来组合使用。例如,如果想同时使用对话和验证工具,可以使用以下命令:
"start:sse": "tsc --project tsconfig.build.json && (npx -y supergateway --stdio \"node dist/index.js --tag conversation,verification\" --port 8000 --baseUrl http://localhost:8000 --ssePath /sse --messagePath /message)"
第 4 步:在 Claude Desktop 中配置 MCP 服务
然后,你可以按如下方式在 Claude 配置文件中配置 MCP 服务:
{
"mcpServers": {
"sinch": {
"command": "npx",
"args": ["-y", "supergateway", "--sse", "http://localhost:8000/sse"]
}
}
}
(如果 MCP 服务未在本地运行,请将 http://localhost:8000/sse 替换为你的 MCP 服务 URL)
选项 3:原生 Streamable HTTP 服务(推荐用于远程连接)
此选项会在 /mcp 上运行一个原生 Streamable HTTP MCP 服务。它可以是单租户或多租户(见下文)。
第 1 步:构建 MCP 服务
cd sinch-mcp-server
npm install
npm run build
步骤 2:选择租户模式
首先读取 MCP_AUTH_MODE,并据此确定租户模式:
- 如果
MCP_AUTH_MODE为client-credentials,则为multi-tenant(客户端凭据) - 如果
MCP_AUTH_MODE为sinchid-agent,则为multi-tenant(sinchid-agent) - 如果未设置
MCP_AUTH_MODE,则为single-tenant,此时必须设置PROJECT_ID、KEY_ID和KEY_SECRET
MCP_AUTH_MODE | 租户模式 | PROJECT_ID/KEY_ID/KEY_SECRET | 工具以何种身份运行 |
|---|---|---|---|
| 设置为已知模式 | 多租户 | 绝不会读取 | 调用方传入的身份 |
| 设置为其他任何值 | — | — | 拒绝启动 |
| 未设置 | 单租户 | 必填,三项都需要 | 服务的环境凭据 |
由于模式会先于其他所有内容读取,环境中遗留的凭据不会悄悄地让多租户服务切回到一个共享账户——在多租户模式下,这些凭据完全不会被读取,无论是用于解析凭据还是用于遥测。无法识别的值会导致启动错误,而不会回退到单租户模式,因为这会完全停用入站身份验证。未设置 MCP_AUTH_MODE 时,如果三项凭据不完整,也会拒绝启动:要么全部设置,要么一项都不设置并指定模式。
单租户(未设置 MCP_AUTH_MODE)
当此 MCP 实例的所有客户端共用同一个 Sinch 项目时使用——实际中通常用于本地开发。凭据保存在服务端,且三项都必须设置:
PORT=8000
PROJECT_ID=
KEY_ID=
KEY_SECRET=
# MCP_AUTH_MODE deliberately unset
注意: 此模式下,
/mcp不执行任何入站身份验证。未设置MCP_AUTH_MODE就是完整的配置,因此没有可供验证的调用方凭据,任何能够访问该端口的人都可以使用该账户进行交易。请将其绑定到 localhost,且不要对外暴露。对于可远程访问的服务,请使用多租户模式。
此处 CONVERSATION_REGION 仍为可选项(默认为 us),且仍可通过提示词覆盖。
多租户(MCP_AUTH_MODE=client-credentials)
当不同客户端必须使用不同的 Sinch 项目时使用。每个客户端都在每次请求中发送自己的凭据:
| 标头 | 值 |
|---|---|
Authorization | Bearer <Base64-encoded projectId:keyId:keySecret> |
此模式下,服务不会从其环境中读取 PROJECT_ID、KEY_ID 或 KEY_SECRET——无论是用于 OAuth 支持的工具,还是用于 span 属性。OAuth 客户端会缓存在内存中,并通过 LRU 淘汰机制管理(默认 256 个条目,可通过 OAUTH_TOKEN_CACHE_MAX_ENTRIES 配置)。
在多租户模式下,必须设置 CONVERSATION_REGION:未设置时服务会拒绝启动,且绝不会默认为 us。每个部署都固定到单一区域,且不能按请求或通过提示词覆盖区域。
形态检查的工作方式
形态检查仅适用于多租户模式。请求会根据配置的形态进行检查;不符合要求时会被拒绝,并返回 401 及 WWW-Authenticate: Bearer 挑战:
client-credentials要求令牌解码后为projectId:keyId:keySecret。SinchID JWT 包含.分隔符,因此无法解码为凭据三元组,会在此处被拒绝。x-agent-id会被忽略:此部署不会读取该值。sinchid-agent要求令牌为三段式 JWT,并且必须包含x-agent-id标头——凭据会从该标头指定的 Agent 安装中解析,Sinch 项目 ID 则取自经过验证的令牌声明,因此缺少该标头的请求无法完成。Base64 凭据三元组不是 JWT,因此会在此处被拒绝。仅有 JWT 的形式还不够:请求获准通过前,还会对令牌进行加密验证(请参阅下文的 SinchID 令牌验证(仅限sinchid-agent))。
完全没有 Authorization 的请求会收到仅包含 realm 的 RFC 6750 挑战(Bearer realm="sinch-mcp"),响应正文中会说明原因;携带了错误_类型_令牌的请求,或验证失败的 JWT,则会收到 error="invalid_token" 及相应描述。
因此,同一镜像的两个部署各自配置不同的 MCP_AUTH_MODE,即可通过不同的主机名服务两类受众,且彼此都不会接受对方的凭据。MCP_AUTH_MODE 对 stdio 不起作用。
SinchID 令牌验证(仅适用于 sinchid-agent)
每个 sinchid-agent 请求的 Authorization JWT 都会先根据配置的 JWKS 进行验证,然后才会放行:签名(RSA,算法固定为 RS256,绝不从令牌自身的 alg 标头读取)、颁发者、受众、有效期(没有 exp 声明的令牌也会被拒绝),以及非空的项目、账户、全局用户和作用域声明。伪造、过期、颁发者或受众不匹配、声明不完整的令牌都会被拒绝,并返回 401,绝不会进入会话创建或工具执行流程。
JWT 验证需要三个环境变量。在 sinchid-agent 模式下,这些变量均为必需项——服务器缺少其中任何一个都将拒绝启动:
| 变量 | 值 |
|---|---|
SINCHID_JWT_ISSUER | 预期的 iss 声明(例如 https://id.sinch.com/) |
SINCHID_JWT_AUDIENCE | 预期的 aud 声明 |
SINCHID_JWT_JWKS_URI | 颁发者 JWKS 文档(公钥签名密钥)的 URL |
Secret Manager 身份验证使用 Google Application Default Credentials。本地开发时,请运行 gcloud auth application-default login;随后 Google 客户端会使用开发者 ADC,无需为每个 Agent 设置凭据环境变量,也不会使用回退方式。如果 ADC 无法推断拥有这些密钥的项目,请设置 GOOGLE_CLOUD_PROJECT。只有在本地提供服务账号 JSON 文件时才需要设置 GOOGLE_APPLICATION_CREDENTIALS;请将其指向该文件的绝对路径,并且绝不要提交该文件。在 Kubernetes 中,Agent 发布版本会从 Secret 挂载由部署管理的 sa-key.json。
完整的 JWKS 文档会保留在内存中。JWKS HTTP 请求在没有网络活动 3 秒后会中止。10 分钟后,服务器会尝试刷新文档,但不会先丢弃已知密钥:如果计划中的刷新失败,使用缓存密钥的令牌仍可在上次成功获取后的一小时内通过验证。之后的成功刷新会立即替换文档,并移除颁发者不再发布的密钥。对于缺少密钥 ID 的令牌,每个 30 秒冷却周期内最多触发一次刷新尝试;冷却时间从每次尝试(包括失败)时开始计算,因此服务中断或随机密钥 ID 洪流不会对 JWKS 端点造成过多请求。新发布的签名密钥会在冷却期结束后的首次成功刷新时获取。成功查询 JWKS 后,未知密钥会被拒绝并返回 401;只有在尝试查询未能完成,或上次成功获取的文档已过期、无法再用于回退验证时,才会返回 503。
sinchid-agent 凭据会在请求时从 Google Secret Manager 中最新版本的 sinch-agent-m2m_<orderId>_<projectId> 加载。其载荷与 client-credentials 使用的 Base64 projectId:keyId:keySecret 数据块相同。orderId 来自 x-agent-id 标头,projectId 则由已验证令牌中的 https://sinch.com/project_id 声明得出。两个标识符都必须是规范 UUID,且在构造 Secret ID 时会转换为小写。解码后凭据中的项目必须与已验证的项目一致。缺失、无法访问、为空、格式错误、不匹配或名称无效的 Secret 都会以安全失败的方式处理,并返回提示响应。此模式绝不会回退使用 PROJECT_ID、KEY_ID 或 KEY_SECRET;这些变量仅用于独立的单租户模式。
Authorization 凭据格式(仅限 HTTP)
- 构建一个 UTF-8 字符串:
projectId:keyId:keySecret(参见 API 凭据)。 - 使用标准 Base64 编码(不含换行符,使用标准
+//字母表,而非 base64url)。 - 在每个 HTTP 请求中发送
Authorization: Bearer <base64>(包括 MCP 会话初始化之后的请求)。
访问密钥密钥可能包含 : 字符;只有前两个 : 用于分隔这三个字段。
如果请求缺少 Authorization 标头、使用了 Bearer 以外的方案,或其令牌不是经过 Base64 编码的 projectId:keyId:keySecret 三元组,HTTP 层不会拒绝该请求:基于 OAuth 的工具会返回提示词响应,内容为 Missing or invalid Authorization header (expected "Bearer <Base64 of projectId:keyId:keySecret>").
示例(多租户):
export SINCH_CREDS=$(printf '%s' 'my-project-id:my-key-id:my-key-secret' | base64)
curl -X POST "http://localhost:8000/mcp" \
-H "Authorization: Bearer ${SINCH_CREDS}" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"example","version":"1.0.0"}}}'
适用范围:Authorization 凭据适用于 Conversation、Numbers 和 Number Lookup 工具。Voice、Verification 和 Mailgun 目前仍使用服务端环境变量。本地 stdio(选项 1)始终使用服务端环境变量。
x-agent-id 标头(仅限 sinchid-agent)
Agent 集成(例如,安装在 Gemini Enterprise 应用中的 Agent)会发送 x-agent-id 标头,其中携带唯一的安装标识符(Marketplace OrderId)。Sinch 项目 ID 由 Authorization JWT 中经过验证的 https://sinch.com/project_id 声明推导得出。两者共同确定服务器从哪个 Google Secret Manager 密钥(sinch-agent-m2m_<orderId>_<projectId>)中解析调用方的 Sinch 凭据。在运行于 MCP_AUTH_MODE=sinchid-agent 的部署中,必须提供 x-agent-id 标头;缺少该标头的请求会在到达工具之前被拒绝,并返回 401。其他情况下不会读取此标头——其他模式会忽略它,stdio 模式下的凭据始终来自环境变量。在通过 M2M 身份验证提供令牌交换功能之前,此自定义标头是一种临时机制。
| 标头 | 值 |
|---|---|
x-agent-id | Agent 安装标识符(例如,GE OrderId) |
Authorization 用户 JWT(Agent 部署)
最终用户完成 OAuth 登录和授权流程后,Agent 集成可以在每个请求中发送生成的 Auth0 用户 JWT:
| 标头 | 值 |
|---|---|
Authorization | Bearer <user JWT> |
令牌通过验证后(参见上文的 SinchID 令牌验证(仅限 SinchID Agent)),服务器会在请求上下文中捕获 Sinch 声明(https://sinch.com/project_id、https://sinch.com/account_id、https://sinch.com/global_user_id)和标准 scope 声明,并将它们记录下来以用于审计。经过验证的 https://sinch.com/project_id 声明会与 x-agent-id 配对,用于从 Secret Manager 获取 M2M API 凭据(sinch-agent-m2m_<orderId>_<projectId>)。单租户模式不会读取 Authorization;在多租户模式下,令牌必须符合部署模式对应的格式并通过验证,否则请求将以 401 被拒绝。从长远来看,用户 JWT 将被交换为 M2M JWT,以取代自定义标头。
Authorization 令牌的_具体类型_取决于部署模式:
| 部署模式 | Bearer 令牌 | Sinch 凭据来源 |
|---|---|---|
| 单租户 | 不读取,也不要求 | 服务器的 PROJECT_ID/KEY_ID/KEY_SECRET |
多租户,client-credentials | Base64 projectId:keyId:keySecret | 令牌本身 |
多租户,sinchid-agent | SinchID 访问令牌(三段式 JWT) | Agent 安装程序(Google Secret Manager) |
两种多租户格式互不相同:JWT 包含 . 分隔符,而 Base64 字母表中不包含该字符,因此凭据三元组不会被误读为令牌,JWT 也不会被解析为凭据。每种多租户部署只接受自身对应的格式,对另一种格式则返回 401 — 参见 MCP_AUTH_MODE。
由于请求只能携带一个 Authorization 标头,上文所述的审计声明仅会在令牌为 JWT 时捕获,也就是说,仅适用于 sinchid-agent 部署。client-credentials 调用方提供的是凭据,而非用户令牌,因此不会记录任何声明。
步骤 3:启动 HTTP 服务
npm run start:http:server
默认情况下,服务监听 http://localhost:8000/mcp(可通过 PORT 覆盖)。
会话存储(Redis)
会话身份存储在 Redis 中,而非进程内存中,因此负载均衡器后面的任何 Pod 都可以验证任何会话 — 无需粘性会话。每个请求都会创建一个独立的短生命周期 McpServer 和 StreamableHTTPServerTransport,并在响应完成后关闭;请求之间不会在内存中保留任何内容。Redis 是必需的 — 除非同时设置 REDIS_HOST 和 REDIS_PORT,否则服务会在启动时立即退出(REDIS_PASSWORD 可选;设置后会自动启用 TLS,例如用于 AWS ElastiCache)。如果 Redis 在短暂重试后仍无法连接,服务会返回 503 Service Unavailable,并附带 JSON-RPC 错误代码 -32003,与 -32001 Session not found 相区别。
由于没有持久的逐会话传输,服务不支持独立的 GET/SSE 流 — GET /mcp 会返回 405。在 POST 请求期间发送的服务端通知(例如工具进度)照常工作;如果在任何请求之外独立推送通知,由于传输是按请求创建的,届时将无处发送。
第 4 步:MCP 客户端配置示例
每种模式发送的标头格式都相同,区别在于令牌携带的是谁的凭据。单租户客户端编码服务器的三元组;多租户客户端编码自身的三元组。
{
"mcpServers": {
"sinch-remote": {
"url": "https://your-host.example.com/mcp",
"headers": {
"Authorization": "Bearer <base64(projectId:keyId:keySecret)>"
}
}
}
}
收到 initialize 响应后,在后续请求中包含服务器返回的 mcp-session-id 标头。
贡献
请参阅 CONTRIBUTING.md,了解贡献指南,包括如何添加新工具以及固定 GitHub Actions 版本。
许可证
本项目采用 Apache License 2.0 许可。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。