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

Method _extract_result_value

src/mcp_cli/chat/tool_processor.py:1265–1338  ·  view source on GitHub ↗

Extract the actual value from MCP response structures. MCP responses can be nested in various ways: 1. Direct value (number, string) 2. Dict with "content" containing MCP ToolResult with .content list 3. Dict with "success"/"result" wrapper 4. List of content

(self, result: Any)

Source from the content-addressed store, hash-verified

1263 return {}
1264
1265 def _extract_result_value(self, result: Any) -> Any:
1266 """Extract the actual value from MCP response structures.
1267
1268 MCP responses can be nested in various ways:
1269 1. Direct value (number, string)
1270 2. Dict with "content" containing MCP ToolResult with .content list
1271 3. Dict with "success"/"result" wrapper
1272 4. List of content blocks [{type: "text", text: "..."}]
1273 5. Object with .content attribute (MCP CallToolResult)
1274 6. String representation like "content=[{'type': 'text', 'text': '4.2426'}]"
1275
1276 This normalizes all formats to extract the core value for binding.
1277 """
1278 if result is None:
1279 return None
1280
1281 # Handle string "None" (bug in some MCP responses)
1282 if result == "None" or result == "null":
1283 return None
1284
1285 # Handle MCP CallToolResult object (has .content attribute)
1286 if hasattr(result, "content") and isinstance(result.content, list):
1287 return self._extract_from_content_list(result.content)
1288
1289 # Handle dict structures
1290 if isinstance(result, dict):
1291 # Case: {"content": <MCP ToolResult object>}
1292 if "content" in result:
1293 content = result["content"]
1294 # MCP ToolResult has a .content attribute that's a list
1295 if hasattr(content, "content"):
1296 return self._extract_from_content_list(content.content)
1297 # Or it might be a direct list
1298 if isinstance(content, list):
1299 return self._extract_from_content_list(content)
1300 # Or a string
1301 if isinstance(content, str):
1302 return self._try_parse_number(content)
1303
1304 # Case: {"success": true, "result": ...}
1305 if "success" in result and "result" in result:
1306 inner = result["result"]
1307 # Recurse if inner is not None/string "None"
1308 if inner is not None and inner != "None":
1309 return self._extract_result_value(inner)
1310 return None
1311
1312 # Case: {"isError": false, "content": ...} (MCP response wrapper)
1313 if "isError" in result:
1314 if result.get("isError"):
1315 return result.get("error") or result.get("content")
1316 return self._extract_result_value(result.get("content"))
1317
1318 # Case: {"text": "value"} direct
1319 if "text" in result and isinstance(result["text"], str):
1320 return self._try_parse_number(result["text"])
1321
1322 # Handle list of content blocks directly

Calls 4

_try_parse_numberMethod · 0.95
_parse_content_reprMethod · 0.95
getMethod · 0.45