flats

module
v0.11.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: MIT

README

flats caretaker gopher logo

Open-source alternative to sites/artifacts

Flats

Sites, apps, documents and designs — built by agents, hosted on your machine.

Latest release CI status

Quick start · What you can build · Connect an agent · Documentation


Flats turns your own machine into a home for the things you build with AI. Deploy a website, run a small server app, share an HTML page, collaborate on a Markdown document or lay out a design canvas. Start Private on local loopback, then choose who can reach it through explicitly permitted network providers.

One CGO-free Go binary. macOS and Linux. A web console, CLI, HTTP API and MCP endpoint. No hosted Flats control plane.

Your machine, your data Built for agent workflows Private by default
Keep code, SQLite databases, persistent files and encrypted secrets locally. Connect Claude Code, Codex, Cursor or another MCP client. Inspect and approve deployments in the console. Use Local or a permitted private network. Public sharing is a separate, approved choice.

What you can build

Type Made for How it goes live
Website Static sites and sandboxed JavaScript or WASI server apps Save a Private Draft and preview it. Approve saving it as a numbered version, then approve deploying that version. Deployed versions support rollback.
Page A single HTML document with bundled assets: charts, reports and visualizations The same Draft, version and deployment flow as websites. No server code or data storage.
Document Live, collaborative Markdown Create or save to run immediately, initially Private. No Draft, versions or publish step.
Design A canvas of HTML artboards: screens, landing pages, posters and click-through prototypes Changes are live at once, initially Private. Every change is kept as a revision you can pin or roll back.

Websites and pages follow the version model: you work on a Private Draft while the live version keeps serving, and previews use isolated data. Saving a version (v1, v2, ...) and deploying it are separate approved steps, so a version can exist without ever going live. Publication and rollback require console approval.

Documents and designs are edited live by people and agents together: private visitors can edit while public visitors read, and changes to an already Public flat are visible immediately. Documents merge agent saves into people's edits; designs keep every change as a whole-canvas revision. Changing visibility in either direction requires approval for every type.

Explore content types for the full lifecycle and agent tools, including save_page, update_document and save_design.

Quick start

1. Install Flats

On macOS or Linux, with an amd64 or arm64 machine:

curl -fsSL https://raw.githubusercontent.com/gosuda/flats/main/install.sh | sh

The installer verifies the release, installs flats to ~/.local/bin and starts it as a background service, without sudo. The default network is Local; other providers are off.

2. Deploy your first site

mkdir -p hello
printf '<h1>Hello from Flats</h1>\n' > hello/index.html
flats save-draft hello ./hello

3. Approve, deploy and open

Run the exact flats create-version command printed by the save above; its --revision and --hash freeze the files you saved, even if someone edits the Draft afterwards. The command asks to save that Draft as version 1. Follow the approval URL it returns, or open the local console, and approve it. That creates v1 but puts nothing live yet. Deploy it with Publish v1 in the console, or request it from the CLI and approve that request too:

flats deploy --flat hello --version 1

Then visit hello.localhost:7879.

flats deploy returns exit code 3 while a request awaits approval, including with --json. Saving a Draft or a version does not make a site live; only deploying a version does.

Run flats status to check the host. See installation and upgrades for installer options, upgrades and backups.

Other ways to run Flats: container, foreground or source
Container

A Linux image for amd64 and arm64 is published with every release. On Linux, use host networking so the console, CLI and agents reach it on loopback:

docker run -d --name flats --restart unless-stopped --network host \
  -v flats-data:/data ghcr.io/gosuda/flats:latest

Never publish the console port to your network: anything that reaches it can approve deploys. See Running Flats in a container for other Docker hosts and network modes.

Foreground
flats serve --config ./flats-demo-data/config.json

On first start, this creates a host with the defaults in ./flats-demo-data. It never does that over a directory that already holds Flats data. Each running host needs its own data directory and ports; see Configuration and storage.

From source

Requires Go 1.27.1 or newer:

go install github.com/gosuda/flats/cmd/flats@latest

Use @main for unreleased changes. This build does not include NetBird; see Serving through NetBird to build the release binary from a checkout.

Agent integration

Connect Claude Code, Codex or Cursor with the Flats plugin, which runs flats mcp (the flats CLI must be on the agent's PATH) to relay the selected host's MCP endpoint; any other MCP client registers http://127.0.0.1:7878/mcp directly. For example, in Claude Code:

claude plugin marketplace add gosuda/flats && claude plugin install flats@flats

Connecting agents covers the other clients, remote hosts (flats connect), client updates and llms.txt. The agent starts with read-only check_client, then reads the server's current guide. For the whole server contract in one document, read resource flats://docs/runtime-api/v1 or call get_runtime_reference with {}. The runtime API v1 reference is embedded in the host and available through MCP without an installed skill or source checkout.

Static and server flats

Static builds need an index.html. For a JavaScript app, add a flats.json:

{"kind":"server"}

Then create server.js:

export default {
  async fetch(request, env) {
    env.DB.exec("CREATE TABLE IF NOT EXISTS hits (n INTEGER)");
    env.DB.exec("INSERT INTO hits VALUES (1)");
    const [{ n }] = env.DB.query("SELECT count(*) AS n FROM hits");
    return Response.json({ hits: n });
  }
};

Save the directory with flats save-draft <slug> <dir>, create a version with flats create-version <slug>, then deploy that version after approval. JavaScript runs in QuickJS on WebAssembly, with SQLite (env.DB), persistent string files (env.FILES), Web Crypto and WebSocket callbacks. There are no Node.js APIs; bundle imports into the uploaded version. Server-side fetch can call exact operator-granted HTTP(S) origins; see Calling external APIs.

WASI, persistent data and environment variables

A .wasm server is a WASI preview1 command instantiated afresh per request: request JSON on stdin, response JSON on stdout, only the flat's configured environment variables and secrets, with no inherited host environment, plus clocks and randomness. It has no SQLite/FILES host ABI, filesystem mounts, outbound network or WebSocket API. See the capability table and response format.

Data survives deploys and ordinary rollbacks. flats rollback hello restores code; --restore-data requests a separately approved restore of the pre-deploy DB and FILES snapshot. Preview data is isolated from live data.

Ordinary environment variables (flats env set hello GREETING 'Hello') and encrypted secrets reach server code as env.NAME, or as environment variables for WASI. Saving a value leaves running workers on their snapshot. The live worker picks up current values at the next approved deployment, redeployment, rollback or data restore, or when the Flats host restarts; a newly created preview also loads them. See App environment variables and Secrets.

Private and public access

Start locally, then enable the providers you need in Settings → Network providers. Allow a provider for an individual flat under Networks on its Settings tab.

Access Providers
Private Local (always on), Tailscale (tailnet ACLs), NetBird¹ (access policies)
Public Portal, Tailscale Funnel, zrok, Cloudflare quick tunnel, NetBird Expose¹

¹ NetBird and NetBird Expose are in the release binary (install.sh and the container image) but not in go install; see NetBird setup.

Host permission alone does not grant a provider to a flat. Configured provider defaults can grant providers to new flats; changing those defaults does not retroactively change existing flats. Tailscale permission does not imply Funnel permission.

Making a flat Public requires an approved transition and a configured, permitted public route. Websites and pages also need a published version; documents and designs run without publication. Configuration alone never publishes or changes visibility. Wait for a route to report ready and verify its endpoint before sharing it: relay availability and network connectivity are external dependencies.

See Private and public access for provider setup, tailnet consoles and upgrades from older hosts.

Security

  • Sandboxed execution. Server code runs in separate worker processes with WebAssembly memory and time limits, bounded request bodies and WebSocket connections, SQLite and FILES quotas, and restricted host capabilities. Each flat and preview gets its own origin.
  • Privileged console. The management listener and console can approve deployments. Approval decisions require the console header and a same-origin browser request. That is CSRF protection, not authentication: a local process that sends those headers can decide approvals. Run only trusted agents on the host and restrict console access with tailnet ACLs.
  • Local secrets. Secrets are encrypted with the local secret.key; secret APIs expose names only. A flat can read and return its own secrets, so deploy code you trust with them. Anyone who can read the data directory can recover those secrets.
  • Back up your data. Immutable code versions are not data backups. Back up the data directory, including secret.key; see what to back up.

Read the design and trust model for the details.

Documentation

Get started Build and operate
Install and upgrade Runtime API reference
Connect an agent Content types and lifecycles
Configure a host Call external APIs
Run in a container Design and trust model
Set up networking Verification gates

Browse the complete documentation index for contracts, internal design and verification guides, and the product specs for what Flats is meant to do, including targets that are not fully implemented yet.


MIT licensed · Releases · Issues

Directories

Path Synopsis
cmd
flats command
Command flats hosts agent-built websites on this machine.
Command flats hosts agent-built websites on this machine.
Package runtimeref contains the agent documentation shipped with the host: guide topics and refusal pages under agent/, and the two versioned references assembled from them.
Package runtimeref contains the agent documentation shipped with the host: guide topics and refusal pages under agent/, and the two versioned references assembled from them.
internal
api
Package api is the HTTP API shared by agents, the CLI and the web console.
Package api is the HTTP API shared by agents, the CLI and the web console.
app
Package app wires every Flats module into the `flats serve` process.
Package app wires every Flats module into the `flats serve` process.
apps/docs
Package docs embeds the built-in collaborative document editor that runs "docs" content-type flats on the Flats JavaScript runtime.
Package docs embeds the built-in collaborative document editor that runs "docs" content-type flats on the Flats JavaScript runtime.
buildinfo
Package buildinfo reports which build of Flats is running: the release version for a release, otherwise the commit it was built from.
Package buildinfo reports which build of Flats is running: the release version for a release, otherwise the commit it was built from.
bundle
Package bundle validates uploaded builds and writes them as immutable version directories.
Package bundle validates uploaded builds and writes them as immutable version directories.
cli
Package cli implements the `flats` command line.
Package cli implements the `flats` command line.
clientstate
Package clientstate describes compatibility between a Flats host and its clients.
Package clientstate describes compatibility between a Flats host and its clients.
config
Package config reads, validates and writes the host configuration file (config.json).
Package config reads, validates and writes the host configuration file (config.json).
console
Package console serves the operator's web console: a single-page app with no build step whose assets are embedded in the binary.
Package console serves the operator's web console: a single-page app with no build step whose assets are embedded in the binary.
contenttype
Package contenttype names the content adapters supported by the host.
Package contenttype names the content adapters supported by the host.
core
Package core implements Flats: flats, versions, deployments, exposure, previews and approvals.
Package core implements Flats: flats, versions, deployments, exposure, previews and approvals.
design
Package design implements the design content type: the source model of artboards (editable text, tweaks), the canvas index, the serving rewrite and the HTTP handler of a design flat.
Package design implements the design content type: the source model of artboards (editable text, tweaks), the canvas index, the serving rewrite and the HTTP handler of a design flat.
doccheck
Package doccheck audits the repository's Markdown documentation: relative links and #anchors must resolve to files Git ships, with exact case, and docs/agent/ topics must not use relative links because MCP and llms.txt serve them outside the repository.
Package doccheck audits the repository's Markdown documentation: relative links and #anchors must resolve to files Git ships, with exact case, and docs/agent/ topics must not use relative links because MCP and llms.txt serve them outside the repository.
doccheck/cmd/doccheck command
Command doccheck audits the repository's Markdown links and anchors.
Command doccheck audits the repository's Markdown links and anchors.
egress
Package egress provides a deny-by-default, bounded HTTP client for guest code.
Package egress provides a deny-by-default, bounded HTTP client for guest code.
expose/cfquick
Package cfquick serves public flats through Cloudflare quick tunnels: an anonymous tunnel on a random *.trycloudflare.com hostname, with no Cloudflare account and no domain.
Package cfquick serves public flats through Cloudflare quick tunnels: an anonymous tunnel on a random *.trycloudflare.com hostname, with no Cloudflare account and no domain.
expose/local
Package local serves flats on one loopback port, routing by Host header (<host>.localhost:<port>).
Package local serves flats on one loopback port, routing by Host header (<host>.localhost:<port>).
expose/portal
Package portal exposes public flats through Portal relays (github.com/gosuda/portal-tunnel).
Package portal exposes public flats through Portal relays (github.com/gosuda/portal-tunnel).
expose/provider
Package provider serves flats on explicitly permitted networks.
Package provider serves flats on explicitly permitted networks.
expose/tsnet
Package tsnet serves flats on the operator's tailnet.
Package tsnet serves flats on the operator's tailnet.
expose/zrok
Package zrok exposes public flats through zrok public shares (github.com/openziti/zrok).
Package zrok exposes public flats through zrok public shares (github.com/openziti/zrok).
forkwatch
Package forkwatch unwedges child processes stuck between fork and exec; it is only needed on macOS.
Package forkwatch unwedges child processes stuck between fork and exec; it is only needed on macOS.
launchd
Package launchd installs `flats serve` as a per-user launchd agent on macOS.
Package launchd installs `flats serve` as a per-user launchd agent on macOS.
lifecyclecheck/adapter command
Command lifecyclecheck is a test-only HTTP host for deterministic provider faults.
Command lifecyclecheck is a test-only HTTP host for deterministic provider faults.
lifecyclecheck/legacyadapter command
Command legacyadapter seeds historical exposure and approval references.
Command legacyadapter seeds historical exposure and approval references.
mcpx
Package mcpx exposes Flats to coding agents as an MCP server over Streamable HTTP (stateless, JSON responses).
Package mcpx exposes Flats to coding agents as an MCP server over Streamable HTTP (stateless, JSON responses).
qjs
runtime
Package runtime runs server flats.
Package runtime runs server flats.
safedir
Package safedir provides checked reads from an anchored directory tree.
Package safedir provides checked reads from an anchored directory tree.
selfupdate
Package selfupdate performs explicit local client resource updates.
Package selfupdate performs explicit local client resource updates.
site
Package site serves the files of one flat version.
Package site serves the files of one flat version.
slug
Package slug validates flat names and builds preview host names.
Package slug validates flat names and builds preview host names.
store
Package store keeps Flats metadata in a single SQLite database.
Package store keeps Flats metadata in a single SQLite database.
systemd
Package systemd installs `flats serve` as a systemd user service on Linux (the counterpart of package launchd on macOS).
Package systemd installs `flats serve` as a systemd user service on Linux (the counterpart of package launchd on macOS).
Package plugins embeds the bootstrap shipped by the Flats plugin.
Package plugins embeds the bootstrap shipped by the Flats plugin.
scripts
tsnet-logout command
Command tsnet-logout logs a stopped tsnet node out of its tailnet, given the node's state directory (for example <data>/tsnet/<host>).
Command tsnet-logout logs a stopped tsnet node out of its tailnet, given the node's state directory (for example <data>/tsnet/<host>).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL