@kolbo/mcp 1.111.0 → 1.112.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -147,7 +147,7 @@ Without the optional skill, the config block alone already exposes every tool
147
147
  | `generate_lipsync` | Source image/video + audio → lipsynced video (Sync-3 adds active-speaker selection, emotion, model mode, temperature) |
148
148
  | `generate_creative_director` | One brief → N coordinated scenes (image or video) |
149
149
  | `generate_music` | Text (+ optional lyrics) → song. Style, title, negative tags, length, and Suno fine-controls (style weight, weirdness, audio weight, persona / singing voice) |
150
- | `generate_speech` | Text + voice → spoken audio. Full expressive/style control: Google/Gemini named voice-direction presets (`style_instructions_preset_id`: warm/dramatic/whisper/…) or free-form `style_instructions`, preset styles + emotions (DeepDub / MiniMax / Cartesia), speed, accent/`language`, and per-provider voice settings (ElevenLabs stability/similarity/style/speaker boost/seed, `enforce_language`, `output_format` mp3/wav, `text_normalization`; DeepDub accent/variance/tempo, MiniMax pitch/volume/intensity/timbre), plus `audio_effect` (phone/radio/megaphone/small_room/hall/distant) + `audio_effect_strength` for any voice at no extra credits. Status returns the same fields for reuse. |
150
+ | `generate_speech` | Text + voice → spoken audio. `eleven_model` (eleven_v4 / eleven_v3 / eleven_multilingual_v2) picks which ElevenLabs model speaks an ElevenLabs voice (stock or own clone; omit = the voice's default; same price; `turbo` needs v4). Full expressive/style control: Google/Gemini named voice-direction presets (`style_instructions_preset_id`: warm/dramatic/whisper/…) or free-form `style_instructions`, preset styles + emotions (DeepDub / MiniMax / Cartesia), speed, accent/`language`, and per-provider voice settings (ElevenLabs stability/similarity/style/speaker boost/seed, `enforce_language`, `output_format` mp3/wav, `text_normalization`; DeepDub accent/variance/tempo, MiniMax pitch/volume/intensity/timbre), plus `audio_effect` (phone/radio/megaphone/small_room/hall/distant) + `audio_effect_strength` for any voice at no extra credits. Status returns the same fields for reuse. |
151
151
  | `generate_sound` | Text → sound effect. Duration, prompt influence, and per-provider controls (Stable Audio guidance, Kie loop/tempo/key, Seed-Audio voice/speed/volume/pitch + reference audio/image) |
152
152
  | `generate_3d` | Text or reference images → 3D model (GLB/FBX/OBJ/USDZ) |
153
153
  | `transcribe_audio` | Audio/video URL or file → text + SRT subtitles. Language, speaker diarization, audio-event tagging, and SRT formatting (words/line, lines/subtitle, caption stretch) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolbo/mcp",
3
- "version": "1.111.0",
3
+ "version": "1.112.0",
4
4
  "description": "Kolbo AI MCP Server - Generate images, videos, music, speech, and sound effects from Claude Code",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -233,8 +233,9 @@ function voiceLabel(sc) { return sc.voice_name || sc.voice || (sc.settings || {}
233
233
  // generate_speech controls. What the API reports it APPLIED wins: \`speech\`
234
234
  // (status / completed payload; a key there is authoritative even when null),
235
235
  // then the raw status result's own fields, then what the caller submitted.
236
- var SPEECH_KEYS = ['turbo', 'speaking_speed', 'stability', 'similarity_boost', 'enforce_language',
236
+ var SPEECH_KEYS = ['eleven_model', 'turbo', 'speaking_speed', 'stability', 'similarity_boost', 'enforce_language',
237
237
  'output_format', 'audio_effect', 'audio_effect_strength', 'seed'];
238
+ var SPEECH_MODELS = { eleven_v4: 'V4', eleven_v3: 'V3', eleven_multilingual_v2: 'V2' };
238
239
  var SPEECH_FORMATS = { mp3_44100_128: 'MP3 128', mp3_44100_192: 'MP3 192', wav_44100: 'WAV' };
239
240
  function withSpeech(settings, a) {
240
241
  SPEECH_KEYS.forEach(function (k) { if (a && a[k] != null) settings[k] = a[k]; });
@@ -251,6 +252,7 @@ function num(v) { return String(Math.round(Number(v) * 100) / 100); }
251
252
  function speechChipsHTML(sc) {
252
253
  if (sc.tool !== 'generate_speech' && !sc.speech) return '';
253
254
  var h = '', v;
255
+ v = speechVal(sc, 'eleven_model'); if (v) h += chip('Model ' + esc(SPEECH_MODELS[v] || v));
254
256
  if (speechVal(sc, 'turbo') === true) h += chip('Turbo');
255
257
  v = speechVal(sc, 'speaking_speed'); if (v != null) h += chip('Speed ' + esc(num(v)) + '×');
256
258
  v = speechVal(sc, 'stability'); if (v != null) h += chip('Stability ' + esc(num(v)));
@@ -1066,7 +1066,8 @@ async function uiCompleted(p, textPayload, extraContent) {
1066
1066
  // voice's face. Exactly the "never show a raw id on a card" rule, broken on
1067
1067
  // the one path the user actually ends up looking at.
1068
1068
  ...(p.voice ? { voice_name: p.voice.name, voice_thumbnail: p.voice.thumbnail } : {}),
1069
- // Speech settings the API reports it applied (generate.js speechFromResult);
1069
+ // Speech settings the API reports it applied (generate.js speechFromResult,
1070
+ // incl. eleven_model); passed through whole.
1070
1071
  // the card prefers them over the submitted `settings`.
1071
1072
  ...(p.speech ? { speech: p.speech } : {}),
1072
1073
  // The RAW generation state, when the caller has one. `phase` above is
@@ -163,7 +163,7 @@ function speechFromResult(r) {
163
163
  stability: vs.stability, similarity_boost: vs.similarity_boost, style: vs.style, use_speaker_boost: vs.use_speaker_boost,
164
164
  speaking_speed: r.speaking_speed, enforce_language: r.enforce_language, output_format: r.output_format,
165
165
  text_normalization: r.text_normalization, audio_effect: r.audio_effect,
166
- audio_effect_strength: r.audio_effect_strength, seed: r.seed,
166
+ audio_effect_strength: r.audio_effect_strength, seed: r.seed, eleven_model: r.eleven_model,
167
167
  };
168
168
  for (const k of Object.keys(out)) if (out[k] === undefined) out[k] = null;
169
169
  return out;
@@ -1100,8 +1100,9 @@ function registerGenerateTools(server, client, options = {}) {
1100
1100
  {
1101
1101
  text: z.string().describe('The text to convert to speech'),
1102
1102
  voice: z.string().optional().describe('Voice ID or display name — MUST come from a `list_voices` result, never constructed. Google/Gemini ids in particular are not validated provider-side: an id that is not in the catalog is silently mapped to another voice (or a default one) and the audio comes back in a voice nobody asked for. Do not pattern-match a locale onto an id you saw for another language. Default: "Rachel"'),
1103
- model: z.string().optional().describe('Model identifier. Use list_models type="text_to_speech" to see options. Default: eleven_v4 (ElevenLabs V4). ElevenLabs V4/V3 voices follow inline audio tags in the text: delivery ([whispers], [shouting], [sarcastic]), reactions ([laughs], [sighs], [clears throat]), pauses ([pause], [long pause]) and, on V4, free-form directions like [Low, steady voice, restrained urgency]. Tags are always English, even in Hebrew text. SSML such as <break> is NOT supported.'),
1103
+ model: z.string().optional().describe('Model identifier. Use list_models type="text_to_speech" to see options. Default: eleven_v4 (ElevenLabs V4). To choose which ElevenLabs model speaks a given ElevenLabs voice (stock or a cloned voice), use `eleven_model` instead. ElevenLabs V4/V3 voices follow inline audio tags in the text: delivery ([whispers], [shouting], [sarcastic]), reactions ([laughs], [sighs], [clears throat]), pauses ([pause], [long pause]) and, on V4, free-form directions like [Low, steady voice, restrained urgency]. Tags are always English, even in Hebrew text. SSML such as <break> is NOT supported.'),
1104
1104
  turbo: z.boolean().optional().describe('ElevenLabs V4 voices ONLY. Turbo: faster generation at half the credits, slightly lower quality. Rejected (TURBO_UNSUPPORTED) for any voice not on ElevenLabs V4. Default false.'),
1105
+ eleven_model: z.enum(['eleven_v4', 'eleven_v3', 'eleven_multilingual_v2']).optional().describe("ElevenLabs voices ONLY (stock voices and the user's own cloned/character ElevenLabs voices). Which ElevenLabs model speaks: eleven_v4 (default for new voices, most expressive, audio tags, Stability/Similarity/Turbo), eleven_v3 (audio tags), eleven_multilingual_v2 (no audio tags; supports `style`). Omit = the voice's own default. Same price for all. Rejected with 400 ELEVEN_MODEL_UNSUPPORTED for non-ElevenLabs voices. `turbo` requires eleven_v4."),
1105
1106
  language: z.string().optional().describe('Language / accent code (e.g., "en-US", "he-IL", "es-ES"). For Google/Gemini voices this is the Accent control (does not translate the text). Default: "en-US"'),
1106
1107
  // ── Expressive style / emotion (provider-specific) ──
1107
1108
  // Google/Gemini: prefer a named preset id from the Kolbo UI picker; free-form
@@ -1145,7 +1146,7 @@ function registerGenerateTools(server, client, options = {}) {
1145
1146
  project_id: projectIdField,
1146
1147
  session_id: sessionIdField
1147
1148
  },
1148
- async ({ text, voice, model, turbo, language, style_instructions_preset_id, style_instructions, style_instructions_label, selected_style, emotion, speaking_speed, stability, similarity_boost, style, use_speaker_boost, enforce_language, output_format, text_normalization, audio_effect, audio_effect_strength, variance, tempo, promptBoost, seed, accentControl, voiceTitle, minimax_pitch, minimax_vol, minimax_intensity, minimax_timbre, project_id, session_id }) => {
1149
+ async ({ text, voice, model, eleven_model, turbo, language, style_instructions_preset_id, style_instructions, style_instructions_label, selected_style, emotion, speaking_speed, stability, similarity_boost, style, use_speaker_boost, enforce_language, output_format, text_normalization, audio_effect, audio_effect_strength, variance, tempo, promptBoost, seed, accentControl, voiceTitle, minimax_pitch, minimax_vol, minimax_intensity, minimax_timbre, project_id, session_id }) => {
1149
1150
  model = await canonicalModelId(client, model, 'text_to_speech'); // lenient id resolution ("z-image" → "z-image/turbo")
1150
1151
  // Resolve the requested voice against the REAL catalog (cached) so the card
1151
1152
  // can show its display name + portrait instead of a raw id, and so an id
@@ -1158,9 +1159,9 @@ function registerGenerateTools(server, client, options = {}) {
1158
1159
  ? `Voice "${voice}" is not in the Kolbo voice catalog. Call list_voices and pass a voice_id it returns — an unrecognised id is NOT rejected, it is silently mapped to a different voice, so the audio will not be the voice you named.`
1159
1160
  : null;
1160
1161
  // ElevenLabs / effect controls carried on the card (undefined keys drop out of the JSON).
1161
- const ttsControls = { turbo, stability, similarity_boost, style, use_speaker_boost, enforce_language, output_format, text_normalization, audio_effect, audio_effect_strength, seed };
1162
+ const ttsControls = { eleven_model, turbo, stability, similarity_boost, style, use_speaker_boost, enforce_language, output_format, text_normalization, audio_effect, audio_effect_strength, seed };
1162
1163
  const gen = await client.post('/v1/generate/speech', {
1163
- text, voice, model, turbo, language,
1164
+ text, voice, model, eleven_model, turbo, language,
1164
1165
  style_instructions_preset_id, style_instructions, style_instructions_label,
1165
1166
  selected_style, emotion, speaking_speed,
1166
1167
  stability, similarity_boost, style, use_speaker_boost,