google-ai-studio-tts — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited google-ai-studio-tts (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This skill drives https://aistudio.google.com/generate-speech in the user's already-open Chrome (via the claude-in-chrome MCP tools) to render audio with Gemini Flash TTS. The user must already be signed in to Google AI Studio in Chrome — never create accounts, never enter passwords, never share credentials.
There are two input modes in the UI. Choose based on what the user asked for:
| User intent | Mode | Why |
|---|---|---|
| Single narrator, monologue, or short voiceover | Text | One textarea, fastest path. |
Multi-speaker dialogue with simple Speaker 1: … lines | Text | Same single textarea — prefix lines with Speaker 1:, Speaker 2:. |
| Multi-speaker with per-line speaker chip, finer control, easy editing | Composer | One block per utterance, each with its own voice chip. |
| Anything where the user explicitly mentions "scene", "sample context", "director's note", or wants the speaker chips visible | Composer | Matches the visible UI elements they're referring to. |
Both modes share the Scene and Sample Context fields and the Speaker settings panel on the right.
Load these claude-in-chrome MCP tools via ToolSearch before starting:
select:mcp__claude-in-chrome__tabs_context_mcp,mcp__claude-in-chrome__tabs_create_mcp,mcp__claude-in-chrome__navigate,mcp__claude-in-chrome__find,mcp__claude-in-chrome__form_input,mcp__claude-in-chrome__javascript_tool,mcp__claude-in-chrome__computertabs_context_mcp({ createIfEmpty: true })
navigate({ tabId, url: "https://aistudio.google.com/generate-speech?model=gemini-3.1-flash-tts-preview" })If the URL shows a banner that the chosen model is unavailable and AI Studio auto-switched to another (e.g. gemini-3.1-flash-tts-preview), accept it — don't fight the redirect. Close the dismiss-banner ("X") with a click before continuing so it doesn't cover Run controls.
The two toggle buttons live at the top right of the playground:
// Switch to Composer
document.querySelectorAll('button.toggle-button').forEach(b => {
if (b.innerText.trim().endsWith('Composer')) b.click();
});
// or for Text
document.querySelectorAll('button.toggle-button').forEach(b => {
if (b.innerText.trim().endsWith('Text')) b.click();
});The active toggle has class ms-button-active.
Both modes share:
textarea[aria-label="Scene"]textarea[aria-label="Sample Context"]These are Angular textareas. Plain el.value = ... will NOT trigger Angular's form binding — use the helper in references/selectors.md, or prefer the form_input MCP tool with a ref obtained from find.
Leave these fields empty if the user did not provide a scene / sample context. They are optional.
One textarea: textarea[aria-label="Enter a prompt"].
Format conventions (these are not validated by the UI but are what the model is trained on):
[warm] Welcome to today's episode.Speaker 1:, Speaker 2:, …Speaker 1: [enthusiastic] Welcome back to the show!
Speaker 2: [agreement] Thanks, glad to be here.See references/audio-tags.md for the inline-tag vocabulary.
Composer renders one speech block per utterance. Each block has:
button.voice-chip.ms-button-filter-chip (text reads Speaker N - VoiceName)textarea[aria-label="Speech block text"]To add a new block: click button.add-speech-block-button. The new block inherits the previous speaker by default.
To populate Composer from a script:
× button if necessary).textarea[aria-label="Speech block text"], indexed in DOM order).The right-hand Speaker settings panel shows one card per active speaker (Speaker 1, Speaker 2, …). Clicking a card opens the full voice picker drawer with 32 voices. See references/voices.md for the full catalogue with their character traits.
Inside the voice picker drawer:
Close the drawer by clicking the × in its top-right when done. The active voice card on the playground has class active-voice-card.
In Composer mode each block's voice chip can be changed independently — clicking it opens a popover where you assign that block to Speaker 1, Speaker 2, … or add a new speaker.
Expand "Model settings" (right panel, above Speaker settings) to reveal Temperature. Range 0–2, default 1. The number input is input.slider-number-input near the label "Temperature". Higher = more variation in delivery. Only touch this if the user asked for it.
Click button.ctrl-enter-submits (the "Run Ctrl ↵" button at the bottom right), or press Ctrl+Enter while focus is in the prompt area:
document.querySelector('button.ctrl-enter-submits').click();Generation usually takes 5–30 s depending on length. Poll for completion by checking the audio player's duration counter (the right-hand 0:00 / X:XX increments once render is done) or by watching for the download icon to become enabled.
Tell the user the audio is ready and point at the playback controls. Downloading is the user's choice — only click the download (cloud-arrow) icon if the user asked for a file.
Speaker 1: [whispers] don't tell anyone. They do not stack across lines.el.value = "…" on Angular textareas without dispatching input and change events; the form will revert. Use the helper in references/selectors.md or form_input.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.