"""Simple MySQL MCP server for Hermes - with async stdin handling.""" import json, sys, os, select import mysql.connector sys.stdin.reconfigure(encoding='utf-8') sys.stdout.reconfigure(encoding='utf-8') def get_conn(): return mysql.connector.connect( host=os.environ.get("MYSQL_HOST", "127.0.0.1"), port=int(os.environ.get("MYSQL_PORT", "33060")), user=os.environ.get("MYSQL_USER", "root"), password=os.environ.get("MYSQL_PASS", ""), database=os.environ.get("MYSQL_DB", ""), charset="utf8mb4", collation="utf8mb4_general_ci", ssl_disabled=True ) def handle_request(req): method = req.get("method", "") req_id = req.get("id", 1) if method == "initialize": return {"jsonrpc": "2.0", "result": { "protocolVersion": "2024-11-05", "serverInfo": {"name": "mysql-mcp", "version": "1.0.0"}, "capabilities": {"tools": {}} }, "id": req_id} if method == "notifications/initialized": return None if method == "ping": return {"jsonrpc": "2.0", "result": {}, "id": req_id} if method == "tools/list": return {"jsonrpc": "2.0", "result": {"tools": [ { "name": "mysql_query", "description": "Execute a SQL query on the MySQL database", "inputSchema": { "type": "object", "properties": { "query": {"type": "string", "description": "SQL query to execute"} }, "required": ["query"] } } ]}, "id": req_id} if method == "tools/call": tool = req.get("params", {}).get("name", "") args = req.get("params", {}).get("arguments", {}) if tool == "mysql_query": try: conn = get_conn() cursor = conn.cursor(dictionary=True) cursor.execute(args["query"]) result = cursor.fetchall() conn.commit() cursor.close() conn.close() return {"jsonrpc": "2.0", "result": { "content": [{"type": "text", "text": json.dumps(result, default=str, indent=2)}] }, "id": req_id} except Exception as e: return {"jsonrpc": "2.0", "result": { "content": [{"type": "text", "text": f"Error: {e}"}], "isError": True }, "id": req_id} return None # Use sys.stdin.buffer for line reading with sys.stdin as f: buf = "" while True: line = f.readline() if not line: break line = line.strip() if not line: continue try: req = json.loads(line) resp = handle_request(req) if resp: sys.stdout.write(json.dumps(resp) + "\n") sys.stdout.flush() except json.JSONDecodeError: pass