Fix: robust MCP handler with proper logging and error handling

This commit is contained in:
2026-06-14 17:13:10 +00:00
parent 63617550a1
commit 208e4195b0
+40 -5
View File
@@ -24,10 +24,19 @@ Auth:
import json import json
import os import os
import sys import sys
import logging
from http.server import HTTPServer, BaseHTTPRequestHandler from http.server import HTTPServer, BaseHTTPRequestHandler
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
import requests import requests
# Configure logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
stream=sys.stdout,
)
logger = logging.getLogger("mcp-summary")
API_KEY = os.environ.get("API_KEY", "").strip() API_KEY = os.environ.get("API_KEY", "").strip()
# Tool definitions # Tool definitions
@@ -99,6 +108,7 @@ def call_llm(text: str, system_prompt: str, max_tokens: int = 2000) -> str:
"top_p": 0.9 "top_p": 0.9
} }
logger.info(f"Calling LLM: {url} model={model_name}")
response = requests.post(url, headers=headers, json=payload, timeout=timeout) response = requests.post(url, headers=headers, json=payload, timeout=timeout)
response.raise_for_status() response.raise_for_status()
@@ -244,8 +254,8 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
"""HTTP handler for MCP summary server.""" """HTTP handler for MCP summary server."""
def log_message(self, format, *args): def log_message(self, format, *args):
# Quiet logs by default # Use our logger instead of default stderr logging
pass logger.info(format % args)
def _send_json(self, status: int, payload: Any): def _send_json(self, status: int, payload: Any):
"""Send JSON response.""" """Send JSON response."""
@@ -266,6 +276,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
def do_GET(self): def do_GET(self):
"""Handle GET requests (health check).""" """Handle GET requests (health check)."""
try:
if self.path == "/": if self.path == "/":
self._send_json(200, { self._send_json(200, {
"service": "mcp-summary", "service": "mcp-summary",
@@ -275,9 +286,17 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
return return
self.send_error(404, "Not Found") self.send_error(404, "Not Found")
except Exception as e:
logger.error(f"GET error: {e}", exc_info=True)
# Ensure we still send something
try:
self.send_error(500, "Internal Server Error")
except Exception:
pass
def do_POST(self): def do_POST(self):
"""Handle MCP JSON-RPC requests.""" """Handle MCP JSON-RPC requests."""
try:
if self.path not in ("/", "/mcp"): if self.path not in ("/", "/mcp"):
self.send_error(404, "Not Found") self.send_error(404, "Not Found")
return return
@@ -301,6 +320,8 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
params = req.get("params") or {} params = req.get("params") or {}
req_id = req.get("id") req_id = req.get("id")
logger.info(f"MCP request: method={method}, id={req_id}")
# MCP: initialize # MCP: initialize
if method == "initialize": if method == "initialize":
self._send_json(200, { self._send_json(200, {
@@ -344,6 +365,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
} }
}) })
except Exception as e: except Exception as e:
logger.error(f"Tool call error: {e}", exc_info=True)
self._send_json(200, { self._send_json(200, {
"jsonrpc": "2.0", "jsonrpc": "2.0",
"id": req_id, "id": req_id,
@@ -357,6 +379,14 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
# Unknown method # Unknown method
self._send_json(400, {"error": "Unknown method: " + str(method)}) self._send_json(400, {"error": "Unknown method: " + str(method)})
except Exception as e:
logger.error(f"POST error: {e}", exc_info=True)
# Fallback response to avoid silent drop
try:
self.send_error(500, "Internal Server Error")
except Exception:
pass
def _call_tool(self, name: str, args: Dict[str, Any]) -> Any: def _call_tool(self, name: str, args: Dict[str, Any]) -> Any:
"""Execute a tool call.""" """Execute a tool call."""
if name == "summarize_document": if name == "summarize_document":
@@ -373,13 +403,18 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
def main(): def main():
"""Start the MCP summary server.""" """Start the MCP summary server."""
port = int(sys.argv[1]) if len(sys.argv) > 1 else int(os.environ.get("PORT", "8080")) port = int(sys.argv[1]) if len(sys.argv) > 1 else int(os.environ.get("PORT", "8080"))
logger.info(f"Starting MCP Summary Server on 0.0.0.0:{port}")
logger.info(f"Auth mode: {'Bearer (API_KEY set)' if API_KEY else 'none (API_KEY not set)'}")
logger.info(f"LLM URL: {os.environ.get('OPENAPI_URL', 'http://localhost:8080/v1')}")
logger.info(f"Model: {os.environ.get('MODEL_NAME', 'gpt-4o')}")
server = HTTPServer(("0.0.0.0", port), MCPSummaryHandler) server = HTTPServer(("0.0.0.0", port), MCPSummaryHandler)
mode = "auth enabled (Bearer)" if API_KEY else "no auth (API_KEY not set)"
print(f"MCP Summary Server listening on 0.0.0.0:{port} [{mode}]")
try: try:
logger.info(f"MCP Summary Server listening on 0.0.0.0:{port}")
server.serve_forever() server.serve_forever()
except KeyboardInterrupt: except KeyboardInterrupt:
print("\nShutting down...") logger.info("Shutting down...")
server.server_close() server.server_close()