debug_templates.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #!/usr/bin/env python3
  2. """
  3. Debug script to check if templates are being handled properly
  4. """
  5. import subprocess
  6. import time
  7. import json
  8. import sys
  9. import os
  10. import threading
  11. import queue
  12. import tempfile
  13. import shutil
  14. class MCPServerTester:
  15. def __init__(self, server_path):
  16. self.server_path = server_path
  17. self.server_process = None
  18. self.message_queue = queue.Queue()
  19. self.test_dir = None
  20. def start_server(self):
  21. """Start MCP server process"""
  22. # Create a temporary directory for testing
  23. self.test_dir = tempfile.mkdtemp(prefix="mcp_test_")
  24. # Create some test files
  25. with open(os.path.join(self.test_dir, "test.txt"), "w") as f:
  26. f.write("Hello, World!")
  27. print(f"Starting MCP server: {self.server_path} with test directory: {self.test_dir}")
  28. self.server_process = subprocess.Popen(
  29. [self.server_path, self.test_dir],
  30. stdin=subprocess.PIPE,
  31. stdout=subprocess.PIPE,
  32. stderr=subprocess.PIPE,
  33. text=False,
  34. bufsize=0
  35. )
  36. # Start thread to read stderr
  37. stderr_thread = threading.Thread(target=self._read_stderr)
  38. stderr_thread.daemon = True
  39. stderr_thread.start()
  40. # Start thread to read stdout
  41. stdout_thread = threading.Thread(target=self._read_stdout)
  42. stdout_thread.daemon = True
  43. stdout_thread.start()
  44. time.sleep(1)
  45. def _read_stderr(self):
  46. """Read stderr output from server"""
  47. while self.server_process and self.server_process.poll() is None:
  48. try:
  49. line = self.server_process.stderr.readline()
  50. if line:
  51. print(f"SERVER STDERR: {line.decode().strip()}")
  52. except:
  53. break
  54. def _read_stdout(self):
  55. """Read stdout output from server without Content-Length parsing"""
  56. buffer = b""
  57. while self.server_process and self.server_process.poll() is None:
  58. try:
  59. data = self.server_process.stdout.readline()
  60. if not data:
  61. break
  62. buffer += data
  63. # Try to parse JSON directly from each line
  64. try:
  65. message = buffer.strip()
  66. if message:
  67. parsed = json.loads(message.decode())
  68. self.message_queue.put(parsed)
  69. print(f"SERVER MESSAGE: {json.dumps(parsed, indent=2)}")
  70. buffer = b""
  71. except json.JSONDecodeError:
  72. # If not valid JSON yet, continue reading
  73. continue
  74. except:
  75. break
  76. def send_jsonrpc_request(self, method, params=None, id=1):
  77. """Send a JSON-RPC request without Content-Length header"""
  78. request = {
  79. "jsonrpc": "2.0",
  80. "method": method,
  81. "id": id,
  82. "params": params or {}
  83. }
  84. request_str = json.dumps(request)
  85. message = f"{request_str}\n"
  86. print(f"SENDING: {repr(message)}")
  87. self.server_process.stdin.write(message.encode())
  88. self.server_process.stdin.flush()
  89. try:
  90. response = self.message_queue.get(timeout=10)
  91. return response
  92. except queue.Empty:
  93. print("TIMEOUT: No response received")
  94. return None
  95. def test_templates(self):
  96. """Test resource template functionality"""
  97. print("\n=== Testing Resource Templates ===")
  98. # Initialize first
  99. init_params = {
  100. "protocolVersion": "2025-11-25",
  101. "capabilities": {},
  102. "clientInfo": {
  103. "name": "test-client",
  104. "version": "1.0.0"
  105. }
  106. }
  107. init_response = self.send_jsonrpc_request("initialize", init_params, id=0)
  108. if init_response:
  109. print("✓ Server initialized successfully")
  110. print(f"Init response: {json.dumps(init_response, indent=2)}")
  111. else:
  112. print("✗ Failed to initialize server")
  113. return False
  114. # Test templates/list
  115. print("\nTesting resources/templates/list...")
  116. templates_response = self.send_jsonrpc_request("resources/templates/list", id=7)
  117. if templates_response:
  118. print(f"Templates response: {json.dumps(templates_response, indent=2)}")
  119. if "result" in templates_response:
  120. result = templates_response["result"]
  121. if "templates" in result:
  122. templates = result["templates"]
  123. print(f"✓ Found {len(templates)} templates")
  124. return True
  125. else:
  126. print("✗ No templates field in response")
  127. return False
  128. else:
  129. print("✗ No result field in response")
  130. return False
  131. else:
  132. print("✗ Failed to list templates")
  133. return False
  134. def cleanup(self):
  135. """Clean up test environment"""
  136. if self.test_dir and os.path.exists(self.test_dir):
  137. shutil.rmtree(self.test_dir)
  138. def stop_server(self):
  139. """Stop MCP server process"""
  140. if self.server_process:
  141. print("\nStopping server...")
  142. self.server_process.terminate()
  143. try:
  144. self.server_process.wait(timeout=5)
  145. except subprocess.TimeoutExpired:
  146. self.server_process.kill()
  147. self.server_process = None
  148. def main():
  149. if len(sys.argv) != 2:
  150. print("Usage: python3 debug_templates.py <server-executable>")
  151. sys.exit(1)
  152. server_path = sys.argv[1]
  153. if not os.path.exists(server_path):
  154. print(f"Error: Server executable '{server_path}' not found")
  155. sys.exit(1)
  156. tester = MCPServerTester(server_path)
  157. try:
  158. tester.start_server()
  159. time.sleep(2)
  160. # Test templates
  161. tester.test_templates()
  162. except KeyboardInterrupt:
  163. print("\nTest interrupted by user")
  164. except Exception as e:
  165. print(f"\nError during test: {e}")
  166. import traceback
  167. traceback.print_exc()
  168. finally:
  169. tester.stop_server()
  170. tester.cleanup()
  171. if __name__ == "__main__":
  172. main()