(params: {
filePath: string
expandVars: boolean
scope: ConfigScope
})
| 1382 | * @returns Validated configuration with any errors |
| 1383 | */ |
| 1384 | export function parseMcpConfigFromFilePath(params: { |
| 1385 | filePath: string |
| 1386 | expandVars: boolean |
| 1387 | scope: ConfigScope |
| 1388 | }): { |
| 1389 | config: McpJsonConfig | null |
| 1390 | errors: ValidationError[] |
| 1391 | } { |
| 1392 | const { filePath, expandVars, scope } = params |
| 1393 | const fs = getFsImplementation() |
| 1394 | |
| 1395 | let configContent: string |
| 1396 | try { |
| 1397 | configContent = fs.readFileSync(filePath, { encoding: 'utf8' }) |
| 1398 | } catch (error: unknown) { |
| 1399 | const code = getErrnoCode(error) |
| 1400 | if (code === 'ENOENT') { |
| 1401 | return { |
| 1402 | config: null, |
| 1403 | errors: [ |
| 1404 | { |
| 1405 | file: filePath, |
| 1406 | path: '', |
| 1407 | message: `MCP config file not found: ${filePath}`, |
| 1408 | suggestion: 'Check that the file path is correct', |
| 1409 | mcpErrorMetadata: { |
| 1410 | scope, |
| 1411 | severity: 'fatal', |
| 1412 | }, |
| 1413 | }, |
| 1414 | ], |
| 1415 | } |
| 1416 | } |
| 1417 | logForDebugging( |
| 1418 | `MCP config read error for ${filePath} (scope=${scope}): ${error}`, |
| 1419 | { level: 'error' }, |
| 1420 | ) |
| 1421 | return { |
| 1422 | config: null, |
| 1423 | errors: [ |
| 1424 | { |
| 1425 | file: filePath, |
| 1426 | path: '', |
| 1427 | message: `Failed to read file: ${error}`, |
| 1428 | suggestion: 'Check file permissions and ensure the file exists', |
| 1429 | mcpErrorMetadata: { |
| 1430 | scope, |
| 1431 | severity: 'fatal', |
| 1432 | }, |
| 1433 | }, |
| 1434 | ], |
| 1435 | } |
| 1436 | } |
| 1437 | |
| 1438 | const parsedJson = safeParseJSON(configContent) |
| 1439 | |
| 1440 | if (!parsedJson) { |
| 1441 | logForDebugging( |
no test coverage detected