affaan-m/ECC · error · Error

MCP config must be a JSON object

Error message

MCP config must be a JSON object

What it means

Thrown by filterMcpConfig() when the config argument is null, undefined, not an object type, or an array. The function only operates on plain JSON objects representing an MCP server configuration document.

Source

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

'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: [],
    };
  }

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Ensure the config is a parsed JSON object (typeof === 'object', not Array.isArray, not null).
  2. If loading from a file, JSON.parse the contents and check the result before passing it in.
  3. Reject or fix config files whose top level is an array or scalar.

Example fix

// before
filterMcpConfig(JSON.parse('[...]'));
// after
filterMcpConfig(JSON.parse('{"mcpServers": {...}}'));
Defensive patterns

Strategy: type-guard

Validate before calling

function isJsonObject(value) {
  return value !== null && typeof value === 'object' && !Array.isArray(value);
}
if (!isJsonObject(config)) {
  throw new Error('MCP config must parse to a JSON object.');
}

Type guard

function isMcpConfigObject(value) {
  return value !== null && typeof value === 'object' && !Array.isArray(value);
}

Try / catch

try {
  result = filterMcpConfig(config, disabled);
} catch (e) {
  if (/MCP config must be a JSON object/.test(e.message)) {
    if (typeof config === 'string') {
      try { config = JSON.parse(config); } catch { throw e; }
      result = filterMcpConfig(config, disabled);
    } else throw e;
  } else throw e;
}

Prevention

When it happens

Trigger: Passing JSON.parse output that is an array or a string; passing null because a config file was empty or unread; passing a stringified JSON by mistake.

Common situations: Reading a .mcp.json that contains a top-level array; a config loader returning null on missing file; double-encoding JSON so the value is a string.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/559543d91d353d3e. Report an issue: GitHub.