Self-hosting

Self-hosting

Run the gateway, source and worker on your own machines, from one PC on a LAN to separate hosts.

Last updated October 22, 2026

A self-hosted Fughetta is the gateway, source and optional worker programs plus the static console. They can run on one PC, with an agent on a tablet reaching it over your LAN, or on separate machines. Application data lives in the Cloudflare Worker/D1 deployment described in the console repository; Supabase Auth is the identity provider.

Program Listens on Stores
source An internal address (default 127.0.0.1:9091), for the gateway only. Project files, node/worldline state, receipts and blobs under its --storage directory.
gateway The public HTTP port for MCP and the console API (default 127.0.0.1:8080). Its configuration file, account snapshot, and usage ledgers under server.storage.
worker Connects out to the gateway. Its work root, content cache and build trees. Needed for build/test/run.

Build from source

You need Linux with io_uring, CMake 4.0 or newer, Ninja, vcpkg, and a Clang that builds C++23 modules (cmake/toolchain.cmake selects it). From the repository root:

cmake --preset release
cmake --build --preset release

The programs are written to build/release/. Build them from the same source and upgrade them together.

1. Start the source

source takes its deployment settings on the command line:

source --bind 127.0.0.1 --port 9091 --storage /var/lib/source/storage

--bind, --port and --storage default to 127.0.0.1, 9091 and storage. Keep the port on an internal network: only the gateway should reach it. A project's files live at <storage>/<workspace>/<project>, so you can also place an existing codebase there before pointing an agent at it. The gateway and source must share the SOURCE_TOKEN environment value used for their internal handshake.

2. Start the gateway

gateway.json needs an authentication section and the accounts service URL:

{
    "server": {
        "public_url": "https://gateway.example.com",
        "console_url": "https://console.example.com",
        "http_bind": "0.0.0.0",
        "http_port": 8080,
        "source": "127.0.0.1:9091",
        "storage": "/var/lib/gateway/state",
        "allowed_origins": ["https://console.example.com"],
        "auth": {
            "mode": "supabase",
            "supabase_url": "https://<ref>.supabase.co",
            "accounts_url": "https://services.fughetta.dev",
            "secret_key_env": "GATEWAY_SERVICE_KEY",
            "admin_key_env": "SUPABASE_ADMIN_KEY",
            "operators": ["you@example.com"],
            "sync_seconds": 30,
            "report_seconds": 300
        },
        "waitlist": {
            "enabled": false,
            "daily_admissions": 0,
            "reset_hour_utc": 0,
            "message": null
        }
    },
    "limits": {},
    "workspaces": {}
}
gateway gateway.json

Without an argument it reads config.json in the current directory. Bind http_bind to 0.0.0.0 or the machine's LAN address to reach it from other devices. Settings under server take effect when the gateway restarts; everything else (workspaces, projects, limits) is changed through the console and applies at once. The gateway saves the file on every change.

secret_key_env names the environment variable holding the Worker service credential (GATEWAY_SERVICE_KEY); the key itself never goes in the configuration. The gateway also reads a .env file beside its configuration file: GATEWAY_SERVICE_KEY, SUPABASE_ADMIN_KEY (the Supabase secret key used to list users, ban them and sign them out) and SOURCE_TOKEN (shared with source). admin_key_env names the Auth administration key's environment variable; it defaults to SUPABASE_ADMIN_KEY. The gateway also reads the account snapshot and reports usage to the Worker every sync_seconds and report_seconds; it keeps the last snapshot on disk, so a restart while the accounts service is unreachable still serves.

console_url is the public console origin used by OAuth discovery and by waitlist decision mail; it must be https in a deployment. waitlist is closed by default. enabled opens the gate, daily_admissions is the number admitted by the daily release (0 admits only by hand), reset_hour_utc is the UTC hour (0–23) at which the allowance resets, and message is an optional line shown on the waiting page. Changes take effect on the next account sync, without a restart.

3. Run the console

The console is a static web app. For development, from the console repository:

bun install
GATEWAY_URL=http://127.0.0.1:8080 bun run dev

The dev server proxies /api, /mcp, /healthz and /metrics to the gateway. For a built deployment, set VITE_GATEWAY_URL=http://<gateway>:8080 before bun run build, then serve dist/client with a static host; bun run preview only serves that build, it does not proxy API requests. Add the console origin to the gateway's server.allowed_origins.

Open the console, create a workspace and a project, and connect your agent to http://<gateway>:8080/mcp.

Authentication and application data

People sign in through a Supabase Auth project. Supabase holds users, credentials, MFA, sessions, bans and the JWKS; it holds no workspaces, tokens or usage. The business Worker and its D1 database hold the application rows and the account snapshot the gateway reads. Point accounts_url at that Worker and use the same GATEWAY_SERVICE_KEY on both sides.

Public requests require a bearer credential. operators (emails or user ids) may change server settings and default limits and read metrics. Build the console with VITE_SUPABASE_URL and VITE_SUPABASE_PUBLISHABLE_KEY to give it sign-in, members and tokens.

Monitoring

GET /healthz is open and reports status, the connected worker count and the protocol fingerprint. Operators can scrape Prometheus metrics at /metrics. Each workspace's storage and tool-call statistics are in the console and the admin API.

Backups

Back up the gateway's configuration file and its server.storage directory (usage ledgers and the account snapshot), the source's --storage directory (project files plus .worldlines and .nodes state), and a D1 export of the business database. The worker work root is disposable; build caches can be rebuilt.