switch_model
Switch the active Whisper model for the current session without restarting Claude Desktop. Accepts a model filename for an already installed model.
Instructions
Switch the active Whisper model for the current session without restarting Claude Desktop. Accepts a model filename (e.g. ggml-large-v3-turbo.bin) or full path. The model must already be installed in your models directory. Use list_models to see installed models, download_model to add new ones. Change is session-scoped — does not persist after Claude Desktop restarts.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| model_name | Yes | Model filename (e.g. ggml-large-v3-turbo.bin) or full path. Must be a .bin file in the configured models directory. |
Implementation Reference
- src/index.ts:1108-1127 (registration)Tool registration in ListToolsRequestSchema handler (lines 1108-1125). Defines switch_model's name, description, and input schema.
name: "switch_model", description: "Switch the active Whisper model for the current session without restarting Claude Desktop. " + "Accepts a model filename (e.g. ggml-large-v3-turbo.bin) or full path. " + "The model must already be installed in your models directory. " + "Use list_models to see installed models, download_model to add new ones. " + "Change is session-scoped — does not persist after Claude Desktop restarts.", inputSchema: { type: "object", properties: { model_name: { type: "string", description: "Model filename (e.g. ggml-large-v3-turbo.bin) or full path. Must be a .bin file in the configured models directory.", }, }, required: ["model_name"], }, }, ], })); - src/index.ts:1115-1125 (schema)Input schema for switch_model. Requires a single string 'model_name' (model filename or full path, must be .bin).
inputSchema: { type: "object", properties: { model_name: { type: "string", description: "Model filename (e.g. ggml-large-v3-turbo.bin) or full path. Must be a .bin file in the configured models directory.", }, }, required: ["model_name"], }, }, - src/index.ts:1478-1549 (handler)Handler for switch_model tool (lines 1478-1549). Validates input (must be .bin, no path traversal), resolves path relative to models directory, enforces security constraint (must be within models dir), checks file exists, prevents switching mid-transcription, then updates the mutable WHISPER_MODEL variable. Returns previous/active model info.
if (name === "switch_model") { const modelInput = (args?.model_name as string)?.trim(); if (!modelInput) return { content: [{ type: "text", text: "model_name is required." }], isError: true }; // Security: must end in .bin if (!modelInput.endsWith(".bin")) { return { content: [{ type: "text", text: `Invalid model: "${modelInput}"\nModel files must end in .bin` }], isError: true, }; } // Security: reject path traversal if (UNSAFE_PATH_RE.test(modelInput)) { return { content: [{ type: "text", text: `Invalid path: "${modelInput}"\nPaths containing ".." or UNC paths are not allowed.` }], isError: true, }; } // Resolve to full path — either absolute or relative to models dir const modelsDir = dirname(WHISPER_MODEL); const resolvedPath = modelInput.includes("\\") || modelInput.includes("/") ? modelInput : join(modelsDir, modelInput); // Security: must live within the configured models directory if (!resolvedPath.startsWith(modelsDir)) { return { content: [{ type: "text", text: `Security error: model must be within the configured models directory (${modelsDir}).` }], isError: true, }; } if (!existsSync(resolvedPath)) { return { content: [{ type: "text", text: `Model not found: ${resolvedPath}\n\n` + `Use list_models to see installed models, or download_model to install a new one.`, }], isError: true, }; } // Process lock — don't switch mid-transcription if (await isWhisperRunning()) { return { content: [{ type: "text", text: "Cannot switch model while a transcription is in progress. Wait for the current job to finish first." }], isError: true, }; } const previousModel = basename(WHISPER_MODEL); WHISPER_MODEL = resolvedPath; const newModel = basename(WHISPER_MODEL); const sizeMb = (statSync(resolvedPath).size / (1024 * 1024)).toFixed(0); const known = MODEL_REGISTRY.find(m => m.filename === newModel); return { content: [{ type: "text", text: `✅ Model switched!\n\n` + `Previous: ${previousModel}\n` + `Active: ${newModel} (${sizeMb} MB)\n` + (known ? `Use case: ${known.useCase}\n` : "") + `\nThis change is session-scoped. To make it permanent, update WHISPER_MODEL in claude_desktop_config.json.`, }], }; } - src/index.ts:32-35 (helper)Mutable module-level variable WHISPER_MODEL that switch_model updates at runtime (line 32-35). Initialized from environment variable or default path.
let WHISPER_MODEL = process.env.WHISPER_MODEL ?? "C:\\whisper\\models\\ggml-base.en.bin"; const FFMPEG_PATH = process.env.FFMPEG_PATH ?? "ffmpeg";