coleam00/Archon · error
MCP config cannot mix top-level "mcpServers" with other keys
Error message
MCP config cannot mix top-level "mcpServers" with other keys: ${mcpPath}. Use either a direct server map or { "mcpServers": { ... } }. What it means
normalizeMcpConfig accepts two shapes: a direct server map, or exactly {"mcpServers": {...}}. If the parsed file has a top-level mcpServers key plus any other keys, the intended shape is ambiguous, so it throws instead of guessing. This catches configs that mix the Claude Desktop wrapper format with stray top-level keys.
Source
Thrown at packages/providers/src/mcp/config.ts:111
`${serverName}.headers`
);
}
result[serverName] = server;
}
return { expanded: result, missingVars };
}
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,View on GitHub (pinned to 0773b97458)
Solutions
- Delete the extra top-level keys so only "mcpServers" remains.
- Or drop the "mcpServers" wrapper and place servers directly at top level.
- Move metadata into a sibling file or into per-server fields instead of top level.
Example fix
// before
{"mcpServers": {"fs": {"command": "npx"}}, "version": 1}
// after
{"mcpServers": {"fs": {"command": "npx"}}} Defensive patterns
Strategy: validation
Validate before calling
const keys = Object.keys(cfg);
if (keys.includes('mcpServers') && keys.length > 1) {
throw new Error('config must be either a direct server map or only {mcpServers: {...}}');
} Prevention
- Pick one format (wrapper or direct map) per project and stick to it.
- Keep comments/metadata out of machine-consumed JSON files.
- Check any merge tool output for accidental top-level key mixing.
When it happens
Trigger: loadMcpConfig on a file like {"mcpServers": {...}, "notes": "..."} or {"mcpServers": {...}, "version": 1}.
Common situations: Starting from a Claude Desktop config and adding custom metadata keys; merge tools combining two config files; adding a "comment" key at top level for documentation.
Related errors
- Run config cannot set both 'assistant' and 'defaultAssistant
- MCP config ${fieldPath}.${key} must be a string (got ${descr
- MCP server "${serverName}" must be a JSON object (got ${desc
- MCP config ${serverName}.env must be a JSON object of string
- MCP config ${serverName}.headers must be a JSON object of st
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/daf7f7a3ce4c59d7.
Report an issue: GitHub.