Skip to content

Commit 37b54b4

Browse files
authored
fix: Add checks and better error messages on server object for mcp run (#297)
1 parent 8b58386 commit 37b54b4

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ python server.py
387387
mcp run server.py
388388
```
389389

390+
Note that `mcp run` or `mcp dev` only supports server using FastMCP and not the low-level server variant.
391+
390392
### Streamable HTTP Transport
391393

392394
> **Note**: Streamable HTTP transport is superseding SSE transport for production deployments.
@@ -694,6 +696,8 @@ if __name__ == "__main__":
694696
asyncio.run(run())
695697
```
696698

699+
Caution: The `mcp run` and `mcp dev` tool doesn't support low-level server.
700+
697701
### Writing MCP Clients
698702

699703
The SDK provides a high-level client interface for connecting to MCP servers using various [transports](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports):

src/mcp/cli/cli.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
import subprocess
77
import sys
88
from pathlib import Path
9-
from typing import Annotated
9+
from typing import Annotated, Any
10+
11+
from mcp.server import FastMCP
12+
from mcp.server import Server as LowLevelServer
1013

1114
try:
1215
import typer
@@ -141,17 +144,48 @@ def _import_server(file: Path, server_object: str | None = None):
141144
module = importlib.util.module_from_spec(spec)
142145
spec.loader.exec_module(module)
143146

147+
def _check_server_object(server_object: Any, object_name: str):
148+
"""Helper function to check that the server object is supported
149+
150+
Args:
151+
server_object: The server object to check.
152+
153+
Returns:
154+
True if it's supported.
155+
"""
156+
if not isinstance(server_object, FastMCP):
157+
logger.error(
158+
f"The server object {object_name} is of type "
159+
f"{type(server_object)} (expecting {FastMCP})."
160+
)
161+
if isinstance(server_object, LowLevelServer):
162+
logger.warning(
163+
"Note that only FastMCP server is supported. Low level "
164+
"Server class is not yet supported."
165+
)
166+
return False
167+
return True
168+
144169
# If no object specified, try common server names
145170
if not server_object:
146171
# Look for the most common server object names
147172
for name in ["mcp", "server", "app"]:
148173
if hasattr(module, name):
174+
if not _check_server_object(getattr(module, name), f"{file}:{name}"):
175+
logger.error(
176+
f"Ignoring object '{file}:{name}' as it's not a valid "
177+
"server object"
178+
)
179+
continue
149180
return getattr(module, name)
150181

151182
logger.error(
152183
f"No server object found in {file}. Please either:\n"
153184
"1. Use a standard variable name (mcp, server, or app)\n"
154-
"2. Specify the object name with file:object syntax",
185+
"2. Specify the object name with file:object syntax"
186+
"3. If the server creates the FastMCP object within main() "
187+
" or another function, refactor the FastMCP object to be a "
188+
" global variable named mcp, server, or app.",
155189
extra={"file": str(file)},
156190
)
157191
sys.exit(1)
@@ -179,6 +213,9 @@ def _import_server(file: Path, server_object: str | None = None):
179213
)
180214
sys.exit(1)
181215

216+
if not _check_server_object(server, server_object):
217+
sys.exit(1)
218+
182219
return server
183220

184221

0 commit comments

Comments
 (0)