Skip to main content
Glama
wondermuttt

Georgia Tech MCP Server

by wondermuttt
POST_DEPLOYMENT_VALIDATION_V2.py11.7 kB
#!/usr/bin/env python3 """ POST-DEPLOYMENT VALIDATION SCRIPT V2 This version tests the ACTUAL MCP protocol flow that ChatGPT uses, not the Python functions directly. This is the ONLY way to ensure our system works with ChatGPT. Usage: python3 POST_DEPLOYMENT_VALIDATION_V2.py """ import sys import time import json import requests from typing import Dict, Any, Optional, Tuple # MCP Server endpoint BASE_URL = "https://wmjump1.henkelman.net:8080" MCP_ENDPOINT = f"{BASE_URL}/mcp/v1/sse" # Global session management SESSION_ID = None def make_mcp_request(method: str, params: Dict[str, Any], request_id: int = 1) -> Tuple[bool, Any]: """ Make an MCP request through the SSE endpoint. Returns (success, response_data) """ global SESSION_ID headers = { "Content-Type": "application/json", "Accept": "application/json,text/event-stream" } # Add session ID if we have one if SESSION_ID: headers["X-Session-ID"] = SESSION_ID payload = { "jsonrpc": "2.0", "method": method, "id": request_id, "params": params } try: response = requests.post(MCP_ENDPOINT, headers=headers, json=payload, timeout=10) if response.status_code != 200: return False, f"HTTP {response.status_code}: {response.text}" # Parse SSE response for line in response.text.split('\n'): if line.startswith('data: '): try: data = json.loads(line[6:]) # Check for errors if 'error' in data: return False, data['error'] # Extract session ID if present if 'result' in data and isinstance(data['result'], dict): if 'sessionId' in data['result']: SESSION_ID = data['result']['sessionId'] return True, data except json.JSONDecodeError: continue return False, "No valid SSE data found in response" except Exception as e: return False, f"Request error: {e}" def test_stateless_access() -> bool: """Test that we can access without session (stateless mode)""" print("Testing stateless access...") # Try a simple tools/list without any session success, response = make_mcp_request("tools/list", {}) if success: print(f"✅ Stateless access works - no session required!") return True else: # If that fails, try the old session-based approach print(f"⚠️ Stateless failed ({response}), trying with session...") params = { "protocolVersion": "1.0.0", "clientInfo": { "name": "validation-client", "version": "1.0.0" } } success, response = make_mcp_request("initialize", params) if success: print(f"✅ Session initialized{f' (ID: {SESSION_ID})' if SESSION_ID else ''}") return True else: print(f"❌ Failed to initialize: {response}") return False def test_search(query: str) -> Tuple[bool, int, Optional[str]]: """ Test search through MCP protocol. Returns (success, result_count, first_result_id) """ params = { "name": "search", "arguments": { "query": query } } success, response = make_mcp_request("tools/call", params) if not success: return False, 0, None # Extract the actual search results from MCP response try: if 'result' in response and 'content' in response['result']: content = response['result']['content'][0]['text'] search_results = json.loads(content) # Handle the dict format we return if isinstance(search_results, dict) and 'results' in search_results: results = search_results['results'] count = search_results.get('count', len(results)) first_id = results[0]['id'] if results else None return True, count, first_id # Handle if it's still a list (shouldn't happen) elif isinstance(search_results, list): count = len(search_results) first_id = search_results[0]['id'] if search_results else None return True, count, first_id except Exception as e: print(f" Error parsing search response: {e}") return False, 0, None def test_fetch(doc_id: str) -> Tuple[bool, bool]: """ Test fetch through MCP protocol. Returns (success, has_content) """ params = { "name": "fetch", "arguments": { "id": doc_id } } success, response = make_mcp_request("tools/call", params) if not success: return False, False # Extract the fetch result from MCP response try: if 'result' in response and 'content' in response['result']: content = response['result']['content'][0]['text'] fetch_result = json.loads(content) # Check if we got actual content has_content = ( isinstance(fetch_result, dict) and 'text' in fetch_result and len(fetch_result['text']) > 0 ) return True, has_content except Exception as e: print(f" Error parsing fetch response: {e}") return False, False def run_validation(): """Run all validation tests through MCP protocol""" print("=" * 80) print("POST-DEPLOYMENT VALIDATION V2 - TESTING ACTUAL MCP PROTOCOL") print("=" * 80) print(f"Timestamp: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}") print(f"Endpoint: {MCP_ENDPOINT}") print() total_tests = 0 passed_tests = 0 critical_failures = [] # Test 1: Can we access without sessions? print("1. MCP ACCESS TEST") total_tests += 1 if test_stateless_access(): passed_tests += 1 else: critical_failures.append("Cannot access MCP endpoint - ChatGPT won't be able to connect!") print("\n⚠️ CRITICAL: Cannot proceed without MCP access") return False # Test 2: Basic search print("\n2. BASIC SEARCH TEST") test_queries = [ ("CS 6300", "Should find Software Development Process"), ("Fall 2025", "Should return semester courses"), ("", "Empty query should return help"), ("xyz123nonsense", "Should return 'no results found' help"), ] for query, description in test_queries: total_tests += 1 print(f" Testing '{query}': {description}") success, count, first_id = test_search(query) if success: if query == "" and count == 0: print(f" ✅ Empty query returns help (count={count})") passed_tests += 1 elif query == "xyz123nonsense" and count == 0: print(f" ✅ Invalid query returns help (count={count})") passed_tests += 1 elif count > 0: print(f" ✅ Found {count} results (first: {first_id})") passed_tests += 1 else: print(f" ❌ Unexpected: count={count}") else: print(f" ❌ Search failed through MCP") if query in ["CS 6300", "Fall 2025"]: critical_failures.append(f"Basic search '{query}' failed - ChatGPT won't find courses!") # Test 3: Search and fetch flow print("\n3. SEARCH AND FETCH FLOW (What ChatGPT does)") total_tests += 1 # First search success, count, course_id = test_search("CS 6515") if success and course_id: print(f" ✅ Search found course: {course_id}") # Then fetch fetch_success, has_content = test_fetch(course_id) if fetch_success and has_content: print(f" ✅ Fetch retrieved course details") passed_tests += 1 else: print(f" ❌ Fetch failed or returned no content") critical_failures.append("Fetch after search failed - ChatGPT can't get course details!") else: print(f" ❌ Initial search failed") critical_failures.append("Search-fetch flow broken - ChatGPT won't work!") # Test 4: Error handling print("\n4. ERROR HANDLING TESTS") # Invalid fetch ID total_tests += 1 fetch_success, has_content = test_fetch("invalid_id_12345") if fetch_success: print(f" ✅ Invalid fetch ID handled gracefully") passed_tests += 1 else: print(f" ❌ Invalid fetch ID caused error") # Test 5: Specific problematic queries from ChatGPT feedback print("\n5. CHATGPT REPORTED ISSUES") problem_queries = [ "CS 6300 O01", # Section search "CS 8803-O20", # Hyphenated course "OMSCS", # Program search ] for query in problem_queries: total_tests += 1 success, count, first_id = test_search(query) if success and count > 0: print(f" ✅ '{query}': Found {count} results") passed_tests += 1 else: print(f" ❌ '{query}': Failed or no results") critical_failures.append(f"Known issue '{query}' still failing") # Summary print("\n" + "=" * 80) print("VALIDATION SUMMARY") print("=" * 80) print(f"Total tests: {total_tests}") print(f"Passed: {passed_tests}") print(f"Failed: {total_tests - passed_tests}") print(f"Success rate: {passed_tests/total_tests*100:.1f}%") if critical_failures: print(f"\n❌ CRITICAL FAILURES ({len(critical_failures)}):") for failure in critical_failures: print(f" - {failure}") print("\n⚠️ DO NOT USE THIS SERVER WITH CHATGPT!") return False else: print("\n✅ ALL TESTS PASSED THROUGH MCP PROTOCOL") print("The server should work correctly with ChatGPT!") return True def check_service_status(): """Check if the MCP service is running""" print("\nSERVICE STATUS CHECK:") try: import subprocess result = subprocess.run(['systemctl', 'is-active', 'gtmcp-mcp'], capture_output=True, text=True) if result.stdout.strip() == 'active': print("✅ Service is active") else: print("❌ Service is not active") return False except Exception as e: print(f"⚠️ Could not check service status: {e}") return True if __name__ == "__main__": print("Starting MCP protocol validation...\n") # Check service service_ok = check_service_status() # Run validation through MCP validation_ok = run_validation() # Final verdict print("\n" + "=" * 80) if service_ok and validation_ok: print("✅ MCP PROTOCOL VALIDATION: PASSED") print("The Georgia Tech MCP Server is ready for use with ChatGPT!") sys.exit(0) else: print("❌ MCP PROTOCOL VALIDATION: FAILED") print("Please fix the issues before using with ChatGPT!") print("\nNOTE: The old validation was testing Python functions directly,") print(" which is why it passed when ChatGPT failed.") sys.exit(1)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wondermuttt/gtmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server