mcpField
O
ops-voice

ops-voice

github.com/davepoon生産性3.7k69 回インストール1 日前に更新
リポジトリ

ops-voice について

ops-voiceは、curl経由のAPI呼び出しで音声関連の操作を行うClaudeスキルです。Bland AIでの通話、ElevenLabsによる音声合成、Groqでの音声文字起こし、APIキーの設定に対応します。

主な機能

  1. 01Bland AIによる電話発信
  2. 02ElevenLabsによるテキスト読み上げ
  3. 03Groq Whisperによる音声文字起こし
  4. 04APIキーの検出と検証

活用シーン

  1. 01プロンプトに基づく電話発信
  2. 02テキストから音声ファイルを作成
  3. 03音声ファイルを文字起こし
  4. 04音声サービスの認証情報を設定・確認

MCP 対応

API認証情報の取得元の一つとしてDoppler MCPツールを利用できます。音声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 環境変数、または Doppler に bland_ai_api_key があること。

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 環境変数、または Doppler に elevenlabs_api_key があること。

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 環境変数、または Doppler に groq_api_key があること。

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"

出力: 標準出力に表示される文字起こしテキスト。


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] ✓ 接続済み、または [service] ✗ 無効なキー — [error]


実行

  1. $ARGUMENTS からサブコマンドを解決します(最初の単語:call / tts / transcribe / setup)
  2. 順序に従って認証情報を解決します:環境変数 → Doppler
  3. 該当する上記の curl ブロックを実行します
  4. 必須のキーがなく、setup が実行されていない場合は、/ops:ops-voice setup を提案します

コメント