MCP 服务器会把一个 API 变成智能体在对话中调用的几个命名工具;当工具返回一个句柄,智能体可以分段轮询,长任务也就能放在它后面运行。粘贴一个播客链接,用法语询问大意,全程无需编写代码。
编码智能体可以像任何程序一样使用 VocalStack API:阅读 API 参考,用 SDK 写几行代码,然后运行。如果任务不需要智能体在旁边值守,这就是正确的做法。
MCP(Model Context Protocol,模型上下文协议)针对的是另一种情况:你正在与一个助手对话,希望它立即转录某段内容,而无需编写代码。MCP 服务器会发布一份简短的命名工具列表,每个工具都带有描述以及参数的 JSON schema。智能体只需读取一次这份列表,并在请求与某个工具匹配时按名称调用它。“转录这期播客,并告诉我他们提到了哪些关于定价的内容”会变成三次工具调用,而智能体始终不会接触到 HTTP 路由。
MCP 服务器分为两类。本地服务器作为客户端的子进程运行,通过 stdio 通信,大多数文件系统和数据库服务器都是这种方式。远程服务器位于一个 URL 之后,使用 Streamable HTTP 协议,它取代了 2025 年 3 月规范修订版中较早的 HTTP+SSE(服务器发送事件)传输方式。客户端发送每个请求,服务器在同一连接上作答;在最终结果之前需要发送的任何内容,都会先以流的形式传回。任何基于当前规范编写的客户端都可以使用这两类服务器。
VocalStack 的服务器属于远程类型,地址为 {{api}}/v1/mcp,使用它的费用与使用 API 相同。你只需要这个 URL。
在控制台的 Developers 区域打开 {{app}}/developers。第一个标签 Connect an AI agent 会显示服务器 URL,以及每个客户端的设置代码片段。下面的三段代码片段与那里显示的内容一致。
在终端中运行:
claude mcp add --transport http vocalstack {{api}}/v1/mcp
将以下内容添加到项目中的 .cursor/mcp.json,若要对所有项目生效,则添加到 ~/.cursor/mcp.json:
{"mcpServers":{"vocalstack":{"url":"{{api}}/v1/mcp"}}}
任何支持 Streamable HTTP 的客户端都可以使用此 URL 添加服务器。下面是控制台显示的通用格式:
{
"vocalstack": {
"type": "streamable-http",
"url": "{{api}}/v1/mcp"
}
}
开始使用无需 API 密钥。客户端第一次连接时,你需要在浏览器中用 VocalStack 账户登录,客户端会保存令牌。控制台用一句话说明了这一点:“第一次需要使用您的 VocalStack 账户登录,无需密钥。”
这是 MCP 授权规范的作用,而不是 VocalStack 的特殊设计。远程服务器对未经身份验证的请求会返回 401,并指向其受保护资源元数据:这是一份小型 JSON 文档,列出授权服务器以及服务器要求的权限范围(scopes)。客户端读取该文档,在浏览器中执行标准的 OAuth 2.1 流程,并获得一个仅针对该服务器签发的令牌。任何遵循规范的远程 MCP 服务器都以同样方式登录,这也是上述客户端无需了解 VocalStack 即可完成登录的原因。
API 密钥同样可用,适用于在服务器或脚本中运行的客户端。以 Authorization: Bearer vs_key_... 的形式发送,与 REST API 使用的请求头相同。密钥在 Developers → API keys 下创建。两个转录工具需要 Write 和 Stream audio 权限。对于文件来说,后者听起来有些奇怪,但这些工具会经过与所有转录相同的创建入口(包括实时转录),而该入口会同时检查这两项权限。读取类工具需要 Read 权限;list_voices 只需要有效的凭据。
登录后,智能体会看到九个工具。你很少需要自己指定它们,但了解它们有助于理解智能体接下来会做什么。
每个工具接收和返回 camelCase 格式的 JSON,字段名与 /v1 接口的数据类型相同;转录的句柄就是其 transcriptionId。
transcribe_url 对公开 URL 上的音频或视频开始转录:文件链接、播客单集、YouTube 视频均可。不接受直播流。可选参数包括:name、spokenLanguage(省略则自动检测语言)、speakerLabels(auto、on 或 off),以及用于仅转录部分音频的 startS/endS。transcribe_file 对智能体持有的文件执行相同操作,文件以 fileBase64 及其 filename 发送。解码后的大小上限为 10 MiB,大约相当于 128 kbps MP3 的十分钟;更大的文件请给智能体一个链接。两者都会立即返回 transcriptionId、state: "queued",以及一个指明等待工具的 next 提示。由智能体创建的转录默认为私有,没有分享链接。
智能体对直播的耐心并不比你更持久;它会不停地调用等待工具,直到有人把笔记本电脑拿走。已完成的录音有明确的结束点,下一组工具等待的正是这个结束点。
工具调用就是一次 HTTP 请求,而 HTTP 请求本就不该持续一小时。客户端会放弃等待,代理会关闭连接,被某个工具阻塞的模型也无法做任何其他事情。因此,对于 MCP 背后的任何长时间任务,模式都与 REST API 相同:启动任务并获得一个句柄,在有限时间内等待,若尚未完成则再次调用。状态由句柄承载,而不是由连接承载。
wait_for_transcription 会阻塞,直到任务变为 done 或 failed,或直到 timeoutS 时间耗尽(默认 50 秒,最长 60 秒,以确保调用低于大多数客户端和代理所设的超时时间)。若结果中 timedOut: true,说明任务仍在运行,智能体应再次调用该工具。在工具等待期间,如果客户端请求了进度通知,服务器会发送 MCP 进度通知:包括百分比以及阶段信息,例如“正在获取 3.1 / 8.0 MB”或“正在转录 01:25 / 02:00”。get_transcription 返回状态,并在完成后返回文本。format: "text" 每个片段输出一行,格式为 [mm:ss] Speaker 1: ...;"segments" 则输出带时间戳的行,包含 start、end、speaker 和 speakerName;includeWords: true 会添加词级时间戳。结果分页返回(offset、limit,默认每页 500 个片段),若还有剩余内容则返回 nextOffset。分页是为模型设计的,而不是为网络设计的。工具返回的所有内容都会被粘贴进智能体的上下文窗口,在那里它会与你的对话争夺空间,并在之后的每一轮都消耗 token。两小时的会议有数万字;若一次性全部返回,就会把你提出的问题挤出上下文。好的 MCP 工具会返回一页内容和一个游标,让智能体自行决定需要多少内容。
连接断开或超时都不会取消任务,因为任务运行在服务器上,而不是在 MCP 请求中。任务完成后,它就成为你库中的又一条记录,后续工具会像处理其他记录一样处理它。
list_transcriptions 按时间倒序列出账户的转录,包含状态和时长;lifecycle 可为 active、archived 或 all。search_transcriptions 在所有转录中搜索说过的内容,支持任何语言,并返回匹配的行,每行附带其所属转录以及说话的秒数。transcriptionId 可将搜索范围限定在某一条转录中;lang 会为每个命中结果添加译文。找到一句话是较容易的那一半。接下来的两个工具用于弄清整段内容说了什么。
get_summary 返回已完成转录的 AI 标题和摘要,可通过 lang 选择翻译。state: "pending" 表示摘要仍在生成(通常在任务完成后几秒内即可就绪),智能体会稍后再次询问。translate_transcription 以文本或带时间戳的片段形式,返回已完成转录的另一种语言版本,分页方式与 get_transcription 相同。译文会被保存,因此再次请求时不会重复处理。list_voices 列出能朗读某种语言转录文本的语音:包括 id、名称、性别、口音(若已知)、质量评级,以及它是默认语音还是你的克隆语音。它只描述语音,并不会让语音朗读新内容(下文会详细说明服务器不做什么)。下面是这些工具在实际中如何串联使用。
添加服务器后,在 Claude Code 中的对话大致如下。你粘贴一个播客链接,并要求用法语给出大意。
智能体调用 transcribe_url:
{ "url": "https://example.org/episodes/42.mp3", "name": "Episode 42", "speakerLabels": "auto" }
它返回 transcriptionId 和 state: "queued",并遵循 next 提示:
{ "transcriptionId": "4f1c...", "timeoutS": 50 }
一期五十分钟的节目转录速度远快于播放速度,但无法在一次等待中完成。第一次等待返回 timedOut: true,进度约为 61%,于是智能体再次调用该工具,得到 state: "done"。
现在,智能体以 lang: "fr" 调用 get_summary:
{ "transcriptionId": "4f1c...", "lang": "fr" }
如果摘要仍为 pending,智能体会等待几秒;否则它会给你一个法语标题和摘要。若你问“他们在哪里谈到了定价?”,它会以 query: "pricing" 和同一个 transcriptionId 调用 search_transcriptions,并引用匹配的行及其时间戳。若要求用法语翻译全文,它就会调用 translate_transcription。
几次工具调用,无需代码,你的库里就多了一条转录。这些调用中的每一次都经过了与 REST 请求相同的关卡,而正是这些关卡决定了费用和限制。
MCP 服务器就是通过另一扇门使用的 API:限制相同,费用相同。
POST /v1/transcriptions 相同的创建入口,因此套餐的创建速率(每小时 10 次、100 次,或自定义数量)、并发转录上限(1 个、5 个或不限)以及额度都同样适用。$5 的注册额度足以支持首次会话,无需绑定银行卡。isError: true,附带 REST API 的错误代码、一句模型可以据此行动的说明,以及 retryable 和 retryAfterS 字段。insufficient_credit 会附带 topUpUrl;rate_limited 会说明需要等待多久。这一点比看上去更重要:模型会阅读错误文本,因此一句可据以行动的话,能让死胡同变成下一次工具调用。/v1/mcp 请求本身:失控的智能体会在任何工具运行之前收到带有 Retry-After 的 HTTP 429 响应。idempotencyKey:重用已完成调用的密钥会重放第一次的结果;若用不同参数重用同一密钥,则会被拒绝。因此,即使智能体自行重试,也不会启动第二个任务。任何会产生费用的工具都应提供此功能,因为智能体的重试频率远高于人类。以上是服务器的边界。另有两件事是有意不做的。
服务器没有将任意文本转为语音的工具,也没有计划添加。VocalStack 只朗读转录文本及其译文,使用预设语音或克隆语音,别无其他。list_voices 告诉智能体哪些语音可以朗读某种语言的转录文本,而不是如何让语音说出新内容。
转录工具同样拒绝直播流。YouTube 直播或电台直播需要使用实时转录,可从控制台启动,或通过 API 参考中的 POST /v1/transcriptions/live 启动。已结束的 YouTube 视频是文件,transcribe_url 可以处理它。
如果你更想自己编写代码,使用 API 转录文件一文介绍了相同步骤的 HTTP 调用写法,而实时转录教程则讲解了 WebSocket。