vercel/ai · error · Error

DeepAgents MCP server ${JSON.stringify(name)} must be config

Error message

DeepAgents MCP server ${JSON.stringify(name)} must be configured with an object value.

What it means

MCP server entries under the `mcpServers` option must each be a plain object (a MultiServerMCPClient connection config). The bridge validates every entry before constructing the client and rejects null, non-object, or array values, naming the offending server key. This prevents malformed configs from reaching `@langchain/mcp-adapters`.

Source

Thrown at packages/harness-deepagents/src/bridge/index.ts:446

      saver: checkpointer,
    });
    return {};
  },
  onDestroy: async () => {
    await closeMcpClient();
    await removeMemorySaverSnapshot(conversationCheckpointPath);
  },
});

async function loadMcpTools({
  mcpServers,
}: {
  mcpServers: Record<string, unknown> | undefined;
}) {
  if (mcpServers == null || Object.keys(mcpServers).length === 0) return [];
  for (const [name, value] of Object.entries(mcpServers)) {
    if (value == null || typeof value !== 'object' || Array.isArray(value)) {
      throw new Error(
        `DeepAgents MCP server ${JSON.stringify(name)} must be configured with an object value.`,
      );
    }
  }
  mcpClient = new MultiServerMCPClient({
    mcpServers: mcpServers as ClientConfig['mcpServers'],
    prefixToolNameWithServerName: true,
    additionalToolNamePrefix: 'mcp',
  });
  return mcpClient.getTools();
}

async function closeMcpClient(): Promise<void> {
  const client = mcpClient;
  mcpClient = undefined;
  mcpToolNames = new Set();
  await client?.close();
}

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Give each MCP server an object value, e.g. `{ mcpServers: { filesystem: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'] } } }`.
  2. Remove null/empty server entries from the config instead of leaving placeholders.
  3. Convert array-form server lists into the keyed-record form `MultiServerMCPClient` expects.
  4. Check env/templating that fills the config isn't resolving a server entry to null or a string.

Example fix

// before
createDeepAgents({ mcpServers: { filesystem: null } })
// after
createDeepAgents({ mcpServers: { filesystem: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'] } } })
Defensive patterns

Strategy: validation

Validate before calling

const entries = Object.entries(mcpServers ?? {});
for (const [name, value] of entries) {
  if (value == null || typeof value !== 'object' || Array.isArray(value)) {
    throw new Error(`MCP server "${name}" must be an object`);
  }
}

Type guard

function isValidMcpServerEntry(v: unknown): v is Record<string, unknown> {
  return v != null && typeof v === 'object' && !Array.isArray(v);
}

Try / catch

try {
  await startSession();
} catch (error) {
  if (error instanceof Error && error.message.includes('must be configured with an object value')) {
    // fix the named mcpServers entry in config
  }
  throw error;
}

Prevention

When it happens

Trigger: Passing `createDeepAgents({ mcpServers: { myServer: null } })`, an array value (`{ myServer: [ ... ] }`), or any non-object value (string, number, boolean) in the `mcpServers` record of the start message.

Common situations: YAML/JSON config where an MCP server was left empty (`server:` with no value); using array-style server lists instead of keyed objects; template/env substitution resolving to null; copying a config shape from a different MCP client that accepts arrays.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/1145d9bfd8d5ed04. Report an issue: GitHub.