The relayfile CLI is the primary interface for humans and CI to work with Relayfile workspaces. It wraps the HTTP API and the mount sync engine into one tool: minimal flags, sensible defaults, composable with pipes (--json everywhere), and no implicit destructive actions (deletes require --yes).
Authentication
The CLI resolves a token in priority order, first match wins:
--tokenflag (one-off override)RELAYFILE_TOKENenv var (CI/CD)- the canonical relay cloud session (cloud-hosted interactive use)
~/.relayfile/credentials.json(self-hosted / API-key compatibility)
For the cloud-hosted path, login is owned by the agent-relay CLI: agent-relay login, then agent-relay workspace switch <name>, then any relayfile command. For self-hosted servers, use the API-key path:
relayfile login --api-key --server https://file.agentrelay.comIf no token is found, the CLI prints: Error: not authenticated. Run 'agent-relay login' for Cloud or set RELAYFILE_TOKEN.
relayfile setup
The low-friction Cloud setup path for humans and agent-guided onboarding. It ensures you're logged in, creates or joins a Cloud workspace, requests a hosted connect session for the chosen provider, waits until it reports ready, and starts the mount loop.
relayfile setup --provider notion --workspace my-project --local-dir ./relayfile-mount| Flag | Default | Description |
|---|---|---|
--provider | prompted (github) | Integration to connect; none to skip |
--workspace | prompted | Workspace name to create or join |
--local-dir | prompted (./relayfile-mount) | Local mount directory |
--cloud-api-url | https://agentrelay.com/cloud | Cloud API URL |
--cloud-token | RELAYFILE_CLOUD_TOKEN | Cloud token for headless setup; skips browser login |
--no-open | false | Print login/connect URLs instead of opening a browser |
--skip-mount | false | Complete setup without starting the mount loop |
--once | false | Run one mount sync cycle and exit |
Re-running with the same workspace name reuses the workspace, refreshes the session, and only opens a new connect flow when the provider isn't already connected. See Relayfile Cloud.
relayfile login
Authenticate through the canonical relay session, or the self-hosted API-key path.
relayfile login [--no-open]
relayfile login --api-key --server https://file.agentrelay.comThe default path delegates to agent-relay login. --api-key keeps the self-hosted compatibility path and writes ~/.relayfile/credentials.json with 0600 permissions.
relayfile seed
Bulk-upload a local directory into a workspace, respecting .gitignore.
relayfile seed my-workspace ./srcIt walks the directory and posts batches to the bulk write endpoint, printing progress.
Two limits as of 0.10.41: seed takes no flags — --dry-run, --exclude, and --batch-size are rejected as undefined — and it resolves credentials only from ~/.relayfile/credentials.json, so it does not work from a relay Cloud session (relayfile login --api-key, or --token, is required). relayfile ops list has the same credential limitation and degrades to local-only results with a warning.
relayfile tree
List a remote workspace path without mounting.
relayfile tree my-workspace / --depth 2| Flag | Default | Description |
|---|---|---|
--depth | 1 | Maximum tree depth |
--json | false | Print the raw API response |
Prints a compact human-readable tree by default; --json is for scripts. relayfile read <workspace> <path> (alias relayfile cat) reads a single file the same way.
relayfile listen
Stream the workspace event feed, optionally running a command per event.
relayfile listen \
--path "/linear/issues/by-state/triage/**" \
--event file.created \
--run "claude --print 'Triage this: {{path}}'"| Flag | Default | Description |
|---|---|---|
--provider | all | Only events from one provider |
--path | all | Path glob to filter on |
--event | all | Event type (file.created, file.updated, file.deleted) |
--run | (none) | Command to execute per event, with placeholder substitution (below) |
--format | text | text or json (one event object per line) |
--background | false | Detach and keep listening |
--run substitutes five placeholders into the command:
| Placeholder | Expands to | Example |
|---|---|---|
{{path}} | the changed path | /runs/pr-59/findings/security.json |
{{type}} | the event type | file.created |
{{provider}} | the owning provider | github |
{{revision}} | the file's revision | rev_2936535 |
{{event}} | the whole event, as space-separated key:value pairs | type:file.created path:/runs/… revision:rev_… eventId:evt_… origin:agent_write … |
Quote {{event}}. It expands to the entire event — a dozen or more space-separated tokens — so an unquoted --run "my-agent --event {{event}}" splatters them across argv. Write --run "my-agent --event '{{event}}'". The single-value placeholders are passed as one argument each.
Events carry eventId, type, path, revision, provider, origin, correlationId, and — for small files — the content inlined. See Events and webhooks.
To keep a subscriber running across reboots, relayfile supervisor install accepts every listen flag and embeds them verbatim into a launchd (macOS) or systemd (Linux) unit that restarts on failure:
relayfile supervisor install \
--path "/linear/issues/by-state/triage/**" --event file.created \
--run "claude --print 'New triage issue at {{path}}. Assign it.'"
relayfile supervisor statuslisten is missing from relayfile --help and relayfile help listen prints the generic help, but relayfile listen --help shows its usage. Expect to supervise it: on a busy workspace the stream can end mid-message, and reconnecting immediately earns a 429 on the WebSocket handshake — run it with --background or under relayfile supervisor install, and back off between reconnects.
relayfile mount
Mount a workspace to a local directory, syncing changes in real time. This replaces the standalone daemon for end users.
relayfile mount my-workspace ./local-mirror| Flag | Default | Description |
|---|---|---|
--interval | 30s | Polling interval between sync cycles |
--once | false | Run a single sync cycle and exit (CI) |
--mode | poll | poll (synced mirror, recommended) or fuse (opt-in, POSIX) |
--background | false | Detach; write PID to .relay/mount.pid, logs to .relay/mount.log |
--no-websocket | false | Disable WebSocket streaming, poll only |
In poll mode the daemon maintains a synced mirror accelerated by a WebSocket invalidation channel. fuse mode is gated by build tags and unavailable in the OSS build (the CLI exits cleanly with a clear message rather than falling back silently). Stop a background mount with relayfile stop and tail its log with relayfile logs.
The relayfile-mount daemon
cmd/relayfile-mount is the minimal single-purpose daemon, kept for backwards compatibility and deployments that want it directly. It's configured by flags or environment variables:
RELAYFILE_TOKEN="$TOKEN" go run ./cmd/relayfile-mount \
--base-url http://localhost:9090 \
--workspace ws_demo \
--local-dir ./relayfile-mount \
--remote-path /github \
--fuse-content-ttl 10s| Flag / env | Default | Description |
|---|---|---|
--base-url / RELAYFILE_BASE_URL | http://127.0.0.1:8080 | Relayfile API base URL |
--workspace / RELAYFILE_WORKSPACE | — (required) | Workspace ID to mount |
--local-dir / RELAYFILE_LOCAL_DIR | — (required) | Local mirror directory |
RELAYFILE_TOKEN | — (required) | Bearer token |
--remote-path / RELAYFILE_REMOTE_PATH | / | Remote subtree to mirror (repeatable) |
--paths-file | — | JSON array or newline list of remote roots |
--fuse-content-ttl / RELAYFILE_MOUNT_FUSE_CONTENT_TTL | 30s | FUSE content cache TTL |
RELAYFILE_MOUNT_INTERVAL | 2s | Polling interval |
RELAYFILE_MOUNT_TIMEOUT | 15s | Per-sync timeout |
See Run locally for the daemon in context and Local development for the no-Docker loop.
Other commands
| Command | Purpose |
|---|---|
relayfile workspace create / list / delete | Manage workspaces |
relayfile export | Download a snapshot (--format tar|json|patch) |
relayfile status | Per-provider sync state, lag, conflicts, denials |
relayfile integration connect / list / disconnect | Manage provider integrations after setup |
relayfile integration available / search | Browse or search the live provider catalog (--refresh, --json) |
relayfile integration set-metadata | Replace flat provider metadata (Jira/Confluence cloudId) |
relayfile integration bind / unbind | Route a provider path glob to a channel webhook |
relayfile pull | Force a reconcile of a path or the whole workspace |
relayfile writeback status / list / retry | Local pending, failed, and dead-lettered writebacks |
relayfile ops list / replay | Inspect and replay dead-lettered writeback ops |
relayfile restart / relayfile supervisor | Restart a mount, or install it as a launchd/systemd service |
relayfile stop / relayfile logs | Control and read a background mount daemon |
relayfile observer | Open the hosted file observer for a workspace |
There is no relayfile permissions command. To find out what a path expects, read the provider's .adapter.md and .schema.json under /discovery/<provider>/…; to see what was denied, read .relay/state.json → deniedPaths in the mirror.
Global flags
| Flag | Env var | Description |
|---|---|---|
--server | RELAYFILE_SERVER | Server base URL |
--token | RELAYFILE_TOKEN | Bearer token |
--workspace | RELAYFILE_WORKSPACE | Workspace name or ID |
--json | — | Emit JSON instead of tables |
--verbose | — | Debug logging to stderr |