unblock_build
Terminate idle build executables like cl.exe or link.exe after specified idle seconds to prevent build processes from hanging. Supports custom process names and dry run mode for testing.
Instructions
Kill build executables idle > idle_seconds.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | ||
| idle_seconds | No | ||
| process_names | No |
Implementation Reference
- src/build_unblocker_mcp/server.py:35-77 (handler)Main handler function for the 'unblock_build' tool. It examines processes matching specified names, checks if they are idle for the given duration, and kills them if not in dry-run mode. Returns a summary dictionary.def unblock_build(idle_seconds: int = 90, process_names: t.List[str] | None = None, dry_run: bool = False) -> dict: """ Terminates hung build executables that are idle for a specified duration. Args: idle_seconds: The duration in seconds a process must be idle to be considered hung. process_names: A list of process names to monitor. Defaults to DEFAULT_PROCESSES. dry_run: If True, logs actions without actually killing processes. Returns: A dictionary summarizing the examination and killing of processes. """ settings = Settings(idle_seconds=idle_seconds, process_names=process_names or DEFAULT_PROCESSES, dry_run=dry_run) examined_count = 0 killed_count = 0 killed_processes = [] for proc in psutil.process_iter(['pid', 'name', 'create_time']): if proc.info['name'] in settings.process_names: examined_count += 1 if is_process_idle(proc, settings.idle_seconds): if settings.dry_run: print(f"Dry run: Would kill process {proc.info['name']} (PID: {proc.info['pid']}) - idle for > {settings.idle_seconds}s", file=sys.stderr) else: try: print(f"Killing process {proc.info['name']} (PID: {proc.info['pid']}) - idle for > {settings.idle_seconds}s", file=sys.stderr) proc.kill() killed_count += 1 killed_processes.append({"name": proc.info['name'], "pid": proc.info['pid']}) except (psutil.NoSuchProcess, psutil.AccessDenied): print(f"Failed to kill process {proc.info['name']} (PID: {proc.info['pid']})", file=sys.stderr) return { "examined": examined_count, "killed": killed_count, "killed_processes": killed_processes, "timestamp": datetime.utcnow().isoformat() + "Z", "dry_run": settings.dry_run, "idle_seconds_threshold": settings.idle_seconds, "process_names_monitored": settings.process_names, }
- src/build_unblocker_mcp/server.py:34-34 (registration)MCP tool registration decorator that registers the unblock_build function with name 'unblock_build'.@mcp.tool(name="unblock_build", description="Kill build executables idle > idle_seconds.")
- Helper function used by the handler to determine if a process is idle based on low CPU usage and sufficient age.def is_process_idle(proc: psutil.Process, idle_seconds: int) -> bool: """Checks if a process is idle based on CPU usage and age.""" try: # Check CPU usage over a 1-second interval cpu_percent = proc.cpu_percent(interval=1.0) if cpu_percent >= 1.0: return False # Check process age create_time = proc.create_time() process_age = time.time() - create_time if process_age < idle_seconds: return False return True except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): # Process may have exited or access denied, treat as not idle for safety return False
- Default list of process names that the tool monitors for hanging builds.DEFAULT_PROCESSES: t.List[str] = [ "cl.exe", "link.exe", "msbuild.exe", "rc.exe", "csc.exe", "devenv.exe", # Visual Studio IDE process, can also hang builds "cmake.exe", "ninja.exe", "make.exe", "gcc.exe", "g++.exe", "clang.exe", "clang++.exe", ]
- Dataclass used internally to hold the tool's configuration settings.@dataclass class Settings: idle_seconds: int = 90 process_names: t.List[str] = field(default_factory=lambda: DEFAULT_PROCESSES) dry_run: bool = False