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 an

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Add at least one server entry under 'mcpServers', e.g. {"mcpServers": {"fs": {"command": "mcp-server-fs", "args": ["/path"]}}}.
  2. If the empty file is intentional scaffolding, don't pass it to the loader — point at the real config.
  3. 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

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


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/d4bdf5e23f803cda. Report an issue: GitHub.