diff --git a/__pycache__/mcp_summary_server.cpython-312.pyc b/__pycache__/mcp_summary_server.cpython-312.pyc new file mode 100644 index 0000000..4661041 Binary files /dev/null and b/__pycache__/mcp_summary_server.cpython-312.pyc differ diff --git a/diagnose.sh b/diagnose.sh new file mode 100644 index 0000000..9563153 --- /dev/null +++ b/diagnose.sh @@ -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 "================================" diff --git a/mcp_summary_server.py b/mcp_summary_server.py index e422fd6..6317d98 100644 --- a/mcp_summary_server.py +++ b/mcp_summary_server.py @@ -24,13 +24,13 @@ Auth: import json import os import sys -import re from http.server import HTTPServer, BaseHTTPRequestHandler from typing import Any, Dict, Optional import requests API_KEY = os.environ.get("API_KEY", "").strip() +# Tool definitions TOOLS_LIST: Dict[str, Any] = { "tools": [ { @@ -56,6 +56,7 @@ TOOLS_LIST: Dict[str, Any] = { def get_bearer_token(headers: Any) -> Optional[str]: + """Extract bearer token from Authorization header.""" auth = (headers.get("Authorization") or "").strip() if auth.startswith("Bearer "): return auth[len("Bearer "):].strip() @@ -63,6 +64,7 @@ def get_bearer_token(headers: Any) -> Optional[str]: def require_auth(headers: Any) -> bool: + """Check authentication if API key is configured.""" # If API_KEY is not set, allow unauthenticated access if not API_KEY: return True @@ -239,11 +241,14 @@ Final summary:""" class MCPSummaryHandler(BaseHTTPRequestHandler): + """HTTP handler for MCP summary server.""" + def log_message(self, format, *args): # Quiet logs by default pass def _send_json(self, status: int, payload: Any): + """Send JSON response.""" body = json.dumps(payload, ensure_ascii=False).encode("utf-8") self.send_response(status) self.send_header("Content-Type", "application/json") @@ -251,7 +256,8 @@ class MCPSummaryHandler(BaseHTTPRequestHandler): self.end_headers() self.wfile.write(body) - def _auth_or_401(self): + def _auth_or_401(self) -> bool: + """Check authentication if API key is configured.""" try: return require_auth(self.headers) except PermissionError: @@ -259,7 +265,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler): return False def do_GET(self): - # Basic info endpoint (not required by MCP, but useful) + """Handle GET requests (health check).""" if self.path == "/": self._send_json(200, { "service": "mcp-summary", @@ -271,7 +277,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler): self.send_error(404, "Not Found") def do_POST(self): - # Streamable HTTP MCP endpoint + """Handle MCP JSON-RPC requests.""" if self.path not in ("/", "/mcp"): self.send_error(404, "Not Found") return @@ -352,6 +358,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler): self._send_json(400, {"error": "Unknown method: " + str(method)}) def _call_tool(self, name: str, args: Dict[str, Any]) -> Any: + """Execute a tool call.""" if name == "summarize_document": text = args.get("text") if not text: @@ -364,6 +371,7 @@ class MCPSummaryHandler(BaseHTTPRequestHandler): def main(): + """Start the MCP summary server.""" 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) mode = "auth enabled (Bearer)" if API_KEY else "no auth (API_KEY not set)" diff --git a/test_mcp_server.py b/test_mcp_server.py new file mode 100644 index 0000000..592b3e8 --- /dev/null +++ b/test_mcp_server.py @@ -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())