Improve error handling and logging for diagnostics
This commit is contained in:
Binary file not shown.
+34
@@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Diagnostic script for MCP Summary Server
|
||||||
|
|
||||||
|
echo "================================"
|
||||||
|
echo "MCP Summary Server Diagnostics"
|
||||||
|
echo "================================"
|
||||||
|
|
||||||
|
# Check if server is running
|
||||||
|
echo -e "\n1. Checking if server process is running..."
|
||||||
|
ps aux | grep mcp_summary_server || echo "Server process not found"
|
||||||
|
|
||||||
|
# Check if port is listening
|
||||||
|
echo -e "\n2. Checking if port is listening..."
|
||||||
|
netstat -tlnp 2>/dev/null | grep 8080 || echo "Port 8080 not listening"
|
||||||
|
|
||||||
|
# Test basic connectivity
|
||||||
|
echo -e "\n3. Testing basic connectivity..."
|
||||||
|
curl -s http://localhost:8080/ || echo "Cannot connect to localhost:8080"
|
||||||
|
|
||||||
|
# Test MCP initialize
|
||||||
|
echo -e "\n4. Testing MCP initialize..."
|
||||||
|
curl -s -X POST http://localhost:8080/ \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' | jq .
|
||||||
|
|
||||||
|
# Test tools list
|
||||||
|
echo -e "\n5. Testing tools list..."
|
||||||
|
curl -s -X POST http://localhost:8080/ \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | jq .
|
||||||
|
|
||||||
|
echo -e "\n================================"
|
||||||
|
echo "Diagnostics complete"
|
||||||
|
echo "================================"
|
||||||
+12
-4
@@ -24,13 +24,13 @@ Auth:
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import re
|
|
||||||
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
|
||||||
|
|
||||||
API_KEY = os.environ.get("API_KEY", "").strip()
|
API_KEY = os.environ.get("API_KEY", "").strip()
|
||||||
|
|
||||||
|
# Tool definitions
|
||||||
TOOLS_LIST: Dict[str, Any] = {
|
TOOLS_LIST: Dict[str, Any] = {
|
||||||
"tools": [
|
"tools": [
|
||||||
{
|
{
|
||||||
@@ -56,6 +56,7 @@ TOOLS_LIST: Dict[str, Any] = {
|
|||||||
|
|
||||||
|
|
||||||
def get_bearer_token(headers: Any) -> Optional[str]:
|
def get_bearer_token(headers: Any) -> Optional[str]:
|
||||||
|
"""Extract bearer token from Authorization header."""
|
||||||
auth = (headers.get("Authorization") or "").strip()
|
auth = (headers.get("Authorization") or "").strip()
|
||||||
if auth.startswith("Bearer "):
|
if auth.startswith("Bearer "):
|
||||||
return auth[len("Bearer "):].strip()
|
return auth[len("Bearer "):].strip()
|
||||||
@@ -63,6 +64,7 @@ def get_bearer_token(headers: Any) -> Optional[str]:
|
|||||||
|
|
||||||
|
|
||||||
def require_auth(headers: Any) -> bool:
|
def require_auth(headers: Any) -> bool:
|
||||||
|
"""Check authentication if API key is configured."""
|
||||||
# If API_KEY is not set, allow unauthenticated access
|
# If API_KEY is not set, allow unauthenticated access
|
||||||
if not API_KEY:
|
if not API_KEY:
|
||||||
return True
|
return True
|
||||||
@@ -239,11 +241,14 @@ Final summary:"""
|
|||||||
|
|
||||||
|
|
||||||
class MCPSummaryHandler(BaseHTTPRequestHandler):
|
class MCPSummaryHandler(BaseHTTPRequestHandler):
|
||||||
|
"""HTTP handler for MCP summary server."""
|
||||||
|
|
||||||
def log_message(self, format, *args):
|
def log_message(self, format, *args):
|
||||||
# Quiet logs by default
|
# Quiet logs by default
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _send_json(self, status: int, payload: Any):
|
def _send_json(self, status: int, payload: Any):
|
||||||
|
"""Send JSON response."""
|
||||||
body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
|
body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
|
||||||
self.send_response(status)
|
self.send_response(status)
|
||||||
self.send_header("Content-Type", "application/json")
|
self.send_header("Content-Type", "application/json")
|
||||||
@@ -251,7 +256,8 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
|
|||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(body)
|
self.wfile.write(body)
|
||||||
|
|
||||||
def _auth_or_401(self):
|
def _auth_or_401(self) -> bool:
|
||||||
|
"""Check authentication if API key is configured."""
|
||||||
try:
|
try:
|
||||||
return require_auth(self.headers)
|
return require_auth(self.headers)
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
@@ -259,7 +265,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
# Basic info endpoint (not required by MCP, but useful)
|
"""Handle GET requests (health check)."""
|
||||||
if self.path == "/":
|
if self.path == "/":
|
||||||
self._send_json(200, {
|
self._send_json(200, {
|
||||||
"service": "mcp-summary",
|
"service": "mcp-summary",
|
||||||
@@ -271,7 +277,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
|
|||||||
self.send_error(404, "Not Found")
|
self.send_error(404, "Not Found")
|
||||||
|
|
||||||
def do_POST(self):
|
def do_POST(self):
|
||||||
# Streamable HTTP MCP endpoint
|
"""Handle MCP JSON-RPC requests."""
|
||||||
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
|
||||||
@@ -352,6 +358,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
|
|||||||
self._send_json(400, {"error": "Unknown method: " + str(method)})
|
self._send_json(400, {"error": "Unknown method: " + str(method)})
|
||||||
|
|
||||||
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."""
|
||||||
if name == "summarize_document":
|
if name == "summarize_document":
|
||||||
text = args.get("text")
|
text = args.get("text")
|
||||||
if not text:
|
if not text:
|
||||||
@@ -364,6 +371,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
"""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"))
|
||||||
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)"
|
mode = "auth enabled (Bearer)" if API_KEY else "no auth (API_KEY not set)"
|
||||||
|
|||||||
@@ -0,0 +1,155 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test script to verify MCP summary server connectivity and functionality.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def test_health_check(url):
|
||||||
|
"""Test basic health check."""
|
||||||
|
try:
|
||||||
|
response = requests.get(url, timeout=5)
|
||||||
|
print(f"✓ Health check: {response.status_code}")
|
||||||
|
print(f" Response: {response.json()}")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ Health check failed: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_mcp_initialize(url, api_key=None):
|
||||||
|
"""Test MCP initialization."""
|
||||||
|
headers = {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
if api_key:
|
||||||
|
headers["Authorization"] = f"Bearer {api_key}"
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 1,
|
||||||
|
"method": "initialize",
|
||||||
|
"params": {
|
||||||
|
"protocolVersion": "2025-11-25",
|
||||||
|
"capabilities": {},
|
||||||
|
"clientInfo": {
|
||||||
|
"name": "test-client",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(url, headers=headers, json=payload, timeout=10)
|
||||||
|
print(f"✓ MCP Initialize: {response.status_code}")
|
||||||
|
print(f" Response: {response.json()}")
|
||||||
|
return response.status_code == 200
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ MCP Initialize failed: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_tools_list(url, api_key=None):
|
||||||
|
"""Test tools/list endpoint."""
|
||||||
|
headers = {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
if api_key:
|
||||||
|
headers["Authorization"] = f"Bearer {api_key}"
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 2,
|
||||||
|
"method": "tools/list",
|
||||||
|
"params": {}
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(url, headers=headers, json=payload, timeout=10)
|
||||||
|
print(f"✓ Tools List: {response.status_code}")
|
||||||
|
print(f" Response: {response.json()}")
|
||||||
|
return response.status_code == 200
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ Tools List failed: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_summarize(url, api_key=None):
|
||||||
|
"""Test summarize_document tool."""
|
||||||
|
headers = {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
if api_key:
|
||||||
|
headers["Authorization"] = f"Bearer {api_key}"
|
||||||
|
|
||||||
|
# Simple test text
|
||||||
|
test_text = """
|
||||||
|
The Supreme Court of Canada decided in R v. Smith, 2020 SCC 15, that the
|
||||||
|
police had violated the accused's section 8 Charter rights by conducting a
|
||||||
|
warrantless search of his vehicle. The Court found that the officers did not
|
||||||
|
have reasonable grounds to believe that evidence would be destroyed if they
|
||||||
|
waited to obtain a warrant. The evidence was excluded under section 24(2) of
|
||||||
|
the Charter, and the conviction was overturned.
|
||||||
|
"""
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 3,
|
||||||
|
"method": "tools/call",
|
||||||
|
"params": {
|
||||||
|
"name": "summarize_document",
|
||||||
|
"arguments": {
|
||||||
|
"text": test_text,
|
||||||
|
"max_length": 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(url, headers=headers, json=payload, timeout=120)
|
||||||
|
print(f"✓ Summarize Test: {response.status_code}")
|
||||||
|
print(f" Response: {response.json()}")
|
||||||
|
return response.status_code == 200
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ Summarize Test failed: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
url = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:8080"
|
||||||
|
api_key = sys.argv[2] if len(sys.argv) > 2 else None
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("MCP Summary Server Test")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f"URL: {url}")
|
||||||
|
print(f"API Key: {'[SET]' if api_key else '[NOT SET]'}")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
print("\n1. Testing health check...")
|
||||||
|
health_ok = test_health_check(url)
|
||||||
|
|
||||||
|
print("\n2. Testing MCP initialization...")
|
||||||
|
init_ok = test_mcp_initialize(url, api_key)
|
||||||
|
|
||||||
|
print("\n3. Testing tools list...")
|
||||||
|
tools_ok = test_tools_list(url, api_key)
|
||||||
|
|
||||||
|
print("\n4. Testing summarize tool...")
|
||||||
|
summarize_ok = test_summarize(url, api_key)
|
||||||
|
|
||||||
|
print("\n" + "=" * 60)
|
||||||
|
print("Summary:")
|
||||||
|
print(f" Health Check: {'✓' if health_ok else '✗'}")
|
||||||
|
print(f" MCP Initialize: {'✓' if init_ok else '✗'}")
|
||||||
|
print(f" Tools List: {'✓' if tools_ok else '✗'}")
|
||||||
|
print(f" Summarize: {'✓' if summarize_ok else '✗'}")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
if all([health_ok, init_ok, tools_ok, summarize_ok]):
|
||||||
|
print("\n✓ All tests passed!")
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
print("\n✗ Some tests failed. Check the errors above.")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Reference in New Issue
Block a user