mcpField
O
ops-voice

ops-voice

github.com/davepoon生产力3.7k69 次安装今天更新
代码仓库

关于 ops-voice

ops-voice 是用于 Claude 的语音操作技能,通过 curl 发起 API 调用。它支持 Bland AI 电话呼叫、ElevenLabs 文本转语音、Groq 音频转录,以及 API 密钥配置。

主要功能

  1. 01通过 Bland AI 拨打电话
  2. 02使用 ElevenLabs 将文本转语音
  3. 03通过 Groq Whisper 转录音频
  4. 04扫描并验证 API 密钥

适用场景

  1. 01根据提示词发起电话呼叫
  2. 02将文本生成音频文件
  3. 03转录音频文件
  4. 04配置并检查语音服务凭据

MCP 相关

该技能可将 Doppler MCP 工具用作 API 凭据来源之一;语音 API 请求通过 curl 发起。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/davepoon/buildwithclaude --skill ops-voice

安装后在 Claude Code 中输入/ops-voice确认已加载。

详细介绍

OPS:VOICE — 语音操作

语音界面命令。所有 API 调用均通过 curl 完成,不依赖 SDK。

凭证解析顺序: userConfig → 环境变量 → Doppler MCP 工具(mcp__doppler__*)→ Doppler CLI 回退(doppler secrets get <KEY> --plain)→ 密码管理器


子命令

解析 $ARGUMENTS,获取命令关键字,然后执行:


call [phone] [prompt] — Bland AI 电话呼叫

需要: userConfig 中的 bland_ai_api_key、BLAND_AI_API_KEY 环境变量或 Doppler 中的密钥。

BLAND_KEY="${BLAND_AI_API_KEY:-$(doppler secrets get BLAND_AI_API_KEY --plain 2>/dev/null || true)}"
PHONE="<extracted from $ARGUMENTS>"
PROMPT="<extracted from $ARGUMENTS or ask user>"
MAX_DURATION="${BLAND_MAX_DURATION:-300}"  # seconds
VOICE="${BLAND_VOICE:-male}"

# Make the call
RESPONSE=$(curl -s -X POST "https://api.bland.ai/v1/calls" \
  -H "authorization: $BLAND_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"phone_number\": \"$PHONE\",
    \"task\": \"$PROMPT\",
    \"voice\": \"$VOICE\",
    \"max_duration\": $MAX_DURATION,
    \"record\": true
  }")

CALL_ID=$(echo "$RESPONSE" | python3 -c "import json,sys; print(json.load(sys.stdin).get('call_id',''))" 2>/dev/null)

# Poll for completion (up to 5 min)
if [ -n "$CALL_ID" ]; then
  echo "Call initiated: $CALL_ID"
  for i in $(seq 1 30); do
    sleep 10
    STATUS=$(curl -s "https://api.bland.ai/v1/calls/$CALL_ID" \
      -H "authorization: $BLAND_KEY" | \
      python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('status',''), d.get('transcripts','')[-1].get('text','') if d.get('transcripts') else '')" 2>/dev/null)
    echo "Status: $STATUS"
    [[ "$STATUS" == completed* ]] && break
  done
fi

输出: 通话 ID、实时状态,以及通话完成后的转录文本。


tts [text] [--voice voice_id] [--out file.mp3] — ElevenLabs 文本转语音

需要: userConfig 中的 elevenlabs_api_key、ELEVENLABS_API_KEY 环境变量或 Doppler 中的密钥。

EL_KEY="${ELEVENLABS_API_KEY:-$(doppler secrets get ELEVENLABS_API_KEY --plain 2>/dev/null || true)}"
VOICE_ID="${ELEVENLABS_VOICE_ID:-21m00Tcm4TlvDq8ikWAM}"  # Rachel (default)
TEXT="<extracted from $ARGUMENTS>"
OUT_FILE="${OUT_FILE:-/tmp/ops-tts-$(date +%s).mp3}"

# List voices if voice name provided (not an ID)
# Synthesize
curl -s -X POST "https://api.elevenlabs.io/v1/text-to-speech/${VOICE_ID}" \
  -H "xi-api-key: $EL_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"text\": \"$TEXT\",
    \"model_id\": \"eleven_monolingual_v1\",
    \"voice_settings\": {\"stability\": 0.5, \"similarity_boost\": 0.75}
  }" \
  --output "$OUT_FILE"

echo "Audio saved to: $OUT_FILE"
# Auto-play on macOS
command -v afplay &>/dev/null && afplay "$OUT_FILE" &

输出: 音频文件路径。在 macOS 上会通过 afplay 自动播放。


transcribe [file_path] — Groq Whisper 转录

需要: userConfig 中的 groq_api_key、GROQ_API_KEY 环境变量或 Doppler 中的密钥。

GROQ_KEY="${GROQ_API_KEY:-$(doppler secrets get GROQ_API_KEY --plain 2>/dev/null || true)}"
AUDIO_FILE="<extracted from $ARGUMENTS>"

if [ ! -f "$AUDIO_FILE" ]; then
  echo "ERROR: File not found: $AUDIO_FILE"
  exit 1
fi

TRANSCRIPT=$(curl -s -X POST "https://api.groq.com/openai/v1/audio/transcriptions" \
  -H "Authorization: Bearer $GROQ_KEY" \
  -F "file=@$AUDIO_FILE" \
  -F "model=whisper-large-v3" \
  -F "response_format=json" | \
  python3 -c "import json,sys; print(json.load(sys.stdin).get('text',''))" 2>/dev/null)

echo "$TRANSCRIPT"

输出: 将转录文本打印到 stdout。


setup — 配置语音 API 密钥

在询问任何信息之前,在单个后台批处理中自动扫描所有来源:

# Env vars
printenv BLAND_AI_API_KEY BLAND_API_KEY ELEVENLABS_API_KEY GROQ_API_KEY 2>/dev/null

# Shell profiles
grep -h 'BLAND\|ELEVENLABS\|GROQ' ~/.zshrc ~/.bashrc ~/.zprofile ~/.envrc 2>/dev/null | grep -v '^#'

# Doppler — ALL projects
for proj in $(doppler projects --json 2>/dev/null | jq -r '.[].slug'); do
  for cfg in dev stg prd; do
    doppler secrets --project "$proj" --config "$cfg" --json 2>/dev/null | \
      jq -r --arg proj "$proj" --arg cfg "$cfg" 'to_entries[] | select(.key | test("BLAND|ELEVENLABS|GROQ"; "i")) | "\(.key)=\(.value.computed | .[0:12])... (doppler:\($proj)/\($cfg))"'
  done
done

# Dashlane
dcli password bland --output json 2>/dev/null | jq -r '.[] | select(.password != null) | "\(.title): key found"'
dcli password elevenlabs --output json 2>/dev/null | jq -r '.[] | select(.password != null) | "\(.title): key found"'
dcli password groq --output json 2>/dev/null | jq -r '.[] | select(.password != null) | "\(.title): key found"'

# Keychain
security find-generic-password -s "bland-ai-api-key" -w 2>/dev/null
security find-generic-password -s "elevenlabs-api-key" -w 2>/dev/null
security find-generic-password -s "groq-api-key" -w 2>/dev/null

展示所有发现结果。仅询问在所有来源中都未找到的密钥。然后在后台验证每个找到的密钥:

  1. Bland AI:curl -s -H "authorization: $KEY" https://api.bland.ai/v1/me — 检查余额
  2. ElevenLabs:curl -s -H "xi-api-key: $KEY" https://api.elevenlabs.io/v1/voices?page_size=1 — 列出语音
  3. Groq:curl -s -H "Authorization: Bearer $KEY" https://api.groq.com/openai/v1/models — 列出模型

报告:[service] ✓ connected 或 [service] ✗ invalid key — [error]


执行

  1. 根据 $ARGUMENTS 解析子命令(第一个词:call / tts / transcribe / setup)
  2. 按顺序解析凭证:环境变量 → Doppler
  3. 执行上方对应的 curl 代码块
  4. 如果缺少必需密钥且未调用 setup,建议使用 /ops:ops-voice setup

评论

支持 Markdown