upstash/context7 · error · Error

MCP args must be a TOML array containing only strings

Error message

MCP args must be a TOML array containing only strings

What it means

Inside the args array, an element does not start with a quote — every element must be a quoted string (basic or literal). Numbers, booleans, nested arrays, or bare words trigger this.

Source

Thrown at packages/cli/src/setup/toml-editor.ts:96

  }
  return { value, start, end: endQuote + 1 };
}

function parseTomlStringArray(
  source: string,
  start: number
): { tokens: TomlStringToken[]; end: number } {
  if (source[start] !== "[") throw new Error("Expected a TOML array for MCP args");

  const tokens: TomlStringToken[] = [];
  let index = start + 1;
  while (index < source.length) {
    index = skipTomlArrayTrivia(source, index);
    if (source[index] === "]") return { tokens, end: index + 1 };

    const quote = source[index];
    if (quote !== '"' && quote !== "'") {
      throw new Error("MCP args must be a TOML array containing only strings");
    }
    if (source.slice(index, index + 3) === quote.repeat(3)) {
      throw new Error("Multiline strings are not supported in MCP args");
    }

    const token =
      quote === '"' ? parseTomlBasicString(source, index) : parseTomlLiteralString(source, index);
    tokens.push(token);
    index = skipTomlArrayTrivia(source, token.end);

    if (source[index] === ",") {
      index++;
      continue;
    }
    if (source[index] !== "]") {
      throw new Error("Expected a comma or closing bracket in MCP args");
    }
  }

View on GitHub (pinned to edc9eeb77b)

Solutions

  1. Quote every element: args = ["8080", "true", "--flag"]
  2. Remove non-string elements — the tool expects string args only
  3. Validate the file with a TOML linter

Example fix

// before
args = ["--port", 8080]
// after
args = ["--port", "8080"]
Defensive patterns

Strategy: validation

Validate before calling

// after locating the array body, every element must start with a quote
const elems = arrayBody.split(',').map(e => e.trim());
if (elems.some(e => e && !e.startsWith('"') && !e.startsWith("'"))) throw new Error('non-string element');

Type guard

function isStringOnlyArray(source: string): boolean {
  return /^\\[[\\s]*("[^"\\n]*"|'[^'\\n]*')(\\s*,\\s*("[^"\\n]*"|'[^'\\n]*'))*\\s*\\]?/.test(source.trim()) || source.trim() === '[]';
}

Try / catch

catch (e) { if (/only strings/.test(e.message)) { /* quote the offending element */ } throw e; }

Prevention

When it happens

Trigger: args = [8080], args = [true], args = [--flag] (bare word), or args = [["a"]] (nested array).

Common situations: Port numbers or flags written without quotes; JSON-style mixed arrays pasted in; forgetting TOML requires quoted strings in this context.

Related errors


AI-assisted analysis of upstash/context7@edc9eeb77b (2026-08-28). Data as JSON: /api/errors/b1b9d5a106f61950. Report an issue: GitHub.