Source code for sktime_mcp.tools.run_command

import subprocess
from typing import Any

# Cap on returned output so a command like `seq 1 100000` (688k chars observed)
# can't overflow the client (BUG-23).
_MAX_OUTPUT_CHARS = 20_000


def _truncate(text: str) -> tuple[str, bool]:
    if len(text) <= _MAX_OUTPUT_CHARS:
        return text, False
    head = _MAX_OUTPUT_CHARS // 2
    tail = _MAX_OUTPUT_CHARS - head
    omitted = len(text) - _MAX_OUTPUT_CHARS
    return (
        f"{text[:head]}\n...[{omitted} characters truncated]...\n{text[-tail:]}",
        True,
    )


[docs] def run_command_tool(command: str) -> dict[str, Any]: """ Run an arbitrary CLI/bash command on the host, in the server's working directory, as the user that launched the server. Note: this executes on the host machine (not a container or sandbox) with the server's own permissions. Output is capped; see ``truncated``. """ try: result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=120) output = result.stdout if result.stderr: output += f"\nErrors:\n{result.stderr}" output, truncated = _truncate(output.strip()) response = { "success": result.returncode == 0, "output": output, "returncode": result.returncode, "truncated": truncated, } # Every other tool reports failures under "error"; do the same on a # non-zero exit so callers can branch on it uniformly. if result.returncode != 0: response["error"] = ( result.stderr.strip() or f"Command exited with code {result.returncode}" ) return response except subprocess.TimeoutExpired: return {"success": False, "error": "Command execution timed out after 120 seconds."} except Exception as e: return {"success": False, "error": str(e)}