@stabgan/openrouter-mcp-multimodal 4.6.0 → 4.6.2

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.
Files changed (67) hide show
  1. package/README.md +60 -52
  2. package/dist/errors.d.ts +3 -12
  3. package/dist/errors.js +2 -6
  4. package/dist/index.js +11 -11
  5. package/dist/logger.d.ts +1 -18
  6. package/dist/logger.js +0 -7
  7. package/dist/model-cache.d.ts +1 -20
  8. package/dist/model-cache.js +1 -20
  9. package/dist/openrouter-api.d.ts +4 -18
  10. package/dist/openrouter-api.js +4 -20
  11. package/dist/tool-definitions.d.ts +1 -0
  12. package/dist/tool-definitions.js +708 -0
  13. package/dist/tool-descriptions.js +6 -8
  14. package/dist/tool-handlers/analyze-audio.d.ts +0 -5
  15. package/dist/tool-handlers/analyze-image.d.ts +0 -6
  16. package/dist/tool-handlers/analyze-image.js +1 -8
  17. package/dist/tool-handlers/analyze-video.d.ts +0 -5
  18. package/dist/tool-handlers/analyze-video.js +0 -7
  19. package/dist/tool-handlers/async-chat.d.ts +17 -13
  20. package/dist/tool-handlers/async-chat.js +43 -66
  21. package/dist/tool-handlers/audio-utils.d.ts +1 -4
  22. package/dist/tool-handlers/audio-utils.js +4 -14
  23. package/dist/tool-handlers/cache.d.ts +2 -18
  24. package/dist/tool-handlers/cache.js +1 -19
  25. package/dist/tool-handlers/chat-completion.d.ts +2 -30
  26. package/dist/tool-handlers/chat-completion.js +13 -33
  27. package/dist/tool-handlers/chat-request.d.ts +25 -0
  28. package/dist/tool-handlers/chat-request.js +38 -0
  29. package/dist/tool-handlers/completion-utils.d.ts +1 -18
  30. package/dist/tool-handlers/completion-utils.js +0 -2
  31. package/dist/tool-handlers/fetch-utils.d.ts +2 -18
  32. package/dist/tool-handlers/fetch-utils.js +3 -51
  33. package/dist/tool-handlers/generate-audio.js +11 -21
  34. package/dist/tool-handlers/generate-image-dedicated.js +17 -65
  35. package/dist/tool-handlers/generate-image-input.d.ts +0 -1
  36. package/dist/tool-handlers/generate-image-input.js +2 -18
  37. package/dist/tool-handlers/generate-image.js +8 -15
  38. package/dist/tool-handlers/generate-video.d.ts +1 -7
  39. package/dist/tool-handlers/generate-video.js +24 -109
  40. package/dist/tool-handlers/health-check.d.ts +1 -9
  41. package/dist/tool-handlers/health-check.js +1 -12
  42. package/dist/tool-handlers/image-source.d.ts +14 -0
  43. package/dist/tool-handlers/image-source.js +23 -0
  44. package/dist/tool-handlers/image-utils.d.ts +5 -0
  45. package/dist/tool-handlers/image-utils.js +23 -0
  46. package/dist/tool-handlers/openai-withresponse.d.ts +1 -10
  47. package/dist/tool-handlers/openai-withresponse.js +0 -7
  48. package/dist/tool-handlers/openrouter-errors.d.ts +2 -18
  49. package/dist/tool-handlers/openrouter-errors.js +2 -34
  50. package/dist/tool-handlers/path-safety.d.ts +10 -15
  51. package/dist/tool-handlers/path-safety.js +30 -55
  52. package/dist/tool-handlers/provider-routing.d.ts +0 -9
  53. package/dist/tool-handlers/provider-routing.js +1 -14
  54. package/dist/tool-handlers/rerank.js +0 -2
  55. package/dist/tool-handlers/search-models.d.ts +0 -6
  56. package/dist/tool-handlers/speech-to-text.js +19 -29
  57. package/dist/tool-handlers/structured-output.d.ts +1 -4
  58. package/dist/tool-handlers/structured-output.js +2 -16
  59. package/dist/tool-handlers/text-to-speech.js +8 -26
  60. package/dist/tool-handlers/video-utils.d.ts +1 -6
  61. package/dist/tool-handlers/video-utils.js +2 -17
  62. package/dist/tool-handlers.js +9 -730
  63. package/dist/tool-icons.d.ts +9 -0
  64. package/dist/tool-icons.js +52 -0
  65. package/dist/version.d.ts +1 -15
  66. package/dist/version.js +1 -15
  67. package/package.json +3 -2
@@ -0,0 +1,708 @@
1
+ import { TOOL_DESCRIPTIONS } from './tool-descriptions.js';
2
+ export const TOOL_DEFINITIONS = [
3
+ {
4
+ name: 'chat_completion',
5
+ description: TOOL_DESCRIPTIONS.chat_completion,
6
+ annotations: {
7
+ title: 'Chat completion',
8
+ readOnlyHint: false,
9
+ destructiveHint: false,
10
+ idempotentHint: false,
11
+ openWorldHint: true,
12
+ },
13
+ inputSchema: {
14
+ type: 'object',
15
+ properties: {
16
+ model: {
17
+ type: 'string',
18
+ description: 'Model ID (optional, uses default). Append `:nitro` for the fastest variant, ' +
19
+ '`:floor` for the cheapest, `:free` for the free tier, `:online` for web search, ' +
20
+ 'or `:exacto` for the best tool-calling accuracy. ' +
21
+ 'Example: `openai/gpt-4o:nitro`. Or pass `online: true` for programmatic web search control.',
22
+ },
23
+ messages: {
24
+ type: 'array',
25
+ minItems: 1,
26
+ items: {
27
+ type: 'object',
28
+ properties: {
29
+ role: { type: 'string', enum: ['system', 'user', 'assistant'] },
30
+ content: {
31
+ oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'object' } }],
32
+ },
33
+ },
34
+ required: ['role', 'content'],
35
+ },
36
+ },
37
+ temperature: { type: 'number', minimum: 0, maximum: 2 },
38
+ max_tokens: {
39
+ type: 'number',
40
+ minimum: 1,
41
+ description: 'Max completion tokens. Falls back to `OPENROUTER_MAX_TOKENS` env var if unset.',
42
+ },
43
+ provider: {
44
+ type: 'object',
45
+ description: 'OpenRouter provider-routing overrides. Merges on top of `OPENROUTER_PROVIDER_*` env defaults. ' +
46
+ 'See https://openrouter.ai/docs/features/provider-routing',
47
+ properties: {
48
+ quantizations: {
49
+ type: 'array',
50
+ items: { type: 'string' },
51
+ description: 'Filter providers by quantization (e.g. `["fp16","int8"]`).',
52
+ },
53
+ ignore: {
54
+ type: 'array',
55
+ items: { type: 'string' },
56
+ description: 'Exclude these provider slugs.',
57
+ },
58
+ sort: {
59
+ type: 'string',
60
+ enum: ['price', 'throughput', 'latency'],
61
+ },
62
+ order: { type: 'array', items: { type: 'string' } },
63
+ require_parameters: { type: 'boolean' },
64
+ data_collection: { type: 'string', enum: ['allow', 'deny'] },
65
+ allow_fallbacks: { type: 'boolean' },
66
+ },
67
+ },
68
+ include_reasoning: {
69
+ type: 'boolean',
70
+ description: "Surface the model's chain-of-thought on `_meta.reasoning` for R1 / Opus 4.7 / Gemini Thinking.",
71
+ },
72
+ online: {
73
+ type: 'boolean',
74
+ description: "Enable OpenRouter's web-search plugin (Exa-backed, $4 / 1000 results).",
75
+ },
76
+ web_max_results: {
77
+ type: 'number',
78
+ minimum: 1,
79
+ description: 'Max web-search results when `online: true` (default 5).',
80
+ },
81
+ cache: {
82
+ type: 'boolean',
83
+ description: 'Enable OpenRouter response caching via `X-OpenRouter-Cache: true`. ' +
84
+ 'Server-wide default settable via `OPENROUTER_CACHE_RESPONSES=1`.',
85
+ },
86
+ cache_ttl: {
87
+ type: 'string',
88
+ description: 'Cache TTL (e.g. `"5m"`, `"1h"`, `"24h"`; 1s-24h range).',
89
+ },
90
+ cache_clear: {
91
+ type: 'boolean',
92
+ description: 'Bust the cache entry for this exact request.',
93
+ },
94
+ },
95
+ required: ['messages'],
96
+ },
97
+ },
98
+ {
99
+ name: 'start_chat_completion',
100
+ description: TOOL_DESCRIPTIONS.start_chat_completion,
101
+ annotations: {
102
+ title: 'Start async chat completion',
103
+ readOnlyHint: false,
104
+ destructiveHint: false,
105
+ idempotentHint: false,
106
+ openWorldHint: true,
107
+ },
108
+ inputSchema: {
109
+ type: 'object',
110
+ properties: {
111
+ model: { type: 'string', description: 'Model ID (same as chat_completion).' },
112
+ messages: {
113
+ type: 'array',
114
+ minItems: 1,
115
+ items: {
116
+ type: 'object',
117
+ properties: {
118
+ role: { type: 'string', enum: ['system', 'user', 'assistant'] },
119
+ content: {
120
+ oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'object' } }],
121
+ },
122
+ },
123
+ required: ['role', 'content'],
124
+ },
125
+ },
126
+ temperature: { type: 'number', minimum: 0, maximum: 2 },
127
+ max_tokens: { type: 'number', minimum: 1 },
128
+ provider: { type: 'object' },
129
+ include_reasoning: { type: 'boolean' },
130
+ online: { type: 'boolean' },
131
+ web_max_results: { type: 'number', minimum: 1 },
132
+ cache: { type: 'boolean' },
133
+ cache_ttl: { type: 'string' },
134
+ cache_clear: { type: 'boolean' },
135
+ },
136
+ required: ['messages'],
137
+ },
138
+ },
139
+ {
140
+ name: 'get_chat_completion_status',
141
+ description: TOOL_DESCRIPTIONS.get_chat_completion_status,
142
+ annotations: {
143
+ title: 'Get async chat completion status',
144
+ readOnlyHint: true,
145
+ destructiveHint: false,
146
+ idempotentHint: true,
147
+ openWorldHint: false,
148
+ },
149
+ inputSchema: {
150
+ type: 'object',
151
+ properties: {
152
+ job_id: {
153
+ type: 'string',
154
+ description: 'The job_id returned by start_chat_completion.',
155
+ },
156
+ },
157
+ required: ['job_id'],
158
+ },
159
+ },
160
+ {
161
+ name: 'analyze_image',
162
+ description: TOOL_DESCRIPTIONS.analyze_image,
163
+ annotations: {
164
+ title: 'Analyze image',
165
+ readOnlyHint: true,
166
+ destructiveHint: false,
167
+ idempotentHint: false,
168
+ openWorldHint: true,
169
+ },
170
+ inputSchema: {
171
+ type: 'object',
172
+ properties: {
173
+ image_path: {
174
+ type: 'string',
175
+ description: 'Required. Local path (inside OPENROUTER_INPUT_DIR sandbox), https URL, or data URL. ' +
176
+ 'Good: `"photo.jpg"`. Bad: `"url": "..."` (wrong key), `"/etc/passwd"` (UNSAFE_PATH).',
177
+ },
178
+ question: {
179
+ type: 'string',
180
+ description: 'Optional question about the image. Defaults to "What\'s in this image?" if omitted. ' +
181
+ 'Good: `"List all text"`. Bad: using `prompt` key (wrong name for this tool).',
182
+ },
183
+ model: { type: 'string' },
184
+ cache_input: {
185
+ type: 'boolean',
186
+ description: 'Attach `cache_control: ephemeral` to the image block so Anthropic / Gemini prompt-cache it. ' +
187
+ 'Repeat questions about the same image save ~10x on Anthropic.',
188
+ },
189
+ cache: { type: 'boolean' },
190
+ cache_ttl: { type: 'string' },
191
+ cache_clear: { type: 'boolean' },
192
+ },
193
+ required: ['image_path'],
194
+ },
195
+ },
196
+ {
197
+ name: 'analyze_audio',
198
+ description: TOOL_DESCRIPTIONS.analyze_audio,
199
+ annotations: {
200
+ title: 'Analyze audio',
201
+ readOnlyHint: true,
202
+ destructiveHint: false,
203
+ idempotentHint: false,
204
+ openWorldHint: true,
205
+ },
206
+ inputSchema: {
207
+ type: 'object',
208
+ properties: {
209
+ audio_path: {
210
+ type: 'string',
211
+ description: 'Local file path (sandboxed to OPENROUTER_INPUT_DIR / OPENROUTER_OUTPUT_DIR / cwd), ' +
212
+ 'http(s) URL, or data URL (base64-encoded audio)',
213
+ },
214
+ question: {
215
+ type: 'string',
216
+ description: 'Question or instruction about the audio (default: transcribe)',
217
+ },
218
+ model: { type: 'string' },
219
+ cache_input: { type: 'boolean' },
220
+ cache: { type: 'boolean' },
221
+ cache_ttl: { type: 'string' },
222
+ cache_clear: { type: 'boolean' },
223
+ },
224
+ required: ['audio_path'],
225
+ },
226
+ },
227
+ {
228
+ name: 'analyze_video',
229
+ description: TOOL_DESCRIPTIONS.analyze_video,
230
+ annotations: {
231
+ title: 'Analyze video',
232
+ readOnlyHint: true,
233
+ destructiveHint: false,
234
+ idempotentHint: false,
235
+ openWorldHint: true,
236
+ },
237
+ inputSchema: {
238
+ type: 'object',
239
+ properties: {
240
+ video_path: {
241
+ type: 'string',
242
+ description: 'Local file path (sandboxed to OPENROUTER_INPUT_DIR / OPENROUTER_OUTPUT_DIR / cwd), ' +
243
+ 'http(s) URL, or base64 data URL. Supported: mp4 / mpeg / mov / webm.',
244
+ },
245
+ question: { type: 'string' },
246
+ model: { type: 'string' },
247
+ cache_input: { type: 'boolean' },
248
+ cache: { type: 'boolean' },
249
+ cache_ttl: { type: 'string' },
250
+ cache_clear: { type: 'boolean' },
251
+ },
252
+ required: ['video_path'],
253
+ },
254
+ },
255
+ {
256
+ name: 'search_models',
257
+ description: TOOL_DESCRIPTIONS.search_models,
258
+ annotations: {
259
+ title: 'Search models',
260
+ readOnlyHint: true,
261
+ destructiveHint: false,
262
+ idempotentHint: true,
263
+ openWorldHint: true,
264
+ },
265
+ inputSchema: {
266
+ type: 'object',
267
+ properties: {
268
+ query: { type: 'string' },
269
+ provider: { type: 'string' },
270
+ capabilities: {
271
+ type: 'object',
272
+ properties: {
273
+ vision: { type: 'boolean' },
274
+ audio: { type: 'boolean' },
275
+ video: { type: 'boolean' },
276
+ },
277
+ },
278
+ limit: { type: 'number', minimum: 1, maximum: 50 },
279
+ offset: { type: 'number', minimum: 0 },
280
+ },
281
+ },
282
+ outputSchema: {
283
+ type: 'object',
284
+ properties: {
285
+ results: { type: 'array', items: { type: 'object' } },
286
+ offset: { type: 'number' },
287
+ limit: { type: 'number' },
288
+ total: { type: 'number' },
289
+ has_more: { type: 'boolean' },
290
+ next_offset: { type: ['number', 'null'] },
291
+ },
292
+ required: ['results', 'offset', 'limit', 'total', 'has_more', 'next_offset'],
293
+ },
294
+ },
295
+ {
296
+ name: 'get_model_info',
297
+ description: TOOL_DESCRIPTIONS.get_model_info,
298
+ annotations: {
299
+ title: 'Get model info',
300
+ readOnlyHint: true,
301
+ destructiveHint: false,
302
+ idempotentHint: true,
303
+ openWorldHint: true,
304
+ },
305
+ inputSchema: {
306
+ type: 'object',
307
+ properties: { model: { type: 'string' } },
308
+ required: ['model'],
309
+ },
310
+ outputSchema: {
311
+ type: 'object',
312
+ properties: {
313
+ id: { type: 'string' },
314
+ name: { type: 'string' },
315
+ context_length: { type: 'number' },
316
+ architecture: { type: 'object' },
317
+ },
318
+ required: ['id'],
319
+ },
320
+ },
321
+ {
322
+ name: 'validate_model',
323
+ description: TOOL_DESCRIPTIONS.validate_model,
324
+ annotations: {
325
+ title: 'Validate model',
326
+ readOnlyHint: true,
327
+ destructiveHint: false,
328
+ idempotentHint: true,
329
+ openWorldHint: true,
330
+ },
331
+ inputSchema: {
332
+ type: 'object',
333
+ properties: { model: { type: 'string' } },
334
+ required: ['model'],
335
+ },
336
+ outputSchema: {
337
+ type: 'object',
338
+ properties: {
339
+ valid: { type: 'boolean' },
340
+ model: { type: 'string' },
341
+ },
342
+ required: ['valid', 'model'],
343
+ },
344
+ },
345
+ {
346
+ name: 'generate_image',
347
+ description: TOOL_DESCRIPTIONS.generate_image,
348
+ annotations: {
349
+ title: 'Generate image',
350
+ readOnlyHint: false,
351
+ destructiveHint: false,
352
+ idempotentHint: false,
353
+ openWorldHint: true,
354
+ },
355
+ inputSchema: {
356
+ type: 'object',
357
+ properties: {
358
+ prompt: { type: 'string' },
359
+ model: { type: 'string' },
360
+ aspect_ratio: {
361
+ type: 'string',
362
+ enum: [
363
+ '1:1',
364
+ '2:3',
365
+ '3:2',
366
+ '3:4',
367
+ '4:3',
368
+ '4:5',
369
+ '5:4',
370
+ '9:16',
371
+ '16:9',
372
+ '21:9',
373
+ '1:4',
374
+ '4:1',
375
+ '1:8',
376
+ '8:1',
377
+ ],
378
+ },
379
+ image_size: { type: 'string', enum: ['0.5K', '1K', '2K', '4K'] },
380
+ max_tokens: { type: 'number', minimum: 1 },
381
+ save_path: { type: 'string' },
382
+ input_images: { type: 'array', items: { type: 'string' } },
383
+ modalities: { type: 'array', items: { type: 'string' } },
384
+ },
385
+ required: ['prompt'],
386
+ },
387
+ },
388
+ {
389
+ name: 'generate_image_dedicated',
390
+ description: TOOL_DESCRIPTIONS.generate_image_dedicated,
391
+ annotations: {
392
+ title: 'Generate image (dedicated API)',
393
+ readOnlyHint: false,
394
+ destructiveHint: false,
395
+ idempotentHint: false,
396
+ openWorldHint: true,
397
+ },
398
+ inputSchema: {
399
+ type: 'object',
400
+ properties: {
401
+ prompt: {
402
+ type: 'string',
403
+ description: 'Text prompt describing the image to generate.',
404
+ },
405
+ model: {
406
+ type: 'string',
407
+ description: 'Image model ID. Default: google/gemini-2.5-flash-image. Browse available at https://openrouter.ai/collections/image-models',
408
+ },
409
+ resolution: {
410
+ type: 'string',
411
+ enum: ['512', '0.5K', '1K', '2K', '4K'],
412
+ description: 'Normalized resolution tier. Provider maps to closest supported size.',
413
+ },
414
+ aspect_ratio: {
415
+ type: 'string',
416
+ description: 'Aspect ratio (e.g. "1:1", "16:9", "9:16", "4:3", "21:9").',
417
+ },
418
+ quality: {
419
+ type: 'string',
420
+ enum: ['auto', 'low', 'medium', 'high'],
421
+ description: 'Image quality level.',
422
+ },
423
+ output_format: {
424
+ type: 'string',
425
+ enum: ['png', 'jpeg', 'webp', 'svg'],
426
+ description: 'Output image format.',
427
+ },
428
+ n: {
429
+ type: 'number',
430
+ minimum: 1,
431
+ maximum: 10,
432
+ description: 'Number of images to generate (model-dependent, default 1).',
433
+ },
434
+ input_references: {
435
+ type: 'array',
436
+ items: { type: 'string' },
437
+ description: 'Reference images for image-to-image workflows. Each entry: local path, http(s) URL, or data URL.',
438
+ },
439
+ save_path: { type: 'string', description: 'Save generated image to this path.' },
440
+ provider: {
441
+ type: 'object',
442
+ description: 'Provider routing overrides (order, sort, allow_fallbacks, etc.).',
443
+ },
444
+ cache: { type: 'boolean' },
445
+ cache_ttl: { type: 'string' },
446
+ cache_clear: { type: 'boolean' },
447
+ },
448
+ required: ['prompt'],
449
+ },
450
+ },
451
+ {
452
+ name: 'generate_audio',
453
+ description: TOOL_DESCRIPTIONS.generate_audio,
454
+ annotations: {
455
+ title: 'Generate audio',
456
+ readOnlyHint: false,
457
+ destructiveHint: false,
458
+ idempotentHint: false,
459
+ openWorldHint: true,
460
+ },
461
+ inputSchema: {
462
+ type: 'object',
463
+ properties: {
464
+ prompt: { type: 'string' },
465
+ model: { type: 'string' },
466
+ voice: { type: 'string' },
467
+ format: { type: 'string' },
468
+ save_path: { type: 'string' },
469
+ },
470
+ required: ['prompt'],
471
+ },
472
+ },
473
+ {
474
+ name: 'text_to_speech',
475
+ description: TOOL_DESCRIPTIONS.text_to_speech,
476
+ annotations: {
477
+ title: 'Text to speech (dedicated API)',
478
+ readOnlyHint: false,
479
+ destructiveHint: false,
480
+ idempotentHint: false,
481
+ openWorldHint: true,
482
+ },
483
+ inputSchema: {
484
+ type: 'object',
485
+ properties: {
486
+ input: {
487
+ type: 'string',
488
+ description: 'Text to convert to speech.',
489
+ },
490
+ model: {
491
+ type: 'string',
492
+ description: 'TTS model. Default: openai/gpt-4o-mini-tts-2025-12-15. Also: google/gemini-flash-tts, mistral/voxtral-mini-tts.',
493
+ },
494
+ voice: {
495
+ type: 'string',
496
+ description: 'Voice ID (model-specific). Default: alloy. OpenAI voices: alloy, echo, fable, onyx, nova, shimmer.',
497
+ },
498
+ response_format: {
499
+ type: 'string',
500
+ enum: ['mp3', 'opus', 'aac', 'flac', 'wav', 'pcm'],
501
+ description: 'Output audio format. Default: mp3.',
502
+ },
503
+ speed: {
504
+ type: 'number',
505
+ minimum: 0.25,
506
+ maximum: 4.0,
507
+ description: 'Speed of speech (0.25 to 4.0). Default: 1.0.',
508
+ },
509
+ instructions: {
510
+ type: 'string',
511
+ description: 'Tone/style instructions (e.g. "speak in a warm, friendly tone"). OpenAI models only.',
512
+ },
513
+ save_path: { type: 'string', description: 'Save audio to this path.' },
514
+ cache: { type: 'boolean' },
515
+ cache_ttl: { type: 'string' },
516
+ cache_clear: { type: 'boolean' },
517
+ },
518
+ required: ['input'],
519
+ },
520
+ },
521
+ {
522
+ name: 'speech_to_text',
523
+ description: TOOL_DESCRIPTIONS.speech_to_text,
524
+ annotations: {
525
+ title: 'Speech to text (dedicated API)',
526
+ readOnlyHint: true,
527
+ destructiveHint: false,
528
+ idempotentHint: false,
529
+ openWorldHint: true,
530
+ },
531
+ inputSchema: {
532
+ type: 'object',
533
+ properties: {
534
+ audio_path: {
535
+ type: 'string',
536
+ description: 'Audio file: local path (sandboxed), http(s) URL, or base64 data URL. Formats: mp3, wav, flac, ogg, webm, mp4.',
537
+ },
538
+ model: {
539
+ type: 'string',
540
+ description: 'STT model. Default: openai/whisper-1. Also: openai/gpt-4o-transcribe, openai/gpt-4o-mini-transcribe.',
541
+ },
542
+ language: {
543
+ type: 'string',
544
+ description: 'ISO-639-1 language code (e.g. "en", "es", "fr"). Improves accuracy.',
545
+ },
546
+ response_format: {
547
+ type: 'string',
548
+ enum: ['json', 'text', 'srt', 'verbose_json', 'vtt'],
549
+ description: 'Output format for transcription. Default: json.',
550
+ },
551
+ temperature: {
552
+ type: 'number',
553
+ minimum: 0,
554
+ maximum: 1,
555
+ description: 'Sampling temperature for transcription (0-1).',
556
+ },
557
+ cache: { type: 'boolean' },
558
+ cache_ttl: { type: 'string' },
559
+ cache_clear: { type: 'boolean' },
560
+ },
561
+ required: ['audio_path'],
562
+ },
563
+ },
564
+ {
565
+ name: 'generate_video',
566
+ description: TOOL_DESCRIPTIONS.generate_video,
567
+ annotations: {
568
+ title: 'Generate video',
569
+ readOnlyHint: false,
570
+ destructiveHint: false,
571
+ idempotentHint: false,
572
+ openWorldHint: true,
573
+ },
574
+ inputSchema: {
575
+ type: 'object',
576
+ properties: {
577
+ prompt: { type: 'string' },
578
+ model: { type: 'string' },
579
+ resolution: { type: 'string' },
580
+ aspect_ratio: { type: 'string' },
581
+ duration: { type: 'number', minimum: 1 },
582
+ seed: { type: 'number' },
583
+ first_frame_image: { type: 'string' },
584
+ last_frame_image: { type: 'string' },
585
+ reference_images: { type: 'array', items: { type: 'string' } },
586
+ provider: { type: 'object' },
587
+ save_path: { type: 'string' },
588
+ max_wait_ms: { type: 'number', minimum: 10000 },
589
+ poll_interval_ms: { type: 'number', minimum: 2000 },
590
+ },
591
+ required: ['prompt'],
592
+ },
593
+ },
594
+ {
595
+ name: 'generate_video_from_image',
596
+ description: TOOL_DESCRIPTIONS.generate_video_from_image,
597
+ annotations: {
598
+ title: 'Generate video from image',
599
+ readOnlyHint: false,
600
+ destructiveHint: false,
601
+ idempotentHint: false,
602
+ openWorldHint: true,
603
+ },
604
+ inputSchema: {
605
+ type: 'object',
606
+ properties: {
607
+ image: {
608
+ type: 'string',
609
+ description: 'First-frame image (path, URL, or data URL). Required.',
610
+ },
611
+ prompt: { type: 'string' },
612
+ model: { type: 'string' },
613
+ resolution: { type: 'string' },
614
+ aspect_ratio: { type: 'string' },
615
+ duration: { type: 'number', minimum: 1 },
616
+ seed: { type: 'number' },
617
+ save_path: { type: 'string' },
618
+ max_wait_ms: { type: 'number', minimum: 10000 },
619
+ poll_interval_ms: { type: 'number', minimum: 2000 },
620
+ },
621
+ required: ['image', 'prompt'],
622
+ },
623
+ },
624
+ {
625
+ name: 'get_video_status',
626
+ description: TOOL_DESCRIPTIONS.get_video_status,
627
+ annotations: {
628
+ title: 'Get video status',
629
+ readOnlyHint: true,
630
+ destructiveHint: false,
631
+ idempotentHint: true,
632
+ openWorldHint: true,
633
+ },
634
+ inputSchema: {
635
+ type: 'object',
636
+ properties: {
637
+ video_id: { type: 'string' },
638
+ save_path: { type: 'string' },
639
+ },
640
+ required: ['video_id'],
641
+ },
642
+ },
643
+ {
644
+ name: 'rerank_documents',
645
+ description: TOOL_DESCRIPTIONS.rerank_documents,
646
+ annotations: {
647
+ title: 'Rerank documents',
648
+ readOnlyHint: true,
649
+ destructiveHint: false,
650
+ idempotentHint: true,
651
+ openWorldHint: true,
652
+ },
653
+ inputSchema: {
654
+ type: 'object',
655
+ properties: {
656
+ query: { type: 'string' },
657
+ documents: { type: 'array', items: { type: 'string' }, minItems: 1 },
658
+ model: { type: 'string' },
659
+ top_n: { type: 'number', minimum: 1 },
660
+ return_documents: { type: 'boolean' },
661
+ },
662
+ required: ['query', 'documents'],
663
+ },
664
+ outputSchema: {
665
+ type: 'object',
666
+ properties: {
667
+ model: { type: 'string' },
668
+ results: {
669
+ type: 'array',
670
+ items: {
671
+ type: 'object',
672
+ properties: {
673
+ index: { type: 'number' },
674
+ score: { type: 'number' },
675
+ document: { type: 'string' },
676
+ },
677
+ required: ['index', 'score'],
678
+ },
679
+ },
680
+ },
681
+ required: ['results'],
682
+ },
683
+ },
684
+ {
685
+ name: 'health_check',
686
+ description: TOOL_DESCRIPTIONS.health_check,
687
+ annotations: {
688
+ title: 'Health check',
689
+ readOnlyHint: true,
690
+ destructiveHint: false,
691
+ idempotentHint: true,
692
+ openWorldHint: true,
693
+ },
694
+ inputSchema: { type: 'object', properties: {} },
695
+ outputSchema: {
696
+ type: 'object',
697
+ properties: {
698
+ ok: { type: 'boolean' },
699
+ server_version: { type: 'string' },
700
+ protocol_version: { type: 'string' },
701
+ api_key_valid: { type: 'boolean' },
702
+ models_cached: { type: 'number' },
703
+ error: { type: 'string' },
704
+ },
705
+ required: ['ok', 'server_version', 'protocol_version', 'api_key_valid', 'models_cached'],
706
+ },
707
+ },
708
+ ];