Skip to main content
Glama
samerfarida

MCP SSH Orchestrator

ssh_cancel_async_task

Halt an active asynchronous task on your SSH-managed infrastructure by specifying its task ID.

Instructions

Cancel a running async task.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
task_idNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The ssh_cancel_async_task tool implementation. It validates the task_id, delegates cancellation to ASYNC_TASKS.cancel_task(), and returns a response with cancellation status.
    @mcp.tool()
    def ssh_cancel_async_task(task_id: str = "", ctx: Context | None = None) -> ToolResult:
        """Cancel a running async task."""
        try:
            # Input validation
            valid, error_msg = _validate_task_id(task_id)
            if not valid:
                return f"Error: {error_msg}"
    
            task_id = task_id.strip()
            success = ASYNC_TASKS.cancel_task(task_id)
            response = {
                "task_id": task_id,
                "cancelled": bool(success),
                "message": (
                    "Cancellation signaled"
                    if success
                    else "Task not found or not cancellable"
                ),
            }
            _ctx_log(
                ctx,
                "info",
                "ssh_cancel_async_task",
                {"task_id": task_id, "cancelled": bool(success)},
            )
            return response
    
        except Exception as e:
            error_str = str(e)
            log_json(
                {"level": "error", "msg": "cancel_async_exception", "error": error_str}
            )
            _ctx_log(
                ctx,
                "debug",
                "ssh_cancel_async_task_error",
                {"task_id": task_id.strip(), "error": sanitize_error(error_str)},
            )
            return f"Cancel error: {sanitize_error(error_str)}"
  • The AsyncTaskManager.cancel_task() method that performs the actual cancellation logic. It looks up the task, sets the cancel event, marks status as cancelled, and sends a notification.
    def cancel_task(self, task_id: str) -> bool:
        """Cancel a running task."""
        with self._lock:
            task_info = self._tasks.get(task_id)
            if task_info and task_info["status"] in ["pending", "running"]:
                task_info["cancel"].set()
                task_info["status"] = "cancelled"
    
                # Send cancellation notification
                self._send_notification(
                    "cancelled",
                    task_id,
                    {
                        "reason": "user_requested",
                        "max_seconds": int(
                            task_info.get("limits", {}).get("max_seconds", 60)
                        ),
                    },
                )
                return True
            return False
  • The @mcp.tool() decorator registering ssh_cancel_async_task as an MCP tool.
    @mcp.tool()
    def ssh_cancel_async_task(task_id: str = "", ctx: Context | None = None) -> ToolResult:
  • The _validate_task_id() helper that validates the task_id input parameter for the ssh_cancel_async_task tool.
    def _validate_task_id(task_id: str) -> tuple[bool, str]:
        """Validate task_id parameter.
    
        Security: Validates task_id format.
        - Length limit: 200 characters
        - Format validation (expected: alias:hash:timestamp)
        - Cannot be empty
    
        Args:
            task_id: Task ID string to validate
    
        Returns:
            Tuple of (is_valid, error_message)
            If valid: (True, "")
            If invalid: (False, error_message)
        """
        if not task_id or not task_id.strip():
            return False, "task_id is required"
    
        task_id = task_id.strip()
    
        # Length validation
        if len(task_id) > MAX_TASK_ID_LENGTH:
            return False, f"task_id too long (max {MAX_TASK_ID_LENGTH} characters)"
    
        # Format validation: should match pattern alias:hash:timestamp
        # Allow alphanumeric, colon, dash, underscore
        if not re.match(r"^[a-zA-Z0-9:_-]+$", task_id):
            return (
                False,
                "task_id contains invalid characters (only alphanumeric, colon, dash, underscore allowed)",
            )
    
        return True, ""
  • Tests for the ssh_cancel_async_task tool, covering invalid task ID and missing task_id cases.
    def test_ssh_cancel_async_task_invalid_task():
        """Test ssh_cancel_async_task with invalid task ID."""
        result = mcp_server.ssh_cancel_async_task(task_id="invalid:task:id")
        assert isinstance(result, dict)
        assert result.get("cancelled") is False
        assert (
            "not found" in result.get("message", "").lower()
            or "not cancellable" in result.get("message", "").lower()
        )
    
    
    def test_ssh_cancel_async_task_no_task_id():
        """Test ssh_cancel_async_task without task_id."""
        result = mcp_server.ssh_cancel_async_task(task_id="")
        # Error case - still returns string
        assert isinstance(result, str) or (
            isinstance(result, dict) and "error" in str(result).lower()
        )
        assert "required" in str(result).lower()
Behavior2/5

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

No annotations are provided, so the description carries full responsibility for behavioral disclosure. It only states the action (cancel) without explaining side effects, whether cancellation is guaranteed, or what happens to the task (e.g., cleanup, error states). The agent lacks insight into the tool's behavior beyond the surface.

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

Conciseness4/5

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

The description is a single sentence, highly concise and front-loaded. It efficiently conveys the core action. However, it may be too terse given the lack of parameter and behavioral details, but conciseness is a strength here even if completeness suffers.

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

Completeness2/5

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

Given the tool has one parameter and an output schema (not shown), the description should at least mention the return value or how to obtain the task_id. It does not, leaving the agent without essential context for proper usage. The minimal nature makes it incomplete for effective selection and invocation.

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

Parameters1/5

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

The input schema has one parameter (task_id) with no description in the schema (0% coverage). The description does not mention the parameter at all, so it adds no meaning beyond the parameter name. The agent must guess the format or origin of the task ID, which is insufficient for reliable invocation.

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

Purpose4/5

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

The description clearly states the tool cancels a running async task. It identifies the verb (cancel) and resource (async task), making the purpose unambiguous. However, it does not distinguish from the sibling tool 'ssh_cancel', which might have a different scope, but the specificity to async tasks provides clarity.

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

Usage Guidelines2/5

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

No guidance on when to use this tool versus alternatives like ssh_cancel or when cancellation is appropriate. There is no mention of prerequisites, such as the task needing to be in a running state, or any fail conditions. The description leaves the agent to infer use cases.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/samerfarida/mcp-ssh-orchestrator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server