MCP server for driving the broadcast avatar of an AITuber. Queue lines with speak, and read what is happening with status.
This is a specialized domain-specific tool set for a theatrical/avatar control system. While tool names are reasonably clear (speak, status, interrupt, react, stage, revise, deck, bgm), descriptions are verbose and domain-specific rather than LLM-optimized. Most descriptions exceed 200 chars and contain implementation details (e.g., 'The brackets are not spoken') rather than clear intent statements. Input schemas are present but lack proper JSON Schema structure, parameters are documented in descriptions but not formally typed in visible schema definitions. No output schemas are documented. Error handling is absent. The domain is niche (avatar control), so some verbosity is expected, but descriptions should still guide LLM selection clearly.
Control the broadcast background music. BGM is separate from synthesized voice and room acoustics. - list rescans the configured show/bgm directory and returns exact .mp3/.flac track ids - play needs an id returned by list; resume continues the selected track without selecting another - volume is the BGM mix level from 0 (silent) to 1 (full); loop controls end-of-track behavior - settings changes only the named BGM mix/DSP/fade fields and requires at least one setting - fade.inSeconds and fade.outSeconds are seconds in the range 0..10. Different-track play crossfades both tracks; 0 is a hard edge. The first/stopped play uses only fade-in. stop fades out over fade.outSeconds and keeps the selection; pause and resume are immediate - The transport actions can also be placed in speak text as [@bgm play], [@bgm play track filename], [@bgm pause] and [@bgm stop]. The filename remainder may contain spaces and Japanese characters; [ and ] are reserved - Inline [@bgm play track] uses the current fade settings; fade is not part of inline cue syntax - DSP is BGM-only: it never changes synthesized voice processing or the staged room
Read a document. Reading only — this cannot present one. - list is the documents the server can see. It returns ids and page counts - read is the text on the pages. Read it to write a script about that document - At most 20 pages per call. For the rest, move from along - Which document is presented is the operator's decision. All the model moves is the page, and that goes in speak's stage.slide
Stop what is being said. mode is required and has no default. now cuts even mid-word. after_line finishes the current line, then throws the rest away.
No documented output schemas. LLMs cannot plan downstream calls or extract required fields without knowing what each tool returns.
Input schemas lack formal JSON Schema type definitions. Parameters are described in text but not formally typed (e.g., 'lines' array type is stated but no minItems/maxItems constraints visible).
Descriptions are verbose and domain-jargon-heavy (e.g., speak: 'Write reading. Only the writer knows how numbers, dates, proper nouns and homographs are read'). LLMs need clear intent statements: WHAT does it do, WHEN to use it, not implementation details.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 46 | 2026-07-28+ | v2 |
An immediate reaction, tied to no line. Nothing is queued; only how it looks right now changes. - Only what is named arrives, together, in one round trip. A call that names nothing sends nothing - perform is an expression and a motion together. expression / gesture replace only one of the two - side names the hand for whichever of the two carries a motion. On its own it sends nothing - An action timed to a line is written with speak's [performance_id] or typed cue, not with react
Edit a queued line. Only the named fields are changed; the rest stay as they were.
Queue lines to be said. What is passed here comes out of the avatar's mouth. - Pass several lines at once. Calling one line at a time puts silence between them - Write reading. Only the writer knows how numbers, dates, proper nouns and homographs are read - [performance_id] is shorthand for [@perform performance_id]. Typed cues are [@perform id], [@expression id], [@gesture id], [@hop id], [@camera face|bust|upper|full], [@slide 3] for an absolute page, [@bgm play], [@bgm play track filename], [@bgm pause] and [@bgm stop]. The brackets are not spoken - For perform, expression, gesture and hop, the whole remainder is the id, so spaces and Japanese characters are allowed - [@bgm play] resumes the selected track. The filename after play may contain spaces and Japanese characters; [ and ] are reserved - BGM volume, looping, fade and DSP stay in the bgm tool or panel settings. room, backdrop, deck and place stay in line-start stage - A document page goes in stage.slide. Write it on the line that talks about that page - Queue lines carrying pages in order and the document follows the speech. This is the only way to keep script and document together
Settings that stick to the broadcast. They stay until changed again, and do not revert across lines. - Changing avatar swaps the whole vocabulary, and from the next call the tools' id lists are replaced - backdrop is where the figure is seen, room is where the voice resonates. Separate axes; either can be changed alone - Voice processing and body tuning are not here. Both are decided against the broadcast mix
What is happening right now, in one round trip. Only the values to branch on; no vocabulary. The document being presented, its page and its page count come back too. Read the vocabulary at hashidate://vocabulary.
No error handling guidance. Tools like 'interrupt' and 'revise' have no documented failure modes or recovery paths. LLMs cannot self-correct on errors.
Parameter enums not formally declared. 'interrupt' mode accepts 'now' or 'after_line' but no enum constraint visible; 'bgm' action accepts multiple values but no enum. Free-form strings invite hallucinated values.