关于 Soprano Connect MCP Server
Soprano Connect MCP Server 将 Soprano Connect 通信平台的能力提供给 AI Agent 和企业应用,用于跨渠道发送消息、管理联系人与通信流程。它通过统一工具支持多种消息内容,并提供可按请求选择的认证方式。
主要功能
- 01跨 SMS、WhatsApp、RCS 等渠道发送消息
- 02发送单条消息与 SMS 广播
- 03查询消息状态和历史记录
- 04只读查找联系人、群组与列表
- 05管理 WhatsApp 模板和媒体
适用场景
- 01向客户发送多渠道通知
- 02向联系人列表发送 SMS 广播
- 03查询消息是否送达
- 04查找广播所需的联系人或列表 ID
MCP 相关
这是一个 MCP 服务,向兼容客户端提供消息发送、状态查询、联系人查找和 WhatsApp 媒体等工具。支持 stdio、Streamable HTTP 和旧版 SSE 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Soprano Connect MCP Server
Soprano Connect MCP Server 可帮助你构建 AI Agent,通过 Soprano Connect(全球通信平台即服务(CPaaS))进行通信、与客户互动并管理通信工作流,所使用的协议为 Model Context Protocol (MCP)。
Soprano Connect MCP Server 支持 AI 助手、副驾驶、自主 Agent 和企业应用安全地与 Soprano Connect 的全球 CPaaS 平台交互。借助自然语言,AI Agent 可以在受控的企业级环境中发送消息、管理客户数据、管理账户,并协调多个渠道的通信。
无需复杂的 API 集成,也无需自定义中间件。只需连接兼容 MCP 的 AI 客户端,即可开始构建智能通信工作流——将任意兼容 MCP 的客户端(Claude、VS Code Copilot、Cursor 等)连接到 Soprano MCP 服务,让你的 Agent 通过自然语言跨多个渠道发送消息并查询送达状态。
💡 为什么选择 Soprano MCP?
Soprano Connect MCP 将通信功能转化为可供 AI Agent 直接使用的 AI 原生工具。借助 Soprano MCP,AI Agent 可以:
- 通过 Soprano Connect 平台支持的所有渠道发送全渠道通信
- 管理联系人和客户联系人列表
- 查询消息历史记录和送达状态
- 自动执行客户互动工作流
- 无需自定义集成代码即可构建 AI 驱动的通信应用场景
- 在企业级安全和治理框架内运行
🛠️ 主要功能
- 通过 Soprano Connect 支持的任意渠道发送通信,例如 SMS、RCS、WhatsApp、Viber、Email、Voice、Mobile Push
- 各渠道的丰富内容——WhatsApp(媒体、交互式按钮/列表、模板、位置、表情回应)、RCS(富媒体卡片、轮播、建议)、Voice(文本转语音、预录音频、通话控制对象)、推送通知
- 广播发送,以及单条/批量消息状态查询
- 只读查询已存储的联系人、群组和列表,以查找广播目标的 ID
- WhatsApp Business(WABA)模板列表,以及媒体上传/删除
- 可插拔的上游(Soprano)身份验证——API Key、OAuth2(客户端凭据)、Basic、Legacy OAuth2,以及用于 WABA 模板的特殊会话 Cookie 方式;按请求选择,凭据由调用方提供,且绝不存储在服务端
📋 前提条件
- 一个 Soprano Design Connect API 账户,并已为你想使用的每个渠道开通相应许可
- Python 3.12+ 和 uv——仅在使用 stdio 传输方式时需要(在本地以子进程方式运行服务)。连接已部署的 streamable HTTP 服务完全无需本地安装 Python
- 支持 MCP 客户端的 AI Agent 或应用
只有在你的 Soprano 账户已订阅并开通相应服务时,才能使用对应的工具/渠道。当前订阅范围之外的功能,必须先通过 Soprano 的入驻或账户管理流程启用,才能使用。
目录
- 💡 为什么选择 Soprano MCP?
- 🔌 传输方式
- ✉️ 消息渠道
- 🧰 可用工具
- 🤖 Agent 权限和访问控制
- 🔐 身份验证
- 🔒 客户端身份验证(可选)
- 🚀 安装和运行
- 🛠️ 故障排除
- 🤝 参与贡献
- 📄 许可证
🔌 传输方式
Soprano MCP 服务支持 MCP 规范定义的两种传输方式。与托管式多租户服务不同,你需要自行运行它(本地运行或部署),因此所有渠道共用一个端点/进程,而不是每个渠道各自使用一个。
可流式传输的 HTTP
支持可流式传输的 HTTP 传输,适用于远程/可部署的场景(例如,在 ALB、Lambda Function URL 或 API Gateway 后面)。将 MCP 客户端指向服务的 /mcp 端点,并将 <mems-mcp-server-url> 替换为你的部署地址(如果在本地运行,则使用 http://127.0.0.1:8000)。
如果服务已启用客户端身份验证(MCP_CLIENT_AUTH_MODE=oauth2.1),并开启了 Layer 2 回退(这是托管部署的推荐设置),则完全不需要 X-Soprano-* 标头:
{
"servers": {
"mems-mcp (http)": {
"type": "http",
"url": "<mems-mcp-server-url>/mcp"
}
}
}
MCP 客户端会将你重定向到 OAuth 登录/授权页面,你可以在其中输入 Soprano Connect 的 API ID 和 API KEY——这是你唯一需要提供的凭据。服务会使用它对你进行身份验证(Layer 1),并通过 Layer 2 回退机制代表你对其自身发往 Soprano 的调用进行身份验证,因此无需再为每个请求添加标头。
否则(MCP_CLIENT_AUTH_MODE=none,或无论如何你都想为每个请求传递不同的 Soprano 凭据),请改用 X-Soprano-* 标头显式提供 Layer 2 凭据:
{
"servers": {
"mems-mcp (http)": {
"type": "http",
"url": "<mems-mcp-server-url>/mcp",
"headers": {
"X-Soprano-Auth-Method": "api_key",
"X-Soprano-Api-Id": "${input:soprano-api-id}",
"X-Soprano-Api-Key": "${input:soprano-api-key}"
}
}
}
}
通常可以省略 X-Soprano-Domain-Url:如果服务自身的公有主机名遵循 mcp- 命名约定(例如 mcp-aus.sopranodesign.com),服务会自动去掉该前缀,推导出你的 Soprano 域名(https://aus.sopranodesign.com)。只有在部署不遵循此约定,或要指定与主机名所暗示的域名不同的域名时,才需显式设置此标头。
以上 X-Soprano-* 标头适用于 api_key 方法。若要使用其他受支持的身份验证方法(请参阅下文的身份验证),请改为使用对应的标头组:
// oauth2 (client credentials)
"headers": {
"X-Soprano-Auth-Method": "oauth2",
"X-Soprano-Client-Id": "${input:soprano-client-id}",
"X-Soprano-Client-Secret": "${input:soprano-client-secret}"
}
// basic
"headers": {
"X-Soprano-Auth-Method": "basic",
"X-Soprano-Username": "${input:soprano-username}",
"X-Soprano-Password": "${input:soprano-password}"
}
// legacy_oauth2
"headers": {
"X-Soprano-Auth-Method": "legacy_oauth2",
"X-Soprano-Username": "${input:soprano-username}",
"X-Soprano-Password": "${input:soprano-password}"
}
旧版
sse传输方式(添加服务的--transport sse标志,端点为/sse)也可供尚不支持可流式传输 HTTP 的 MCP 客户端使用。
stdio
对于本地使用场景(例如由 VS Code、Claude Desktop 等作为子进程启动),请使用 --transport stdio 运行。由于 stdio 没有 HTTP 标头,Soprano 凭据需改用 SOPRANO_* 环境变量提供:
{
"servers": {
"mems-mcp (stdio)": {
"type": "stdio",
"command": "uv",
"args": ["run", "--directory", "${workspaceFolder}", "mems-mcp", "--transport", "stdio"],
"env": {
"SOPRANO_DOMAIN_URL": "https://aus.sopranodesign.com",
"SOPRANO_AUTH_METHOD": "api_key",
"SOPRANO_API_ID": "${input:soprano-api-id}",
"SOPRANO_API_KEY": "${input:soprano-api-key}"
}
}
}
}
与上文相同,可将 env 块替换为其他身份验证方法对应的配置:
// oauth2 (client credentials)
"env": {
"SOPRANO_DOMAIN_URL": "https://aus.sopranodesign.com",
"SOPRANO_AUTH_METHOD": "oauth2",
"SOPRANO_CLIENT_ID": "${input:soprano-client-id}",
"SOPRANO_CLIENT_SECRET": "${input:soprano-client-secret}"
}
// basic
"env": {
"SOPRANO_DOMAIN_URL": "https://aus.sopranodesign.com",
"SOPRANO_AUTH_METHOD": "basic",
"SOPRANO_USERNAME": "${input:soprano-username}",
"SOPRANO_PASSWORD": "${input:soprano-password}"
}
// legacy_oauth2
"env": {
"SOPRANO_DOMAIN_URL": "https://aus.sopranodesign.com",
"SOPRANO_AUTH_METHOD": "legacy_oauth2",
"SOPRANO_USERNAME": "${input:soprano-username}",
"SOPRANO_PASSWORD": "${input:soprano-password}"
}
✉️ 消息渠道
所有渠道都通过一个通用的 send_message 工具公开(由 channel 参数选择目标),而不是为每个渠道单独提供一个 MCP 服务——这样既能访问 Connect API 支持的每种渠道专属富媒体内容类型,又能保持工具面简洁(减少令牌占用)。
| 渠道 | channel 值 | 支持的富媒体内容 |
|---|---|---|
| SMS | sms | 仅纯文本 |
whatsapp | 媒体(图片/视频/文档/音频)、交互式按钮/列表、预先批准的模板、位置、表情回应、上下文(回复) | |
| RCS | rcs | 富媒体卡片、轮播、建议回复/操作、媒体 |
email | 纯文本 | |
| Voice | voice | 文本转语音、预录音频文件、Call Control Objects |
| Viber | viber | 纯文本(Connect API 指南未说明富媒体内容) |
| Mobile Push Notification | pushnotification | 标题 + 正文 |
每次调用 send_message 只能发送给一个收件人(以逗号/分号分隔的收件人列表会被拒绝)。若要触达多个收件人,请使用 send_broadcast,向 Soprano 账户中已存储的列表、联系人或群组发送广播——使用 list_contacts、list_groups 和 list_lists 查找其 ID。
🧰 可用工具
| 工具 | 描述 | 对应接口 |
|---|---|---|
send_message | 通过任一受支持的渠道(SMS、WhatsApp、RCS、Email、Voice、Viber、Push),向一位收件人发送单条实时消息。 提示词示例:“向 +33612345678 发送 WhatsApp 消息,告知对方订单已发货。” | POST /cgpapi/messages/{channel} |
get_message_status | 查询此前发送的单条消息的送达状态。 提示词示例:“SMS 消息 123456 的送达状态是什么?” | GET /cgpapi/messages/{channel}/{id} |
get_batch_status | 一次查询多条 SMS 消息的送达状态。 提示词示例:“查询这 10 条 SMS 消息 ID 的送达状态。” | POST /cgpapi/batch/messages/status |
send_broadcast | 向 Soprano 账户中已存储的列表、联系人和/或群组发送 SMS 广播订单(通过 ID 引用;不接受原始电话号码)。 提示词示例:“向‘North Region’联系人列表中的所有人广播发送风暴预警 SMS。” | POST /cgpapi/broadcast/sms |
list_contacts | 查找已存储的联系人(ID、姓名、手机、电子邮件),以获取可用作 send_broadcast 目标的 ID。只读;可按名字、姓氏、手机或电子邮件筛选;分页(每页最多 100 条)。提示词示例:“查找 Jo Smith 的联系人 ID。” | GET /rest/contacts |
list_groups | 查找已存储的联系人群组(ID、名称)。只读;可按名称筛选;分页。 提示词示例:“有哪些名称中包含‘alert’的群组?” | GET /rest/groups |
list_lists | 查找已存储的收件人列表(ID、名称)。只读;可按名称筛选;分页。 提示词示例:“我们的‘Appointments’列表的 ID 是什么?” | GET /rest/lists |
list_whatsapp_templates | 列出已批准的 WhatsApp Business (WABA) 消息模板。 提示词示例:“有哪些已获批的 WhatsApp 订单确认模板?” | GET /cgpapi/waba/templates |
upload_whatsapp_media | 上传媒体(图片/视频/文档/音频),以用于 WhatsApp 消息。 提示词示例:“上传这张产品图片,以便我通过 WhatsApp 发送。” | POST /cgpapi/waba/media/{source} |
delete_whatsapp_media | 删除此前上传的 WhatsApp 媒体。 提示词示例:“删除我们刚上传的 WhatsApp 媒体文件。” | DELETE /cgpapi/waba/media/{id} |
阅读 list_contacts、list_groups 和 list_lists 的结果
每个工具都会返回 {items, page, limit, total, has_more}。筛选条件为部分匹配且不区分大小写;在 list_contacts 中提供多个筛选条件时,必须全部匹配。limit 默认为 25(最大为 100)。
items为空表示没有匹配的记录。- 若要获取下一页,请在
has_more为true时再次调用,并将page加 1(筛选条件和limit保持不变)。建议优先使用筛选,而不是逐页遍历所有记录。 - 只有第 1 页才会提供
total;list_lists使用name筛选时,total为null。 list_contacts仅返回普通联系人(后端搜索仅限此类联系人);不会返回其他类型的联系人记录,例如用户。- 群组和列表名称并非唯一,因此请使用
id。
🤖 Agent 权限与访问控制
每个工具都带有 MCP 标准的工具注解(readOnlyHint、destructiveHint、openWorldHint),客户端可据此在调用前实施治理,例如:send_message/send_broadcast/upload_whatsapp_media 不是只读工具,且会触达开放世界(实际发送消息并产生费用);delete_whatsapp_media 还会额外标记为具有破坏性。list_contacts、list_groups 和 list_lists 是只读工具,但 list_contacts 会将真实手机号和电子邮件地址返回到 Agent 的上下文中,因此请为 Agent 配置适当范围的凭据。由于发送消息会带来实际成本和声誉影响,请使用 MCP 客户端/宿主的权限控制(确认提示、允许列表、范围受限的凭据)来管理这些工具,而不要授予 Agent 不受限制的访问权限——有关指导,请参阅 MCP 规范中的实现注意事项。
🔐 身份验证
Soprano 凭据按每次请求提供,不会存储在服务端,也不会在调用之间缓存。凭据的提供方式取决于传输方式(streamable-http/sse 使用 HTTP 标头,stdio 使用环境变量):
| 身份验证方式 | stdio 环境变量 | HTTP 标头 |
|---|---|---|
| API Key | SOPRANO_AUTH_METHOD=api_key、SOPRANO_API_ID、SOPRANO_API_KEY | X-Soprano-Auth-Method: api_key、X-Soprano-Api-Id、X-Soprano-Api-Key |
| OAuth2(客户端凭据) | SOPRANO_AUTH_METHOD=oauth2、SOPRANO_CLIENT_ID、SOPRANO_CLIENT_SECRET | X-Soprano-Auth-Method: oauth2、X-Soprano-Client-Id、X-Soprano-Client-Secret |
| Basic | SOPRANO_AUTH_METHOD=basic、SOPRANO_USERNAME、SOPRANO_PASSWORD | X-Soprano-Auth-Method: basic、X-Soprano-Username、X-Soprano-Password |
| 旧版 OAuth2 | SOPRANO_AUTH_METHOD=legacy_oauth2、SOPRANO_USERNAME、SOPRANO_PASSWORD | X-Soprano-Auth-Method: legacy_oauth2、X-Soprano-Username、X-Soprano-Password |
会话 Cookie(仅限 list_whatsapp_templates) | SOPRANO_AUTH_METHOD=session_cookie、SOPRANO_SESSION_COOKIE | X-Soprano-Auth-Method: session_cookie、X-Soprano-Session-Cookie |
两种传输方式都还需要目标域名——SOPRANO_DOMAIN_URL(stdio)或 X-Soprano-Domain-Url(HTTP),例如 https://aus.sopranodesign.com。对于 streamable-http/sse,如果服务自身的公共主机名遵循 mcp- 命名约定(例如 mcp-aus.sopranodesign.com),则可以省略此标头;系统会自动去掉此前缀以推导域名。
🔒 客户端身份验证(可选)
以上内容均属于第 2 层(此服务 → Soprano)。此外,你也可以要求对传入的 MCP 请求进行身份验证(第 1 层 — 客户端 → 此服务),默认关闭:
| 环境变量 | 必填 | 说明 |
|---|---|---|
MCP_CLIENT_AUTH_MODE | — | none(默认)或 oauth2.1 |
MCP_OAUTH_ISSUER_URL | 如果为 oauth2.1 | 授权服务器的颁发者 URL,可用逗号分隔,适用于此部署服务多个域名的情况。使用内置的可自托管授权服务器时,系统会根据调用方自己的 Host 标头自动按请求推导此值,因此可以不设置。 |
MCP_OAUTH_AUDIENCE | 如果为 oauth2.1 | 预期的令牌 aud 声明,可用逗号分隔 — 使用可自托管授权服务器时,系统也会按上述方式逐个请求推导此值。 |
MCP_OAUTH_RESOURCE_SERVER_URL | 如果为 oauth2.1 | 此服务自身的公开 URL — 当请求的 Host 与任何已配置的域名都不匹配时,用作回退默认值。 |
MCP_OAUTH_JWKS_URI | 可选 | 默认为 {issuer}/.well-known/jwks.json |
MCP_OAUTH_REQUIRED_SCOPES | 可选 | 必需范围,以逗号分隔 |
适用于任何符合标准的 OAuth2/OIDC 授权服务器(Auth0、Okta、Cognito 等)。
内置的可自托管授权服务器
部分 MCP 客户端(已确认:Zendesk Agent)需要完整的交互式 OAuth 2.0 授权码 + 同意流程,而非仅验证持有者令牌。无需另行搭建 IdP,此服务可以充当自己的授权服务器,并使用调用方的 Connect API ID/API KEY 作为其身份 — 以下路由始终会挂载;当 MCP_CLIENT_AUTH_MODE=oauth2.1 且 MCP_OAUTH_ISSUER_URL 指向此部署时,这些路由即可发挥作用:
GET/POST /oauth/authorize— 登录 + 同意表单;根据请求自身的Host标头推导 Connect API 域名(如果遵循mcp-约定),并据此验证 API ID/API KEY;否则回退到MEMS_CONNECT_API_URLPOST /oauth/token— 支持authorization_code(+ PKCE)、client_credentials和refresh_token授权类型POST /oauth/register— RFC 7591 动态客户端注册;始终注册公开客户端(受 PKCE 保护),不会签发client_secretGET /.well-known/oauth-authorization-server/GET /.well-known/jwks.json— RFC 8414/7517 发现元数据
大多数 MCP 客户端会根据这些元数据自动发现必需范围。如果你的客户端无法自动发现,请在 {your-deployment-url}/.well-known/oauth-authorization-server 中查看其 scopes_supported 列表,并在客户端中手动配置。
| 环境变量 | 必填 | 说明 |
|---|---|---|
MEMS_CONNECT_API_URL | 是 | 回退 Connect API 域名;当请求的 Host 无法通过 mcp- 约定推导域名时使用(例如,一个部署服务多个域名的情况) |
MCP_OAUTH_SIGNING_KEY(或用于 AWS Secrets Manager ARN 的 MCP_OAUTH_SIGNING_KEY_SECRET_ARN) | 建议 | 用于签发 JWT 的 PEM RSA 私钥;如果两者均未设置,则会生成临时密钥(并发出警告)— 仅适用于单个本地进程 |
MCP_OAUTH_CLIENTS_TABLE / _CODES_TABLE / _CONSENTS_TABLE / _AUDIT_TABLE / _REFRESH_TOKENS_TABLE | 可选 | 用于存储客户端、授权码、同意记录、审计记录和刷新令牌的 DynamoDB 表名(默认为 mems-mcp-oauth-*)— 需要用于 boto3 的 AWS 凭证 |
MCP_OAUTH_LAYER2_FALLBACK / MCP_OAUTH_LAYER2_CREDENTIALS_TABLE | 可选 | 允许无法发送 X-Soprano-* 标头的客户端,在第 2 层调用中复用其在第 1 层进行身份验证时使用的 Connect 身份(需主动启用;会在服务端缓存真实 API KEY,并设置 TTL 上限) |
🚀 安装与运行
git clone https://github.com/soprano-mcp/mcp.git
cd mcp
uv sync
# stdio (local subprocess, e.g. launched by an MCP client config)
uv run mems-mcp --transport stdio
# streamable-http (remote/deployable)
uv run mems-mcp --transport streamable-http
# host/port: MEMS_MCP_HOST (default 127.0.0.1), MEMS_MCP_PORT (default 8000)
🛠️ 故障排除
身份验证问题
- 确认
X-Soprano-*标头(或SOPRANO_*环境变量)与 5 种受支持的身份验证方式之一完全匹配,包括域名 URL。 list_whatsapp_templates是唯一需要session_cookie身份验证的例外——其他工具均接受另外 4 种方式。
消息发送问题
- 确保收件人的目标地址适用于相应渠道(SMS/WhatsApp/RCS/Voice/Viber 使用电话号码,Email 使用电子邮件地址)。
- 检查
get_message_status(SMS 则检查get_batch_status)——send_message成功响应仅表示 Soprano 已接受 请求(状态为ENROUTE),并不表示消息已送达。 - 某些渠道/账户需要在 Soprano 端明确开通许可或配置(例如 Viber 客户端连接)——如果身份验证和有效负载均无问题,但 API 返回许可相关错误,请联系 Soprano 支持团队。
其他问题
- Connect API 返回的错误会通过工具的错误文本显示(Soprano 的
errorDescription字段)。如需了解更深入的 HTTP 层级详情,请参阅 Connect API 指南中的响应/错误格式文档。
🤝 贡献
欢迎在此仓库提交问题和拉取请求。
📄 许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。