---
title: "LyricWinter MCP tools reference"
description: "Every tool exposed by the LyricWinter Studio MCP server, with inputs, required scopes, side effects, and the recommended agent workflow."
canonical_url: https://lyricwinter.com/docs/mcp-tools
markdown_url: https://lyricwinter.com/docs/mcp-tools.md
last_updated: 2026-09-30
status: beta
---
# LyricWinter MCP tools reference

> Every tool exposed by the LyricWinter Studio MCP server, with inputs, required scopes, side effects, and the recommended agent workflow.

The LyricWinter MCP server exposes 22 tools. Read-only Studio tools need the `studio:read` scope; tools that create or change Studio content need `studio:write`. Voice tools need `voices:read` or `voices:write`. Every tool calls the [LyricWinter REST API](/docs/api) as the connected user.

## In ChatGPT, Claude, and other chat apps

Chat apps that support interactive MCP Apps show a story player and a voice panel inside the conversation. The server tells the model to call `create_audio_story` once with the full story text: the player shows casting and generation progress, then plays the finished audio with the script. Use `play_story` to reopen a story, `share_story` for a public link, `find_voices` with `recast_character` to change a character's voice, and `add_my_voice` when the user wants their own voice. Listing tools and loading the widgets works before an account is linked; every tool that reads or changes an account asks the user to connect LyricWinter.

## Recommended workflow for coding agents

For advanced work on existing Studio projects, use `list_projects` and `list_project_sections` to find IDs, read documents before changing them or generating audio, treat workflow starts as asynchronous and call `get_workflow` until they finish, and never repeat a paid audio start unless the user wants another run.

A typical session:

1. `list_projects` to find the project, or `create_story` to start a new one.
2. `get_document` to read the script and its versions.
3. `start_audio_workflow` after the user confirms which sections to generate.
4. `get_workflow` until the run reaches `completed`, `partially_completed`, `failed`, or `cancelled`.
5. `get_section_media` or `get_playback_manifest` to return playable audio.

## Tool summary

| Tool | Purpose | Scope | Side effects |
| --- | --- | --- | --- |
| `profile` | Identify the connected account | `studio:read` | None |
| `create_audio_story` | Turn story text into fully cast audio with a player | `studio:write` | Creates content, consumes words |
| `play_story` | Open the player for an existing story | `studio:write` | Prepares an MP3 mix |
| `share_story` | Create a public listening link | `studio:write` | Publishes the story |
| `find_voices` | Search the voice library or the user's voices | none, or `voices:read` | None |
| `recast_character` | Change a character's voice and regenerate their lines | `studio:write`, `voices:read` | Changes casting, consumes words |
| `add_my_voice` | Open the voice panel to add the user's own voice | `voices:write` | None until the user uploads |
| `get_story_state` | Player only: refresh progress and the audio URL | `studio:write` | Prepares an MP3 mix |
| `upload_voice_sample` | Voice panel only: create a private voice from a sample | `voices:write` | Creates a voice |
| `get_voice_status` | Voice panel only: check voice processing | `voices:read` | None |
| `list_projects` | List projects and standalone stories | `studio:read` | None |
| `list_project_sections` | List a project's sections in order | `studio:read` | None |
| `get_document` | Read a section's document | `studio:read` | None |
| `list_project_speakers` | List a project's speakers | `studio:read` | None |
| `create_story` | Create a standalone story | `studio:write` | Creates content |
| `create_section` | Add a section to a project | `studio:write` | Creates content |
| `prepare_sections` | Structure sections into a script | `studio:write` | Changes documents |
| `start_audio_workflow` | Generate audio | `studio:write` | Consumes words |
| `get_workflow` | Check workflow progress | `studio:read` | None |
| `cancel_workflow` | Cancel a running workflow | `studio:write` | Stops work |
| `get_section_media` | Get per-block audio for a section | `studio:read` | None |
| `get_playback_manifest` | Get the compiled playback timeline | `studio:read` | None |

## Results and errors

The chat-app tools (`create_audio_story`, `play_story`, `share_story`, `find_voices`, `recast_character`, `add_my_voice`) return a short summary for the model as `structuredContent`; the full script, line timings, and signed audio URL go only to the player in `_meta`. The other tools return the REST API's JSON response, including `data` and `request_id`. Tools that accept a `mutation_id` wrap it as `{ "result": ..., "mutation_id": "..." }` so the agent can retry the same change. A failed tool sets `isError` and returns the API error, plus the `mutation_id` when there is one. If LyricWinter could not confirm whether a write happened, the error says "No result was confirmed"; retry with the same `mutation_id`.

## Account

### `profile`

Identifies the connected LyricWinter account. Returns `id`, `name`, and `email` as structured content. Takes no input.

## Projects and sections

### `list_projects`

Lists the user's Studio projects and standalone stories with their IDs. Takes no input. Calls [`GET /studio/projects`](/docs/api/projects).

### `list_project_sections`

Lists the sections of one project in order, including each section's ID and the project's `section_order_version`. Calls [`GET /studio/projects/{projectId}/sections`](/docs/api/sections).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | UUID | Yes | The project to list. |

### `create_story`

Creates a standalone Studio story from text. Calls [`POST /studio/sections`](/docs/api/sections).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `title` | string, 1–500 characters | Yes | Story title. |
| `raw_text` | string, 1–100,000 characters | Yes | The story text. |
| `mutation_id` | UUID | No | Reuse only when retrying the exact same creation. Generated if omitted. |

### `create_section`

Adds a section to an existing project. Read the project's sections first to get its current `section_order_version`. Calls [`POST /studio/projects/{projectId}/sections`](/docs/api/sections).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | UUID | Yes | The project to add to. |
| `base_section_order_version` | integer or null | Yes | The `section_order_version` from `list_project_sections`. |
| `title` | string, 1–500 characters | Yes | Section title. |
| `raw_text` | string, 1–100,000 characters | Yes | The section text. |
| `mutation_id` | UUID | No | Reuse only when retrying the exact same creation. |

## Documents and speakers

### `get_document`

Reads a section's current document: its version, blocks, speakers, and edit targets. Agents should read the document before generating audio. Calls [`GET /studio/sections/{sectionId}/document`](/docs/api/documents).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `section_id` | UUID | Yes | The section to read. |

### `list_project_speakers`

Lists the speakers used in a project and their casting status. Calls [`GET /studio/projects/{projectId}/speakers`](/docs/api/documents).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | UUID | Yes | The project to inspect. |

## Workflows

### `prepare_sections`

Starts an asynchronous workflow that structures sections into narration and dialogue without generating audio. Poll `get_workflow` for completion. Calls [`POST /studio/projects/{projectId}/workflows`](/docs/api/workflows) with `workflow_kind: "prepare_sections"`.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | UUID | Yes | The project that owns the sections. |
| `section_ids` | array of UUIDs, 1–100 | Yes | Sections to prepare. |
| `mutation_id` | UUID | No | Reuse only when retrying the same request. |

### `start_audio_workflow`

Starts the paid, asynchronous Create Audio workflow for selected sections. It prepares text, casts voices, directs performances, adds sound effects, and generates audio. Confirm the scope and cost with the user first, then poll `get_workflow`. Calls [`POST /studio/projects/{projectId}/workflows`](/docs/api/workflows) with `workflow_kind: "create_audio"`.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | UUID | Yes | The project that owns the sections. |
| `section_ids` | array of UUIDs, 1–12 | Yes | Sections to generate. |
| `include_generated_sfx` | boolean | No | Add AI-generated sound effects. Defaults to `true`. |
| `place_project_sounds` | boolean | No | Place sounds linked to the project. Defaults to `true`. |
| `mutation_id` | UUID | No | Reuse only when retrying the same run. A new ID starts a new, separately billed run. |

### `get_workflow`

Returns a workflow's status, current stage, step progress, warnings, and errors. Calls [`GET /studio/workflows/{workflowRunId}`](/docs/api/workflows).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `workflow_id` | UUID | Yes | The `run.id` returned when the workflow started. |

### `cancel_workflow`

Requests cancellation of a running workflow. Agents should ask the user before cancelling. Calls [`POST /studio/workflows/{workflowRunId}/cancel`](/docs/api/workflows).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `workflow_id` | UUID | Yes | The workflow to cancel. |

## Media and playback

### `get_section_media`

Returns the generated audio state of every block in a section, with short-lived signed playback URLs. Calls [`GET /studio/sections/{sectionId}/media`](/docs/api/media).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `section_id` | UUID | Yes | The section to inspect. |

### `get_playback_manifest`

Returns the compiled playback timeline for a section. Pass the versions returned by `get_document`. Calls [`GET /studio/sections/{sectionId}/playback-manifest`](/docs/api/media).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `section_id` | UUID | Yes | The section to play. |
| `document_version` | integer | Yes | `document.document_version` from `get_document`. |
| `speaker_registry_version` | integer | Yes | `document.speaker_registry_version` from `get_document`. |

## Listening in chat apps

### `create_audio_story`

Turns a story, fanfic, script, or chapter into fully cast audio. Creates a standalone story ([`POST /studio/sections`](/docs/api/sections)) and starts Create audio, which detects characters, casts voices, directs the performances, and adds sound. Returns the story player, which tracks progress on its own. Uses words from the user's balance.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `story_text` | string, 1–100,000 characters | Yes | The complete story text. |
| `title` | string, 1–200 characters | No | Story title. Derived from the first line if omitted. |
| `sound_effects` | boolean | No | Add ambient sound and sound effects. Defaults to `true`. |

### `play_story`

Opens the player for a story the user already made. Prepares an MP3 mix of the current audio when needed.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `section_id` | UUID | No | The story to open. Defaults to the user's most recent story. |

### `share_story`

Publishes a story and returns its public listening link. Anyone with the link can listen and read the script. Calls [`POST /studio/sections/{sectionId}/share`](/docs/api/sections).

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `section_id` | UUID | Yes | The story to share. |

## Voices

### `find_voices`

Searches LyricWinter's public voice library, or the user's own voices, and returns voice IDs for `recast_character`. Library search works without a linked account.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `query` | string, up to 200 characters | No | Words describing the voice, or a voice name. |
| `mine` | boolean | No | Search only the user's voices. Requires a linked account. |

### `recast_character`

Changes a character's voice with Studio's preferred engine for that voice, then regenerates the character's lines unless told not to.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `section_id` | UUID | Yes | The story. |
| `character` | string | Yes | The character's name as shown in the cast. |
| `voice_id` | UUID | Yes | A voice from `find_voices`. |
| `regenerate_audio` | boolean | No | Regenerate the changed lines. Defaults to `true`. |

### `add_my_voice`

Opens the voice panel, where the user records or uploads a 10–30 second sample of their own voice and confirms they have permission to use it. The new voice is private.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `voice_name` | string, 1–80 characters | No | Suggested name for the voice. |

## Player and voice panel

These tools are called by the widgets and hidden from the model.

### `get_story_state`

Refreshes a story's progress, cast, script timings, and signed audio URL.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `section_id` | UUID | Yes | The story. |
| `workflow_id` | UUID or null | No | The Create audio run to track. |

### `upload_voice_sample`

Creates a private voice from the user's sample through the same upload flow as LyricWinter's apps.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string, 1–80 characters | Yes | Voice name. |
| `mime_type` | string | Yes | The sample's audio type, such as `audio/webm`. |
| `data_base64` | string | Yes | The sample, base64-encoded, up to 2.5 MB. |
| `permission_confirmed` | `true` | Yes | The user confirmed they have permission to use this voice. |

### `get_voice_status`

Checks whether a new voice has finished processing.

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `voice_id` | UUID | Yes | The voice to check. |
