Sessions
Manage persistent SSH sessions on remote hosts.
Sessions provide a persistent context that binds a host, root directory, and working directory together. Instead of specifying the host and path for every file operation, you open a session once and then run commands within it — all confined to a sandboxed directory tree.
Why Sessions?
Without sessions, every nefia fs command requires --host and a full path. Sessions solve this by maintaining state across commands:
- Context persistence — The host, root directory, and working directory carry over between commands.
- Path sandboxing — All operations are confined to the root directory.
SafeJoinprevents path traversal via../, normalizes Windows backslashes and drive-letter roots, and rejects escapes such as UNC paths. - Automatic cleanup — Expired sessions are garbage-collected without manual intervention.
Opening a Session
Use nefia session open to create a new session bound to a host:
nefia session open --host my-server --root /var/www/myappSession opened: a1b2c3d4 Host: my-server Root: /var/www/myapp Cwd: /var/www/myapp Shell: /bin/bash
The returned session ID is used for all subsequent operations within this session.
Flags
| Flag | Description |
|---|---|
--host | (required) Host ID to open the session on |
--root | Root directory on the remote host (sandbox). Defaults to the host's configured root field, or the remote user's home directory |
--cwd | Initial working directory relative to root. Defaults to the root directory |
Managing Sessions
List Active Sessions
nefia session listSESSION_ID HOST ROOT LAST_USED a1b2c3d4 my-server /var/www/myapp 2026-03-04T10:30:00Z f9e8d7c6 dev-box /home/deploy/app 2026-03-04T08:15:00Z
The list command performs a lazy garbage-collection pass, automatically removing any expired sessions before displaying results.
Close a Session
nefia session close a1b2c3d4You do not need to type the full session ID. Prefix matching works with a minimum of 8 characters.
Session ID Format
Session IDs are 64-character hex strings (32 bytes of cryptographic randomness). In display output, they are truncated to the first 8 characters for readability.
Prefix Matching
You only need to provide enough characters to uniquely identify a session. The minimum prefix length is 8 characters.
Use the --session (or -s) flag to target a session:
nefia fs list --session a1b2c3d4 --path .
nefia fs read --session a1b2c3d4 --path config/app.yamlPath Sandboxing
Every session is confined to its root directory. The SafeJoin function rejects any operation that would escape the sandbox:
# This works — path is within the root
nefia fs read --session a1b2c3d4 --path config/app.yaml
# These are rejected on POSIX roots:
nefia fs read --session a1b2c3d4 --path ../../etc/passwd # path traversal
nefia fs read --session a1b2c3d4 --path /etc/passwd # absolute pathWhen the session root is a Windows path (for example C:\Users\app), backslashes are normalized to forward slashes and the result is kept inside that root (e.g. C:/Users/app/config.yaml). UNC paths and relative drive-letter escapes are rejected.
Error: path denied: path escapes root: "../../etc/passwd"
Session TTL and Expiration
Sessions have a default time-to-live of 24 hours from the last use. After the TTL expires, the session can no longer be used — attempting to access it returns an error and automatically removes it from the store.
Configuring TTL
Set session_ttl_minutes in your nefia.yaml to override the default:
session_ttl_minutes: 480 # 8 hours instead of 24A value of 0 uses the default 24-hour TTL.
LastUsedAt Tracking
Each time a session is accessed, its LastUsedAt timestamp is updated. To reduce disk I/O, updates are throttled to at most once per minute — rapid successive accesses within the same minute do not trigger additional disk writes.
Per-Client Session Limit
Each MCP client is limited to 50 concurrent sessions. Attempting to open a 51st session returns an error. Close unused sessions with nefia session close or nefia.session.close to free up capacity.
Session Ownership
Sessions are bound to the MCP client that created them. One client cannot list or close sessions created by another client. This isolation ensures that concurrent AI agents operating on the same Nefia instance do not interfere with each other's session state.
Garbage Collection
Nefia automatically cleans up expired sessions in the background. The garbage collector runs every 5 minutes by default and removes sessions that have exceeded their TTL.
Configuring GC Interval
Set session_gc_interval_minutes in your nefia.yaml:
session_gc_interval_minutes: 10 # run GC every 10 minutesStorage Location
Sessions are persisted to a JSON file at:
- macOS:
~/Library/Application Support/nefia/state/sessions.json - Linux:
~/.config/nefia/state/sessions.json - Windows:
%AppData%\nefia\state\sessions.json
The file is written atomically (temp file, fsync, chmod 0600, rename) and protected by a cross-process file lock.
MCP Tool Integration
When using Nefia as an MCP server, sessions are managed through dedicated tools:
| MCP Tool | Description |
|---|---|
nefia.session.open | Open a new session (returns session_id) |
nefia.session.close | Close a session by ID |
Once a session is open, pass session_id to any file system tool instead of host_id:
nefia.fs.read { "session_id": "a1b2c3d4...", "path": "config/app.yaml" }
nefia.fs.write { "session_id": "a1b2c3d4...", "path": "config/app.yaml", "content": "..." }
nefia.fs.list { "session_id": "a1b2c3d4...", "path": "." }
nefia.fs.patch { "session_id": "a1b2c3d4...", "path": "config/app.yaml", "patch": "..." }
nefia.exec { "session_id": "a1b2c3d4...", "command": "ls -la" }When using session_id, paths are resolved relative to the session's root directory and sandboxed by SafeJoin.
Working with File Operations
Sessions integrate directly with all nefia fs subcommands. Pass the --session flag to operate within a session context:
# List files in the session's working directory
nefia fs list --session a1b2c3d4 --path .
# Read a file relative to the root directory
nefia fs read --session a1b2c3d4 --path config/database.yaml
# Write a file from local disk
nefia fs write --session a1b2c3d4 --path config/database.yaml --in ./local-database.yamlPractical Workflow
Here is a typical session-based workflow for deploying a configuration update:
Open a session on the target host:
nefia session open --host prod-web-1 --root /etc/nginxReview the current configuration:
nefia fs read --session a1b2c3d4 --path nginx.conf
nefia fs list --session a1b2c3d4 --path conf.d/Upload the updated configuration:
nefia fs write --session a1b2c3d4 --path conf.d/app.conf --in ./new-app.confValidate and reload Nginx:
nefia exec --host prod-web-1 -- nginx -t && systemctl reload nginxClose the session:
nefia session close a1b2c3d4Related
Full reference for all Nefia CLI commands including fs subcommands.
Organize target PCs with hosts, groups, and tag-based targeting.