Skip to content

Commit 3177cfe

Browse files
jqnatividadclaude
andcommitted
fix(mcpb): expand template variables in config paths
Fixed issue where paths like ${HOME}/Downloads were used literally instead of being expanded to actual home directory paths. Changes to config.ts: - Added expandTemplateVars() function to expand template variables: * ${HOME} → User's home directory (Unix/Mac) * ${USERPROFILE} → User's home directory (Windows) * ${DESKTOP} → Desktop directory * ${DOCUMENTS} → Documents directory * ${DOWNLOADS} → Downloads directory * ${TEMP}, ${TMPDIR} → Temporary directory - Updated getStringEnv() to expand variables in single paths - Updated getStringArrayEnv() to expand variables in path arrays This allows Claude Desktop extension configuration values like "${HOME}/Downloads" to properly resolve to "/Users/username/Downloads" at runtime. Also updated manifest.json author from personal to company name. Regenerated qsv-mcp-server.mcpb with fixes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent c783cf2 commit 3177cfe

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

.claude/skills/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"version": "13.0.0",
55
"description": "Complete CSV data-wrangling toolkit with 66 commands for transforming, analyzing, and validating tabular data. Process local CSV, Excel, and JSONL files without uploading.",
66
"author": {
7-
"name": "Joel Natividad",
8-
"url": "https://github.com/dathere/qsv"
7+
"name": "datHere, Inc.",
8+
"url": "https://dathere.com"
99
},
1010
"repository": {
1111
"type": "git",

.claude/skills/qsv-mcp-server.mcpb

542 Bytes
Binary file not shown.

.claude/skills/src/config.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,44 @@
55
* Supports both legacy MCP server and Desktop Extension modes.
66
*/
77

8+
import { homedir, tmpdir } from 'os';
9+
import { join } from 'path';
10+
11+
/**
12+
* Expand template variables in strings
13+
* Supports: ${HOME}, ${USERPROFILE}, ${DESKTOP}, ${DOCUMENTS}, ${DOWNLOADS}, ${TEMP}, ${TMPDIR}
14+
*/
15+
function expandTemplateVars(value: string): string {
16+
if (!value) return value;
17+
18+
const home = homedir();
19+
20+
// Get platform-specific special directories
21+
const desktop = process.platform === 'win32'
22+
? join(home, 'Desktop')
23+
: join(home, 'Desktop');
24+
25+
const documents = process.platform === 'win32'
26+
? join(home, 'Documents')
27+
: join(home, 'Documents');
28+
29+
const downloads = process.platform === 'win32'
30+
? join(home, 'Downloads')
31+
: join(home, 'Downloads');
32+
33+
const temp = tmpdir();
34+
35+
// Replace template variables
36+
return value
37+
.replace(/\$\{HOME\}/g, home)
38+
.replace(/\$\{USERPROFILE\}/g, home)
39+
.replace(/\$\{DESKTOP\}/g, desktop)
40+
.replace(/\$\{DOCUMENTS\}/g, documents)
41+
.replace(/\$\{DOWNLOADS\}/g, downloads)
42+
.replace(/\$\{TEMP\}/g, temp)
43+
.replace(/\$\{TMPDIR\}/g, temp);
44+
}
45+
846
/**
947
* Parse integer from environment variable with validation
1048
*/
@@ -59,19 +97,25 @@ function parseFloatEnv(envVar: string, defaultValue: number, min?: number, max?:
5997

6098
/**
6199
* Get string from environment variable with default
100+
* Expands template variables like ${HOME}, ${USERPROFILE}, etc.
62101
* Uses nullish coalescing (??) to allow empty strings while falling back for undefined/null
63102
*/
64103
function getStringEnv(envVar: string, defaultValue: string): string {
65-
return process.env[envVar] ?? defaultValue;
104+
const value = process.env[envVar] ?? defaultValue;
105+
return expandTemplateVars(value);
66106
}
67107

68108
/**
69109
* Get string array from environment variable (split by delimiter)
110+
* Expands template variables in each path
70111
*/
71112
function getStringArrayEnv(envVar: string, defaultValue: string[], delimiter: string): string[] {
72113
const value = process.env[envVar];
73114
if (!value) return defaultValue;
74-
return value.split(delimiter).filter(s => s.length > 0);
115+
return value
116+
.split(delimiter)
117+
.filter(s => s.length > 0)
118+
.map(s => expandTemplateVars(s));
75119
}
76120

77121
/**

0 commit comments

Comments
 (0)