DocumentaçãoCódigo
Disponível a partir do plano Builder

Linha de comando e chaves

Traga a definição do seu projeto para o disco, rode o app na sua máquina e publique de volta, sem sair do terminal.

Custo em créditos: nenhum passo deste guia consome crédito de IA.

A linha de comando da Fabapp é o mesmo projeto que você constrói no Studio, visto de outro lugar. Ela não é um produto separado nem um app diferente: pull traz os arquivos de definição para a sua pasta, push devolve o que você editou, e dev roda o app localmente no mesmo template que a plataforma usa para publicar.

Ela vem junto com o servidor MCP, que é como o Claude Code, o Cursor e outros assistentes leem e escrevem no seu projeto.

O que você precisa

  • Node 20 ou mais novo. Confira com node --version.
  • O plano Builder ou superior. A linha de comando é liberada a partir do Builder. Se o seu plano ainda não inclui, a tela de Chaves e CLI mostra o que muda e leva direto para a assinatura.

Nada mais. A ferramenta não tem uma única dependência: ela guarda uma credencial e conversa com a sua conta, e cada pacote no caminho poderia alcançar as duas coisas.

Autorizando esta máquina

Você nunca cria uma chave à mão. Quem cria é o comando de login:

npx @fabappai/cli login

Ele abre o navegador numa página da Fabapp com um código curto. Você confere que o código na tela é o mesmo que apareceu no terminal, autoriza, e pronto: a máquina fica conectada. Em servidor ou CI, sem navegador, use --no-open e abra o endereço manualmente.

Isso é o fluxo de dispositivo, e ele existe por um motivo bem concreto: uma chave que você copia e cola passa por lugares onde chaves não deveriam passar, como o histórico do shell, um canal de chat ou um arquivo de configuração que acaba num repositório. Aqui a chave nasce já dentro da sua máquina e nunca é exibida.

Onde a credencial fica

No chaveiro do sistema operacional. Quando a máquina não tem chaveiro, ela vai para um arquivo com permissão 0600, e o comando diz que foi para lá. Uma ferramenta que silenciosamente escolhe o lugar pior ensina você a achar que é sempre seguro.

Permissão de leitura ou de escrita

Por padrão, o login pede permissão de leitura e escrita. Para uma máquina que só precisa consultar, peça menos:

npx @fabappai/cli login --scopes "read"

Uma credencial só de leitura não enxerga os comandos de escrita, nem no terminal nem no servidor MCP. Anunciar uma operação que vai responder 403 é pior do que não anunciar: o assistente tenta, falha, e tenta de novo com outros argumentos, porque a recusa parece um problema com o pedido e não com a permissão.

O primeiro projeto no disco

Se o projeto ainda não existe, comece pelo terminal mesmo:

npx @fabappai/cli create "Meu app"

Ele cria o projeto e a primeira tela, e já amarra a pasta atual a ele. Era o último passo que só dava para fazer no navegador. Se o projeto já existe, amarre pelo id:

npx @fabappai/cli link <id-do-projeto>
npx @fabappai/cli pull

O link amarra a pasta atual a um projeto, conferindo o seu acesso antes de escrever qualquer coisa. O pull traz os arquivos de definição: fab.schema.json (as entidades e os campos), fab.automations.json, fab.settings.json, fab.connectors.json e o fab.config.json de cada tela.

Edite, e devolva:

npx @fabappai/cli push

Rodando na sua máquina e publicando

npx @fabappai/cli dev

Na primeira vez, o dev baixa o app e monta uma área de trabalho em .fabapp/workspace com o mesmo template que a plataforma usa para publicar, instala as dependências e sobe o Vite. Nas vezes seguintes ele reaproveita o que já está lá. Use --app <tela> quando o projeto tiver mais de uma tela, e --port para trocar a porta.

Edite o que está em src/, veja no navegador, e publique:

npx @fabappai/cli deploy

O deploy faz duas coisas, nessa ordem: sobe o que você mudou e só então publica. A ordem importa. Publicar antes de subir publicaria o que está no servidor, o comando pareceria ter funcionado e o seu trabalho ficaria para trás. Se quiser subir sem publicar, para revisar no Studio antes, use --no-publish.

Bibliotecas e plugins

Instalar uma biblioteca funciona do jeito que você espera: npm install <pacote> dentro de .fabapp/workspace, e o deploy leva junto os pacotes que você acrescentou desde que a área de trabalho foi montada. Qualquer pacote que rode no navegador serve.

Três coisas ficam de fora, e o deploy avisa antes de subir:

  • A versão dos pacotes da plataforma. React, Vite, Tailwind e os componentes Radix vêm sempre na versão da plataforma, porque o SDK e os componentes prontos foram feitos em cima dela. Trocar a versão aqui não muda nada no app publicado.
  • Configuração de build. O vite.config.ts, o index.html e o tsconfig são da plataforma e voltam ao original a cada publicação. Um postcss.config.js, um tailwind.config.js ou uma linha @plugin num arquivo CSS não rodam no build.
  • Arquivos que não são texto. O código do app é texto UTF-8, no servidor e no build. Uma imagem, uma fonte ou um áudio em public/ fica em casa e o deploy diz qual é; suba pelo Studio (Marca ou o storage do app) e referencie pela URL. Um logo vetorial pode ficar no código como .svg.
  • Pacotes que só funcionam em servidor, como drivers de banco de dados ou bibliotecas que precisam de chave secreta. O app roda no navegador de quem visita; esse código vai numa função de backend.

Plugins de build vêm de uma lista. Um plugin roda código dentro do build, então a plataforma só liga os que ela revisou: para o Tailwind, @tailwindcss/typography (textos longos), tailwind-scrollbar, tailwindcss-safe-area (o entalhe do celular) e tailwindcss-motion (animações); para o Vite, vite-plugin-svgr (SVG como componente), vite-plugin-node-polyfills, @mdx-js/rollup (páginas em MDX), vite-plugin-wasm e vite-plugin-glsl. Para ligar um deles, é só instalar o pacote. A plataforma registra o plugin com a configuração dela, e o dev faz a mesma coisa na sua máquina, então o que você vê localmente é o que vai ao ar.

O que ela não faz, de propósito

Não apaga. Nem no pull nem no deploy. Um arquivo que sumiu da sua pasta é reportado, nunca removido do app. A sua cópia pode estar velha em relação ao servidor (a IA pode ter editado o app no Studio enquanto isso), e apagar lá por causa de uma ausência aqui destrói trabalho que ninguém pediu para gerenciar.

Não sobrescreve o que você editou. O dev monta a área de trabalho uma vez; nas execuções seguintes ele compara e avisa quando o template mudou, em vez de passar por cima. Reconstruir é decisão sua (--reset), e ele avisa que isso apaga suas edições.

Não envia o que não é seu. O deploy manda só o que você mudou. Os componentes da plataforma, o SDK e o esqueleto do app ficam onde estão.

Não guarda credencial de integração. Os arquivos fab.connectors.json e fab.integrations.json são só de leitura: eles dizem o que o projeto tem conectado, para que um assistente saiba que existe e quais operações chamar, e nunca a credencial. Conectar e rotacionar acontece na plataforma.

Usando com Claude Code e outros assistentes

O servidor MCP usa a credencial que o login já guardou. Ele nunca pede um segredo e nunca mostra um.

{ "mcpServers": { "fabapp": { "command": "npx", "args": ["-y", "@fabappai/cli", "mcp"] } } }

Esse bloco serve para a maioria dos clientes. O que muda é onde ele mora:

Cliente Onde colocar
Claude Code claude mcp add fabapp -- npx -y @fabappai/cli mcp, ou o bloco mcpServers no ~/.claude.json
Aplicativo do Claude o bloco mcpServers no claude_desktop_config.json
Cursor .cursor/mcp.json no projeto, ou ~/.cursor/mcp.json para todos eles
VS Code (Copilot) .vscode/mcp.json
Windsurf o arquivo de configuração de MCP, na pasta do Codeium
Cline / Roo o arquivo que o próprio painel de MCP da extensão abre
Zed o bloco de context servers do settings.json
Codex CLI o config.toml dele, que declara o mesmo comando em TOML
opencode o bloco mcp do opencode.json, como servidor local rodando esse comando
Antigravity a configuração de MCP, pelo painel de MCP do próprio editor

O comando é a parte nossa e não muda. O lugar é decisão de cada cliente e muda de versão para versão: quando esta tabela discordar da documentação do seu cliente, quem está certo é ela.

A ferramenta mais importante é a fabapp_read_definition: sem o schema em mãos, um id de modelo errado responde 404 e um campo inventado responde 422. É a primeira coisa que um agente deveria chamar.

O que o assistente enxerga depende da permissão que você concedeu: uma credencial só de leitura não recebe as ferramentas de escrita. E a fabapp_write_definition se recusa a rodar antes de a fabapp_docs ter sido chamada na mesma conversa, porque um schema escrito sem o contrato inventa tipo de campo e regra de acesso, e as duas coisas falham em silêncio.

Vendo e revogando as máquinas conectadas

No painel, abra Perfil e vá em Chaves e CLI. A tela lista cada máquina autorizada com o nome que ela informou, a permissão que recebeu e quando foi usada pela última vez.

Revogar é imediato e vale para o servidor inteiro: a máquina revogada para de funcionar na próxima chamada, mesmo que a credencial continue no disco dela. O caminho contrário não é verdade: rodar logout numa máquina esquece a credencial ali, e ela continua válida no servidor até ser revogada aqui. Quando um notebook some, é esta tela que resolve, não o logout.

Quando alguma coisa não funciona

"Plano não inclui a linha de comando". O login só emite credencial a partir do Builder. A tela de Chaves e CLI mostra o plano necessário.

O código do navegador não bate com o do terminal. Não autorize. Feche a página e rode o login de novo: os dois códigos são gerados no mesmo pedido e só divergem se você estiver olhando para uma autorização que não é a sua.

push reclama de um arquivo que o app não pode sobrescrever. Ele diz qual é. Isso é melhor do que salvar com um 200 e não mudar nada.

Outra API. FABAPP_API_URL troca o endereço base, que por padrão é https://api.fabapp.ai.

Abrir a Fabapp
Relacionados
Conhecendo o StudioCréditos: o que gasta, o que não gasta