PrefectHQ/fastmcp · error · ValueError

No MCP servers defined in the config: {file_path}

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.

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)

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.