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
| Name | Required | Description | Default |
|---|---|---|---|
| vm | Yes | ||
| remote_path | Yes | ||
| local_path | Yes |
Implementation Reference
- src/sympathy_mcp/transport.py:325-350 (handler)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], )
- src/sympathy_mcp/server.py:195-217 (registration)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}"
- src/sympathy_mcp/transport.py:55-62 (helper)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}'")
- src/sympathy_mcp/transport.py:65-70 (helper)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)