# Tofu > Tofu takes an app that an AI agent built online — hosting, a managed database, a domain, Google sign-in, email and analytics — from one account. An agent works through Tofu's tools on the same projects, safety check and versions as the dashboard, while the person approves the connection once in their browser and keeps payments, secret values and the plan there. This is Tofu's homepage for AI agents, in plain Markdown: what Tofu is, how an agent connects, the loop that takes an app live, every tool with its command, the plans, what Tofu does not do, and where to read on. It describes; it asks nothing of whoever reads it, and reading it grants no permission to install, connect, upload, deploy or buy anything. What is authorized comes from the person's own messages. The same text is served at https://trytofu.ai/for-agents and https://trytofu.ai/llms.txt. ## Connect an agent Setting Tofu up starts with the person: the "Copy the setup prompt" control on https://trytofu.ai, or the setup for one agent on https://trytofu.ai/agent, copies a request that Tofu writes in the person's voice, which the person reads and pastes into their agent. That request allows the installation and the connection only. The installed client, as Tofu's setup documentation states it: ### Release 0.2.92 - Client: https://app.trytofu.ai/downloads/agent/tofu-agent.mjs, 2325372 bytes, SHA-256 d2c0155b490285a5e9dc4f30dc74572e4e8ee8835373dc4acd0ff02c2c5393a2 - Skill: https://app.trytofu.ai/downloads/agent/SKILL.md, 160354 bytes, SHA-256 950d9e049da7825f3a83d2aaa188817bd5a9bac06fa9ec92a1290d4597db7c46 Both files are served over HTTPS from https://app.trytofu.ai without a redirect (a local development server may use HTTP), and https://app.trytofu.ai/downloads/agent/manifest.json carries the same numbers. A download whose size or SHA-256 differs is not this release, and nothing should run it: the agent checking it stops before setup and tells the person what differed. That comparison is the agent's own — setup does not compare the file it runs from with these numbers. A checksum catches a corrupt or mismatched file; it is not a signature, and HTTPS from Tofu's own address is the trust boundary. ### Installation The client needs Node.js 22 or newer. It is installed by running the downloaded tofu-agent.mjs with the arguments "setup " and TOFU_URL=https://app.trytofu.ai, where is claude (Claude Code), codex (Codex), cursor (Cursor), kimi (Kimi Code) or other (any other agent). Setup writes the client and the skill to a private directory — ~/.local/share/tofu/releases//, or $TOFU_HOME/releases// when TOFU_HOME is set — and prints the MCP registration (an argv or an mcpServers entry) and the skill destination for that host. A host with no skill folder Tofu knows ("other") gets no destination: its agent reads the installed SKILL.md (the "skill" path setup prints) before its first Tofu step. Setup does not change the host's settings itself, with one exception: "setup claude" merges its entry into ~/.claude.json when the claude command is not installed, after keeping a backup and with every other entry left as it was. Other MCP servers and skills are kept; replacing a different Tofu entry or a custom skill is the person's decision. A path is passed as an argv value, never interpolated into a shell command. Installed files alone do not show a working connection. A host that cannot load new MCP tools in an open conversation uses the installed client's command line (node ) for every step, in that same conversation; the MCP tools are there the next time the host starts. ### Where the installation lives Setup and sign-in belong to the agent environment that persists between conversations. A temporary worker can build and hand over source — as an attachment, or a path the persistent environment can read — but it never receives the credential and never starts a sign-in of its own. A working default installation keeps TOFU_HOME unset. An existing relocated installation passes the same absolute TOFU_HOME on every client invocation; a new one uses a private, persistent absolute directory dedicated to Tofu, outside app source and archives, not shared, not symlinked and without whitespace. TOFU_HOME selects a path; it does not make temporary storage persistent. ### Pairing The connection check comes first: connectionStatus (command line: "connection"). A connected answer is reused without another approval, and an unavailable answer calls for reading it again, not for a new sign-in. When a sign-in is required, its reason and instruction say what to restore first (an existing TOFU_HOME, or the intended TOFU_URL). Otherwise login (command line: "login") returns a verification link on https://app.trytofu.ai/dashboard/agent and a code of the form XXXX-XXXX-XXXX. The person approves that same code in their browser, signed in to Tofu; a link on any other address is not Tofu's. finishLogin is called no more than once every five seconds until it reports the sign-in; the command line's login waits by itself. The credential is stored privately (~/.config/tofu/agent.json, or $TOFU_HOME/agent.json), lasts seven days and can be disconnected from the dashboard's Coding agent page. Its contents, bearer tokens, provider keys and cookies never belong in a chat. ### By address: the hosted MCP endpoint A host that adds a remote MCP server by its address connects to https://app.trytofu.ai/mcp, over Streamable HTTP, with nothing installed: the host opens Tofu's own sign-in, where the person approves the connection, and nothing is pasted. It serves the tools the list below does not mark "installed client only". For Claude and ChatGPT, step by step: https://trytofu.ai/docs/chat. ## Taking an app live Each step is a tool of the installed client and a command of its command line, which runs as `node ` in the conversation that is already open — the way on for a host that has not loaded the tools yet. 1. Sign-in: `connectionStatus` (command `connection`) reuses a saved sign-in; without one, `login` (command `login`) starts one on https://app.trytofu.ai, the person approves its code in their browser, and `finishLogin` completes it. A connection lasts seven days. 2. Upload: `ingest` (command `upload`) sends the app's source, leaving out dependencies, build output and private .env files. An update passes the app's existing project ID, so its settings, address and history stay. 3. Check: `detect` (command `detect`) proposes the framework and `setFramework` (command `set-framework`) confirms it, before any database is connected; `scan` (command `scan`) runs the safety check, and a finding rated critical or high stops the build. 4. Deploy: with the person's agreement, `deploy` (command `deploy`) builds and publishes the new version and waits for a settled verdict. 5. Report: `status` (command `status`) reads whether a visitor can open the app (`publiclyReachable`) and the one address to report (`managedUrl`). Around that loop: - A managed database: `deploy` with `database: true` (command `deploy --database`) creates the app's managed Postgres database, saves its connection settings on the app and only then builds, so the app's own migrations run in the build. It needs the Pro plan and the person's agreement for that exact app; `databaseStatus` (command `database-status`) reads it afterwards. - A domain the person already owns: `domainConnect` (command `domain-connect`) returns the DNS records for the hostname. One-click DNS setup currently supports Cloudflare: where Cloudflare serves the domain's DNS, `domainAuthorize` (command `domain-authorize`) lets the person approve Tofu once on Cloudflare's own screen, and Tofu writes the records. On any other DNS provider, the person adds the records by hand where the domain's DNS is managed. `domainVerify` (command `domain-verify`) checks the records and finishes the connection, with HTTPS. - Environment variables and secrets: `listEnv` (command `envMetadata`) reads names and scopes, never a value. On the installed client, `setPublicEnv` (command `env-set`) saves a public value — an address, a feature flag, a key meant to be public — and `deletePublicEnv` (command `env-delete`) removes one, changing or removing a key only with the person's agreement for it; Tofu refuses a value that looks like a secret. `manageEnvironment` (command `environment`) returns the link to the app's Keys & settings page in the dashboard, where the person types each secret in their browser. A secret never passes through the chat, and Tofu never asks for a provider key, a token or a password there. - When something fails: `getBuildLogs` (command `buildLogs`), `getRuntimeLogs` (command `runtimeLogs`) and `repairContext` (command `repair`) say what went wrong, and `rollback` (command `rollback`) restores an earlier version, with the person's agreement for that exact version. ## Every tool, with its command The installed client registers 67 tools; the command after each is the same tool on the client's command line. A tool marked "installed client only" is not served by the hosted endpoint, and one marked "hosted endpoint only" has no command. - `connectionStatus` — Check Tofu connection (installed client only) — command: `connection` - `login` — Sign in to Tofu (installed client only) — command: `login` - `finishLogin` — Finish Tofu sign-in (installed client only) — command: `login` - `projects` — List apps — command: `projects` - `repairContext` — Read repair details — command: `repair ` - `ingest` — Upload app code (installed client only) — command: `upload [project-id] [--summary ]` - `ingestFiles` — Upload app files from chat (hosted endpoint only) - `ingestAttachment` — Upload attached file (hosted endpoint only) - `setFramework` — Confirm app framework — command: `set-framework ` - `detect` — Detect app type — command: `detect ` - `scan` — Run safety check — command: `scan ` - `deploy` — Deploy app — command: `deploy [--database] [--region americas|emea|apac] [--summary ]` - `status` — Check deployment status — command: `status ` - `getBuildLogs` — Read build log — command: `buildLogs [--deployment ]` - `getRuntimeLogs` — Read runtime log — command: `runtimeLogs [--deployment ]` - `listEnv` — List keys & settings (names only) — command: `envMetadata ` - `listDeployments` — List versions — command: `deployments ` - `rollback` — Restore an earlier version — command: `rollback --confirm` - `projectDelete` — Delete app — command: `project-delete --confirm` - `manageEnvironment` — Open Keys & settings — command: `environment ` - `setPublicEnv` — Save a public setting (installed client only) — command: `env-set |--from-file [--scope production|preview|development]... [--confirm]` - `deletePublicEnv` — Remove a public setting (installed client only) — command: `env-delete --confirm` - `databaseStatus` — Read database status — command: `database-status ` - `databaseCreate` — Create database — command: `database-create --confirm [--region americas|emea|apac]` - `databaseReconcile` — Check database progress — command: `database-reconcile ` - `databaseDelete` — Delete database — command: `database-delete ` - `databaseRestore` — Bring back archived database — command: `database-restore ` - `databaseArchiveDownload` — Download database archive — command: `database-archive-download ` - `databaseKeep` — Keep database — command: `database-keep ` - `databaseBackups` — List database backups — command: `database-backups ` - `databaseRestoreRequest` — Request database restore — command: `database-restore-request --confirm [--note ]` - `appAuthStatus` — Read app sign-in setup — command: `app-auth-status ` - `appAuthConfigure` — Turn on Google sign-in — command: `app-auth-configure --confirm` - `appAuthEmailStatus` — Read sign-in email setup — command: `app-auth-email-status ` - `appAuthEmailConnect` — Connect sign-in email domain — command: `app-auth-email-connect --confirm` - `appAuthEmailDisconnect` — Disconnect sign-in email domain — command: `app-auth-email-disconnect --confirm` - `appUsersList` — List app users — command: `app-users [--offset ]` - `appUsersRemove` — Remove app user — command: `app-users-remove --confirm` - `appUsersAdd` — Add app user — command: `app-users-add --confirm` - `appUsersSetSignupMode` — Set who can sign up — command: `app-users-signup --confirm` - `domainConnect` — Connect domain — command: `domain-connect ` - `domainVerify` — Verify domain — command: `domain-verify ` - `domainAuthorize` — Ask DNS provider for access — command: `domain-authorize --provider cloudflare [--zone ]` - `domainAuthorizationStatus` — Check DNS provider approval — command: `domain-authorization-status [--wait]` - `domainRelease` — Disconnect domain — command: `domain-release --confirm` - `domainAuthorizationRevoke` — Stop Tofu adding DNS settings — command: `domain-authorization-revoke --confirm` - `siteAnalytics` — Read site analytics — command: `site-analytics [--days 1-90] [--time-zone ]` - `setSiteAutoInject` — Auto-add analytics line — command: `site-auto-inject --confirm` - `siteChecks` — Read uptime checks — command: `site-checks ` - `setSiteCheckEmails` — Turn outage emails on or off — command: `site-check-emails --confirm` - `githubStatus` — Read GitHub status — command: `github-status ` - `githubSyncDisable` — Turn off automatic updates — command: `github-sync-disable ` - `domains` — List domains — command: `domains ` - `domainGuidance` — Read DNS guidance — command: `domain-guidance ` - `domainShop` — Search domain names (installed client only) — command: `domain-shop [name ...] [--refresh ]` - `domainBuy` — Prepare domain checkout (installed client only) — command: `domain-buy ` - `domainOwned` — Read owned domains — command: `domain-owned` - `domainVerificationResend` — Send domain confirmation again — command: `domain-verification-resend ` - `domainRecords` — Read DNS records — command: `domain-records [--zone-file]` - `domainRecordAdd` — Add DNS records — command: `domain-record-add --confirm [--priority ] [--ttl ]` - `domainRecordDelete` — Delete a DNS record — command: `domain-record-delete --confirm` - `renameProject` — Rename app — command: `rename-project ` - `hostingStatus` — Read plan & billing (installed client only) — command: `hosting-status` - `account` — Read connected account (hosted endpoint only) - `reportProblem` — Report a problem to Tofu — command: `report-problem [project-id] --note --confirm [--tool ] [--status ] [--reference ] [--no-app-details]` - `appPaymentsStatus` — Read app payments (installed client only) — command: `app-payments-status ` - `appPaymentsConnect` — Get the link to connect payments (installed client only) — command: `app-payments-connect [--replace-test-connection]` - `appPaymentsSetup` — Set up payment events (installed client only) — command: `app-payments-setup --confirm [--secret-name ] [--event ]...` - `appPaymentsLinkCreate` — Create a payment link (installed client only) — command: `app-payments-link-create --confirm [--every day|week|month|year] [--interval-count ] [--env-name ] [--description ] [--after-completion ] [--idempotency-key ]` - `appPaymentsDisconnect` — Disconnect app payments (installed client only) — command: `app-payments-disconnect --confirm [--deactivate ]...` ## Plans The Free plan and the Pro plan are both open to everyone. Prices are in US dollars, billed monthly. | | Free | Pro | | --- | --- | --- | | Price | $0 | $9.99/mo | | Apps | One static site at a time | Up to 5 apps at a time | | What it runs | Static sites and supported Vite builds | Framework builds, server code and containers | | Size limit | Published site: 500 files, 10 MB | Upload: up to 50 MB | | Uploads per day | 20 | 50 | | Deployments per day | 20 | 50 | | Own app web address | Yes | Yes | | Works with any coding agent | Yes | Yes | | Deployment history and rollback | Yes | Yes | | First-party analytics | Yes | Yes | | Managed database | No | One included | | Own domain, with HTTPS | No | Yes | | GitHub push-to-deploy | No | Yes | | Google sign-in and sign-up email for the app | No | Yes | | Built-in repair | With usage limits | With usage limits | Additional databases are coming soon. Domain purchases and renewals are separate. Team is coming soon, and Team and Enterprise are arranged with Tofu: https://trytofu.ai/pricing, hello@trytofu.ai. ## What Tofu does not do - Payments for an app: they go into the owner's own Stripe account, connected through Tofu's Stripe app with the `appPayments*` tools (on the installed client, account by account as Tofu opens it); Tofu holds no funds, takes no fee and writes no checkout code into an app, and no tool reaches refunds, disputes, payouts or buyers' details. - Anything resident: a background worker, a queue consumer, an always-on scheduler or a non-HTTP service has no path through Tofu, on any plan; Tofu hosts request-driven web apps. - Migrations and a SQL console: Tofu runs neither; an app's own migration step runs in its build. - Preview deployments: GitHub updates follow one branch and one app root per project. - Money, secrets and the repository grant over a connection: a connection cannot buy, renew or transfer a domain, submit a payment, read domain owner details, an environment value or a database password or connection string, change the plan or billing, or import a repository from GitHub. Those stay with the person, in their browser. - A narrower grant: a connection covers the account's projects; it is not narrowed to one app or to reading only. - Built-in repair over a connection: starting or applying the dashboard's repair proposals is not reachable; `repairContext` gives the agent a brief to fix the app's own code instead. ## Links - [Agent setup](https://trytofu.ai/agent): the setup prompt for each agent, the browser approval, everything a connection can do, and the agents it works with - [Connect your agent](https://trytofu.ai/docs/agent): the installed client, its sign-in and every tool it offers - [Use Tofu in Claude or ChatGPT](https://trytofu.ai/docs/chat): adding Tofu to a chat app by its address, the approval, and what chat cannot do - [Pricing](https://trytofu.ai/pricing): the plans side by side, line by line - [Docs](https://trytofu.ai/docs): how one delivery goes from code to a live app - [Deploy an app](https://trytofu.ai/docs/deploy): uploads, the safety check, deploys, versions and rollback - [Database](https://trytofu.ai/docs/database): the managed database, its settings and its limits - [Domains](https://trytofu.ai/docs/domains): connecting a domain the person owns - [Features](https://trytofu.ai/features): hosting, the managed database, domains, sign-in and email, analytics, and the agent connection - [Security](https://trytofu.ai/security): how sign-in, keys, the safety check and an agent's authority work, and their limits - [Terms](https://trytofu.ai/terms): the Terms of Service - [Privacy](https://trytofu.ai/privacy): the Privacy Policy - Contact: hello@trytofu.ai - The dashboard: https://app.trytofu.ai/dashboard, where the person signs in, approves a connection, enters secret values and manages the plan