Docs

Connect your agent

Tofu’s client runs beside your coding agent and reaches the same authenticated control plane as the dashboard. You approve it once in your browser, and Tofu tells your agent to ask you before it puts your app online, adds a database, changes a domain, spends money, puts back an earlier version or deletes something.

Agent tools

  • login
  • finishLogin
  • connectionStatus

The local client

Tofu's client is a local stdio MCP bridge: your agent runs it, and it reaches the same authenticated control plane as the dashboard. Node.js 22 or newer is required.

Start on the setup page, pick your coding agent (Another agent covers any agent not listed), and paste the setup prompt into it. The prompt carries the size and SHA-256 of the client and the skill, and asks your agent to stop, running nothing, if a download does not match.

terminal · the install the prompt runsshell
# Private install (0700/0600), then the registration it emits for this client:
TOFU_URL=https://app.trytofu.ai node tofu-agent.mjs setup codex
codex mcp add tofu --env TOFU_URL=https://app.trytofu.ai --env TOFU_CLIENT=codex -- <absolute-node> <absolute-client> mcp

TOFU_URL selects the exact trusted origin (HTTPS, or loopback in development) and TOFU_CLIENT names the connection and grants nothing; setup emits argv and configuration without touching your agent settings, and installs the client and skill privately.

A saved credential alone is not proof of connection: the client checks with Tofu. When a host has not picked up a new MCP server in the session it is already in, the installed client’s own command line does the same work without one — see the skill’s Installation and CLI fallback — and the connection is there the next time that host starts.

Connect by URL

A host that takes a remote MCP server by its address connects to Tofu's hosted endpoint, with nothing to install.

the hosted endpointurl
https://app.trytofu.ai/mcp

Add the address as a custom connector or remote MCP server; your host then opens Tofu's own page, where you approve the connection, and nothing is pasted. In Claude, add Tofu from its listing in Claude's connector directory with Connect to Claude; to add it there by its address instead, open claude.ai's add-connector dialog with Tofu's name and address filled in (it does not fill them in on iPhone). The connection appears on the dashboard's Coding agent page, where Disconnect ends it.

Step by step for Claude and ChatGPT, with reconnecting and troubleshooting: Use Tofu in Claude or ChatGPT.

Signing in

A device flow: the agent starts it, you finish it in a browser where you are already signed in to Tofu.

  1. The agent asks for a code

    login returns a code and a same-origin approval URL.

  2. You approve the request you started

    In the browser, on Tofu, for the code your own agent printed.

  3. The agent finishes

    finishLogin (at most once every five seconds) completes it.

The connection lasts 30 days and is revoked on the dashboard's Coding agent page; only a hash of the credential is stored.

How to recognise a real approval. A real Tofu approval happens only at /dashboard/agent?code=, on the same Tofu address you signed in to, and only when a code arrives as XXXX-XXXX-XXXX printed by a coding agent you started yourself — or at /oauth/consent, on that same address, when an app you are connecting to Tofu sends you there and the page names where the sign-in returns. Refuse anything else. Nobody from Tofu, and no other site, needs an approval code, a password, a provider key or a token — and Tofu never asks for one.

Every tool

The same capabilities as the dashboard, grouped the way the dashboard is.

The bridge exposes 108 tools, 13 by default: your agent loads those, and reaches every other tool as a command of the same installed client, or loads all of them with TOFU_TOOLS=all, which setup <host> --tools all writes into the host's registration.

GroupTools
ConnectionconnectionStatus, login, finishLogin
Sourceprojects, ingest, pullSource, galleryApps, galleryCopy, builderLink, detect, setFramework, scan
Deploydeploy, status, listDeployments, getBuildLogs, getRuntimeLogs, repairContext, rollback, projectDelete
SettingslistEnv, setPublicEnv, deletePublicEnv, manageEnvironment
DatabasedatabaseStatus, databaseCreate, databaseReconcile, databaseDelete, databaseRestore, databaseArchiveDownload, databaseKeep, databaseBackups, databaseRestoreRequest, databaseMigrations, databaseMigrationsSwitch, databaseMigrationsSkip
Sign-inappAuthStatus, appAuthConfigure, appUsersList, appUsersAdd, appUsersRemove, appUsersSetSignupMode, appUsersSetPrivate, appInvitesList, appInvitesCreate, appInvitesRevoke, appSharingGet, appSharingSetMode, appSharingAddPeople, appSharingRemovePeople, appSharingNewCode, appSharingSignOutEveryone, appSharingSetOpenPaths
Sign-in emailappAuthEmailStatus, appAuthEmailConnect, appAuthEmailDisconnect, appUsersSendEmail
DomainsdomainConnect, domainVerify, domainAuthorize, domainAuthorizationStatus, domainRelease, domainAuthorizationRevoke, domains, domainGuidance, domainShop, domainBuy, domainOwned, domainVerificationResend, domainRecords, domainRecordAdd, domainRecordDelete
PaymentsappPaymentsStatus, appPaymentsConnect, appPaymentsSetup, appPaymentsLinkCreate, appPaymentsDisconnect
App emailappEmailStatus, appEmailSetup, appEmailSetSending, appEmailNewKey, appEmailRemove
Tofu AIappAiStatus, appAiSetup, appAiDisconnect
SandboxessandboxList, sandboxModelStatus, sandboxSetModel, sandboxSetAgent, sandboxCreate, sandboxDelete, sandboxStart, sandboxSleep, sandboxExec, sandboxChat, sandboxNewToken
Test copiescreateTestCopy, makeLive, removeTestCopy
TrafficsiteAnalytics, setSiteAutoInject
Site checkssiteChecks, setSiteCheckEmails
GitHubgithubStatus, githubSyncDisable
Hosting & app namerenameProject, hostingStatus
HelpreportProblem

listEnv returns names and scopes and no values. setPublicEnv and deletePublicEnv save and remove a public value — an address, a feature flag, a key meant to be public — and Tofu refuses one that looks like a secret; a secret is entered in the dashboard. Nothing here can change billing, buy or transfer a domain, or run SQL. In a zone the owner keeps elsewhere, DNS is written only through an approval the owner gave on the provider's own screen: domainAuthorize hands the owner that link, after which Tofu writes the records the connection asked for, and appAuthEmailConnect writes the six sending records into a zone only when that approval exists, reporting them to publish by hand otherwise. A domain bought through Tofu sits in Tofu's own registrar account, so domainRecordAdd and domainRecordDelete change the owner's records there, keeping a copy of the zone first; they never touch the records Tofu keeps for the site, and an agent never deletes a mail (MX) or verification (TXT) record.

builderLink answers whether the Tofu builder can open one of your apps and, when it can, hands your agent the link that opens it, for you to open yourself, signed in. It changes nothing, and when the builder cannot open that app, the answer says why. No coding agent is needed for the builder itself: Tofu builder is the other way in.

The five payments tools connect an app to the owner's own Stripe account through Tofu's Stripe app, on the installed client only. appPaymentsConnect hands the owner a link to Tofu's own page, which they open signed in, and Stripe's page installs the app in the account they choose — nobody types a key. appPaymentsSetup saves the secret the app verifies its payment events with, and appPaymentsLinkCreate makes a product, its price and a Payment Link in that account. The money goes to the owner's account, never through Tofu, and refunds, payouts and disputes stay in their Stripe Dashboard, where no tool reaches.

What it asks first

Your agent acts on your instructions, and Tofu tells it to ask for your agreement before it puts an app online, adds a database, changes a domain, spends money, puts back an earlier version or deletes something. Tofu can’t see your conversation with it, so it can’t check that the agent asked: connect only agents and apps you trust, and disconnect any of them on the Coding agent page.

These tools need a literal confirmed: true for the exact app or connection they act on — an earlier deploy, scan or upload is not that agreement, and without the literal nothing is sent:

ToolWhy it asks
databaseCreateIt spends Tofu's money.
rollbackIt changes which version answers the app's address.
domainRecordAddIt changes what a domain bought through Tofu answers, its mail included.
domainRecordDeleteThe domain stops answering that record; Tofu keeps a copy of the zone first, which the dashboard's Restore puts back.
databaseRestoreRequestIt asks a person at Tofu to put the whole database back to one of its daily backups, which loses everything saved after that backup.
databaseMigrationsSwitch, databaseMigrationsSkipWith the switch off, Tofu runs none of that app's setup steps, so a new database starts without their tables unless the app's build runs them; a skipped step never runs, even if it changes later.
projectDeleteIt removes that one app, takes its address offline for good, and deletes the app's managed database with it in the same request, for good and with everything saved in it; the delete itself keeps no copy (a copy Tofu already holds of a running database, such as the archive it was restored from, is untouched). To keep the data, ask Tofu (hello@trytofu.ai) for an export, or for a transfer to your own Supabase organization, before you delete the app. databaseDelete deletes the database alone and keeps the app.
appAuthConfigureIt writes into that one app's own auth service and changes how its users sign in.
appAuthEmailConnect, appAuthEmailDisconnectThey write that app's mail settings, its DNS zone and the provider's sending identity.
appUsersRemove, appUsersAdd, appUsersSetSignupMode, appUsersSetPrivateThey change who can get into that app: removing a person deletes their account and signs them out, adding one lets that address in, the switch decides whether anyone can sign up, and Private decides what the app's address answers everyone without a pass.
appUsersSendEmailIt hands the email provider one message for up to ten of that app's own people, from the app's own verified address, each getting their own copy — and a message that went out cannot be recalled.
appInvitesCreate, appInvitesRevokeThey hand one person a way into a private app — the first one to open the link, who then keeps in for up to 30 days — or turn a link off again.
appSharingSetMode, appSharingAddPeople, appSharingRemovePeople, appSharingNewCode, appSharingSignOutEveryone, appSharingSetOpenPathsThey decide who can open that app: choosing only people you list or anyone with a code puts Tofu's sign-in page in front of the whole app, people using it now included — Tofu doesn't email the people you add, so you send them the link — and the others take access away, cut off the old code, make everyone get back in, or leave exact paths open to anyone, for services like webhooks.
domainRelease, domainAuthorizationRevokeThe user sees that connection change.
setSiteAutoInjectIt decides what the next published site hands its visitors.
setSiteCheckEmailsTurning the emails off is how you stop hearing that your site is down.
deletePublicEnvThe app's next deploy is built without that value, so code that reads it may stop working.
reportProblemIt sends your own words to Tofu's team in your name, with your app's status attached; a person at Tofu reads every report, and Tofu emails you a receipt.
appPaymentsSetupIt saves the secret your app verifies its payment events with in that app's settings.
appPaymentsLinkCreateIt creates a product, its price and a Payment Link in your own Stripe account; a live link takes real payments at once, so the agent names the account, the amount, the currency and whether it repeats first.
appPaymentsDisconnectYour app stops hearing about payments; it deactivates only the Payment Links you name, and any other keeps taking payments.
appEmailSetupIt writes a key your app sends email with, and its sending address, into that app's settings; nothing is sent.
appEmailNewKeyIt gives the app a new key; the previous one keeps sending for seven days unless you ask for it to stop at once.
appEmailRemoveThe app stops sending email for good, and its email settings come out of the app.
appAiSetupIt makes your app its own Tofu AI key and writes it, hidden, into that app's settings with Tofu AI's address; asked to, it deletes a value of the app's own under the same name.
appAiDisconnectThe app's Tofu AI key stops working at once, and its two values come out of the app.
sandboxDeleteIt deletes that one sandbox for good, on the installed client only: its machine, every file and conversation in it, and its token.
sandboxNewTokenIt ends that sandbox's earlier token at once, so code that uses it stops being let in. On the installed client only, which saves the new token to a private file and never shows it in the chat.

deploy with database: true creates a database in the same call; the flag itself is that agreement, so it is sent only after you agreed to a database for that exact app. setPublicEnv asks for confirmed: true only to change a key that already holds a public value — its value or its scopes; saving a new one needs nothing more.

On the installed client only, createTestCopy, makeLive and removeTestCopy answer their plan without confirmed: true and act only with it, which Tofu tells the agent to send only once you agreed to that plan: a private test copy of a live server app, the version you tested there made the live app's, or the copy removed with its database for good. makeLive also names the check you agreed to by its digest, and asks whether the live app gets its own database when the copy has one.

databaseDelete and databaseRestore ask for the app's own name instead of a literal. The first removes one managed database this account owns — the data, the schema and the Supabase project behind it, permanently, and the delete keeps no copy (for an archived database, every copy Tofu holds for the app goes with it; a copy Tofu already holds for a running one, such as the archive it was brought back from, is untouched); the second puts an archived database back into a new one Tofu runs and pays for, which needs the account's plan to include a managed database for the app: the paid plans do, and so does the Free plan where Tofu offers its one database, for an app that is live. Both refuse a name that is not that app's own. databaseArchiveDownload hands the owner short-lived links to an archived database's stored copy — the data, its manifest and, when the archive carries the app's stored files, one tar of them — that work for about ten minutes, and changes nothing. databaseKeep is the Database page's Keep this database: it counts as use of that app's database, so an inactivity warning (databaseStatus's inactivity) ends. It works for a paying account. The Free plan's own database needs none: Tofu keeps it and never archives it for going unused. A database warned because a free trial ended is kept by starting a paid plan.

databaseBackups lists a running database's daily backups — one a day, kept for seven days — and changes nothing. databaseRestoreRequest asks a person at Tofu to put the database back to one of them: it emails the request and sends you a confirmation, and nothing changes until that person does the restore and emails you. Replying to the confirmation before then cancels it.

Get help

When something in Tofu is not working, tell Tofu’s team: from the dashboard, through your coding agent or AI app, or by email.

  • Report a problem in the dashboard. Signed in, choose Report a problem in the account menu at the foot of the sidebar, or open app.trytofu.ai/dashboard/report. Say what happened and pick the kind of problem; opened inside an app, the form adds that app’s status unless you untick Include my app’s details. A person at Tofu reads every report, and Tofu keeps it for 180 days.
  • Ask your coding agent or AI app to report it. It shows you the exact words first, and reportProblem sends them only once you agree, with your app’s status unless you leave it out. Tofu emails you a receipt: reply to it to add something or to withdraw the report. When Tofu cannot email one, its answer says so: write to us with the report’s reference instead.
  • Write to us. For a question, for anything that is not a problem in Tofu itself, when you cannot sign in, or when the report page or your agent says Tofu isn’t taking problem reports: hello@trytofu.ai.
  • A security vulnerability. Report it the way the security page’s Report a vulnerability describes; the same address is in /.well-known/security.txt.

What your agent cannot do

  • Stays with you. It 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 your plan or billing, or import a private repository from GitHub. Those stay with you.

  • Secrets are typed in the dashboard. manageEnvironment hands you the dashboard address for the app; no tool takes or returns a secret, and no tool returns any environment value. setPublicEnv takes a public value only.

  • GitHub needs your browser. Importing a private repository or turning automatic updates on uses your own GitHub session in the dashboard; an agent can read the state and turn updates off.

  • By URL, a narrower set. The hosted endpoint serves every tool except the device sign-in, the saved-credential check, the upload from your own disk, the download of an app’s code into a folder on it, the two tools that show a plan or prices, the one that leads to buying a domain and, for now, the tools that save public settings, connect payments, set up an app’s email, connect an app to Tofu AI, list or copy Gallery apps, read and change Tofu-applied migrations, or make, remove and make live a test copy. No sandbox tool is served there either.

  • Repairs happen in your code. repairContext hands your agent a read-only brief to fix a failed build in your code; no tool edits the app's code inside Tofu. builderLink says whether the builder can open the app, and when it can, hands you a link to open yourself.