(AI generated. Not reviewed.)
Running the Fichero backend remotely on ACENET
This is the supported connection model for using ACENET as the compute host while
the Mac app stays the UI: run the backend on ACENET bound to remote loopback,
then SSH-forward the remote 127.0.0.1:8765 to the Mac’s 127.0.0.1:8765.
Keep the backend private. Do not bind it to 0.0.0.0; the API is designed for a
loopback client and also rejects non-loopback requests in middleware.
This page covers SSH loopback forwarding for ACENET. For a lab machine reached
over a tailnet, use the same loopback-only engine model with
tailscale serve. Do not use tailscale funnel
or bind the engine directly to a Tailscale, LAN, or public address.
Start the engine on ACENET
On the ACENET host:
cd ~/code/fichero
export FICHERO_REMOTE_BACKEND=1
export FICHERO_REMOTE_BACKEND_BIND_HOST=127.0.0.1
PYTHONPATH=fichero-server/src:fichero-cli/src /path/to/.venv/bin/python -m fichero_cli engine start --port 8765
If you want foreground logs instead of the detached engine manager:
cd ~/code/fichero
export FICHERO_REMOTE_BACKEND=1
export FICHERO_REMOTE_BACKEND_BIND_HOST=127.0.0.1
PYTHONPATH=fichero-server/src /path/to/.venv/bin/uvicorn fichero_server.api.main:app \
--host 127.0.0.1 \
--port 8765
The engine writes its bearer token on the remote host at:
"$HOME/Library/Application Support/Fichero/.api-key"
Open the SSH tunnel from the Mac
If you can SSH directly to the host running the backend:
ssh -N -L 8765:127.0.0.1:8765 <user>@<acenet-host>
If the backend runs on a compute node reached through a login node, use ProxyJump:
ssh -N -J <user>@<login-host> -L 8765:127.0.0.1:8765 <user>@<compute-node>
Leave this SSH process running. The Mac app connects to
https://127.0.0.1:8765 (pinned TLS — a plain-HTTP engine cannot connect), so
the app-compatible tunnel must normally use local port 8765. If local port 8765 is occupied, use another local port for CLI
or MCP work:
ssh -N -L 18765:127.0.0.1:8765 <user>@<acenet-host>
export FICHERO_API_URL=http://127.0.0.1:18765
Auth token
The health endpoint is unauthenticated, but library operations require
Authorization: Bearer <token>. The Python CLI and MCP server discover the
local token file by default; when using a remote backend they need the remote
token instead:
export FICHERO_API_KEY="$(ssh <user>@<acenet-host> \
'cat "$HOME/Library/Application Support/Fichero/.api-key"')"
The Swift app reads the same token path on the Mac. For app testing against a remote backend, copy the remote token into the Mac token file for the session, or run only unauthenticated health checks until the Swift side grows an explicit remote-backend token setting. Preserve the previous local token if you still need a local engine:
mkdir -p "$HOME/Library/Application Support/Fichero"
cp "$HOME/Library/Application Support/Fichero/.api-key" \
"$HOME/Library/Application Support/Fichero/.api-key.local-backup" 2>/dev/null || true
ssh <user>@<acenet-host> \
'cat "$HOME/Library/Application Support/Fichero/.api-key"' \
> "$HOME/Library/Application Support/Fichero/.api-key"
chmod 600 "$HOME/Library/Application Support/Fichero/.api-key"
Library paths
The backend resolves all library and source paths on the machine where the
backend runs. A Mac path such as /Users/daniel/Documents/Book.fichero is not a
valid ACENET path unless that path also exists there.
For CLI and MCP calls, set the remote .fichero package path explicitly:
export FICHERO_API_URL=http://127.0.0.1:18765
export FICHERO_API_KEY=<remote-token>
export FICHERO_LIBRARY_PATH=/remote/project/Library.fichero
PYTHONPATH=fichero-server/src:fichero-cli/src /path/to/python -m fichero_cli --json health
For the Mac app, open a library whose path can be resolved by the remote backend
or expect library-specific calls to fail with a missing or invalid
X-Fichero-Library-Path context. In practice, remote-heavy workflows should use
a library package stored on ACENET and CLI/MCP automation until the Swift UI has
an explicit remote-library path control.
Validation
From the Mac, with the tunnel running:
curl -s http://127.0.0.1:8765/api/health
The health payload includes remote_backend diagnostics. In remote mode,
expect:
{
"remote_backend": {
"enabled": true,
"connection_model": "ssh-loopback",
"token_configured": true,
"library_path_configured": true
}
}
If FICHERO_REMOTE_BACKEND=1 is set with
FICHERO_REMOTE_BACKEND_BIND_HOST=0.0.0.0 or another non-loopback host, startup
fails. Remote mode is intentionally SSH-loopback only.
For the general engine bind host, FICHERO_BIND_HOST defaults to 127.0.0.1.
Wildcard binds (0.0.0.0 and ::) are refused. Other non-loopback values are
allowed only with
FICHERO_ALLOW_NON_LOOPBACK_BIND=I_UNDERSTAND_SHARED_SECRET_RISK, which is an
owner-debugging escape hatch and not the supported remote-backend model. The
shared-secret token is not an internet-facing auth boundary.
For CLI validation against an alternate local tunnel port:
export FICHERO_API_URL=http://127.0.0.1:18765
export FICHERO_API_KEY=<remote-token>
PYTHONPATH=fichero-server/src:fichero-cli/src /path/to/python -m fichero_cli --json health
Expected failure modes:
connection refused: the engine is not running, the tunnel is closed, or the local port is wrong.401 missing or invalid Authorization header: the Mac/CLI is using the local token instead of the remote token.403 loopback only: the backend was exposed over the network instead of reached through SSH loopback forwarding.- missing or empty library data:
X-Fichero-Library-Pathpoints at a Mac path or a non-existent remote.ficheropackage.