From 531b66effec403d1d2a6858325dc804e02418d5c Mon Sep 17 00:00:00 2001 From: Adam Outler Date: Sat, 29 Nov 2025 02:44:55 +0000 Subject: [PATCH] Coderabit changes --- server/api_server/api_server_start.py | 11 +++++------ server/api_server/mcp_routes.py | 24 +++++++++++++++++------- server/api_server/tools_routes.py | 5 +++-- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/server/api_server/api_server_start.py b/server/api_server/api_server_start.py index 39772c65..f63f7836 100755 --- a/server/api_server/api_server_start.py +++ b/server/api_server/api_server_start.py @@ -76,9 +76,6 @@ from .mcp_routes import mcp_bp # noqa: E402 [flake8 lint suppression] # Flask application app = Flask(__name__) -# ... (CORS settings) ... - -# ... (rest of file) ... # Register Blueprints app.register_blueprint(tools_bp, url_prefix='/api/tools') @@ -111,12 +108,14 @@ CORS( def log_request_info(): """Log details of every incoming request.""" # Filter out noisy requests if needed, but user asked for drastic logging - mylog("none", [f"[HTTP] {request.method} {request.path} from {request.remote_addr}"]) - mylog("none", [f"[HTTP] Headers: {dict(request.headers)}"]) + mylog("verbose", [f"[HTTP] {request.method} {request.path} from {request.remote_addr}"]) + # Filter sensitive headers before logging + safe_headers = {k: v for k, v in request.headers if k.lower() not in ('authorization', 'cookie', 'x-api-key')} + mylog("debug", [f"[HTTP] Headers: {safe_headers}"]) if request.method == "POST": # Be careful with large bodies, but log first 1000 chars data = request.get_data(as_text=True) - mylog("none", [f"[HTTP] Body: {data[:1000]}"]) + mylog("debug", [f"[HTTP] Body length: {len(data)} chars"]) @app.errorhandler(404) diff --git a/server/api_server/mcp_routes.py b/server/api_server/mcp_routes.py index b65539a6..dc7a33b9 100644 --- a/server/api_server/mcp_routes.py +++ b/server/api_server/mcp_routes.py @@ -5,7 +5,9 @@ import uuid import queue import requests import threading +import logging from flask import Blueprint, request, Response, stream_with_context, jsonify +from helper import get_setting_value mcp_bp = Blueprint('mcp', __name__) @@ -16,7 +18,9 @@ sessions_lock = threading.Lock() # Cache for OpenAPI spec to avoid fetching on every request openapi_spec_cache = None -API_BASE_URL = "http://localhost:20212/api/tools" +BACKEND_PORT = get_setting_value("GRAPHQL_PORT") + +API_BASE_URL = f"http://localhost:{BACKEND_PORT}/api/tools" def get_openapi_spec(): @@ -28,7 +32,7 @@ def get_openapi_spec(): try: # Fetch from local server # We use localhost because this code runs on the server - response = requests.get(f"{API_BASE_URL}/openapi.json") + response = requests.get(f"{API_BASE_URL}/openapi.json", timeout=10) response.raise_for_status() openapi_spec_cache = response.json() return openapi_spec_cache @@ -61,7 +65,11 @@ def map_openapi_to_mcp_tools(spec): content = details["requestBody"].get("content", {}) if "application/json" in content: schema = content["application/json"].get("schema", {}) - tool["inputSchema"] = schema + tool["inputSchema"] = schema.copy() + if "properties" not in tool["inputSchema"]: + tool["inputSchema"]["properties"] = {} + if "required" not in tool["inputSchema"]: + tool["inputSchema"]["required"] = [] # Extract parameters from 'parameters' list (query/path params) - simplistic support if "parameters" in details: @@ -145,15 +153,16 @@ def process_mcp_request(data): headers = { "Content-Type": "application/json" } + if "Authorization" in request.headers: headers["Authorization"] = request.headers["Authorization"] url = f"{API_BASE_URL}{target_path}" if target_method == "POST": - api_res = requests.post(url, json=tool_args, headers=headers) + api_res = requests.post(url, json=tool_args, headers=headers, timeout=30) elif target_method == "GET": - api_res = requests.get(url, params=tool_args, headers=headers) + api_res = requests.get(url, params=tool_args, headers=headers, timeout=30) else: api_res = None @@ -236,8 +245,9 @@ def handle_sse(): else: # Notification or no response needed return "", 202 - except Exception: - pass + except Exception as e: + # Log but don't fail - malformed requests shouldn't crash the endpoint + logging.getLogger(__name__).debug(f"SSE POST processing error: {e}") return jsonify({"status": "ok", "message": "MCP SSE endpoint active"}), 200 diff --git a/server/api_server/tools_routes.py b/server/api_server/tools_routes.py index 5e84f781..0b569201 100644 --- a/server/api_server/tools_routes.py +++ b/server/api_server/tools_routes.py @@ -208,7 +208,8 @@ def get_open_ports(): cmd, capture_output=True, text=True, - check=True + check=True, + timeout=120 ) # Parse output for open ports @@ -388,7 +389,7 @@ def wol_wake_device(): try: # Using wakeonlan command result = subprocess.run( - ["wakeonlan", mac], capture_output=True, text=True, check=True + ["wakeonlan", mac], capture_output=True, text=True, check=True, timeout=10 ) return jsonify( {