Skip to main content
Glama

OpenRouter MCP Server

by slyfox1186
PROTECTION.md4.57 kB
# MCP Server Graceful Shutdown Protection ## Overview This document describes the protection mechanisms implemented to prevent MCP server connection breaks when Claude Code sends abrupt stop signals (ESC key presses). ## Problem When users press ESC in Claude Code while the MCP server is processing a request (especially long-running API calls to OpenRouter), the sudden termination can: - Break the MCP server connection - Leave requests in an inconsistent state - Require full Claude Code restart to reconnect - Lose conversation state mid-request ## Solution ### 1. Request State Tracking The server now tracks all active requests using the `GracefulShutdownProtection` class: ```python # Register request when starting GracefulShutdownProtection.register_request(req_id, "chat", continuation_id) # Always unregister when done (try/finally block) GracefulShutdownProtection.unregister_request(req_id) ``` **Benefits:** - Knows which requests are currently processing - Can wait for completion before shutdown - Preserves conversation state during shutdown ### 2. Signal Handlers Proper signal handling for SIGINT and SIGTERM: ```python def signal_handler(signum, frame): """Handle shutdown signals gracefully""" logger.info(f"PROTECTION: Received signal {signum}, initiating graceful shutdown...") GracefulShutdownProtection.handle_shutdown() sys.exit(0) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) ``` **Benefits:** - Intercepts Ctrl+C and termination signals - Gives active requests up to 30 seconds to complete - Preserves conversation state for incomplete requests ### 3. Client Disconnect Detection Enhanced main loop detects various disconnect scenarios: ```python # EOF detection (client closed stdin) if not line: eof_count += 1 if eof_count >= max_eof_retries: logger.warning("Client likely disconnected") GracefulShutdownProtection.handle_shutdown() break # Broken pipe detection except BrokenPipeError: logger.warning("Broken pipe detected, client disconnected") GracefulShutdownProtection.handle_shutdown() break ``` **Benefits:** - Detects when Claude Code closes the connection - Prevents hanging processes - Ensures clean shutdown even on abrupt disconnects ### 4. Response Protection The `send_response()` function is protected against client disconnects: ```python def send_response(response_data): try: if shutdown_requested: return # Skip response if shutting down # ... send response ... except BrokenPipeError: GracefulShutdownProtection.handle_shutdown() ``` **Benefits:** - Won't crash when trying to send to disconnected client - Triggers graceful shutdown on disconnect detection ## Graceful Shutdown Process When a shutdown is detected: 1. **Mark shutdown requested** - No new requests accepted 2. **Wait for active requests** - Up to 30 seconds for completion 3. **Preserve conversation state** - Any incomplete conversations are saved 4. **Log protection events** - Clear audit trail of shutdown process 5. **Clean exit** - Proper process termination ## Testing Run the protection test suite: ```bash python3 test_protection.py ``` Tests verify: - ✅ SIGINT signal handling - ✅ Broken pipe detection - ✅ Active request protection ## Configuration Key configuration parameters: ```python max_wait = 30 # Maximum seconds to wait for active requests max_eof_retries = 5 # EOF retries before assuming disconnect ``` ## Logging Protection events are logged with `PROTECTION:` prefix: ``` PROTECTION: Registered active request abc123 (chat) PROTECTION: Shutdown requested with 2 active requests PROTECTION: Waiting for 2 active requests to complete... (5s/30s) PROTECTION: All requests completed, proceeding with shutdown PROTECTION: Main loop exited, server shutdown complete ``` ## Benefits 1. **Connection Stability** - MCP server survives client disconnects 2. **Data Integrity** - Conversation state preserved during shutdowns 3. **User Experience** - No need to restart Claude Code after ESC presses 4. **Observability** - Clear logging of protection events 5. **Robustness** - Handles multiple disconnect scenarios gracefully ## Implementation Notes - Uses thread-safe request tracking with locks - Minimal performance overhead (tracking is lightweight) - Backwards compatible with existing MCP protocol - Works in Docker containers with proper signal forwarding - Preserves all existing functionality while adding protection

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/slyfox1186/claude-code-openrouter'

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