langchain-ai/deepagents · error · ValueError
'mcpServers' field is empty - no servers configured
Error message
'mcpServers' field is empty - no servers configured
What it means
The `mcpServers` key is present and is a dictionary, but it contains no server entries. `_validate_mcp_config_top_level` raises this ValueError because a config with zero MCP servers is almost certainly a mistake — the agent would silently run with no MCP tools.
Source
Thrown at libs/code/deepagents_code/mcp_tools.py:1175
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)
def _drop_invalid_mcp_config_servers(
config: dict[str, Any],
) -> tuple[dict[str, Any], dict[str, str]]:
"""Remove invalid server entries without rejecting valid siblings.
Callers use this only after config precedence has been resolved, so anView on GitHub (pinned to a1af029e6e)
Solutions
- Add at least one server entry under 'mcpServers', e.g. {"mcpServers": {"fs": {"command": "mcp-server-fs", "args": ["/path"]}}}.
- If the empty file is intentional scaffolding, don't pass it to the loader — point at the real config.
- Check whether a script/editor emptied the file and restore the server entries from version control.
Example fix
// before
{"mcpServers": {}}
// after
{"mcpServers": {"filesystem": {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]}}} Defensive patterns
Strategy: validation
Validate before calling
cfg = json.load(open(path))
if not cfg.get("mcpServers"):
raise SystemExit("no MCP servers configured; add entries under 'mcpServers'") Type guard
def has_any_server(cfg: dict) -> bool:
return bool(cfg.get("mcpServers")) Try / catch
try:
load_mcp_config(path)
except ValueError as e:
if "no servers configured" in str(e):
point_at_real_config() # or add server entries
else:
raise Prevention
- Never commit placeholder-empty configs where a real one is expected.
- After any script edits the config, assert len(cfg['mcpServers']) > 0.
- Keep project and personal server entries in separate files so one can't blank the other.
When it happens
Trigger: Loading a config file containing {"mcpServers": {}}, typically a freshly scaffolded or emptied file, passed to _load_mcp_config_top_level.
Common situations: Creating a placeholder config before adding servers; a merge or migration script that dropped all server entries; a shared repo config where servers live in user-local files and the project file is intentionally empty.
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
- MCP config must contain 'mcpServers' field. Expected format:
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/d4bdf5e23f803cda.
Report an issue: GitHub.