Skip to content

Commit 35fdc25

Browse files
jqnatividadclaude
andauthored
feat(mcp): qsv installer refactor (#3609)
* refactor(mcp): replace package manager install with GitHub Releases direct download The qsv_setup installer previously tried Homebrew/Scoop which fails in GUI environments (Claude Desktop) due to PATH issues. Now downloads the qsvmcp binary directly from GitHub Releases API, extracts it, and installs to a discoverable location (/usr/local/bin or ~/.local/bin on Unix, %LOCALAPPDATA%\Programs\qsv on Windows). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(mcp): complete platform support matrix and harden installer - Add missing ASSET_SUFFIXES for linux-x64, linux-arm64, and darwin-x64 so direct download works on Linux and Intel Mac (not just macOS ARM) - Replace write-then-delete writability check with fs.accessSync(W_OK) to avoid leaving stale temp files on crash - Fix Unix zip extraction to handle nested directory structures by extracting full archive then searching for binary (matching Windows behavior) - Use test.skip with reason messages instead of silent platform guards so CI reports clearly show skipped vs passed tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(mcp): harden find fallback and add unsupported platform test Guard against empty-string result from /usr/bin/find when no binary is found in the extracted zip, and add a test verifying that unsupported platform keys (freebsd, sunos, aix) return null from the asset suffix lookup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(mcp): test against real ASSET_SUFFIXES map and remove redundant guard Export ASSET_SUFFIXES from installer.ts so the unsupported-platform test validates the actual map instead of a duplicated local copy. Also remove the redundant `&& findResult.length > 0` check since an empty string after .trim() is already falsy. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(mcp): remove qsv installation for platforms that Claude Desktop does not support * fix(mcp): use auto-detected qsv binary path instead of hardcoded "qsv" default SkillExecutor and FilesystemResourceProvider both hardcoded "qsv" as the default binary name, causing ENOENT failures when only qsvmcp is installed. Now both fall back to config.qsvBinPath which auto-detects qsvmcp or qsv. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(mcp): update qsvBinPath JSDoc to reflect auto-detection default The FilesystemConfig.qsvBinPath comment still said "default: 'qsv'" after the previous commit switched to auto-detected paths via appConfig. Also verified the two review findings: - maxFilesPerListing: FilesystemConfig never declared this field, so the rename to appConfig.maxFilesPerListing is correct (no regression). - qsvBinPath fallback chain: config.qsvBinPath || appConfig.qsvBinPath is necessary since mcp-server.ts passes qsvBinPath in the constructor. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(mcp): align installer tests with removed platform support (e1e9187) Tests for macOS x64, Linux x64, and Linux ARM64 still expected asset suffixes after those platforms were removed from ASSET_SUFFIXES. Now they correctly expect null, fixing the CI failure on ubuntu-latest. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(mcp): address Copilot review — harden installer fetch, escaping, and paths - Add User-Agent header and AbortSignal timeout to GitHub API and download fetch calls, matching the pattern in update-checker.ts - Escape single quotes in PowerShell string interpolation to prevent injection from paths containing apostrophes (e.g. O'Connor) - Use os.homedir() instead of env var fallbacks (USERPROFILE/"", HOME/"/tmp") for reliable install directory resolution - Fix macOS manual instructions to specify aarch64-apple-darwin asset name - Fix setup tool hint from "qsv.dathere.com" to "GitHub Releases" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(mcp): hoist psEscape to module scope and remove redundant escaping of fixed binaryName Moves psEscape helper from inside the try block to module scope (avoids unnecessary allocation on non-Windows platforms) and drops the redundant psEscape(binaryName) call since binaryName is always "qsvmcp"/"qsvmcp.exe". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2070072 commit 35fdc25

File tree

5 files changed

+261
-147
lines changed

5 files changed

+261
-147
lines changed

.claude/skills/src/executor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ export class SkillExecutor {
168168
private qsvBinary: string;
169169
private workingDirectory: string;
170170

171-
constructor(qsvBinary: string = "qsv", workingDirectory?: string) {
171+
constructor(qsvBinary: string = config.qsvBinPath, workingDirectory?: string) {
172172
this.qsvBinary = qsvBinary;
173173
this.workingDirectory = workingDirectory || process.cwd();
174174
}

0 commit comments

Comments
 (0)