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
- Check the file exists at the given path (os.path.exists) and fix the path
- Populate the JSON with an mcpServers object, e.g. {"mcpServers": {"myserver": {...}}}
- 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
- Verify the config path exists and is non-empty before loading
- Use absolute paths (Path.expanduser()/resolve())
- Never leave zero-byte config files behind on failed writes
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
- Invalid URL: {url}
- At least one of 'tools', 'include_tags', or 'exclude_tags' i
- Invalid root: {r}
- Invalid roots handler: {handler}
- identity_assertion.trusted_issuers must not be empty
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/abab8153daf6f4c1.
Report an issue: GitHub.