File Operations
Read, write, sync, and manage files on remote hosts via SFTP.
Nefia provides file system subcommands and a directory sync command for working with files on remote hosts. All operations run over the encrypted VPN tunnel using SFTP.
Commands Overview
| Command | Description |
|---|---|
nefia fs read | Read a file from a remote host |
nefia fs write | Write a file to a remote host |
nefia fs list | List directory contents |
nefia fs stat | Show file metadata |
nefia sync | Synchronise a local directory to remote hosts |
The four fs subcommands require either --host (-H) or --session (-s) to specify the target. The --path flag is always required. The sync command uses --host or --target instead (see Directory Sync below).
Reading Files
Use nefia fs read to fetch the contents of a remote file and print them to stdout:
nefia fs read --host my-server --path /etc/hostnamemy-server.prod.internal
Pipe the output to local tools for further processing:
nefia fs read --host db-01 --path /etc/postgresql/16/main/postgresql.conf | grep max_connectionsBase64 Output
Use --base64 to force base64-encoded output, useful for binary files:
nefia fs read --host my-server --path /opt/app/icon.png --base64Streaming Download with --out
Use --out to download a file directly to a local path. This streams the data from disk to disk without buffering in memory, supporting files up to 3 GB:
nefia fs read --host my-server --path /var/backups/db-dump.sql.gz --out ./db-dump.sql.gzDownloading db.sql.gz... [===================> ] 48% 120.5 MB / 250.0 MB 15.2 MB/s ETA 9s
When the download completes, Nefia prints the total bytes transferred and the local destination path.
Writing Files
Use nefia fs write to upload content to a remote file. You must provide either --text or --in.
Text Content via --text
Pass text content directly with the --text flag:
nefia fs write --host my-server --path /etc/app/config.txt --text "new-config-value"Streaming Upload with --in
Use --in to upload a local file. This streams the data directly, supporting files up to 3 GB:
nefia fs write --host my-server --path /opt/releases/app.tar.gz --in ./app.tar.gzUploading app.tar.gz (1.2 GB)... [===================> ] 48% 576.0 MB / 1.2 GB 24.3 MB/s ETA 26s
Listing Directories
Use nefia fs list to view the contents of a remote directory:
nefia fs list --host my-server --path /var/log/TYPE SIZE MTIME NAME dir 4096 2026-02-20T08:00:00Z nginx/ file 28672 2026-02-24T12:34:00Z syslog file 14336 2026-02-24T12:34:00Z auth.log file 8192 2026-02-23T00:00:00Z kern.log file 2048 2026-02-20T09:15:00Z dpkg.log
File Metadata
Use nefia fs stat to retrieve metadata for a single file or directory:
nefia fs stat --host my-server --path /etc/nginx/nginx.confPath: /etc/nginx/nginx.conf Type: file Size: 2847 bytes Permissions: -rw-r--r-- Modified: 2026-02-18 14:22:31
Transfer Progress
When downloading (--out) or uploading (--in), Nefia displays a progress bar showing transfer speed and estimated time remaining. The progress bar pre-fetches the remote file size (for downloads) or reads the local file size (for uploads) to show accurate percentages.
The progress bar adapts to the terminal:
- TTY mode: The bar updates in place with real-time percentage, speed, and ETA.
- Non-TTY mode: A summary line is printed at percentage milestones.
Use --quiet (-q) to suppress the progress bar entirely.
Transfer Resume
Interrupted file transfers can be resumed automatically. When a transfer fails mid-way, Nefia saves progress metadata in a .nefia.partial sidecar file. On retry, the transfer resumes from where it left off using single-pass SHA-256 verification.
This is particularly useful for large file transfers over unreliable connections — no need to re-transfer gigabytes of data after a brief network interruption.
JSON Output
All four subcommands support --output json (or -o json) for machine-readable output:
nefia fs stat --host my-server --path /etc/hostname --output json
nefia fs list --host my-server --path /var/log/ --output json
nefia fs read --host my-server --path /etc/hostname --output jsonSession-Based File Operations
Instead of specifying --host on every command, you can use a session. A session binds a host to a root directory, and all --path values are resolved relative to that root:
# Open a session
nefia session open --host db-01 --root /etc/app
# File operations use relative paths within the session root
nefia fs read --session <id> --path config.yaml
nefia fs write --session <id> --path config.yaml --in ./new-config.yaml
nefia fs list --session <id> --path .
nefia fs stat --session <id> --path config.yaml
# Close the session
nefia session close <id>The session acts as a sandbox: paths that attempt to escape the root directory (via ../) are rejected.
Timeouts
Individual SFTP operations are subject to a configurable timeout of 5 minutes by default. Adjust this with ssh.sftp_timeout_sec:
ssh:
sftp_timeout_sec: 600 # 10 minutesAs a last resort, the transport layer applies a 30-minute hard safety timeout that activates only when no other deadline is set (e.g., when using SFTP via MCP without a request-level timeout). This prevents indefinite hangs on unresponsive peers. Streaming operations (fs read --out, fs write --in) are not subject to this safety timeout.
File Size Limits
By default, Nefia enforces a 10 MB maximum for inline file operations (fs read without --out, fs write --text). Streaming operations (fs read --out, fs write --in) support files up to 3 GB.
To change the maximum file size, update your nefia.yaml:
ssh:
max_file_size_bytes: 3221225472 # 3 GB (default)Directory Sync
Use nefia sync to synchronise an entire local directory to one or more remote hosts. Only changed files are transferred -- unchanged files are skipped automatically. This is the recommended way to deploy configuration directories, application bundles, or any tree of files that should match the local copy.
nefia sync <local-dir> <remote-dir> --target <selector>The command takes two positional arguments: the local directory to read from and the remote directory to write to. A target selector (--host or --target) is required.
Basic Usage
# Sync a config directory to all hosts
nefia sync ./configs /etc/app/ --target all
# Sync to a single host
nefia sync ./deploy /opt/app/ --host my-pc
# Sync to a host group
nefia sync ./dist /var/www/html/ --target group:webserversChange Detection
By default, Nefia compares files using size + modification time. If either differs, the file is re-transferred. For stricter comparison, use --checksum to compute a SHA256 hash of both the local and remote file:
nefia sync ./configs /etc/app/ --target all --checksumDry Run
Use --dry-run to preview what would change without transferring any files:
nefia sync ./configs /etc/app/ --target all --dry-runSyncing ./configs → /etc/app/ on 3 host(s) [DRY RUN] Local: 12 files, 48.2 KB
[web-01] transfer app.conf 2.1 KB (size changed) transfer routes.yaml 1.4 KB (new file) skip database.yaml Summary: 2 transfer, 10 skip (3.5 KB) [web-02] transfer app.conf 2.1 KB (size changed) transfer routes.yaml 1.4 KB (new file) skip database.yaml Summary: 2 transfer, 10 skip (3.5 KB) [web-03] skip app.conf transfer routes.yaml 1.4 KB (new file) skip database.yaml Summary: 1 transfer, 11 skip (1.4 KB)
The dry-run output lists each planned action (transfer, mkdir, delete, rmdir, skip) per host, along with file sizes and the reason for transfer.
Deleting Extra Remote Files
By default, files that exist on the remote host but not locally are left untouched. Use --delete to remove them:
nefia sync ./configs /etc/app/ --target all --deleteWhen --delete is specified, Nefia prompts for confirmation before proceeding (unless --yes is passed). The prompt warns that remote-only files will be removed.
Excluding Files
Use --exclude to skip files matching glob patterns. The flag can be repeated:
nefia sync ./project /opt/app/ --target all --exclude "*.log" --exclude ".git" --exclude "node_modules"Excluded files are filtered from both the local scan and the remote comparison, so they are never transferred or deleted.
Concurrency
Sync runs against multiple hosts in parallel, controlled by the global --concurrency (-c) flag. Within each host, file transfers run with a per-host concurrency of 4 by default. Adjust this with --file-concurrency:
nefia sync ./deploy /opt/app/ --target all --concurrency 10 --file-concurrency 8Flags Reference
| Flag | Type | Default | Description |
|---|---|---|---|
--checksum | boolean | false | Use SHA256 checksum for comparison instead of size+mtime |
--delete | boolean | false | Delete remote files not present locally |
--dry-run | boolean | false | Preview changes without transferring |
--exclude | string[] | -- | Glob patterns to exclude (can be repeated) |
--file-concurrency | int | 4 | Concurrent file transfers per host |
Global flags --host (-H), --target (-t), --concurrency (-c), --yes (-y), and --output (-o) also apply.
JSON Output
Use --output json for machine-readable results. Each host entry includes transfer counts, byte totals, duration, and (in dry-run mode) the full action plan:
nefia sync ./configs /etc/app/ --target all --output json
nefia sync ./configs /etc/app/ --target all --dry-run --output jsonError Handling
File operations return structured error codes for common failures:
| Code | Title | Description |
|---|---|---|
E3001 | File not found | The requested file does not exist on the remote host. |
E3002 | Permission denied | The SSH user lacks permission to access the file or directory. |
E3003 | File too large | The file exceeds the maximum allowed size for inline transfer. Use --out / --in for streaming. |
E3004 | SFTP operation failed | A general SFTP failure (e.g., subsystem not enabled, disk full). |
E3005 | Path denied by policy | The path is outside allowed_roots or matches a deny_paths rule. |
Use nefia explain <code> to see detailed resolution steps for any error code:
nefia explain E3001Nefia includes contextual information in error messages to help diagnose issues:
- SFTP timeout errors include the operation name and a configuration hint. For example:
sftp read timed out: the operation did not complete within the configured timeout (check defaults.timeout in config). - Streaming transfer errors include the number of bytes transferred before the failure, so you can tell how far the transfer progressed. For example:
sftp stream read failed after 12345 bytes: connection reset. - Symlink rejections explain the security rationale:
symlinks are rejected to prevent path traversal attacks; write to the resolved real path instead.
See the Error Codes reference for the full catalog of all error codes.
MCP Server Tools
The MCP server exposes 24 file operation tools for AI agents:
| Tool | Description |
|---|---|
nefia.fs.read | Read file contents (text or base64 for binary). |
nefia.fs.write | Write or overwrite a file. |
nefia.fs.patch | Apply a unified diff patch to a file. |
nefia.fs.list | List directory contents with metadata. |
nefia.fs.stat | Get file metadata (size, permissions, timestamps). |
nefia.fs.copy | Copy a file on the remote host. |
nefia.fs.move | Move or rename a file. |
nefia.fs.remove | Delete a file or directory. |
nefia.fs.mkdir | Create a directory (with parents). |
nefia.fs.chmod | Change file permissions. |
nefia.fs.chown | Change file owner and group. |
nefia.fs.find | Find files matching name/size/time patterns. |
nefia.fs.grep | Search file contents with regex. |
nefia.fs.tail | Get the last N lines of a file. |
nefia.fs.du | Show disk usage of a directory. |
nefia.fs.diff | Show unified diff between two files. |
nefia.fs.symlink | Create a symbolic link. |
nefia.fs.readlink | Read the target of a symbolic link. |
nefia.fs.archive.create | Create a tar.gz or zip archive. |
nefia.fs.archive.extract | Extract an archive to a directory. |
nefia.fs.stream_read | Stream a large file download (up to 3 GB). |
nefia.fs.stream_write | Stream a large file upload (up to 3 GB). |
nefia.fs.stream_read_resumable | Resumable streaming download with offset. |
nefia.fs.stream_write_resumable | Resumable streaming upload with offset. |
Related
Execute commands across multiple hosts with targeting and concurrency control.
Manage scoped working contexts for file and exec operations.
Complete reference for all file system commands and flags.