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