Skip to main content
Glama

RhinoMCP

ws_adapter.py3.48 kB
#!/usr/bin/env python """ WebSocket adapter for connecting Windsurf to the RhinoMCP server. This script forwards messages between Windsurf and the RhinoMCP server, acting as an adapter layer that handles the WebSocket connection. """ import asyncio import json import sys import websockets from typing import Dict, Any, Optional, List import logging from websockets.exceptions import ConnectionClosed # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler("ws_adapter.log"), logging.StreamHandler(sys.stderr) ] ) logger = logging.getLogger("ws-adapter") # Target RhinoMCP server URL TARGET_URL = "ws://127.0.0.1:5000" async def forward_messages(): """Forward messages between stdin/stdout and the WebSocket server.""" try: logger.info(f"Connecting to RhinoMCP server at {TARGET_URL}") async with websockets.connect(TARGET_URL) as websocket: logger.info("Connected to RhinoMCP server") # Start tasks for handling stdin->websocket and websocket->stdout stdin_task = asyncio.create_task(forward_stdin_to_websocket(websocket)) ws_task = asyncio.create_task(forward_websocket_to_stdout(websocket)) # Wait for either task to complete (or fail) done, pending = await asyncio.wait( [stdin_task, ws_task], return_when=asyncio.FIRST_COMPLETED ) # Cancel any pending tasks for task in pending: task.cancel() # Check for exceptions for task in done: try: task.result() except Exception as e: logger.error(f"Task error: {str(e)}") except Exception as e: logger.error(f"Connection error: {str(e)}") async def forward_stdin_to_websocket(websocket): """Forward messages from stdin to the WebSocket server.""" loop = asyncio.get_event_loop() while True: # Read a line from stdin (non-blocking) line = await loop.run_in_executor(None, sys.stdin.readline) if not line: logger.info("End of stdin, closing connection") break # Parse and forward the message try: message = line.strip() logger.debug(f"Sending to WS: {message}") await websocket.send(message) except Exception as e: logger.error(f"Error forwarding stdin to WebSocket: {str(e)}") break async def forward_websocket_to_stdout(websocket): """Forward messages from the WebSocket server to stdout.""" try: async for message in websocket: logger.debug(f"Received from WS: {message}") # Write to stdout and flush print(message, flush=True) except ConnectionClosed: logger.info("WebSocket connection closed") except Exception as e: logger.error(f"Error forwarding WebSocket to stdout: {str(e)}") if __name__ == "__main__": try: # Run the message forwarding loop asyncio.run(forward_messages()) except KeyboardInterrupt: logger.info("Adapter terminated by user") except Exception as e: logger.error(f"Unhandled exception: {str(e)}") sys.exit(1)

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/a01110946/RhinoMCP'

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