Spaces:
Sleeping
Sleeping
Update start_mcp.py
Browse files- start_mcp.py +54 -11
start_mcp.py
CHANGED
|
@@ -116,22 +116,54 @@ def run_sse(host: str, port: int):
|
|
| 116 |
if session_id not in connections:
|
| 117 |
return JSONResponse({"error": "invalid session"}, status_code=400)
|
| 118 |
|
| 119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
method = body.get("method")
|
| 121 |
params = body.get("params", {})
|
| 122 |
message_id = body.get("id")
|
| 123 |
|
| 124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
async def handle_request():
|
| 127 |
try:
|
| 128 |
if method == "initialize":
|
|
|
|
|
|
|
|
|
|
| 129 |
result: Dict[str, Any] = {
|
| 130 |
"protocolVersion": "2024-11-05",
|
| 131 |
"serverInfo": {"name": "GNoME-Materials-Discovery", "version": "1.0.0"},
|
| 132 |
"capabilities": {"tools": {}},
|
| 133 |
}
|
| 134 |
elif method == "tools/list":
|
|
|
|
|
|
|
|
|
|
| 135 |
tools = []
|
| 136 |
for tool in service._tool_manager._tools.values():
|
| 137 |
tools.append(
|
|
@@ -143,6 +175,9 @@ def run_sse(host: str, port: int):
|
|
| 143 |
)
|
| 144 |
result = {"tools": tools}
|
| 145 |
elif method == "tools/call":
|
|
|
|
|
|
|
|
|
|
| 146 |
tool_name = params.get("name")
|
| 147 |
arguments = params.get("arguments", {})
|
| 148 |
tool = service._tool_manager._tools.get(tool_name)
|
|
@@ -155,21 +190,29 @@ def run_sse(host: str, port: int):
|
|
| 155 |
tool_response = tool.fn(**arguments)
|
| 156 |
result = {"content": [{"type": "text", "text": json.dumps(tool_response)}]}
|
| 157 |
elif method == "notifications/initialized":
|
| 158 |
-
|
|
|
|
| 159 |
return
|
| 160 |
else:
|
|
|
|
|
|
|
|
|
|
| 161 |
raise ValueError(f"Unsupported method: {method}")
|
| 162 |
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
| 164 |
except Exception as exc:
|
| 165 |
logger.exception("Error handling request")
|
| 166 |
-
response
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
|
|
|
| 173 |
|
| 174 |
asyncio.create_task(handle_request())
|
| 175 |
return JSONResponse({"ok": True})
|
|
|
|
| 116 |
if session_id not in connections:
|
| 117 |
return JSONResponse({"error": "invalid session"}, status_code=400)
|
| 118 |
|
| 119 |
+
try:
|
| 120 |
+
body = await request.json()
|
| 121 |
+
except Exception as e:
|
| 122 |
+
logger.error("Failed to parse request body: %s", e)
|
| 123 |
+
return JSONResponse({"error": "Invalid JSON"}, status_code=400)
|
| 124 |
+
|
| 125 |
+
if not isinstance(body, dict):
|
| 126 |
+
logger.error("Request body is not a dictionary")
|
| 127 |
+
return JSONResponse({"error": "Invalid request format"}, status_code=400)
|
| 128 |
+
|
| 129 |
method = body.get("method")
|
| 130 |
params = body.get("params", {})
|
| 131 |
message_id = body.get("id")
|
| 132 |
|
| 133 |
+
# Check if this is a notification (no id) or a request (has id)
|
| 134 |
+
is_notification = message_id is None
|
| 135 |
+
|
| 136 |
+
if not method:
|
| 137 |
+
logger.error("Missing 'method' field in request")
|
| 138 |
+
if not is_notification:
|
| 139 |
+
# Send error response for requests without method
|
| 140 |
+
async def send_error():
|
| 141 |
+
error_response = {
|
| 142 |
+
"jsonrpc": "2.0",
|
| 143 |
+
"id": message_id,
|
| 144 |
+
"error": {"code": -32600, "message": "Invalid Request: missing 'method' field"},
|
| 145 |
+
}
|
| 146 |
+
await connections[session_id].put(error_response)
|
| 147 |
+
asyncio.create_task(send_error())
|
| 148 |
+
return JSONResponse({"error": "Missing method"}, status_code=400)
|
| 149 |
+
|
| 150 |
+
logger.info("Received method=%s id=%s (notification=%s)", method, message_id, is_notification)
|
| 151 |
|
| 152 |
async def handle_request():
|
| 153 |
try:
|
| 154 |
if method == "initialize":
|
| 155 |
+
if is_notification:
|
| 156 |
+
logger.warning("initialize received as notification, ignoring")
|
| 157 |
+
return
|
| 158 |
result: Dict[str, Any] = {
|
| 159 |
"protocolVersion": "2024-11-05",
|
| 160 |
"serverInfo": {"name": "GNoME-Materials-Discovery", "version": "1.0.0"},
|
| 161 |
"capabilities": {"tools": {}},
|
| 162 |
}
|
| 163 |
elif method == "tools/list":
|
| 164 |
+
if is_notification:
|
| 165 |
+
logger.warning("tools/list received as notification, ignoring")
|
| 166 |
+
return
|
| 167 |
tools = []
|
| 168 |
for tool in service._tool_manager._tools.values():
|
| 169 |
tools.append(
|
|
|
|
| 175 |
)
|
| 176 |
result = {"tools": tools}
|
| 177 |
elif method == "tools/call":
|
| 178 |
+
if is_notification:
|
| 179 |
+
logger.warning("tools/call received as notification, ignoring")
|
| 180 |
+
return
|
| 181 |
tool_name = params.get("name")
|
| 182 |
arguments = params.get("arguments", {})
|
| 183 |
tool = service._tool_manager._tools.get(tool_name)
|
|
|
|
| 190 |
tool_response = tool.fn(**arguments)
|
| 191 |
result = {"content": [{"type": "text", "text": json.dumps(tool_response)}]}
|
| 192 |
elif method == "notifications/initialized":
|
| 193 |
+
# This is a notification, no response needed
|
| 194 |
+
logger.info("Client initialized notification received")
|
| 195 |
return
|
| 196 |
else:
|
| 197 |
+
if is_notification:
|
| 198 |
+
logger.info("Unknown notification method: %s, ignoring", method)
|
| 199 |
+
return
|
| 200 |
raise ValueError(f"Unsupported method: {method}")
|
| 201 |
|
| 202 |
+
# Only send response for requests (not notifications)
|
| 203 |
+
if not is_notification:
|
| 204 |
+
response = {"jsonrpc": "2.0", "id": message_id, "result": result}
|
| 205 |
+
await connections[session_id].put(response)
|
| 206 |
except Exception as exc:
|
| 207 |
logger.exception("Error handling request")
|
| 208 |
+
# Only send error response for requests (not notifications)
|
| 209 |
+
if not is_notification:
|
| 210 |
+
response = {
|
| 211 |
+
"jsonrpc": "2.0",
|
| 212 |
+
"id": message_id,
|
| 213 |
+
"error": {"code": -32000, "message": str(exc)},
|
| 214 |
+
}
|
| 215 |
+
await connections[session_id].put(response)
|
| 216 |
|
| 217 |
asyncio.create_task(handle_request())
|
| 218 |
return JSONResponse({"ok": True})
|