From 73d36d05123c6c396d78ef710b87788dc879da63 Mon Sep 17 00:00:00 2001 From: blasty Date: Fri, 24 Jul 2026 14:23:18 +0200 Subject: worker: inject custom tools on startup (self-sufficient, no spawn.sh needed) The worker reuses ida-pro-mcp's @tool functions, but our custom tools (heads/read_raw/resolve_names/func_types/del_type/set_lvar_type) only exist because server/patch_server.py injected them into the installed api_types.py -- which historically only ran via spawn.sh. On a fresh box (or worker-only setup with spawn.sh gone) those tools would be missing and heads/listing would break. _ensure_tools_injected() now runs patch_server.main() (idempotent, IDA-free) at the top of _open_and_register, before ida_pro_mcp.ida_mcp is imported, so the worker guarantees its own tool surface. Verified under /usr/bin/python: injection runs and heads/read_raw/resolve_names/func_types land in api_types.py. This is the prerequisite for deleting spawn.sh from the worker path. --- idatui/worker.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/idatui/worker.py b/idatui/worker.py index 8e82af8..64cafb3 100644 --- a/idatui/worker.py +++ b/idatui/worker.py @@ -59,9 +59,29 @@ def recv(sock: socket.socket): # --------------------------------------------------------------------------- # # worker # --------------------------------------------------------------------------- # +def _ensure_tools_injected() -> None: + """Inject idatui's custom tools (heads/read_raw/resolve_names/func_types/...) + into the installed ida_pro_mcp, idempotently, so the worker is self-sufficient + without spawn.sh having run server/patch_server.py first. Must run BEFORE + ida_pro_mcp.ida_mcp is imported (the injected code lives in api_types.py).""" + import importlib.util + repo = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + patch = os.path.join(repo, "server", "patch_server.py") + if not os.path.exists(patch): + return + try: + spec = importlib.util.spec_from_file_location("_idatui_patch", patch) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) # IDA-free; just defines + patches api_types + mod.main() + except Exception as e: # noqa: BLE001 -- tools may already be present + sys.stderr.write(f"idatui: tool injection skipped: {e}\n") + + def _open_and_register(binpath: str): """Open the DB (main thread) then import ida-pro-mcp so every @tool registers against this live database. Returns (tools_dict, module_name, save_fn).""" + _ensure_tools_injected() # before any ida_pro_mcp import import idapro idapro.enable_console_messages(False) if idapro.open_database(binpath, run_auto_analysis=True): # nonzero == failure -- cgit v1.3.1-sl0p