fix: accept both string and dict for body/params in n8n_api_call
All checks were successful
Build and Push n8n MCP Docker Image / build (push) Successful in 19s
All checks were successful
Build and Push n8n MCP Docker Image / build (push) Successful in 19s
Handle the case where MCP clients may pass JSON as either a string or dict object. Adds _normalize_json_param helper to handle both formats gracefully, preventing Pydantic validation errors.
This commit is contained in:
37
server.py
37
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,
|
||||
|
||||
Reference in New Issue
Block a user