diff --git a/server.py b/server.py index 464fd1f..1f1738c 100644 --- a/server.py +++ b/server.py @@ -338,12 +338,34 @@ async def trigger_webhook( # ============================================================================= +def _normalize_json_param(value: str | dict[str, Any] | None) -> dict[str, Any]: + """Normalize a parameter that can be either a JSON string or a dict. + + This handles the case where MCP clients may pass either: + - A JSON string: '{"key": "value"}' + - A dict object: {"key": "value"} + """ + if value is None: + return {} + if isinstance(value, dict): + return value + if isinstance(value, str): + if not value or value == "{}": + return {} + try: + parsed = json.loads(value) + return parsed if isinstance(parsed, dict) else {} + except json.JSONDecodeError: + return {} + return {} + + @mcp.tool() async def n8n_api_call( endpoint: str, method: str = "GET", - params: str = "{}", - body: str = "{}", + params: str | dict[str, Any] | None = None, + body: str | dict[str, Any] | None = None, ) -> str: """Execute a raw API call to n8n. @@ -353,8 +375,8 @@ async def n8n_api_call( Args: endpoint: API endpoint path (e.g., '/workflows', '/credentials') method: HTTP method (GET, POST, PUT, PATCH, DELETE) - params: JSON string of query parameters (optional) - body: JSON string of request body for POST/PUT/PATCH (optional) + params: Query parameters as JSON string or dict (optional) + body: Request body as JSON string or dict for POST/PUT/PATCH (optional) Examples: - Create workflow: n8n_api_call('/workflows', 'POST', body='{"name": "My Workflow", "nodes": [...], "connections": {...}}') @@ -362,11 +384,8 @@ async def n8n_api_call( - List credentials: n8n_api_call('/credentials') - Create tag: n8n_api_call('/tags', 'POST', body='{"name": "production"}') """ - try: - params_dict = json.loads(params) if params else {} - body_dict = json.loads(body) if body else {} - except json.JSONDecodeError as e: - return json.dumps({"error": True, "message": f"Invalid JSON: {e}"}) + params_dict = _normalize_json_param(params) + body_dict = _normalize_json_param(body) result = await client.request( method=method,