MCPcopy Create free account
hub / github.com/IBM/mcp-cli / unwrap_tool_result

Function unwrap_tool_result

src/mcp_cli/utils/serialization.py:11–44  ·  view source on GitHub ↗

Unwrap middleware ``ToolExecutionResult`` wrappers and MCP result dicts. When middleware is enabled, ``ToolManager`` returns the result wrapped in a ``ToolExecutionResult`` object (from ``chuk_tool_processor.mcp.middleware``). The inner payload is typically ``{"isError": bool, "content"

(obj: Any, *, max_depth: int = _UNWRAP_MAX_DEPTH)

Source from the content-addressed store, hash-verified

9
10
11def unwrap_tool_result(obj: Any, *, max_depth: int = _UNWRAP_MAX_DEPTH) -> Any:
12 """Unwrap middleware ``ToolExecutionResult`` wrappers and MCP result dicts.
13
14 When middleware is enabled, ``ToolManager`` returns the result wrapped in
15 a ``ToolExecutionResult`` object (from ``chuk_tool_processor.mcp.middleware``).
16 The inner payload is typically ``{"isError": bool, "content": ToolResult}``.
17 This peels off those layers to get the actual content.
18
19 Raises ``RuntimeError`` if any wrapper layer reports failure.
20 """
21 depth = 0
22 while (
23 hasattr(obj, "success")
24 and hasattr(obj, "result")
25 and not isinstance(obj, dict)
26 ):
27 if depth >= max_depth:
28 raise RuntimeError(f"Exceeded max unwrap depth ({max_depth})")
29 if not obj.success:
30 error = getattr(obj, "error", None) or "Unknown tool error"
31 raise RuntimeError(error)
32 obj = obj.result
33 depth += 1
34
35 # Unwrap MCP call_tool dict pattern: {"isError": ..., "content": ...}
36 if isinstance(obj, dict) and "content" in obj and "isError" in obj:
37 if obj["isError"]:
38 error_msg = obj.get("error") or obj.get("content") or "Tool returned an error"
39 if not isinstance(error_msg, str):
40 error_msg = str(error_msg)
41 raise RuntimeError(error_msg)
42 obj = obj["content"]
43
44 return obj
45
46
47def to_serializable(obj: Any) -> Any:

Calls 1

getMethod · 0.45