Skip to content

Commit 0941e59

Browse files
committed
fix(mcp): reject missing flag values
1 parent 54cc356 commit 0941e59

2 files changed

Lines changed: 33 additions & 4 deletions

File tree

src/integrations.mjs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ function headerName(header) {
2020
return i === -1 ? null : String(header).slice(0, i).trim();
2121
}
2222

23+
function flagValue(rest, index, flag) {
24+
const value = rest[index + 1];
25+
if (value === undefined || value === "--") return { error: `${flag} requires a value` };
26+
return { value };
27+
}
28+
2329
/** Parse `/mcp` tokens (after the `mcp` word) into { list } | { spec } | { error }. */
2430
export function parseMcp(tokens) {
2531
const verb = tokens[0];
@@ -32,10 +38,26 @@ export function parseMcp(tokens) {
3238
for (let i = 0; i < rest.length; i++) {
3339
const t = rest[i];
3440
if (t === "--") { cmdParts = rest.slice(i + 1); break; }
35-
else if (t === "--name") name = rest[++i];
36-
else if (t === "-t" || t === "--transport") transport = rest[++i];
37-
else if (t === "-e" || t === "--env") env.push(splitKV(rest[++i]));
38-
else if (t === "-H" || t === "--header") headers.push(rest[++i]);
41+
else if (t === "--name") {
42+
const next = flagValue(rest, i, t);
43+
if (next.error) return next;
44+
name = next.value; i++;
45+
}
46+
else if (t === "-t" || t === "--transport") {
47+
const next = flagValue(rest, i, t);
48+
if (next.error) return next;
49+
transport = next.value; i++;
50+
}
51+
else if (t === "-e" || t === "--env") {
52+
const next = flagValue(rest, i, t);
53+
if (next.error) return next;
54+
env.push(splitKV(next.value)); i++;
55+
}
56+
else if (t === "-H" || t === "--header") {
57+
const next = flagValue(rest, i, t);
58+
if (next.error) return next;
59+
headers.push(next.value); i++;
60+
}
3961
else positional.push(t);
4062
}
4163

test/mcp.test.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ test("parseMcp: env and header flags reject empty names", () => {
8484
assert.deepEqual(parseMcp(["install", "https://x.dev/mcp", "--env", "EMPTY="]).spec.env, [["EMPTY", ""]]);
8585
});
8686

87+
test("parseMcp: flags that need values reject missing values", () => {
88+
assert.match(parseMcp(["install", "https://x.dev/mcp", "--name"]).error, /--name requires a value/);
89+
assert.match(parseMcp(["install", "https://x.dev/mcp", "--transport", "--"]).error, /--transport requires a value/);
90+
assert.match(parseMcp(["install", "https://x.dev/mcp", "--env"]).error, /--env requires a value/);
91+
assert.match(parseMcp(["install", "https://x.dev/mcp", "--header"]).error, /--header requires a value/);
92+
});
93+
8794
test("runMcpAdd summarizes added / skipped / not-installed", async () => {
8895
const spec = { name: "s", target: "https://x.dev/mcp", env: [], headers: ["A: b"] };
8996
const plan = planMcpAdd(spec, { installedSet: new Set(["claude", "opencode"]) }); // gemini/codex not installed; codex also skips

0 commit comments

Comments
 (0)