langchain-ai/deepagents · error · ValueError
MCP config must contain 'mcpServers' field. Expected format:
Error message
MCP config must contain 'mcpServers' field. Expected format: {"mcpServers": {"server-name": {...}}} What it means
After loading and JSON-parsing the config file, `_validate_mcp_config_top_level` requires the top-level object to have an `mcpServers` key holding the server definitions. A JSON file that parses fine but lacks this key raises this ValueError describing the expected shape. The library only recognizes the {"mcpServers": {"server-name": {...}}} format.
Source
Thrown at libs/code/deepagents_code/mcp_tools.py:1167
raise json.JSONDecodeError(error_msg, exc.doc, exc.pos) from exc
def _validate_mcp_config_top_level(config: dict[str, Any]) -> None:
"""Validate top-level MCP configuration fields.
Args:
config: Parsed MCP config dictionary.
Raises:
TypeError: If top-level fields have wrong types.
ValueError: If required top-level fields are missing.
"""
if "mcpServers" not in config:
error_msg = (
"MCP config must contain 'mcpServers' field. "
'Expected format: {"mcpServers": {"server-name": {...}}}'
)
raise ValueError(error_msg)
if not isinstance(config["mcpServers"], dict):
error_msg = "'mcpServers' field must be a dictionary"
raise TypeError(error_msg)
if not config["mcpServers"]:
error_msg = "'mcpServers' field is empty - no servers configured"
raise ValueError(error_msg)
def _validate_mcp_config_servers(config: dict[str, Any]) -> None:
"""Validate every server in an MCP configuration.
Args:
config: Parsed MCP config dictionary.
"""
for server_name, server_config in config["mcpServers"].items():
_validate_server_config(server_name, server_config)View on GitHub (pinned to a1af029e6e)
Solutions
- Rename the top-level key to 'mcpServers' and nest each server dict under it.
- If the file is an array of servers, wrap it: {"mcpServers": {name: serverDef, ...}}.
- Verify you're loading the intended MCP config file, not another JSON document.
Example fix
// before
{"fs": {"command": "mcp-server-fs"}}
// after
{"mcpServers": {"fs": {"command": "mcp-server-fs"}}} Defensive patterns
Strategy: validation
Validate before calling
import json
cfg = json.load(open(path))
if "mcpServers" not in cfg:
raise SystemExit("config must have top-level 'mcpServers' object") Type guard
def has_mcp_servers(cfg: object) -> bool:
return isinstance(cfg, dict) and "mcpServers" in cfg Try / catch
try:
load_mcp_config(path)
except ValueError as e:
if "'mcpServers' field" in str(e):
rewrite_top_level_key(path)
else:
raise Prevention
- Validate the config against the {"mcpServers": {...}} schema in CI.
- Copy example configs from this library's docs, not from other MCP clients with different schemas.
- Keep MCP configs in dedicated files (e.g. .mcp.json), never reuse unrelated JSON files.
When it happens
Trigger: Passing a config file whose root is e.g. {"servers": {...}}, a bare array of servers, a Claude-Desktop-style file using a different key, or any JSON object without 'mcpServers' (e.g. a package.json passed by mistake).
Common situations: Using a config exported from another MCP client with a different top-level schema; hand-writing the file and nesting servers directly at the root; pointing the loader at the wrong JSON file entirely.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid MCP config at {mcp_config_path}: {exc}
- Server '{server_name}' cannot set both 'allowedTools' and 'd
- Server '{server_name}' '{field_name}' must be a list of stri
- Server '{server_name}' '{field_name}' must be non-empty; omi
- 'mcpServers' field must be a dictionary
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/edb437d195816cae.
Report an issue: GitHub.