All Documentation

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.

PropertyValue
Endpointhttps://<host>/api/v1/mcp
TransportStreamable HTTP (stateless, JSON responses)
AuthenticationAuthorization: Bearer <api key> or X-API-Key header
CapabilitiesTools 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

ToolRequired scopeWhat it does
initiate_asset_uploadcanvas:write | models:write | lines:write | sfx:write | music:writeReserve a direct upload for images (64 MiB), meshes (512 MiB), or audio (256 MiB); PUT raw bytes to the returned URL
complete_asset_uploadcanvas:write | models:write | lines:write | sfx:write | music:writeValidate and publish an upload; retries with the same uploadId do not duplicate versions
verify_access—Show the connection's organization and scopes
list_projectsprojects:readList projects (each with its artDirection when set)
get_projectprojects:readGet one project, including its 3D-model art direction
get_organization_modelingorganization:readThe organization and its organization-wide art direction for 3D models
set_organization_modelingorganization:writeReplace (or clear with an empty string) the organization-wide art direction every model job inherits
create_projectprojects:writeCreate a project (the workspace voices, characters, and content belong to); optional artDirection sets the 3D-model house style
list_characterscharacters:readList characters (optional project filter)
get_charactercharacters:readGet one character
create_charactercharacters:writeCreate a character (internal or external voice)
delete_charactercharacters:writeDelete a character (guarded against live-endpoint use)
list_internal_voicesinternal_voices:readList Voice Studio custom voices
design_internal_voiceinternal_voices:writeDesign voice previews from a prompt (spends credits)
save_internal_voiceinternal_voices:writePersist a designed preview (spends credits)
delete_internal_voiceinternal_voices:writeDelete an internal voice (guarded)
list_contentlines:read | sfx:read | models:read | music:readSearch saved lines, sound effects, and 3D models (contentType filter)
get_contentlines:read | sfx:read | models:read | music:readGet one item with full version history (models include every file's URL)
set_active_content_versionlines:write | sfx:write | models:write | music:writePin which version of an item is active
update_contentlines:write | sfx:write | models:write | music:writeRename an item, replace its tags, or link a model to a character (a model's name is its asset name)
delete_contentlines:write | sfx:write | models:write | music:writeDelete an item and all version files
get_model_catalogmodels:readThe 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_presetsmodels:readThe rig contracts in force for the organization and, with projectId, the project: bones, sockets, clips, bounds and which scope each came from
create_model_presetmodels:writeDefine 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_presetmodels:writeReplace a stored preset by id; omitted fields keep their values, the whole contract is re-validated
delete_model_presetmodels:writeDelete a preset of your own; models already built to it are untouched
generate_modelmodels:writeStart 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_jobmodels:readPoll a job: status, stage, round, preview render URLs, cost, art-direction layers used
list_model_jobsmodels:readList jobs, optionally by status / project / content item
wait_for_model_jobmodels:readLong-poll a job for up to 240 s; call it in a loop until done
refine_modelmodels:writeStart 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_jobmodels:writeCancel a queued or running job
initiate_model_importmodels:writeStep 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_importmodels:writeStep 2: turn the uploaded object into a saved model (thumbnail, GLB preview, files) — no credits, no build
start_model_sessionmodels:writeStart 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_messagemodels:writeSay something in a conversation: one message, one turn job; approve a paid tool the agent proposed with approvedTools
get_model_sessionmodels:readThe conversation so far — every message, what each turn did, its renders and cost — and the turn running, if any
export_model_sessionmodels:writeSave what the conversation has built as a version of the model
generate_sfxsfx:writeGenerate a sound effect; optional save to the library
get_music_catalogmusic:readThe music models: id, name, maxDurationSeconds and credits. Read it first — the list is operator-editable
generate_musicmusic:writeGenerate a music track — loop, bed, sting or full cue; optional save to the library. Charged per generation, so length is free
generate_speechtts:generateGenerate speech for a character; optional save as a line (needs lines:write)
enhance_textcharacters:readRewrite a line as the character would say it; optional delivery markup. Free
sample_charactertts:generateAudition a character with sample text
update_charactercharacters:writeEdit a character's name, persona, project, or voice binding
update_projectprojects:writeEdit 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_projectprojects:writeDelete an empty project (guarded against characters, voices, and content)
list_live_endpointslive_endpoints:readList live endpoints (optional project / character filter)
get_live_endpointlive_endpoints:readGet one live endpoint, including its public TTS path
create_live_endpointlive_endpoints:writeCreate a live endpoint for a character (text, TTL, enhancement flags, voice settings)
update_live_endpointlive_endpoints:writeEdit a live endpoint; only provided fields change
delete_live_endpointlive_endpoints:writeDelete a live endpoint
sample_internal_voiceinternal_voices:readAudition a Voice Studio custom voice
get_canvas_catalogcanvas:readCanvas: the picture models with credit estimates, editors, background removal, upscalers, and the named sizes
generate_imagecanvas:writeGenerate a picture from a prompt (menu, HUD, icon, key art) and save it; transparent returns a PNG with alpha (spends credits)
edit_imagecanvas:writeA new version of a Canvas image: an instruction edit, a background cutout, a 2x upscale, or all three (spends credits)
start_canvas_sessioncanvas:writeStart 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_messagecanvas:writeOne message, one Canvas turn (spends credits)
get_canvas_sessioncanvas:readThe Canvas conversation so far, with the pictures each turn made
export_canvas_sessioncanvas:writeSave what the Canvas conversation has made as a version of the image
start_sound_sessionlines:write | sfx:write | music:writeStart 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_messagelines:write | sfx:write | music:writeOne message, one Sound turn (spends credits)
get_sound_sessionlines:read | sfx:read | music:readThe Sound conversation so far, with the meters and waveforms each turn produced
export_sound_sessionlines:write | sfx:write | music:writeSave 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

TopicBehavior
Rate limit60 requests/minute per key, shared with the REST API
CreditsGeneration tools spend organization credits; failures refund automatically
SessionsThe server is stateless — no session ids, safe behind serverless scaling
ErrorsTool failures return readable messages (scope, validation, balance) the agent can act on