Skill

Generate Russian Speech from Text

Claude Code skill that speaks its answers out loud through a Yandex Station smart speaker in Alice's voice, over the local Glagol protocol.


91
Spark score
out of 100
Updated 4 months ago
Version 1.0.0
Models
claude

Add to Favorites

Why it matters

Leverage Yandex SpeechKit TTS to generate high-quality audio from Russian text. This asset is ideal for applications requiring natural-sounding voiceovers or spoken content in Russian.

Outcomes

What it gets done

01

Convert Russian text into spoken audio

02

Utilize Yandex SpeechKit for TTS generation

03

Provide audio output for various applications

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/yandex-tts | bash

Overview

Yandex Text-to-Speech

Lets Claude Code speak its answers out loud through a Yandex Station smart speaker, using Alice's voice. It connects to the station over the local Glagol WebSocket protocol and sends the text via a repeat_phrase command. Use it when a response should be read aloud through a Yandex smart speaker instead of just displayed as text. Requires a Yandex account with a linked station on the same local network as the machine running Claude Code.

What it does

The Yandex Text-to-Speech skill lets Claude Code speak its responses out loud through a Yandex Station smart speaker, in Alice's voice. When a user asks Claude to say something through the speaker, Claude Code sends the text to a small Python script (tts.py), which talks to the Yandex Quasar API to obtain a conversation_token, then connects directly to the station over the local network via the Glagol protocol - a local WebSocket API on port 1961 - and issues a repeat_phrase command that makes the station speak the text.

When to use - and when NOT to

Use it whenever a user asks for a spoken answer through the speaker, or whenever it's contextually useful to have the response read aloud by Alice. It is not a general text-to-speech engine for arbitrary output devices - it only works with Yandex speakers that support the Glagol protocol, and only when the computer running Claude Code and the station are on the same local network. Long responses are not fully spoken either: text is capped at 500 characters, and anything past that limit is truncated, so it is best suited to short confirmations or summaries rather than long-form narration.

Inputs and outputs

Setup is a one-time process: clone the skill into ~/.claude/skills/speak, copy .env.example to .env, and fill in a MUSIC_TOKEN (a Yandex OAuth token obtained via a documented session-id -> x_token -> music_token exchange, based on the method from the AlexxIT/YandexStation project). Running tts.py --list-devices discovers every speaker on the account via mDNS and prints its id and platform, which are copied into DEVICE_ID and DEVICE_PLATFORM in .env:

~/.claude/skills/speak/scripts/tts.py --list-devices

Once configured, tts.py "some text" sends that text to the station to be spoken; --discover finds and saves the station's IP via mDNS. The CONVERSATION_TOKEN and its expiry are cached automatically and refreshed roughly every 25 minutes; before speaking, the script strips Markdown formatting, code blocks, and special characters from the input text.

Integrations

There are no external runtime dependencies - the skill is pure Python 3.10+ standard library, including its own WebSocket client implemented per RFC 6455. It requires macOS for automatic IP discovery (via the dns-sd command over mDNS's _yandexio._tcp service); on Linux the station's IP must be set manually via STATION_IP. It works with any Yandex speaker that speaks Glagol, including the Yandex Station, Station 2, Station Max, Station Mini, Station Mini 2, Station Lite, Yandex Module/Module 2, and several third-party Glagol-compatible speakers (JBL Link Portable, JBL Link Music, Elari SmartBeat, DEXP Smartbox). Common failure modes documented include a refused connection on port 1961 (station offline or on a different network), a stale MUSIC_TOKEN after roughly a year (requiring the token procedure again), and an expired CONVERSATION_TOKEN, which self-heals by simply deleting the cached token fields from .env.

Who it's for

Users running Claude Code at home or in a home-office setup who already own a Yandex Station (or another Glagol-compatible speaker) and want Claude's answers read aloud through it, rather than only displayed as text.

Source README

claude-skill-yandex-tts -- Claude Code Skill for text-to-speech via Yandex Station

A skill for Claude Code that enables voice output through Yandex Station using Alice's voice. When a user asks to speak something through the speaker or have an answer read aloud, Claude Code automatically sends the text to the station.

How it works

┌─────────────┐     ┌──────────────┐     ┌───────────────────┐     ┌────────────────┐
│ Claude Code  │────>│  /speak      │────>│  Yandex Quasar    │────>│ Yandex Station │
│  (CLI)       │     │  tts.py      │     │  API (Glagol)     │     │  (Alice)       │
└─────────────┘     └──────────────┘     └───────────────────┘     └────────────────┘
                     Pure Python 3          WebSocket (WSS)         Text-to-speech
                     Stdlib only            port 1961               with Alice voice

Glagol protocol is the local WebSocket API for Yandex Station. The script:

  1. Obtains conversation_token via Yandex Quasar API (OAuth authorization)
  2. Connects directly to the station over local network (WSS, port 1961)
  3. Sends repeat_phrase command -- the station speaks the text in Alice's voice
  4. Token is cached for 25 minutes, station IP is auto-discovered via mDNS

Requirements

  • Python 3.10+ (uses type hints dict[str, str], str | None)
  • macOS (mDNS discovery via dns-sd; on Linux you need to specify IP manually)
  • Yandex account with a linked Yandex Station
  • Computer and station must be on the same local network

No external dependencies -- the script uses only Python's standard library.

Installation

1. Clone the repository

git clone git@github.com:rasperepodvipodvert/claude-skill-yandex-tts.git ~/.claude/skills/speak

2. Create config

cp ~/.claude/skills/speak/.env.example ~/.claude/skills/speak/.env

3. Get tokens (see section below)

Fill in MUSIC_TOKEN in the .env file.

4. Find Device ID

~/.claude/skills/speak/scripts/tts.py --list-devices

Output will show all speakers on your account:

Fetching device list...
Scanning local network via mDNS...
  Station Mini  platform=yandexmini_2  id=XXXXXXXXXXXXXXX  IP: 192.168.1.100

Copy the id and platform to .env:

DEVICE_ID=XXXXXXXXXXXXXXX
DEVICE_PLATFORM=yandexmini_2

5. Test

~/.claude/skills/speak/scripts/tts.py "Hello, I'm Claude!"

If everything is configured correctly, the speaker will say the text.

6. Make script executable (if needed)

chmod +x ~/.claude/skills/speak/scripts/tts.py

Getting tokens

You need a MUSIC_TOKEN (Yandex OAuth token). The token retrieval procedure is based on the method from the AlexxIT/YandexStation project and uses public client_id/client_secret from the Yandex Music app.

Step 1: Get session_id via login

Log in to https://passport.yandex.ru and extract Session_id from cookies.

Or programmatically (requires password, 2FA, etc.) -- manual retrieval via browser is recommended.

Step 2: Get x_token

curl -s 'https://mobileproxy.passport.yandex.net/1/bundle/oauth/token_by_sessionid' \
  -H 'Ya-Client-Host: passport.yandex.ru' \
  -H 'Ya-Client-Cookie: Session_id=YOUR_SESSION_ID_HERE' \
  -d 'client_id=c0ebe342af7d48fbbbfcf2d2eedb8f9e&client_secret=ad0a908f0aa341a182a37ecd75bc319e'

Response contains x_token:

{"status": "ok", "x_token": "y0_AgAAAA..."}

Step 3: Get music_token (OAuth)

curl -s 'https://oauth.yandex.ru/token' \
  -d 'grant_type=x-token&client_id=23cabbbdc6cd418abb4b39c32c41195d&client_secret=53bc75238f0c4d08a118e51fe9203300&access_token=YOUR_X_TOKEN_HERE'

Response contains access_token -- this is your MUSIC_TOKEN:

{"access_token": "y0_AgAAAAAF...", "token_type": "bearer", ...}

Step 4: Write to .env

MUSIC_TOKEN=y0_AgAAAAAF...

Note: The client_id and client_secret in the commands above are public keys from Yandex apps (from the YandexStation project). They are not secrets.

MUSIC_TOKEN lifetime: The token is valid for approximately 1 year. After expiration, repeat the retrieval procedure (steps 1--3).

Usage

From command line

# Speak text
~/.claude/skills/speak/scripts/tts.py "Good morning! It will be sunny today."

# List all speakers on account (with mDNS IP discovery)
~/.claude/skills/speak/scripts/tts.py --list-devices

# Discover station IP via mDNS and save to .env
~/.claude/skills/speak/scripts/tts.py --discover

As a Claude Code skill

After installation in ~/.claude/skills/speak/, the skill is available automatically. Claude Code will use it when:

  • User asks to read the answer aloud
  • User asks to say something through the speaker
  • It makes sense in the conversation to speak the answer

Example:

> /speak Tell me a joke through the speaker

Configuration (.env)

Variable Description Required
MUSIC_TOKEN Yandex OAuth token Yes
DEVICE_ID Device ID (from --list-devices) Yes
DEVICE_PLATFORM Platform (e.g. yandexmini_2) Yes
STATION_IP Station IP address (auto-discovered via mDNS) No*
CONVERSATION_TOKEN Cached session token (auto-managed) No
CONVERSATION_TOKEN_EXPIRES Token expiration time (auto-managed) No

* If STATION_IP is not specified or the station doesn't respond, the script will attempt to find it via mDNS automatically.

Features

  • Zero dependencies -- pure Python 3, stdlib only. WebSocket client implemented manually per RFC 6455.
  • Auto IP discovery -- station is found via mDNS (_yandexio._tcp service). On macOS uses dns-sd.
  • Token caching -- conversation_token is saved to .env and refreshed every 25 minutes.
  • Text cleanup -- Markdown formatting, code blocks, special characters are automatically removed before playback.
  • 500 character limit -- longer texts are truncated.

Speaker compatibility

The script works with any Yandex speaker that supports the Glagol protocol:

Model Platform ID
Yandex Station (large) yandexstation
Yandex Station 2 yandexstation_2
Yandex Station Max yandexstation_2
Yandex Station Mini yandexmini
Yandex Station Mini 2 yandexmini_2
Yandex Station Lite yandexmicro
Yandex Module yandexmodule
Yandex Module 2 yandexmodule_2
JBL Link Portable linkplay_a98
JBL Link Music jbl_link_music
Elari SmartBeat elari_a98
DEXP Smartbox dexp_smartbox

Platform ID may differ across revisions. Use --list-devices to get the exact value.

Troubleshooting

Issue Solution
connection refused on port 1961 Station is offline or computer is not on the same network. Check that the station is on and both devices are on the same LAN.
mDNS can't find station Make sure computer and station are on the same network. On Linux mDNS may not work -- specify IP manually in STATION_IP in .env.
conversation_token expired (auth errors when sending) Delete CONVERSATION_TOKEN and CONVERSATION_TOKEN_EXPIRES from .env -- the script will get a new token automatically.
token expired / errors with MUSIC_TOKEN Token has expired (lifetime ~1 year). Repeat the MUSIC_TOKEN retrieval procedure (steps 1--3 from "Getting tokens" section).

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.