Ligne de commande et clés
Amenez la définition de votre projet sur votre disque, lancez l'application sur votre machine et publiez-la sans quitter le terminal.
La ligne de commande Fabapp, c'est le même projet que celui que vous construisez dans Studio, vu d'ailleurs. Ce
n'est ni un produit à part ni une autre application : pull amène les fichiers de définition dans votre dossier,
push renvoie ce que vous avez modifié, et dev exécute l'application en local sur le même gabarit que celui
utilisé pour la publication.
Elle est livrée avec le serveur MCP, par lequel Claude Code, Cursor et d'autres assistants lisent et écrivent dans votre projet.
Ce qu'il vous faut
- Node 20 ou plus récent. Vérifiez avec
node --version. - Le plan Builder ou supérieur. La ligne de commande est ouverte à partir de Builder. Si votre plan ne l'inclut pas encore, l'écran Clés et CLI montre ce qui change et mène directement à l'abonnement.
Rien d'autre. L'outil n'a pas une seule dépendance : il détient une identification et parle à votre compte, et chaque paquet du graphe pourrait atteindre les deux.
Autoriser cette machine
Vous ne créez jamais de clé à la main. C'est la commande de connexion qui la crée :
npx @fabappai/cli login
Elle ouvre le navigateur sur une page Fabapp affichant un code court. Vous vérifiez que le code à l'écran est bien
celui affiché dans le terminal, vous autorisez, et la machine est connectée. Sur un serveur ou en CI, sans
navigateur, utilisez --no-open et ouvrez l'adresse vous-même.
C'est le flux d'appareil, et il existe pour une raison très concrète : une clé que l'on copie-colle passe par des endroits où une clé ne devrait pas passer, comme l'historique du shell, un canal de discussion ou un fichier de configuration qui finit dans un dépôt. Ici la clé naît à l'intérieur de votre machine et n'est jamais affichée.
Où vit l'identification
Dans le trousseau du système. Quand la machine n'en a pas, elle va dans un fichier en 0600, et la commande le
dit. Un outil qui choisit silencieusement le moins bon endroit vous apprend que c'est toujours sûr.
Permission de lecture ou d'écriture
Par défaut, la connexion demande la lecture et l'écriture. Pour une machine qui n'a qu'à consulter, demandez moins :
npx @fabappai/cli login --scopes "read"
Une identification en lecture seule ne voit même pas les commandes d'écriture, ni dans le terminal ni dans le serveur MCP. Annoncer une opération qui répondra 403 est pire que de ne pas l'annoncer : l'assistant essaie, échoue et recommence avec d'autres arguments, parce que le refus ressemble à un problème de requête et non de permission.
Le premier projet sur le disque
Si le projet n'existe pas encore, commencez depuis le terminal :
npx @fabappai/cli create "Mon app"
Il crée le projet et son premier écran, et lie le dossier courant à celui-ci. C'était la dernière étape qui ne pouvait se faire que dans le navigateur. Si le projet existe déjà, liez-le par son id :
npx @fabappai/cli link <id-du-projet>
npx @fabappai/cli pull
link rattache le dossier courant à un projet, en vérifiant votre accès avant d'écrire quoi que ce soit.
pull récupère les fichiers de définition : fab.schema.json (les entités et leurs champs),
fab.automations.json, fab.settings.json, fab.connectors.json et le fab.config.json de chaque écran.
Modifiez, puis renvoyez :
npx @fabappai/cli push
La faire tourner chez vous, et publier
npx @fabappai/cli dev
À la première exécution, dev télécharge l'app et assemble un espace de travail dans .fabapp/workspace sur le
modèle même avec lequel la plateforme publie, installe les dépendances et lance Vite. Ensuite il réutilise ce qui est
déjà là. Utilisez --app <écran> quand le projet en a plusieurs, et --port pour changer de port.
Modifiez ce qui est sous src/, regardez dans le navigateur, et publiez :
npx @fabappai/cli deploy
deploy fait deux choses, dans cet ordre : il envoie ce que vous avez changé, et seulement ensuite il publie.
L'ordre compte. Publier avant d'envoyer publierait ce qui est sur le serveur, la commande aurait l'air d'avoir
fonctionné, et votre travail resterait derrière. Pour envoyer sans publier, afin de relire dans le Studio d'abord,
utilisez --no-publish.
Bibliothèques et plugins
Installer une bibliothèque marche comme vous l'attendez : npm install <paquet> dans .fabapp/workspace, et le
deploy emporte les paquets que vous avez ajoutés depuis que l'espace de travail a été monté. Tout paquet qui
tourne dans un navigateur convient.
Trois choses restent en dehors, et le deploy vous prévient avant l'envoi :
- La version des paquets de la plateforme. React, Vite, Tailwind et les composants Radix sont toujours dans la version de la plateforme, parce que le SDK et les composants prêts à l'emploi reposent dessus. Changer la version ici ne change rien à l'app publiée.
- La configuration de build. Le
vite.config.ts, l'index.htmlet letsconfigappartiennent à la plateforme et reviennent à l'original à chaque publication. Unpostcss.config.js, untailwind.config.jsou une ligne@plugindans un fichier CSS ne s'exécutent pas pendant le build. - Les fichiers qui ne sont pas du texte. Le code de l'app est du texte UTF-8, sur le serveur comme dans le
build. Une image, une police ou un son dans
public/reste chez vous et ledeployle nomme ; envoyez-le depuis le Studio (Marque, ou le stockage de l'app) et référencez-le par son URL. Un logo vectoriel peut rester dans le code en.svg. - Les paquets qui ne marchent que sur un serveur, comme les pilotes de base de données ou les bibliothèques qui demandent une clé secrète. L'app tourne dans le navigateur du visiteur ; ce code va dans une fonction backend.
Les plugins de build viennent d'une liste. Un plugin exécute du code pendant le build, alors la plateforme n'active
que ceux qu'elle a vérifiés : pour Tailwind, @tailwindcss/typography (textes longs), tailwind-scrollbar,
tailwindcss-safe-area (l'encoche du téléphone) et tailwindcss-motion (animations) ; pour Vite,
vite-plugin-svgr (le SVG comme composant), vite-plugin-node-polyfills, @mdx-js/rollup (des pages en MDX),
vite-plugin-wasm et vite-plugin-glsl. Pour en activer un, il suffit d'installer le paquet. La plateforme
enregistre le plugin avec sa propre configuration, et le dev fait la même chose sur votre machine : ce que vous
voyez en local est ce qui part en ligne.
Ce qu'elle ne fait pas, volontairement
Elle ne supprime pas. Ni dans pull ni dans deploy. Un fichier disparu de votre dossier est signalé,
jamais retiré de l'application. Votre copie peut être en retard sur le serveur (l'IA a pu modifier l'application
dans Studio entre-temps), et supprimer là-bas à cause d'une absence ici détruit un travail que personne ne nous a
demandé de gérer.
Elle n'écrase pas ce que vous avez modifié. dev assemble l'espace de travail une fois ; ensuite il compare
et vous prévient quand le gabarit a changé, au lieu de passer par-dessus. Reconstruire est votre décision
(--reset), et il vous dit que cela efface vos modifications.
Elle n'envoie pas ce qui n'est pas à vous. deploy n'envoie que ce que vous avez changé. Les composants de la
plateforme, le SDK et la coquille de l'application restent où ils sont.
Elle ne détient aucune identification d'intégration. fab.connectors.json et fab.integrations.json sont en
lecture seule : ils disent ce que le projet a connecté, pour qu'un assistant sache que cela existe et quelles
opérations appeler, et jamais l'identification elle-même. Connecter et renouveler se fait sur la plateforme.
L'utiliser avec Claude Code et d'autres assistants
Le serveur MCP utilise l'identification que login a déjà rangée. Il ne demande jamais de secret et n'en montre
jamais.
{ "mcpServers": { "fabapp": { "command": "npx", "args": ["-y", "@fabappai/cli", "mcp"] } } }
Ce bloc convient à la plupart des clients. Ce qui change, c'est l'endroit où il vit :
| Client | Où le placer |
|---|---|
| Claude Code | claude mcp add fabapp -- npx -y @fabappai/cli mcp, ou le bloc mcpServers dans ~/.claude.json |
| Application Claude | le bloc mcpServers dans claude_desktop_config.json |
| Cursor | .cursor/mcp.json dans le projet, ou ~/.cursor/mcp.json pour tous |
| VS Code (Copilot) | .vscode/mcp.json |
| Windsurf | son fichier de configuration MCP, dans le dossier Codeium |
| Cline / Roo | le fichier qu'ouvre le panneau MCP de l'extension |
| Zed | le bloc context servers de settings.json |
| Codex CLI | son config.toml, qui déclare la même commande en TOML |
| opencode | le bloc mcp d'opencode.json, comme serveur local lançant cette commande |
| Antigravity | sa configuration MCP, depuis le panneau MCP de l'éditeur |
La commande est notre part et ne change pas. L'emplacement appartient à chaque client et bouge d'une version à l'autre : quand ce tableau contredit la documentation de votre client, c'est la documentation qui a raison.
L'outil qui compte le plus est fabapp_read_definition : sans le schéma sous la main, un mauvais identifiant de
modèle répond 404 et un champ inventé répond 422. C'est la première chose qu'un agent devrait appeler.
Ce que l'assistant voit dépend de la permission que vous avez accordée : une credential en lecture seule ne reçoit
pas les outils d'écriture. Et fabapp_write_definition refuse de s'exécuter avant que fabapp_docs ait été appelée
dans la même conversation, car un schema écrit sans le contrat invente des types de champ et des règles d'accès, et
les deux échouent en silence.
Voir et révoquer les machines connectées
Dans le panneau, ouvrez Profil puis Clés et CLI. L'écran liste chaque machine autorisée avec le nom qu'elle a donné, la permission qu'elle a reçue et sa dernière utilisation.
La révocation est immédiate et vaut pour tout le serveur : la machine révoquée cesse de fonctionner dès l'appel
suivant, même si l'identification est encore sur son disque. L'inverse n'est pas vrai : lancer logout sur une
machine oublie l'identification là, et elle reste valable sur le serveur jusqu'à sa révocation ici. Quand un
portable disparaît, c'est cet écran qui règle la question, pas logout.
Quand quelque chose ne marche pas
« Votre plan n'inclut pas la ligne de commande. » La connexion n'émet d'identification qu'à partir de Builder. L'écran Clés et CLI indique le plan nécessaire.
Le code du navigateur ne correspond pas à celui du terminal. N'autorisez pas. Fermez la page et relancez
login : les deux codes viennent de la même requête et ne diffèrent que si vous regardez une autorisation qui
n'est pas la vôtre.
push se plaint d'un fichier que l'application ne peut pas écraser. Il dit lequel. C'est mieux que d'enregistrer
avec un 200 sans rien changer.
Une autre API. FABAPP_API_URL change l'adresse de base, par défaut https://api.fabapp.ai.