PrefectHQ/fastmcp · error · ValueError

No MCP servers defined in the config

Error message

No MCP servers defined in the config: {file_path}

What it means

MCPConfig.from_file loads a JSON config file and validates it; if the file is missing, empty, or contains only whitespace, it raises ValueError('No MCP servers defined in the config: <path>'). It treats a non-existent or blank file as an invalid config rather than silently returning an empty model.

Solutions

  1. Check the file exists at the given path (os.path.exists) and fix the path
  2. Populate the JSON with an mcpServers object, e.g. {"mcpServers": {"myserver": {...}}}
  3. If the file should be created on demand, create and write valid JSON before calling from_file

Example fix

// before
config = MCPConfig.from_file(Path("~/.mcp.json"))
// after
path = Path("~/.mcp.json").expanduser()
assert path.exists(), f"missing config: {path}"
config = MCPConfig.from_file(path)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
import json
def config_file_ready(p: Path) -> bool:
    if not p.exists():
        return False
    text = p.read_text(encoding="utf-8").strip()
    if not text:
        return False
    return bool(json.loads(text).get("mcpServers"))

Try / catch

try:
    cfg = MCPConfig.from_file(path)
except ValueError as e:
    print(f"bad or empty config: {e}"); sys.exit(1)

Prevention

When it happens

Trigger: from_file(path) where path does not exist, or the file exists but read_text().strip() is empty (0-byte file or whitespace only). Also reached via update_config_file flows.

Common situations: Pointing at a .mcp.json path that was never created; a failed write left an empty file; wrong working directory so the relative path resolves to a nonexistent file.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/abab8153daf6f4c1. Report an issue: GitHub.

Appendix: source

Thrown at fastmcp_slim/fastmcp/mcp_config.py:358

    def to_dict(self) -> dict[str, Any]:
        """Convert MCPConfig to dictionary format, preserving all fields."""
        return self.model_dump(exclude_none=True)

    def write_to_file(self, file_path: Path) -> None:
        """Write configuration to JSON file."""
        file_path.parent.mkdir(parents=True, exist_ok=True)
        file_path.write_text(self.model_dump_json(indent=2), encoding="utf-8")

    @classmethod
    def from_file(cls, file_path: Path) -> Self:
        """Load configuration from JSON file."""
        if file_path.exists() and (
            content := file_path.read_text(encoding="utf-8").strip()
        ):
            return cls.model_validate_json(content)

        raise ValueError(f"No MCP servers defined in the config: {file_path}")


class CanonicalMCPConfig(MCPConfig):
    """Canonical MCP configuration format.

    This defines the standard configuration format for Model Context Protocol servers.
    The format is designed to be client-agnostic and extensible for future use cases.
    """

    mcpServers: dict[str, CanonicalMCPServerTypes] = Field(default_factory=dict)

    @override
    def add_server(self, name: str, server: CanonicalMCPServerTypes) -> None:
        """Add or update a server in the configuration."""
        self.mcpServers[name] = server


def update_config_file(

View on GitHub (pinned to 1f02114297)