Skip to main content
Glama

ossicle

使用 Deepgram 转录本地媒体文件和 URL,可作为 Claude Code 的 MCP 服务器,也可作为独立 CLI 使用。转录结果以 Markdown 形式写入磁盘;任何大内容都不会内联返回。

每个任务在发送任何内容之前都会根据其测量的时长进行定价,如果任务的估算超过配置的每任务上限,则会被直接拒绝。这个保护机制正是这个包的意义所在。

要求

  • Node >= 20

  • ffprobe 和 ffmpeg 位于 PATH 上(用于时长测量和 16 kHz 单声道 opus 上传)

  • 如果你想要 URL 输入,yt-dlp 位于 PATH 上

  • 一个 Deepgram API 密钥

Related MCP server: whipscribe-mcp

安装

npm install
npm run build
cp .env.example .env    # then fill in DEEPGRAM_API_KEY

配置

配置仅从包根目录下的 .env 文件读取。Shell 导出的变量和 claude mcp add --env 标志会被有意忽略,因此无论由哪个项目启动,服务器行为都完全一致。

变量

必需

默认值

含义

DEEPGRAM_API_KEY

是

—

Deepgram API 密钥

DEEPGRAM_MODEL

否

nova-3

转录模型

DEEPGRAM_USD_PER_MINUTE

否

0.0043

每个音频分钟的价格,用于估算

MAX_COST_PER_JOB_USD

否

1.00

每任务硬性上限。超过即拒绝,绝不提示

TRANSCRIPTION_OUTPUT_DIR

否

./output

任务文件夹的写入位置。相对路径相对于包根目录解析

OPENROUTER_API_KEY

仅用于格式化

—

格式化步骤的密钥。转录永远不需要它

OPENROUTER_MODEL

否

openai/gpt-4o-mini

格式化步骤向其请求结构的模型

FORMAT_HEADINGS_MIN_SENTENCES

否

120

低于此句数时,格式化仅添加段落和标签,不添加章节

MCP 服务器

claude mcp add ossicle -- node "<absolute path to this repo>/dist/index.js"

transcribe

输入

类型

默认值

备注

source

string

必需

本地文件路径,或 yt-dlp 能获取的任何 URL

diarize

boolean

false

实验性。 带说话人标签的 ## Speaker N [mm:ss] 块

model

string

配置的模型

Deepgram 模型覆盖

language

string

en

口语语言代码

force

boolean

false

即使命中缓存也重新转录。会再次产生费用

返回转录路径、任务文件夹、时长、估算和实际花费的美元金额、cached 标志,以及限制在 500 字符内的预览。完整转录保留在磁盘上。

说话人分离

说话人分离是实验性的,默认关闭。在真实录音中,Deepgram 经常错误归属说话人轮次,导致带说话人标签的输出比普通段落更难读。因此该标志仅保留给那些说话人分离值得承担该风险的情况,而不是作为常规选项推荐。它仍然是缓存键的一部分,因此切换它永远不会返回过时的转录。

format_transcript

输入

类型

默认值

备注

target

string

必需

来自 transcribe 结果的 job_dir,或原始本地文件路径

force

boolean

false

重新向模型请求结构。会再次产生费用

对已存在于磁盘上的转录进行第二次可选处理。参见 格式化。

estimate_cost

接受相同的 source,返回时长、估算美元金额、美元上限,以及任务是否会被允许。不会发出 Deepgram 请求。URL 仍会被下载,因为否则无法得知时长,因此这不产生 Deepgram 费用,但并非即时。

CLI

transcribe ./interview.mp4 --diarize   # experimental, labels are often wrong
transcribe ./lecture.mp3 --estimate
transcribe ./clip.mp4 --json | jq .transcript_path

标志

默认值

含义

--diarize

关闭

实验性。 标记说话人

--model <name>

DEEPGRAM_MODEL,否则 nova-3

Deepgram 模型

--language <code>

en

口语语言

--out <dir>

TRANSCRIPTION_OUTPUT_DIR,否则 ./output

输出目录

--force

关闭

即使命中缓存也重新转录

--estimate

关闭

打印时长和估算美元金额,然后退出

--json

关闭

在 stdout 上仅打印一个 JSON 对象,不打印其他内容

--help

—

列出所有标志

退出代码:0 成功,2 因超过成本上限而被拒绝,3 配置错误或缺少二进制文件,1 其他所有情况。

transcribe format ./output/interview-final-8a2c1d0b7e64
transcribe format ./interview.mp4 --force

format 子命令接受一个任务文件夹或产生该文件夹的本地文件,并接受 --force 和 --json。

格式化

原始转录准确但几乎不可读:一整块文本,或每四句就被一个听不到说话人的规则切断的段落。格式化步骤在不允许语言模型接触文字的情况下修复了这个问题。

转录被拆分为编号的句子,并发送给一个廉价的 OpenRouter 模型,该模型仅回复结构:段落分隔符后面的索引、可选的 { startIndex, title } 章节标题,以及三到八个 kebab-case 主题标签。然后从存储的句子数组重新构建 Markdown。丢失、改写或虚构的句子在构造上就不可能,而不是通过审查来防止,因为模型永远不会返回任何文本。

  • 选择性加入。 transcribe 永远不会为你格式化。运行 format_transcript 或 transcribe format。

  • 仅部分失败。 句子按窗口发送。计划无效或请求持续失败的窗口会被重试,然后保留为普通段落并报告为跳过的范围。转录永远不会比原始渲染更差。

  • 短转录没有章节。 低于 FORMAT_HEADINGS_MIN_SENTENCES 时,模型只被要求生成段落和标签。四分钟的语音笔记不需要三个虚构的章节。

  • 与转录一样缓存。 计划写入任务文件夹中的 format.json。第二次调用会从中重新渲染,不花费任何费用;force 会重新调用模型。在已格式化的任务上重新运行 transcribe 会重新应用存储的计划,而不是覆盖它。

  • 同样的成本保护。 格式化在任何请求之前被定价,超过 MAX_COST_PER_JOB_USD 会被拒绝。每次调用都是它自己的任务:它永远不会与 Deepgram 已收取的费用相加。

输出布局

<TRANSCRIPTION_OUTPUT_DIR>/<slug>-<key12>/

  URL sources:   never-gonna-give-you-up-dQw4w9WgXcQ-1f3b9c2d4e5a/
  Local files:   interview-final-8a2c1d0b7e64/
  audio.opus       the 16 kHz mono upload
  audio.<ext>      the yt-dlp download, for URL sources, kept so re-runs never re-fetch
  response.json    Deepgram's raw response
  format.json      the structure plan, once the transcript has been formatted
  transcript.md    YAML front matter plus the rendered transcript

缓存

缓存键是源标识加上改变转录的选项:model、diarize 和 language。本地文件通过其字节的 SHA-256 标识;URL 通过 yt-dlp 提取器 ID 标识,因此跟踪参数和短链接变体永远不会导致第二次付费转录。

文件夹名称是装饰性的:对于 URL,它是视频标题后跟视频 ID;对于本地文件,它是文件名。任务仅通过尾部的 <key12> 找到,因此无论其可读部分是什么,文件夹都会被复用。上传者重命名的视频,或由旧版本工具命名的文件夹,仍然会命中缓存,而不是为同一转录支付两次费用。

命中时从存储的 response.json 重新渲染 transcript.md,而不是返回旧的 Markdown,因此格式化器的改进可以零成本地惠及旧任务。只有 --force / force: true 会重新调用 Deepgram。

开发

npm test          # vitest
npm run typecheck
npm run build

没有测试会生成二进制文件或接触网络:ffprobe、ffmpeg 和 yt-dlp 通过可注入的命令运行器,Deepgram 通过可注入的 fetch。

Related MCP Connectors

Related MCP Servers