Skip to content

Commit 8a8f419

Browse files
feat: items 7 + 9 bridge surfaces — 8 cartridges + boj_vector + boj_multimodal (#103)
## Summary Closes the bridge-surface portion of epic #87 items 7 and 9. Backend dispatch (Elixir/Zig) tracked separately in tracker issues #100 (vector) and #101 (multi-modal). Eight new cartridges in two domains; two new umbrella bridge tools. ## Item 7 — Vector databases (4 cartridges) | Cartridge | Provider strength | |---|---| | \`pinecone-mcp\` | Hosted serverless indexes; dimension + metric required at create-time | | \`weaviate-mcp\` | Hybrid (vector + BM25) search; schema-driven classes; modular vectorisers | | \`qdrant-mcp\` | Rust-native; payload filtering; sparse + dense vectors; self-host or cloud | | \`chromadb-mcp\` | Embedded or client/server; LLM-app-focused; document storage alongside vectors | All four share a **7-operation manifest**: \`authenticate\` / \`list_collections\` / \`create_collection\` / \`delete_collection\` / \`upsert\` / \`query\` / \`delete\`. Provider-specific extras live under \`params\` (Pinecone namespace, Weaviate alpha-hybrid weight, Qdrant score_threshold, Chroma embedding_function). ## Item 9 — Multi-modal (4 cartridges) | Cartridge | Role | Worker-compat? | |---|---|---| | \`whisper-mcp\` | Speech-to-text (OpenAI API + local whisper.cpp backends) | ✅ HTTP API | | \`elevenlabs-mcp\` | Text-to-speech, voice cloning (premium), multilingual | ✅ HTTP API | | \`replicate-mcp\` | Image/video/audio generation; async prediction model | ✅ HTTP API | | \`ffmpeg-mcp\` | Local transcoding (probe/extract/concat/trim) | ❌ **Local-only** per ADR-0013 | ffmpeg-mcp is the glue: extract audio from video → whisper transcribe; extract frames → replicate vision model; etc. ## Bridge tools (2 new) Both follow the \`boj_search\` umbrella pattern from PR #99: \`\`\` boj_vector {operation, provider ∈ {pinecone|weaviate|qdrant|chromadb}, ...} boj_multimodal {operation, provider ∈ {whisper|elevenlabs|replicate|ffmpeg}, ...} \`\`\` Each dispatches via \`invokeCartridge\` to the right cartridge. \`hardeningGate\` requires \`operation\`. Domain classifications added: \`vector\`, \`multimodal\`. ## Offline-menu All 8 cartridges added to \`mcp-bridge/lib/offline-menu.js\` (Teranga tier) so they surface in \`boj_menu\` even when the REST backend is offline. ## Tool count 42 (after \`boj_search\`) → **44** (after \`boj_vector\` + \`boj_multimodal\`). Per the umbrella-tool design choice in #100/#101, adding 8 cartridges added only 2 bridge tools — not 8. ## Tests - ✅ 15/15 existing tests pass (no regressions) - ✅ \`tools/list\` advertises both new tools end-to-end (verified via \`deno run\`) ## What's NOT in this PR - Idris2 ABI, Zig FFI, Deno adapter for any of the 8 cartridges — just the manifest + bridge wiring - Tests against live provider APIs — surface captured; contract testing comes with backend impl - Backend dispatch in the Elixir/Zig layer — per-cartridge follow-up work (~1-2 days each per the trackers) ## Sequencing This closes the **mechanical** portion of items 7 and 9. The trackers (#100, #101) update on merge — backends remain open for follow-up sessions. Epic #87 status after this lands: - Tier A: items 1, 8, 13 done in code; items 7, 9 **surfaces done** (backends pending); item 14 RFC only - Tier B: 6/6 RFCs done - Tier C: items 11, 12 untouched 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b22e475 commit 8a8f419

11 files changed

Lines changed: 268 additions & 1 deletion

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "https://boj.dev/schemas/cartridge/v1.json",
3+
"spdx": "MPL-2.0",
4+
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
5+
"name": "chromadb-mcp",
6+
"version": "0.1.0",
7+
"description": "Chroma vector DB — embedded (local persistent) or client/server; LLM-app-focused; metadata + document storage alongside vectors.",
8+
"domain": "vector",
9+
"tier": "Teranga",
10+
"protocols": ["MCP", "REST"],
11+
"auth": { "method": "optional_bearer", "env_var": "CHROMA_AUTH_TOKEN", "credential_source": "Optional — embedded mode has no auth; client/server may use bearer token." },
12+
"api": { "base_url": "local://chromadb-mcp", "content_type": "application/json" },
13+
"tools": [
14+
{ "name": "vector_authenticate", "description": "Store Chroma endpoint URL (or 'embedded' for in-process) + optional bearer.", "inputSchema": { "type": "object", "properties": { "endpoint": { "type": "string" }, "auth_token": { "type": "string" }, "embedding_function": { "type": "string" } }, "required": ["endpoint"] } },
15+
{ "name": "vector_list_collections", "description": "List collections.", "inputSchema": { "type": "object", "properties": {} } },
16+
{ "name": "vector_create_collection", "description": "Create a collection with optional embedding function + metadata.", "inputSchema": { "type": "object", "properties": { "name": { "type": "string" }, "metadata": { "type": "object" }, "embedding_function": { "type": "string" } }, "required": ["name"] } },
17+
{ "name": "vector_delete_collection", "description": "Delete a collection.", "inputSchema": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"] } },
18+
{ "name": "vector_upsert", "description": "Add documents + vectors + metadata. Chroma computes embeddings if not provided.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "ids": { "type": "array" }, "documents": { "type": "array" }, "embeddings": { "type": "array" }, "metadatas": { "type": "array" } }, "required": ["collection", "ids"] } },
19+
{ "name": "vector_query", "description": "Query by text or embedding with where-filter + document-content filter.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "query_texts": { "type": "array" }, "query_embeddings": { "type": "array" }, "n_results": { "type": "integer" }, "where": { "type": "object" }, "where_document": { "type": "object" } }, "required": ["collection"] } },
20+
{ "name": "vector_delete", "description": "Delete documents by id or where-filter.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "ids": { "type": "array" }, "where": { "type": "object" } }, "required": ["collection"] } }
21+
]
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"$schema": "https://boj.dev/schemas/cartridge/v1.json",
3+
"spdx": "MPL-2.0",
4+
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
5+
"name": "elevenlabs-mcp",
6+
"version": "0.1.0",
7+
"description": "Text-to-speech via ElevenLabs API — high-quality voices, multilingual, voice cloning (premium tier), streaming output.",
8+
"domain": "multimodal",
9+
"tier": "Teranga",
10+
"protocols": ["MCP", "REST"],
11+
"auth": { "method": "api_key", "env_var": "ELEVENLABS_API_KEY", "credential_source": "ElevenLabs account → Profile → API Keys." },
12+
"api": { "base_url": "local://elevenlabs-mcp", "content_type": "application/json" },
13+
"tools": [
14+
{ "name": "audio_authenticate", "description": "Store ElevenLabs API key.", "inputSchema": { "type": "object", "properties": { "api_key": { "type": "string" } }, "required": ["api_key"] } },
15+
{ "name": "audio_synthesize", "description": "Generate speech from text. Returns audio (mp3 / pcm / opus).", "inputSchema": { "type": "object", "properties": { "text": { "type": "string" }, "voice_id": { "type": "string" }, "model_id": { "type": "string", "enum": ["eleven_multilingual_v2", "eleven_turbo_v2", "eleven_monolingual_v1"] }, "output_format": { "type": "string", "enum": ["mp3_44100_128", "pcm_44100", "opus_48000_128"] }, "stability": { "type": "number" }, "similarity_boost": { "type": "number" } }, "required": ["text", "voice_id"] } },
16+
{ "name": "audio_list_voices", "description": "List available voices on the account (preset + custom).", "inputSchema": { "type": "object", "properties": {} } },
17+
{ "name": "audio_clone_voice", "description": "Create a custom voice from sample audio (premium tier only).", "inputSchema": { "type": "object", "properties": { "name": { "type": "string" }, "samples": { "type": "array" }, "description": { "type": "string" } }, "required": ["name", "samples"] } }
18+
]
19+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://boj.dev/schemas/cartridge/v1.json",
3+
"spdx": "MPL-2.0",
4+
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
5+
"name": "ffmpeg-mcp",
6+
"version": "0.1.0",
7+
"description": "Local FFmpeg gateway — probe metadata, transcode formats, extract audio, extract frames, concatenate, trim. Glue between whisper / replicate / browser screenshots. Local-only — requires host ffmpeg binary; not Worker-compatible.",
8+
"domain": "multimodal",
9+
"tier": "Teranga",
10+
"protocols": ["MCP", "REST"],
11+
"auth": { "method": "none", "env_var": null, "credential_source": "No auth — operates on local files. Sandbox via FFMPEG_ALLOWED_PATHS env if exposing to multi-tenant deployments." },
12+
"api": { "base_url": "local://ffmpeg-mcp", "content_type": "application/json" },
13+
"tools": [
14+
{ "name": "media_probe", "description": "Probe metadata (codec, duration, streams, dimensions). Read-only.", "inputSchema": { "type": "object", "properties": { "input": { "type": "string" } }, "required": ["input"] } },
15+
{ "name": "media_transcode", "description": "Convert between formats with optional bitrate / resolution / codec overrides.", "inputSchema": { "type": "object", "properties": { "input": { "type": "string" }, "output": { "type": "string" }, "video_codec": { "type": "string" }, "audio_codec": { "type": "string" }, "video_bitrate": { "type": "string" }, "resolution": { "type": "string" } }, "required": ["input", "output"] } },
16+
{ "name": "media_extract_audio", "description": "Extract audio track to its own file (mp3 / wav / opus). Useful as a Whisper input prep step.", "inputSchema": { "type": "object", "properties": { "input": { "type": "string" }, "output": { "type": "string" }, "format": { "type": "string", "enum": ["mp3", "wav", "opus", "aac"] } }, "required": ["input", "output"] } },
17+
{ "name": "media_extract_frames", "description": "Extract frames at a given interval or specific timestamps. Useful as Replicate vision-model input prep.", "inputSchema": { "type": "object", "properties": { "input": { "type": "string" }, "output_pattern": { "type": "string" }, "fps": { "type": "number" }, "timestamps": { "type": "array" } }, "required": ["input", "output_pattern"] } },
18+
{ "name": "media_concat", "description": "Concatenate multiple files into one (same codec required, or transcode-then-concat).", "inputSchema": { "type": "object", "properties": { "inputs": { "type": "array" }, "output": { "type": "string" } }, "required": ["inputs", "output"] } },
19+
{ "name": "media_trim", "description": "Trim/cut to a specific time range.", "inputSchema": { "type": "object", "properties": { "input": { "type": "string" }, "output": { "type": "string" }, "start": { "type": "string" }, "end": { "type": "string" }, "duration": { "type": "string" } }, "required": ["input", "output", "start"] } }
20+
]
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "https://boj.dev/schemas/cartridge/v1.json",
3+
"spdx": "MPL-2.0",
4+
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
5+
"name": "pinecone-mcp",
6+
"version": "0.1.0",
7+
"description": "Pinecone hosted vector DB — serverless indexes, upsert, similarity search, namespaces, metadata filtering.",
8+
"domain": "vector",
9+
"tier": "Teranga",
10+
"protocols": ["MCP", "REST"],
11+
"auth": { "method": "api_key", "env_var": "PINECONE_API_KEY", "credential_source": "Pinecone console; environment-scoped." },
12+
"api": { "base_url": "local://pinecone-mcp", "content_type": "application/json" },
13+
"tools": [
14+
{ "name": "vector_authenticate", "description": "Store Pinecone API key.", "inputSchema": { "type": "object", "properties": { "api_key": { "type": "string" }, "environment": { "type": "string" } }, "required": ["api_key"] } },
15+
{ "name": "vector_list_collections", "description": "List indexes (Pinecone calls them indexes).", "inputSchema": { "type": "object", "properties": {} } },
16+
{ "name": "vector_create_collection", "description": "Create a new index. Pinecone-specific: dimension + metric required.", "inputSchema": { "type": "object", "properties": { "name": { "type": "string" }, "dimension": { "type": "integer" }, "metric": { "type": "string", "enum": ["cosine", "euclidean", "dotproduct"] } }, "required": ["name", "dimension"] } },
17+
{ "name": "vector_delete_collection", "description": "Delete an index.", "inputSchema": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"] } },
18+
{ "name": "vector_upsert", "description": "Insert/update vectors with optional metadata + namespace.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "vectors": { "type": "array" }, "namespace": { "type": "string" } }, "required": ["collection", "vectors"] } },
19+
{ "name": "vector_query", "description": "Similarity search. Supports metadata filter + namespace.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "query": { "type": "array" }, "top_k": { "type": "integer" }, "namespace": { "type": "string" }, "filter": { "type": "object" } }, "required": ["collection", "query"] } },
20+
{ "name": "vector_delete", "description": "Delete vectors by id, namespace, or filter.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "ids": { "type": "array" }, "namespace": { "type": "string" }, "filter": { "type": "object" } }, "required": ["collection"] } }
21+
]
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "https://boj.dev/schemas/cartridge/v1.json",
3+
"spdx": "MPL-2.0",
4+
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
5+
"name": "qdrant-mcp",
6+
"version": "0.1.0",
7+
"description": "Qdrant vector DB — Rust-native; payloads + filtering; sparse + dense vectors; self-host or Qdrant Cloud.",
8+
"domain": "vector",
9+
"tier": "Teranga",
10+
"protocols": ["MCP", "REST", "gRPC"],
11+
"auth": { "method": "api_key", "env_var": "QDRANT_API_KEY", "credential_source": "Qdrant Cloud dashboard or self-hosted bearer." },
12+
"api": { "base_url": "local://qdrant-mcp", "content_type": "application/json" },
13+
"tools": [
14+
{ "name": "vector_authenticate", "description": "Store Qdrant URL + API key.", "inputSchema": { "type": "object", "properties": { "url": { "type": "string" }, "api_key": { "type": "string" } }, "required": ["url"] } },
15+
{ "name": "vector_list_collections", "description": "List collections.", "inputSchema": { "type": "object", "properties": {} } },
16+
{ "name": "vector_create_collection", "description": "Create a collection. Vector params: size (dim) + distance metric.", "inputSchema": { "type": "object", "properties": { "name": { "type": "string" }, "vector_size": { "type": "integer" }, "distance": { "type": "string", "enum": ["Cosine", "Euclid", "Dot"] } }, "required": ["name", "vector_size"] } },
17+
{ "name": "vector_delete_collection", "description": "Delete a collection.", "inputSchema": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"] } },
18+
{ "name": "vector_upsert", "description": "Insert/update points with payload.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "points": { "type": "array" } }, "required": ["collection", "points"] } },
19+
{ "name": "vector_query", "description": "Search by vector with payload filter + score threshold.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "vector": { "type": "array" }, "limit": { "type": "integer" }, "filter": { "type": "object" }, "score_threshold": { "type": "number" } }, "required": ["collection", "vector"] } },
20+
{ "name": "vector_delete", "description": "Delete points by id or filter.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "ids": { "type": "array" }, "filter": { "type": "object" } }, "required": ["collection"] } }
21+
]
22+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"$schema": "https://boj.dev/schemas/cartridge/v1.json",
3+
"spdx": "MPL-2.0",
4+
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
5+
"name": "replicate-mcp",
6+
"version": "0.1.0",
7+
"description": "Replicate hosted ML models — image generation (Stable Diffusion, FLUX), video (Veo, Kling), upscaling, vision (LLaVA), audio (MusicGen). Async prediction model with polling.",
8+
"domain": "multimodal",
9+
"tier": "Teranga",
10+
"protocols": ["MCP", "REST"],
11+
"auth": { "method": "api_token", "env_var": "REPLICATE_API_TOKEN", "credential_source": "Replicate account → API tokens." },
12+
"api": { "base_url": "local://replicate-mcp", "content_type": "application/json" },
13+
"tools": [
14+
{ "name": "media_authenticate", "description": "Store Replicate API token.", "inputSchema": { "type": "object", "properties": { "api_token": { "type": "string" } }, "required": ["api_token"] } },
15+
{ "name": "media_run_model", "description": "Run a model by owner/name:version with inputs. Returns prediction_id; poll via media_get_prediction.", "inputSchema": { "type": "object", "properties": { "model": { "type": "string", "description": "Format owner/name or owner/name:version" }, "inputs": { "type": "object" }, "webhook": { "type": "string" } }, "required": ["model", "inputs"] } },
16+
{ "name": "media_list_models", "description": "Search or list models in the Replicate catalog by collection/owner/name.", "inputSchema": { "type": "object", "properties": { "query": { "type": "string" }, "owner": { "type": "string" }, "collection": { "type": "string" } } } },
17+
{ "name": "media_get_prediction", "description": "Get status + output of a prediction.", "inputSchema": { "type": "object", "properties": { "prediction_id": { "type": "string" } }, "required": ["prediction_id"] } },
18+
{ "name": "media_cancel_prediction", "description": "Cancel a running prediction.", "inputSchema": { "type": "object", "properties": { "prediction_id": { "type": "string" } }, "required": ["prediction_id"] } }
19+
]
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "https://boj.dev/schemas/cartridge/v1.json",
3+
"spdx": "MPL-2.0",
4+
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
5+
"name": "weaviate-mcp",
6+
"version": "0.1.0",
7+
"description": "Weaviate vector DB — hybrid (vector + BM25 + filter) search, schema-driven classes, modular vectorisers; self-host or cloud.",
8+
"domain": "vector",
9+
"tier": "Teranga",
10+
"protocols": ["MCP", "REST", "gRPC", "GraphQL"],
11+
"auth": { "method": "api_key", "env_var": "WEAVIATE_API_KEY", "credential_source": "Weaviate Cloud Console or self-hosted instance bearer." },
12+
"api": { "base_url": "local://weaviate-mcp", "content_type": "application/json" },
13+
"tools": [
14+
{ "name": "vector_authenticate", "description": "Store Weaviate endpoint URL + API key.", "inputSchema": { "type": "object", "properties": { "endpoint": { "type": "string" }, "api_key": { "type": "string" } }, "required": ["endpoint"] } },
15+
{ "name": "vector_list_collections", "description": "List classes (Weaviate calls collections 'classes').", "inputSchema": { "type": "object", "properties": {} } },
16+
{ "name": "vector_create_collection", "description": "Create a class with property schema + vectoriser.", "inputSchema": { "type": "object", "properties": { "name": { "type": "string" }, "properties": { "type": "array" }, "vectorizer": { "type": "string" } }, "required": ["name"] } },
17+
{ "name": "vector_delete_collection", "description": "Delete a class and all its objects.", "inputSchema": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"] } },
18+
{ "name": "vector_upsert", "description": "Insert/update objects; vectoriser computes embedding if not provided.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "objects": { "type": "array" } }, "required": ["collection", "objects"] } },
19+
{ "name": "vector_query", "description": "Hybrid (vector + BM25 + filter) search. Set alpha to weight vector vs BM25.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "query": { "type": "string" }, "vector": { "type": "array" }, "alpha": { "type": "number" }, "limit": { "type": "integer" }, "where": { "type": "object" } }, "required": ["collection"] } },
20+
{ "name": "vector_delete", "description": "Delete objects by id or where-filter.", "inputSchema": { "type": "object", "properties": { "collection": { "type": "string" }, "ids": { "type": "array" }, "where": { "type": "object" } }, "required": ["collection"] } }
21+
]
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"$schema": "https://boj.dev/schemas/cartridge/v1.json",
3+
"spdx": "MPL-2.0",
4+
"copyright": "Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>",
5+
"name": "whisper-mcp",
6+
"version": "0.1.0",
7+
"description": "Speech-to-text via OpenAI Whisper API + local whisper.cpp fallback. Transcription, language detection, optional translation to English.",
8+
"domain": "multimodal",
9+
"tier": "Teranga",
10+
"protocols": ["MCP", "REST"],
11+
"auth": { "method": "optional_api_key", "env_var": "OPENAI_API_KEY", "credential_source": "Required for API backend; local whisper.cpp backend needs no auth." },
12+
"api": { "base_url": "local://whisper-mcp", "content_type": "application/json" },
13+
"tools": [
14+
{ "name": "audio_authenticate", "description": "Store OpenAI key (for API backend) or path to whisper.cpp binary (for local).", "inputSchema": { "type": "object", "properties": { "backend": { "type": "string", "enum": ["openai", "local"] }, "api_key": { "type": "string" }, "model_path": { "type": "string" } }, "required": ["backend"] } },
15+
{ "name": "audio_transcribe", "description": "Transcribe audio file or URL to text. Word-level timestamps optional.", "inputSchema": { "type": "object", "properties": { "source": { "type": "string" }, "language": { "type": "string" }, "timestamps": { "type": "boolean" }, "model": { "type": "string", "enum": ["whisper-1", "tiny", "base", "small", "medium", "large", "large-v3"] } }, "required": ["source"] } },
16+
{ "name": "audio_detect_language", "description": "Detect spoken language from a short audio sample.", "inputSchema": { "type": "object", "properties": { "source": { "type": "string" } }, "required": ["source"] } },
17+
{ "name": "audio_translate", "description": "Transcribe and translate any source language to English.", "inputSchema": { "type": "object", "properties": { "source": { "type": "string" }, "model": { "type": "string" } }, "required": ["source"] } }
18+
]
19+
}

0 commit comments

Comments
 (0)