{"record":{"id":"592c7e5fad348715","repo":"upstash/context7","slug":"expected-a-comma-or-closing-bracket-in-mcp-args","errorCode":null,"errorMessage":"Expected a comma or closing bracket in MCP args","messagePattern":"Expected a comma or closing bracket in MCP args","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/setup/toml-editor.ts","lineNumber":112,"sourceCode":"    const quote = source[index];\n    if (quote !== '\"' && quote !== \"'\") {\n      throw new Error(\"MCP args must be a TOML array containing only strings\");\n    }\n    if (source.slice(index, index + 3) === quote.repeat(3)) {\n      throw new Error(\"Multiline strings are not supported in MCP args\");\n    }\n\n    const token =\n      quote === '\"' ? parseTomlBasicString(source, index) : parseTomlLiteralString(source, index);\n    tokens.push(token);\n    index = skipTomlArrayTrivia(source, token.end);\n\n    if (source[index] === \",\") {\n      index++;\n      continue;\n    }\n    if (source[index] !== \"]\") {\n      throw new Error(\"Expected a comma or closing bracket in MCP args\");\n    }\n  }\n  throw new Error(\"Unterminated TOML array in MCP args\");\n}\n\nfunction findTomlServerArgs(\n  raw: string,\n  serverName: string\n): { start: number; end: number; tokens: TomlStringToken[] } | null {\n  const escapedName = serverName.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n  const tableKey = `(?:mcp_servers|\"mcp_servers\"|'mcp_servers')`;\n  const serverKey = `(?:${escapedName}|\"${escapedName}\"|'${escapedName}')`;\n  const headerRe = new RegExp(\n    `^[\\\\uFEFF\\\\t ]*\\\\[[\\\\t ]*${tableKey}[\\\\t ]*\\\\.[\\\\t ]*${serverKey}[\\\\t ]*\\\\][\\\\t ]*(?:#.*)?\\\\r?$`,\n    \"m\"\n  );\n  const header = headerRe.exec(raw);\n  if (!header) return null;","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/upstash/context7/blob/4416fb855b8f752be735e34f943b5d0762701aad/packages/cli/src/setup/toml-editor.ts#L94-L130","documentation":"This error is thrown by the hand-rolled TOML string-array parser in parseTomlStringArray when, after parsing a string element inside an `args = [...]` array of an MCP server entry, the next meaningful character is neither a comma nor the closing `]`. The parser exists so the CLI can surgically edit a config file without a full TOML parser; it only accepts the strict shape `args = [\"a\", \"b\"]` and throws on anything it cannot safely rewrite byte-for-byte.","triggerScenarios":"Calling patchTomlStdioApiKey on a TOML file whose `[mcp_servers.<name>]` body has an args array with two adjacent string values and no comma (e.g. `args = [\"x\" \"y\"]`), a trailing element followed by a non-bracket character (e.g. a stray identifier or number like `args = [\"x\", -y]`), or a misplaced character after skipping whitespace/comments.","commonSituations":"Hand-edited or tool-generated configs using a non-standard TOML dialect (e.g. space-separated lists copied from JSON-without-commas or another format), merge conflicts that dropped commas, or truncated files that mangle the array separator.","solutions":["Open the TOML file and add a comma between every two array elements in the args line","Ensure the args array ends with `]` immediately after the last element (only whitespace/comments allowed before it)","Remove any non-string elements (numbers, booleans, sub-tables) from the args array — the editor only supports arrays of strings","Regenerate the server entry with the CLI's setup command to get a canonical args line"],"exampleFix":"// before (invalid TOML array syntax)\nargs = [\"-y\" \"@context7/mcp\"]\n// after\nargs = [\"-y\", \"@context7/mcp\"]","handlingStrategy":"validation","validationCode":"const argsLine = raw.match(/^[\\t ]*args[\\t ]*=[\\t ]*\\[[^\\]]*\\]/m);\nif (!argsLine || !/\"|'|,|\\s*\\]/.test(argsLine[0]) || /[\"']\\s+[\"']/.test(argsLine[0].slice(1, -1))) {\n  throw new Error(\"args array is malformed: missing comma or bad separator\");\n}","typeGuard":"function hasWellFormedArgsArray(toml: string): boolean {\n  const m = toml.match(/^[\\t ]*args[\\t ]*=[\\t ]*(\\[[^\\]]*\\])/m);\n  return !!m && m[1].split(\"[\")[1].trim() !== \"\" ? /^[^\\]]*,[^\\]]*$|^\\s*$|^\\[[^\\]]*,.*\\]$/.test(m[1]) || !/[\"']\\s+[\"']/.test(m[1]) : true;\n}","tryCatchPattern":"try {\n  await patchTomlStdioApiKey(tomlPath, serverName, apiKey);\n} catch (e) {\n  if (e.message.includes(\"comma or closing bracket\")) {\n    console.error(`Malformed args array in ${tomlPath}: fix commas/brackets manually`, e);\n  }\n}","preventionTips":["Always separate array elements with commas when hand-editing TOML","Validate the TOML with a real TOML parser (e.g. taplo, @iarna/toml) before letting automated tools rewrite it","Avoid hand-editing configs right after merge conflicts — re-run the setup command instead"],"tags":["toml","parsing","config","mcp"],"backgroundTag":"invalid-argument-format","analyzedSha":"4416fb855b8f752be735e34f943b5d0762701aad","analyzedAt":"2026-09-16T20:28:07.148Z","contentChangedAt":"2026-09-16T20:28:07.148Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}