coleam00/Archon · error

MCP config field "mcpServers" must be a JSON object: ${mcpPa

Error message

MCP config field "mcpServers" must be a JSON object: ${mcpPath}

What it means

When a config uses the {"mcpServers": ...} wrapper form, the value of mcpServers must be a JSON object mapping server names to server objects. A null, array, or primitive value means there are no valid server definitions, so normalizeMcpConfig throws including the config path.

Source

Thrown at packages/providers/src/mcp/config.ts:118

function normalizeMcpConfig(
  parsed: Record<string, unknown>,
  mcpPath: string
): Record<string, unknown> {
  const keys = Object.keys(parsed);
  if (!keys.includes('mcpServers')) {
    return parsed;
  }

  if (keys.length > 1) {
    throw new Error(
      `MCP config cannot mix top-level "mcpServers" with other keys: ${mcpPath}. Use either a direct server map or { "mcpServers": { ... } }.`
    );
  }

  const servers = parsed.mcpServers;
  if (typeof servers !== 'object' || servers === null || Array.isArray(servers)) {
    throw new Error(`MCP config field "mcpServers" must be a JSON object: ${mcpPath}`);
  }

  return servers as Record<string, unknown>;
}

/**
 * Load MCP server config from a JSON file and expand environment variables.
 */
export async function loadMcpConfig(
  mcpPath: string,
  cwd: string,
  envSource: EnvSource = process.env
): Promise<LoadedMcpConfig> {
  const fullPath = isAbsolute(mcpPath) ? mcpPath : resolve(cwd, mcpPath);

  let raw: string;
  try {
    raw = await readFile(fullPath, 'utf-8');

View on GitHub (pinned to 0773b97458)

Solutions

  1. Replace null/array with an object: {"mcpServers": {}} for zero servers.
  2. Add at least one server definition under mcpServers.
  3. If the file was meant to disable MCP entirely, remove the mcpServers key and point the caller at a different config.

Example fix

// before
{"mcpServers": null}
// after
{"mcpServers": {"fs": {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]}}}
Defensive patterns

Strategy: validation

Validate before calling

if ('mcpServers' in cfg) {
  const s = cfg.mcpServers;
  if (typeof s !== 'object' || s === null || Array.isArray(s)) {
    throw new Error('mcpServers must be an object');
  }
}

Type guard

const isServerMap = (v: unknown): v is Record<string, Record<string, unknown>> =>
  typeof v === 'object' && v !== null && !Array.isArray(v) &&
  Object.values(v).every((x) => typeof x === 'object' && x !== null && !Array.isArray(x));

Prevention

When it happens

Trigger: loadMcpConfig on {"mcpServers": null}, {"mcpServers": []}, or {"mcpServers": "..."} (alone as the only key).

Common situations: A template left mcpServers empty/null; a script serialized an empty list instead of an object; hand-deleting all servers left the wrong JSON shape; YAML empty value became null.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/032f73c524a30d82. Report an issue: GitHub.