# Tofu > Tofu (trytofu.ai) is a hosting and deployment service for apps built with AI tools. One account covers hosting, a managed Postgres database, sign-in, a custom domain, email to the app's users, analytics and payments into the owner's own Stripe account. This is Tofu's homepage for AI agents, in plain Markdown: who Tofu is for and how a person starts, how an agent connects, the loop that takes an app live, the plans, what Tofu does not do, every tool with its command, 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 at https://trytofu.ai/llms.txt (the address the llms.txt convention names). ## Who Tofu is for Tofu is for people who made an app with an AI tool and want it online, including people who do not write code. Tofu checks the app, puts it online on hosting Tofu manages, and keeps its code, settings, data and versions together. It writes the app's database, sign-in and email settings itself, so nothing is copied from one provider to another. 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. The Free plan costs $0, with no time limit: 1 app online, hosted with the code behind its pages, at its own web address or the person's own domain, with HTTPS. It includes a managed Postgres database, sign-in for up to 5 people for each app, email to the app's users, visitor analytics, a safety check on every update and every version kept. Payments in the app and roles for the app's people come with a paid plan. The Free plan and the paid plans are open to everyone. A person starts in one of two ways here: - From any coding agent: Tofu's setup message, copied on https://trytofu.ai and pasted into the agent the person already uses, asks the agent to install Tofu's client and connect it to the person's Tofu account, which the person approves once in their browser (the next section has the details). - From a chat app that adds tools by address, such as Claude or ChatGPT: Tofu's hosted MCP endpoint at https://app.trytofu.ai/mcp needs nothing installed, and the chat app opens Tofu's own sign-in, where the person approves the connection. ## Connect an agent Setting Tofu up starts with the person: the setup message's copy control on https://trytofu.ai and the setup for one agent on https://trytofu.ai/agent each copy 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.159 - Client: https://app.trytofu.ai/downloads/agent/tofu-agent.mjs, 2741015 bytes, SHA-256 7129a53dae58d1127e0ccb538fd0cf392284b54613c69349bf3034820ffa9be1 - Skill: https://app.trytofu.ai/downloads/agent/SKILL.md, 20094 bytes, SHA-256 6c1d659fcea56ac1ff082bd67cd3340529a2534d8d3ef5d04230f3bc4e6fca73 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 30 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: [Use Tofu in Claude or ChatGPT](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, and for every tool beyond the 13 its MCP server loads by default, whose own description `help ` prints. The installed skill is a short core that says which of its guides to read before each action, and the same command line prints them: `guide` lists the guides, and `guide ` prints one. 1. Sign-in: `connectionStatus` (command `connection`) reuses a saved sign-in; without one, `login` (command `login`) starts one on https://app.trytofu.ai for the person to approve with its code in their browser, and `finishLogin` completes it. A connection lasts 30 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: a finding rated critical or high (a known shape of harm to other people, such as malware, phishing or a leaked key) stops the build, and a medium or low finding never does: one about the app's own data is the person's choice, so tell them what it means and let them choose; any other is a suspicious pattern to look at before going live. 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 a migration step in the app's build, if it has one, runs against the new database; where the app's Database page says so, Tofu applies the app's own supabase/migrations files before the build instead. It needs the person's agreement for that exact app and a database the account's plan includes. On the Free plan, the account's one app gets one database: on Tofu's shared static hosting once the app is live, created with `databaseCreate` (command `database-create`) and the person's agreement, and for any other Free app from its first deploy, through the deploy above. `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. ## Plans The Free plan and the paid plans are open to everyone. Prices are in US dollars, billed monthly. | | Free | Starter | Pro | | --- | --- | --- | --- | | Price | $0 | $5/mo | $20/mo | | Apps the account has online | 1 app | Up to 5 apps | Unlimited apps | | What it runs | The app's pages, and the code behind them | Same | Same | | Room for a project's files | A published site up to 500 files and 50 MB · for an app that runs on a server, send a project up to 50 MB | Send a project up to 50 MB | Same | | Uploads a day | 20 | 50 | 200 | | Deployments a day | 20 | 50 | 200 | | Sign-in for the app | Included · up to 5 people for each app | Included · up to 10 people for each app | Included · up to 50 people for each app | | Roles and permissions | No | Yes | Yes | | Email the app’s users | Yes | Yes | Yes | | Payments in the app | No | Yes | Yes | | Saved data, for the account's apps | 1 included | 5 included | 25 included | | Backups and recovery | Daily backups, kept 7 days · a database we archive comes back with one click | Same | Same | | Cloud coding agent | 30 minutes a day | 2 hours a day | Unlimited | | Unlimited AI tokens | Included | Same | Same | | Works with any coding agent | Yes | Yes | Yes | | Own web address and domain, with HTTPS | Yes | Yes | Yes | | Version history and one-click rollback | Yes | Yes | Yes | | See how many people visit the app | Yes | Yes | Yes | | GitHub push-to-deploy | Yes | Yes | Yes | | A safety check on every update | Yes | Yes | Yes | | The full report when an update fails | No | No | Yes | | The “Shipped live by Tofu.” line | At the bottom of the app's pages, where Tofu can add it | No Tofu line | Same | | Support | Help guides and email | Same | Same | | Paying | Free — no card needed | Monthly, cancel anytime | Same | | The account's data | Yours — download any time | Same | Same | When every included database is in use, deleting a database on an app’s Database page frees a place for another app. Domain purchases and renewals are separate. The plans are compared at https://trytofu.ai/pricing and anything larger is arranged with Tofu: hello@trytofu.ai. ### The free trial The Starter plan and the Pro plan each start with a 7-day free trial. The person starts it signed in on https://app.trytofu.ai/dashboard/plans by entering a card on Stripe's checkout page; nothing is charged until the trial ends, and they can cancel any time before then in Plan & billing. An agent cannot start it for them. Each account gets one free trial: an account that already had a paid plan or a free trial starts a paid plan without one. `hostingStatus` (command `hosting-status`) reads the plan, and its `message` names a running trial and when it ends. ## 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, on a paid plan, for an app that runs server code); 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. - A SQL console, or a migration of Tofu's own: Tofu has neither. It applies an app's own supabase/migrations files only where the app's Database page says so; otherwise the app's own migration step runs them 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 private 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. - Fix in builder over a connection: the dashboard's Fix in builder opens the Tofu builder in a browser and is not reachable; `repairContext` gives the agent a brief to fix the app's own code instead. ## Every tool, with its command The installed client has 94 tools, 13 by default: its MCP server loads `connectionStatus`, `login`, `finishLogin`, `projects`, `ingest`, `setFramework`, `detect`, `scan`, `deploy`, `status`, `manageEnvironment`, `databaseStatus`, `hostingStatus`, and the others with `TOFU_TOOLS=all`, which `setup --tools all` writes into the host's registration. The command after each tool is the same tool on the client's command line, loaded or not. 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 [--email
| --cancel]` - `finishLogin` — Finish Tofu sign-in (installed client only) — command: `login [--email
| --cancel]` - `projects` — List apps — command: `projects` - `repairContext` — Read repair details — command: `repair ` - `ingest` — Upload app code (installed client only) — command: `upload [project-id] [--summary ]` - `pullSource` — Download app code (installed client only) — command: `pull [folder]` - `galleryApps` — List apps to copy from the gallery (installed client only) — command: `gallery-apps` - `galleryCopy` — Copy an app from the gallery (installed client only) — command: `gallery-copy ` - `ingestFiles` — Upload app files from chat (hosted endpoint only) - `ingestAttachment` — Upload attached file (hosted endpoint only) - `ingestPublicRepository` — Import public repository (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|--no-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 ]` - `databaseMigrations` — Read Tofu-applied migrations (installed client only) — command: `database-migrations ` - `databaseMigrationsSwitch` — Switch Tofu-applied migrations (installed client only) — command: `database-migrations-switch --confirm` - `databaseMigrationsSkip` — Skip a migration file (installed client only) — command: `database-migrations-skip ...|--through --confirm` - `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` - `appUsersSetPrivate` — Open or close the app — command: `app-users-private --confirm` - `appUsersSendEmail` — Send a message to app users — command: `app-users-send-email --to ... --subject --text --confirm` - `appInvitesList` — List invite links — command: `app-invites ` - `appInvitesCreate` — Create an invite link — command: `app-invites-create [--days 1-30] --confirm` - `appInvitesRevoke` — Revoke an invite link — command: `app-invites-revoke --confirm` - `appSharingGet` — Read who can open an app — command: `app-sharing ` - `appSharingSetMode` — Choose who can open an app — command: `app-sharing-mode link|people|code [--email
]... --confirm` - `appSharingAddPeople` — Add people who can open an app — command: `app-sharing-add --email
... --confirm` - `appSharingRemovePeople` — Remove people who can open an app — command: `app-sharing-remove --email
... --confirm` - `appSharingNewCode` — Make a new access code — command: `app-sharing-new-code --confirm` - `appSharingSignOutEveryone` — Sign everyone out of an app — command: `app-sharing-sign-out --confirm` - `appSharingSetOpenPaths` — Keep paths open on a private app — command: `app-sharing-open-paths --path ...|--none --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 |--from-file --confirm [--priority ] [--ttl ]` - `domainRecordDelete` — Delete a DNS record — command: `domain-record-delete --confirm [--type --host --answer ]` - `builderLink` — Get the Continue in builder link — command: `builder-link ` - `renameProject` — Rename app — command: `rename-project ` - `hostingStatus` — Read plan & billing (installed client only) — command: `hosting-status [--after-payment]` - `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 ]...` - `appEmailStatus` — Read app email (installed client only) — command: `app-email-status ` - `appEmailSetup` — Set up app email (installed client only) — command: `app-email-setup --confirm` - `appEmailSetSending` — Pause or resume app email (installed client only) — command: `app-email-set-sending ` - `appEmailNewKey` — Give app email a new key (installed client only) — command: `app-email-new-key --confirm [--revoke-old]` - `appEmailRemove` — Remove app email (installed client only) — command: `app-email-remove --confirm` - `createTestCopy` — Make a test copy (installed client only) — command: `create-test-copy [--confirm] [--database|--no-database]` - `removeTestCopy` — Remove a test copy (installed client only) — command: `remove-test-copy [--confirm]` - `makeLive` — Make a test copy live (installed client only) — command: `make-live [--confirm --digest ] [--database|--no-database]` ## Links - [Agent setup](https://trytofu.ai/agent): the setup message 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, where the person signs in, approves a connection, enters secret values and manages the plan: https://app.trytofu.ai/dashboard