summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorblasty <peter@haxx.in>2026-07-24 01:49:57 +0200
committerblasty <peter@haxx.in>2026-07-24 01:49:57 +0200
commit1e108ddfd1ba3baec6c4e2b2340644ebf6edd290 (patch)
tree2da7475d73c474afe9f119d6b5cf8f298f47604f
parentworker: spawn under the IDA python (has ida_pro_mcp), not the TUI's (diff)
downloadida-tui-1e108ddfd1ba3baec6c4e2b2340644ebf6edd290.tar.gz
ida-tui-1e108ddfd1ba3baec6c4e2b2340644ebf6edd290.tar.xz
ida-tui-1e108ddfd1ba3baec6c4e2b2340644ebf6edd290.zip
worker: wrap non-dict tool returns as {"result": ...} to match MCP shapes
The MCP server sets structuredContent = result if isinstance(result, dict) else {"result": result} (zeromcp mcp.py:832), and domain.py parses that exact shape — e.g. function_of() reads payload["result"] from lookup_funcs, which returns a bare list. Our worker returned the raw list, so function_of got a non-dict and returned None: hence "F5 — cursor is not inside a defined function" on Tab. Replicate the rule in the worker's dispatch: dict passes through, anything else (list/scalar) is wrapped as {"result": ...}. Fixes function_of and every other list-returning tool (resolve_names, xref_query, list_funcs) in one shot.
-rw-r--r--idatui/worker.py6
1 files changed, 5 insertions, 1 deletions
diff --git a/idatui/worker.py b/idatui/worker.py
index e1d3c44..8e82af8 100644
--- a/idatui/worker.py
+++ b/idatui/worker.py
@@ -112,7 +112,11 @@ def serve(sockpath: str, binpath: str) -> None:
fn = tools.get(name)
if fn is None:
raise KeyError(f"unknown tool: {name!r}")
- return fn(**args)
+ result = fn(**args)
+ # Match the MCP server's structuredContent: a dict passes through, any
+ # other return (list/scalar) is wrapped as {"result": ...}. domain.py
+ # parses that exact shape (e.g. lookup_funcs -> payload["result"]).
+ return result if isinstance(result, dict) else {"result": result}
try:
os.unlink(sockpath)