|
6 | 6 | import subprocess
|
7 | 7 | import sys
|
8 | 8 | 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 |
10 | 13 |
|
11 | 14 | try:
|
12 | 15 | import typer
|
@@ -141,17 +144,48 @@ def _import_server(file: Path, server_object: str | None = None):
|
141 | 144 | module = importlib.util.module_from_spec(spec)
|
142 | 145 | spec.loader.exec_module(module)
|
143 | 146 |
|
| 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.warn( |
| 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 | + |
144 | 169 | # If no object specified, try common server names
|
145 | 170 | if not server_object:
|
146 | 171 | # Look for the most common server object names
|
147 | 172 | for name in ["mcp", "server", "app"]:
|
148 | 173 | 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 |
149 | 180 | return getattr(module, name)
|
150 | 181 |
|
151 | 182 | logger.error(
|
152 | 183 | f"No server object found in {file}. Please either:\n"
|
153 | 184 | "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.", |
155 | 189 | extra={"file": str(file)},
|
156 | 190 | )
|
157 | 191 | sys.exit(1)
|
@@ -179,6 +213,9 @@ def _import_server(file: Path, server_object: str | None = None):
|
179 | 213 | )
|
180 | 214 | sys.exit(1)
|
181 | 215 |
|
| 216 | + if not _check_server_object(server, server_object): |
| 217 | + sys.exit(1) |
| 218 | + |
182 | 219 | return server
|
183 | 220 |
|
184 | 221 |
|
|
0 commit comments