Command line and keys
Bring your project's definition to disk, run the app on your own machine, and publish it back without leaving the terminal.
The Fabapp command line is the same project you build in Studio, seen from somewhere else. It is not a separate
product or a different app: pull brings the definition files into your folder, push sends back what you edited,
and dev runs the app locally on the same template the platform publishes with.
It ships with the MCP server, which is how Claude Code, Cursor and other assistants read and write in your project.
What you need
- Node 20 or newer. Check with
node --version. - The Builder plan or above. The command line is unlocked from Builder on. If your plan does not include it yet, the Keys and CLI screen shows what changes and takes you straight to the subscription.
Nothing else. The tool has not a single dependency: it holds a credential and talks to your account, and every package in the graph could reach both.
Authorising this machine
You never create a key by hand. The login command creates it for you:
npx @fabappai/cli login
It opens your browser on a Fabapp page showing a short code. You check that the code on screen is the one printed
in your terminal, authorise, and the machine is connected. On a server or in CI, with no browser, use --no-open
and open the address yourself.
This is the device flow, and it exists for a very concrete reason: a key you copy and paste travels through places keys should not travel, such as shell history, a chat channel, or a config file that ends up in a repository. Here the key is born inside your machine and is never displayed.
Where the credential lives
In the operating system's keychain. When the machine has no keychain, it goes into a 0600 file, and the command
says so. A tool that quietly picks the worse place teaches you it is always safe.
Read or write permission
By default, login asks for read and write. For a machine that only needs to look, ask for less:
npx @fabappai/cli login --scopes "read"
A read-only credential does not even see the write commands, in the terminal or in the MCP server. Advertising an operation that will answer 403 is worse than not advertising it: the assistant tries, fails, and tries again with different arguments, because the refusal looks like a problem with the request rather than with the permission.
Your first project on disk
npx @fabappai/cli link <project-id>
npx @fabappai/cli pull
link ties the current folder to a project, checking your access before writing anything. pull brings down
the definition files: fab.schema.json (the entities and their fields), fab.automations.json,
fab.settings.json, fab.connectors.json, and each screen's fab.config.json.
Edit, and send it back:
npx @fabappai/cli push
To run the app on your machine before publishing:
npx @fabappai/cli dev
And to publish what you edited:
npx @fabappai/cli deploy
What it will not do, on purpose
It will not delete. Neither in pull nor in deploy. A file that disappeared from your folder is
reported, never removed from the app. Your copy may be stale relative to the server (the AI may have edited
the app in Studio meanwhile), and deleting there because of an absence here destroys work nobody asked us to
manage.
It will not write over what you edited. dev assembles the workspace once; on later runs it compares and
warns you when the template drifted, instead of overwriting. Rebuilding is your call (--reset), and it tells you
that this deletes your edits.
It will not push what is not yours. deploy sends only what you changed. The platform's components, the SDK
and the app's shell stay where they are.
It will not hold an integration credential. fab.connectors.json and fab.integrations.json are read-only:
they say what the project has connected, so an assistant knows it exists and which operations to call, and never
the credential. Connecting and rotating happens on the platform.
Using it with Claude Code and other assistants
The MCP server uses the credential login already stored. It never asks for a secret and never shows one.
{ "mcpServers": { "fabapp": { "command": "npx", "args": ["-y", "@fabappai/cli", "mcp"] } } }
The tool that matters most is fabapp_read_definition: without the schema at hand, a wrong model id answers 404
and an invented field answers 422. It is the first thing an agent should call.
Seeing and revoking connected machines
In the panel, open Profile and go to Keys and CLI. The screen lists every authorised machine with the name it reported, the permission it was granted, and when it was last used.
Revoking is immediate and applies server-wide: the revoked machine stops working on its next call, even with the
credential still on its disk. The other direction is not true: running logout on a machine forgets the
credential there, and it stays valid on the server until it is revoked here. When a laptop goes missing, this
screen is what settles it, not logout.
When something does not work
"Your plan does not include the command line." Login only issues a credential from Builder on. The Keys and CLI screen names the plan you need.
The browser code does not match the terminal one. Do not authorise. Close the page and run login again: both
codes come from the same request and only differ when you are looking at an authorisation that is not yours.
push complains about a file the app cannot overwrite. It says which one. That is better than saving with a
200 and changing nothing.
Another API. FABAPP_API_URL changes the base address, which defaults to https://api.fabapp.ai.