affaan-m/ECC · error

MCP config must include an mcpServers object

Error message

MCP config must include an mcpServers object

What it means

filterMcpConfig expects the config object to contain an mcpServers key holding a plain object of named server entries. A config without mcpServers, or where mcpServers is an array/null/primitive, has nothing to filter and is treated as malformed.

Solutions

  1. Add an mcpServers object to the config, even if empty: { "mcpServers": {} }.
  2. Rename the top-level key to mcpServers to match the expected schema.
  3. Verify the config file matches the current schema version of the tool.
  4. Ensure the value passed is the whole config object, not just a nested section.

Example fix

// before
{ "servers": { "context7": {} } }
// after
{ "mcpServers": { "context7": {} } }
Defensive patterns

Strategy: validation

Validate before calling

if (!config || typeof config !== 'object' || Array.isArray(config) ||
    !config.mcpServers || typeof config.mcpServers !== 'object' || Array.isArray(config.mcpServers)) {
  throw new Error('Config must contain a plain mcpServers object')
}

Type guard

function hasMcpServers(cfg) {
  return cfg !== null && typeof cfg === 'object' && !Array.isArray(cfg) &&
    cfg.mcpServers !== null && typeof cfg.mcpServers === 'object' && !Array.isArray(cfg.mcpServers)
}

Try / catch

try {
  const filtered = filterMcpConfig(config, disabled)
} catch (err) {
  if (err.message.includes('mcpServers object')) {
    console.error('Add an "mcpServers": { ... } section to the config')
  } else throw err
}

Prevention

When it happens

Trigger: Passing a config object lacking mcpServers entirely, or where config.mcpServers is an array, null, or a string (e.g. a config file with the servers under a different key).

Common situations: Hand-edited mcp-servers.json where the mcpServers block was renamed or deleted; merging configs that flattened mcpServers; older config formats using a different schema key.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/abf14b29bf02e79a. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/mcp-config.js:19

'use strict';

function parseDisabledMcpServers(value) {
  return [...new Set(
    String(value || '')
      .split(',')
      .map((entry) => entry.trim())
      .filter(Boolean)
  )];
}

function filterMcpConfig(config, disabledServerNames = []) {
  if (!config || typeof config !== 'object' || Array.isArray(config)) {
    throw new Error('MCP config must be a JSON object');
  }

  const servers = config.mcpServers;
  if (!servers || typeof servers !== 'object' || Array.isArray(servers)) {
    throw new Error('MCP config must include an mcpServers object');
  }

  const disabled = new Set(parseDisabledMcpServers(disabledServerNames));
  if (disabled.size === 0) {
    return {
      config: {
        ...config,
        mcpServers: { ...servers },
      },
      removed: [],
    };
  }

  const nextServers = {};
  const removed = [];

  for (const [name, serverConfig] of Object.entries(servers)) {
    if (disabled.has(name)) {

View on GitHub (pinned to 8321021c54)