{"record":{"id":"4d9c9ec7dcfbf625","repo":"farion1231/cc-switch","slug":"type-mcp-url","errorCode":null,"errorMessage":"${type} 类型的 MCP 服务器必须包含 url 字段","messagePattern":"(.+?) 类型的 MCP 服务器必须包含 url 字段","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/utils/tomlUtils.ts","lineNumber":151,"sourceCode":"      server.env = env;\n      knownFields.add(\"env\");\n    }\n    if (config.cwd && typeof config.cwd === \"string\") {\n      server.cwd = config.cwd;\n      knownFields.add(\"cwd\");\n    }\n\n    // 保留所有未知字段（如 timeout_ms 等扩展字段）\n    for (const key of Object.keys(config)) {\n      if (!knownFields.has(key)) {\n        server[key] = config[key];\n      }\n    }\n\n    return server;\n  } else if (type === \"http\" || type === \"sse\") {\n    if (!config.url || typeof config.url !== \"string\") {\n      throw new Error(`${type} 类型的 MCP 服务器必须包含 url 字段`);\n    }\n\n    const server: McpServerSpec = {\n      type: type as \"http\" | \"sse\",\n      url: config.url,\n    };\n    knownFields.add(\"type\");\n    knownFields.add(\"url\");\n\n    // 可选字段\n    if (config.headers && typeof config.headers === \"object\") {\n      const headers: Record<string, string> = {};\n      for (const [k, v] of Object.entries(config.headers)) {\n        headers[k] = String(v);\n      }\n      server.headers = headers;\n      knownFields.add(\"headers\");\n    }","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/farion1231/cc-switch/blob/a2e22f330273a5b6ffa87cb8b82b624601bac562/src/utils/tomlUtils.ts#L133-L169","documentation":"For entries declaring type \"http\" or \"sse\", a string url is mandatory ('http/sse MCP server must include url field'). Thrown when the type explicitly selects a remote transport but url is missing, misspelled, or not a string.","triggerScenarios":"type = \"http\" with only command/args present; url key misspelled or wrong case (TOML keys are case-sensitive); url set to a non-string value.","commonSituations":"Converting a stdio config to remote and forgetting the url line; key typo like 'URL =' after hand-editing.","solutions":["Add url = \"https://mcp.example.com/...\" to the entry","Check the spelling and case of the url key","Drop the type line if the server is actually a local stdio process"],"exampleFix":"# before (throws)\ntype = \"http\"\ncommand = \"npx\"\n\n# after\ntype = \"http\"\nurl = \"https://mcp.example.com/mcp\"","handlingStrategy":"validation","validationCode":"function isRemoteEntry(e: Record<string, unknown>): e is { type: \"http\" | \"sse\"; url: string } {\n  return (\n    (e.type === \"http\" || e.type === \"sse\") &&\n    typeof e.url === \"string\" &&\n    e.url.length > 0\n  );\n}\n\nif ((entry.type === \"http\" || entry.type === \"sse\") && !isRemoteEntry(entry)) {\n  setImportError(\"http/sse servers must include url\");\n}","typeGuard":"function isRemoteEntry(e: Record<string, unknown>): e is { type: \"http\" | \"sse\"; url: string } {\n  return (\n    (e.type === \"http\" || e.type === \"sse\") &&\n    typeof e.url === \"string\" &&\n    e.url.length > 0\n  );\n}","tryCatchPattern":"try {\n  const server = tomlToMcpServer(tomlText);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"必须包含 url 字段\")) {\n    setImportError(\"Add url = \\\"https://...\\\" to the http/sse server entry\");\n  } else {\n    throw e;\n  }\n}","preventionTips":["Pair every type = \"http\"/\"sse\" line with a url line","TOML keys are case-sensitive - write url, not URL or Url","Drop the type line for local stdio servers instead of leaving a typeless remote entry"],"tags":["toml","mcp","http","validation"],"backgroundTag":null,"analyzedSha":"a2e22f330273a5b6ffa87cb8b82b624601bac562","analyzedAt":"2026-08-16T03:46:07.889Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}