Skip to main content
Glama

vm_file_pull

Transfer files from remote virtual machines to your local system using SCP for efficient file management in Incus VM environments.

Instructions

Pull a file from a remote host to the local host via SCP.

Args:
    vm: Name of the host (as configured in hosts.toml).
    remote_path: Absolute path to the file on the remote host.
    local_path: Destination path on the local host.

Returns:
    Success confirmation or error message.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
vmYes
remote_pathYes
local_pathYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Main implementation of vm_file_pull - pulls a file from a remote host to the local host via SCP. Validates inputs, creates local directory if needed, and uses _run_scp to perform the transfer.
    async def vm_file_pull(
        vm: str,
        remote_path: str,
        local_path: str,
    ) -> ExecResult:
        """Pull a file from a remote host to the local host via SCP.
    
        Args:
            vm: Name of the host (as configured in hosts.toml).
            remote_path: Absolute path to the file on the remote host.
            local_path: Destination path on the local host.
    
        Returns:
            ExecResult with operation details.
        """
        host = _resolve_host(vm)
        _validate_path(remote_path)
        _validate_local_path(local_path)
    
        local_dir = Path(local_path).parent
        local_dir.mkdir(parents=True, exist_ok=True)
    
        return await _run_scp(
            host,
            [f"{host.scp_prefix}{remote_path}", local_path],
        )
  • MCP tool registration wrapper for vm_file_pull. Decorated with @mcp.tool(), this function calls the underlying transport implementation and formats the result as a user-friendly string with success/error messages.
    @mcp.tool()
    async def vm_file_pull(
        vm: str,
        remote_path: str,
        local_path: str,
    ) -> str:
        """Pull a file from a remote host to the local host via SCP.
    
        Args:
            vm: Name of the host (as configured in hosts.toml).
            remote_path: Absolute path to the file on the remote host.
            local_path: Destination path on the local host.
    
        Returns:
            Success confirmation or error message.
        """
        try:
            result = await _vm_file_pull(vm, remote_path, local_path)
            if result.exit_code == 0:
                return f"Successfully pulled {vm}:{remote_path} -> {local_path}"
            return f"ERROR pulling file: {result.stderr.strip()}"
        except (ValueError, KeyError, RuntimeError, OSError) as e:
            return f"ERROR: {e}"
  • Path validation helper - validates that remote paths are non-empty, contain no null bytes, and are absolute (start with '/'). Used by vm_file_pull to validate the remote_path parameter.
    def _validate_path(path: str) -> None:
        """Validate a file path on the remote host (basic safety checks)."""
        if not path or not path.strip():
            raise ValueError("Path cannot be empty")
        if "\x00" in path:
            raise ValueError("Path cannot contain null bytes")
        if not path.startswith("/"):
            raise ValueError(f"Path must be absolute (start with /): '{path}'")
  • Local path validation helper - validates that local paths are non-empty and contain no null bytes. Used by vm_file_pull to validate the local_path parameter.
    def _validate_local_path(path: str) -> None:
        """Validate a local file path on the host."""
        if not path or not path.strip():
            raise ValueError("Local path cannot be empty")
        if "\x00" in path:
            raise ValueError("Path cannot contain null bytes")
  • Host resolution helper - resolves a VM/host name to its SSH configuration from the loaded config. Used by vm_file_pull to get the HostConfig for the target VM.
    def _resolve_host(vm: str) -> HostConfig:
        """Resolve a VM/host name to its SSH config."""
        _validate_host_name(vm)
        config = _get_config()
        return config.get_host(vm)
Behavior3/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions the transfer method (SCP) and that it pulls files, implying a read operation, but does not detail authentication needs, error handling, rate limits, or file overwrite behavior. It adds basic context but lacks depth for a mutation-like tool.

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 well-structured with a clear opening sentence followed by Args and Returns sections. It is front-loaded with the core purpose and efficiently details parameters and return values without unnecessary elaboration, though the Returns section could be slightly more informative.

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

Completeness4/5

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

Given the tool's moderate complexity (file transfer via SCP), no annotations, and an output schema present (which covers return values), the description is reasonably complete. It explains the action, parameters, and return intent, but could improve by addressing behavioral aspects like authentication or error scenarios to fully compensate for missing annotations.

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

Parameters4/5

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

The description provides clear semantics for all three parameters (vm as host name, remote_path as absolute path on remote, local_path as destination on local), compensating for the 0% schema description coverage. It explains what each parameter represents, adding value beyond the bare schema, though it doesn't specify format constraints like path syntax.

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 clearly states the tool's purpose with a specific verb ('Pull'), resource ('a file'), and method ('via SCP'), distinguishing it from siblings like vm_file_push (which pushes files) and vm_file_read (which reads files without transferring). It explicitly mentions source (remote host) and destination (local host), making the action unambiguous.

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 usage by specifying the tool transfers files from remote to local via SCP, but does not explicitly state when to use it versus alternatives like vm_file_read (for reading remote files without local storage) or vm_file_push (for reverse transfers). No exclusions or prerequisites are mentioned, leaving some ambiguity in context.

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/bobbyhiddn/Sympathy-MCP'

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