Skip to main content
Glama
x0base

mcp-security-toolkit

by x0base

interactsh_stop

Terminates a registered interactsh-client session and deletes its log file to clean up residual data.

Instructions

Stop a previously-registered interactsh-client session and clean up.

Terminates the spawned interactsh-client process (best-effort) and removes the session descriptor. The log file is removed by default (set delete_log=False to keep it for post-mortem).

Args: token: token returned by interactsh_register. delete_log: also remove the session log file (default True).

Returns: {"stopped": bool, "log_removed": bool, "note": str | None}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tokenYes
delete_logNo

Implementation Reference

  • The core handler for the interactsh_stop tool. Validates token, reads the session file, sends SIGTERM to the process group, optionally deletes the log file (with path traversal protection), removes the session descriptor, and returns a status dict.
    def interactsh_stop(token: str, delete_log: bool = True) -> dict:
        """Stop a previously-registered interactsh-client session and clean up.
    
        Terminates the spawned `interactsh-client` process (best-effort) and
        removes the session descriptor. The log file is removed by default
        (set `delete_log=False` to keep it for post-mortem).
    
        Args:
            token: token returned by `interactsh_register`.
            delete_log: also remove the session log file (default True).
    
        Returns:
            {"stopped": bool, "log_removed": bool, "note": str | None}
        """
        if not _validate_token(token):
            return {"error": "invalid token format (expected 12 hex chars from interactsh_register)"}
    
        sp = _session_path(token)
        if not sp.exists():
            return {"error": f"unknown token: {token}"}
    
        try:
            session = json.loads(sp.read_text())
        except (OSError, json.JSONDecodeError) as e:
            return {"error": f"failed to read session: {e}"}
    
        stopped = False
        pid = session.get("pid")
        if isinstance(pid, int) and pid > 0:
            try:
                os.killpg(os.getpgid(pid), signal.SIGTERM)
                stopped = True
            except (ProcessLookupError, PermissionError, OSError):
                stopped = False
    
        log_removed = False
        if delete_log:
            log = Path(session.get("log_path", ""))
            # Defense in depth: never unlink anything outside our sessions dir,
            # even if a tampered session descriptor points elsewhere.
            if log.exists() and _path_is_inside(log, SESSIONS_DIR):
                try:
                    log.unlink()
                    log_removed = True
                except OSError:
                    log_removed = False
    
        sp.unlink(missing_ok=True)
    
        return {
            "stopped": stopped,
            "log_removed": log_removed,
            "note": None if stopped else "process already exited or no permission to signal",
        }
  • Registers interactsh_stop as an MCP tool on the FastMCP server.
    mcp.tool()(interactsh.interactsh_stop)
  • Validates token format (12 hex characters) before stop processing.
    def _validate_token(token: str) -> bool:
        return isinstance(token, str) and bool(TOKEN_REGEX.match(token))
  • Returns the filesystem path for a session descriptor JSON file.
    def _session_path(token: str) -> Path:
        SESSIONS_DIR.mkdir(parents=True, exist_ok=True)
        try:
            os.chmod(SESSIONS_DIR, 0o700)
        except OSError:
            pass
        return SESSIONS_DIR / f"{token}.json"
  • Defense-in-depth check ensuring log deletion doesn't escape the sessions directory.
    def _path_is_inside(child: Path, parent: Path) -> bool:
        """True iff resolved `child` is at or below resolved `parent`."""
        try:
            child.resolve().relative_to(parent.resolve())
            return True
        except (ValueError, OSError):
            return False

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.3.1

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It states termination of the process (best-effort) and removal of session descriptor and log file (by default). This is fairly transparent, though it does not mention graceful vs forceful termination or other side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise (four sentences) with a clear structure: main purpose, details, then Args and Returns. Every sentence adds value with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple stop/cleanup tool with 2 parameters (1 required) and no output schema, the description covers the action, inputs, and return format completely. The returns are explicitly described in a structured note.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but the description adds significant value: token is described as 'token returned by interactsh_register', and delete_log is described as 'also remove the session log file (default True)'. This fully explains the parameters' purposes.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool stops a previously-registered interactsh-client session and cleans up. It uses specific verbs ('stop', 'clean up') and resource ('interactsh-client session'). The sibling tools include interactsh_register and interactsh_poll, making this distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use after registration and polling, but does not explicitly state when to use this tool versus alternatives (e.g., interactsh_register, interactsh_poll). No when-not or alternative guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.