MCP Server
Give AI agents scoped access to Tonetta — voices, characters, content, and audio generation as MCP tools
Overview
Tonetta hosts a Model Context Protocol (MCP) server, so AI agents like Claude Code, Claude Desktop, and claude.ai projects can work with your organization directly: browse voices, create characters, search saved content, and generate speech or sound effects.
It can also generate rigged 3D models. The server authenticates with the same scoped API keys as the REST API — and the tool list itself is filtered by the key's scopes. An agent connected with a read-only key never even sees the write tools.
| Property | Value |
|---|---|
| Endpoint | https://<host>/api/v1/mcp |
| Transport | Streamable HTTP (stateless, JSON responses) |
| Authentication | Authorization: Bearer <api key> or X-API-Key header |
| Capabilities | Tools only |
Connecting
Claude Code (CLI)
claude mcp add --transport http toneboard https://<host>/api/v1/mcp \
--header "Authorization: Bearer <your-api-key>"Project config (.mcp.json)
{
"mcpServers": {
"toneboard": {
"type": "http",
"url": "https://<host>/api/v1/mcp",
"headers": { "Authorization": "Bearer <your-api-key>" }
}
}
}Try it
After connecting, ask the agent to run verify_access — it reports the organization and scopes the connection has, which explains exactly which tools are available.
Unreal Engine
The Tonetta Unreal plugin talks to tonetta.io directly with your API key — it does not need this MCP server. It also registers TonettaEditor.TonettaService as a native UE 5.8 AI toolset, so an agent already connected to Unreal's own MCP server (the engine's Unreal MCP plugin, optionally with VibeUE) gets the same operations as the table below plus import_content, which turns generated audio into USoundWave assets. Connect this hosted server as well only when the agent works outside the editor, or when the editor is not running.
Tools
| Tool | Required scope | What it does |
|---|---|---|
initiate_asset_upload | canvas:write | models:write | lines:write | sfx:write | music:write | Reserve a direct upload for images (64 MiB), meshes (512 MiB), or audio (256 MiB); PUT raw bytes to the returned URL |
complete_asset_upload | canvas:write | models:write | lines:write | sfx:write | music:write | Validate and publish an upload; retries with the same uploadId do not duplicate versions |
verify_access | — | Show the connection's organization and scopes |
list_projects | projects:read | List projects (each with its artDirection when set) |
get_project | projects:read | Get one project, including its 3D-model art direction |
get_organization_modeling | organization:read | The organization and its organization-wide art direction for 3D models |
set_organization_modeling | organization:write | Replace (or clear with an empty string) the organization-wide art direction every model job inherits |
create_project | projects:write | Create a project (the workspace voices, characters, and content belong to); optional artDirection sets the 3D-model house style |
list_characters | characters:read | List characters (optional project filter) |
get_character | characters:read | Get one character |
create_character | characters:write | Create a character (internal or external voice) |
delete_character | characters:write | Delete a character (guarded against live-endpoint use) |
list_internal_voices | internal_voices:read | List Voice Studio custom voices |
design_internal_voice | internal_voices:write | Design voice previews from a prompt (spends credits) |
save_internal_voice | internal_voices:write | Persist a designed preview (spends credits) |
delete_internal_voice | internal_voices:write | Delete an internal voice (guarded) |
list_content | lines:read | sfx:read | models:read | music:read | Search saved lines, sound effects, and 3D models (contentType filter) |
get_content | lines:read | sfx:read | models:read | music:read | Get one item with full version history (models include every file's URL) |
set_active_content_version | lines:write | sfx:write | models:write | music:write | Pin which version of an item is active |
update_content | lines:write | sfx:write | models:write | music:write | Rename an item, replace its tags, or link a model to a character (a model's name is its asset name) |
delete_content | lines:write | sfx:write | models:write | music:write | Delete an item and all version files |
get_model_catalog | models:read | The 3D model catalog: the operator-curated LLM list (vision flag, estimated and reserved credits per tier), tiers, presets with bones / sockets / clips, styles, targets; the build agent chooses its own vendors |
list_model_presets | models:read | The rig contracts in force for the organization and, with projectId, the project: bones, sockets, clips, bounds and which scope each came from |
create_model_preset | models:write | Define a rig contract of your own (bones, hierarchy, sockets, clips, bounds), for the organization or one project; a name shared with a built-in replaces it whole |
update_model_preset | models:write | Replace a stored preset by id; omitted fields keep their values, the whole contract is re-validated |
delete_model_preset | models:write | Delete a preset of your own; models already built to it are untouched |
generate_model | models:write | Start a 3D model generation job from a prompt (reserves credits). The prompt is the whole specification — the agent picks the name, rig (unless preset names one), style and finish; returns the job id immediately |
get_model_job | models:read | Poll a job: status, stage, round, preview render URLs, cost, art-direction layers used |
list_model_jobs | models:read | List jobs, optionally by status / project / content item |
wait_for_model_job | models:read | Long-poll a job for up to 240 s; call it in a loop until done |
refine_model | models:write | Start a refine job on a saved model from plain instructions (new version) — “make the wings 20% longer”, “scuff up the paint”; the fal.ai vendor keys default to the version's own |
cancel_model_job | models:write | Cancel a queued or running job |
initiate_model_import | models:write | Step 1 of importing a mesh you already have (GLB / FBX / OBJ): reserves a storage key and answers a presigned PUT URL to send the bytes to |
complete_model_import | models:write | Step 2: turn the uploaded object into a saved model (thumbnail, GLB preview, files) — no credits, no build |
start_model_session | models:write | Start a conversation with the build agent: the message is the brief (a new model is created), or pass contentId to talk about an existing one. The agent does one step per message and asks where to go next |
send_model_message | models:write | Say something in a conversation: one message, one turn job; approve a paid tool the agent proposed with approvedTools |
get_model_session | models:read | The conversation so far — every message, what each turn did, its renders and cost — and the turn running, if any |
export_model_session | models:write | Save what the conversation has built as a version of the model |
generate_sfx | sfx:write | Generate a sound effect; optional save to the library |
get_music_catalog | music:read | The music models: id, name, maxDurationSeconds and credits. Read it first — the list is operator-editable |
generate_music | music:write | Generate a music track — loop, bed, sting or full cue; optional save to the library. Charged per generation, so length is free |
generate_speech | tts:generate | Generate speech for a character; optional save as a line (needs lines:write) |
enhance_text | characters:read | Rewrite a line as the character would say it; optional delivery markup. Free |
sample_character | tts:generate | Audition a character with sample text |
update_character | characters:write | Edit a character's name, persona, project, or voice binding |
update_project | projects:write | Edit project name, description, default sample text, or artDirection — the house style every 3D model job in the project inherits (an empty string clears it) |
delete_project | projects:write | Delete an empty project (guarded against characters, voices, and content) |
list_live_endpoints | live_endpoints:read | List live endpoints (optional project / character filter) |
get_live_endpoint | live_endpoints:read | Get one live endpoint, including its public TTS path |
create_live_endpoint | live_endpoints:write | Create a live endpoint for a character (text, TTL, enhancement flags, voice settings) |
update_live_endpoint | live_endpoints:write | Edit a live endpoint; only provided fields change |
delete_live_endpoint | live_endpoints:write | Delete a live endpoint |
sample_internal_voice | internal_voices:read | Audition a Voice Studio custom voice |
get_canvas_catalog | canvas:read | Canvas: the picture models with credit estimates, editors, background removal, upscalers, and the named sizes |
generate_image | canvas:write | Generate a picture from a prompt (menu, HUD, icon, key art) and save it; transparent returns a PNG with alpha (spends credits) |
edit_image | canvas:write | A new version of a Canvas image: an instruction edit, a background cutout, a 2x upscale, or all three (spends credits) |
start_canvas_session | canvas:write | Start a conversation with the Canvas agent: composite art step by step (sprite sheets, button states, 9-slice panels, text) from a brief or about an existing image |
send_canvas_message | canvas:write | One message, one Canvas turn (spends credits) |
get_canvas_session | canvas:read | The Canvas conversation so far, with the pictures each turn made |
export_canvas_session | canvas:write | Save what the Canvas conversation has made as a version of the image |
start_sound_session | lines:write | sfx:write | music:write | Start a conversation with the Sound agent: about a saved line, effect or track (loudness, radio and room processing, trims, fades, loops), or from a brief — it generates with the sound-effects and music models, compares takes, and makes the result game-ready |
send_sound_message | lines:write | sfx:write | music:write | One message, one Sound turn (spends credits) |
get_sound_session | lines:read | sfx:read | music:read | The Sound conversation so far, with the meters and waveforms each turn produced |
export_sound_session | lines:write | sfx:write | music:write | Save the processed clip as a new version of the line or effect |
Not on MCP by design
The two multipart upload endpoints (POST /api/v1/content and POST /api/v1/content/{id}/versions) have no tool: MCP arguments are JSON, and the Unreal plugin imports in the other direction. Everything else on the REST API is a tool with the same arguments; by-id tools take id (a descriptive alias such as projectId / contentId is also accepted).
Per-item scoping
Content tools check the item's type at call time: a key with only sfx:write can manage sound effects but gets a scope error on lines or 3D models, even through the same tool.
3D models are asynchronous
generate_model and refine_model return a job id at once; the model takes minutes. Agents should call wait_for_model_job in a loop until done, then get_content for the file URLs. See 3D Models.
Example Session
A typical agent workflow with a key scoped to characters:read, tts:generate, and lines:write:
You: "Generate a greeting line for the Narrator character and save it as 'Greeting v3'."
Agent:
1. verify_access -> sees tts:generate, lines:write, characters:read
2. list_characters -> finds "Narrator" (id: chr_...)
3. generate_speech -> { characterId: "chr_...", text: "Welcome...",
saveName: "Greeting v3" }
4. Replies with the audio URL; the line is in Saved Content as the active version.Notes
| Topic | Behavior |
|---|---|
| Rate limit | 60 requests/minute per key, shared with the REST API |
| Credits | Generation tools spend organization credits; failures refund automatically |
| Sessions | The server is stateless — no session ids, safe behind serverless scaling |
| Errors | Tool failures return readable messages (scope, validation, balance) the agent can act on |