Aller au contenu

Mon Garde-Manger

janvier 20266 min de lectureEn cours

L'applicationCode source

Au départ, je voulais juste un garde-manger sous la main : une page où je vois ce que j’ai en stock, où j’ajoute un ingrédient, où je filtre, et c’est tout.

Aujourd’hui, Mon Garde-Manger suit mon stock, frais ou congelé, et me prévient quand il en reste peu. Il range aussi mes recettes, que je suis étape par étape sur mon téléphone. Et surtout, Claude peut lire le stock et écrire dedans. L’application est en ligne sur my-kitchen.kevin-dev.com, et l’inscription est ouverte.

Pour en arriver là, il a fallu deux versions. J’ai utilisé la première pendant plusieurs mois, et c’est à l’usage que j’ai vu ce qui coinçait.

La première version, et sa corvée

Je l’ai commencée en janvier, en Next.js. L’inventaire et les recettes vivaient dans le localStorage du navigateur, sans compte. Un export et un import en JSON servaient de sauvegarde, et un bouton copiait l’inventaire en texte, pour le coller dans un assistant. Pour l’affichage des recettes, j’ai repris la façon dont Claude les présente dans son interface, adaptée à mon cas.

De ce bouton est né un petit skill pour Claude. Il prenait le texte du garde-manger et en tirait des recettes faisables avec ce que j’avais vraiment en stock, au format JSON, prêtes à être importées. C’est devenu ma façon principale de remplir l’application. Voilà la bibliothèque de cette première version, avec son bouton « Importer », et à droite le convertisseur d’unités, qui est toujours là.

La bibliothèque de recettes de la première version, avec trois recettes, le bouton « Importer » et le convertisseur d’unités à droite.

Le circuit était toujours le même. Je copiais l’inventaire, je le collais dans Claude, je récupérais le JSON et je l’importais. Après avoir cuisiné, je revenais dans l’application pour retirer à la main ce que je venais d’utiliser. Chaque étape est courte. Mises bout à bout, plusieurs fois par semaine, elles finissaient par peser plus que la cuisine elle-même. Et forcément, je le faisais de moins en moins.

L’assistant branché sur le garde-manger

En septembre, j’ai refait l’application pour supprimer cette boucle. La nouvelle version a un serveur MCP, le protocole qui laisse un assistant appeler des outils précis au lieu de passer par des fichiers. On ajoute l’adresse de l’application comme connecteur dans Claude, Claude Code ou ChatGPT, on se connecte, et l’assistant voit le garde-manger.

Chaque outil fait une seule chose, comme décompter d’un coup ce qu’une recette a utilisé. La liste est fixe, donc je sais exactement ce que l’assistant peut modifier.

Le skill a suivi. Il lit le stock lui-même, me demande ce que l’application ne peut pas savoir, comme le nombre de repas ou le moment où je vais cuisiner, puis me propose des pistes.

Claude lit le garde-manger, pose quatre questions sur les repas à préparer, puis propose cinq recettes faites avec le stock.

Une fois mon choix fait, il écrit les recettes dans ma bibliothèque. Il fait ensuite le compte de ce qu’elles utilisent, et me demande avant de le retirer du stock.

Claude annonce que les deux recettes sont dans Mon Garde-Manger, montre dans un tableau ce qu’elles utilisent et ce qu’il restera, puis demande s’il retire ces quantités du stock.

Je n’ai plus rien à lui coller, ni rien à importer.

Un compte, puis OAuth

Pour que l’assistant sache à qui appartient un garde-manger, il fallait des comptes. Les données sont dans une base PostgreSQL que seule l’application peut joindre, sur mon serveur, et elle est sauvegardée chaque jour. La première version ne stockait rien chez moi. Celle-ci stocke tout, et c’est à moi de m’en occuper.

Au début, l’assistant se connectait avec un jeton personnel, créé depuis l’espace compte, qu’il envoyait dans un en-tête. Un serveur OAuth me paraissait beaucoup de travail pour rien, puisque Claude acceptait très bien ce jeton. Moins d’un mois plus tard, Claude et ChatGPT n’acceptaient plus d’en-tête fixe sur leurs connecteurs. Ils cherchent un serveur OAuth à partir de l’adresse MCP, comme le demande la spécification.

L’application a donc le sien, avec oidc-provider. L’assistant ouvre une page de consentement dans le navigateur, j’accepte, et il ne voit ensuite que mon compte. L’espace compte liste les assistants connectés, et je peux couper l’accès de chacun. Les jetons personnels, je les ai supprimés, puisque plus aucun client ne les envoyait.

Le mode cuisine, sur deux écrans

C’est la partie de la première version que je tenais à garder telle quelle. On choisit une recette sur le PC, et on la suit sur le téléphone posé sur le plan de travail. Un code à six chiffres et un QR code s’affichent, on scanne, et le téléphone rejoint la session sans avoir besoin de compte. Les deux écrans avancent ensemble, une étape à la fois. Quand le minuteur d’une étape se termine, ça bipe et le téléphone vibre. L’écran reste allumé pendant toute la recette, parce qu’on a les mains prises. Voilà l’écran de la première version, sur l’étape du guanciale, avec son minuteur de cinq minutes et, en bas, celui des pâtes qui tourne encore.

Le mode cuisine de la première version, sur l’étape « Faire revenir le guanciale » avec son minuteur de cinq minutes, et en bas celui des pâtes, à 9 min 51.

Depuis, le minuteur de l’étape a sa propre barre, juste au-dessus des boutons. Sur une étape longue, il défilait avec le texte, et il fallait remonter pour le lancer.

Derrière, les deux appareils demandent l’état de la session au serveur toutes les demi-secondes. Le piège, c’était l’heure. Un téléphone peut avoir plusieurs secondes d’écart avec le PC, donc un minuteur ne garde que l’heure de son départ, prise sur l’horloge du serveur, et chaque appareil en déduit le temps qui reste. La session, qui vivait dans un Redis à part, est maintenant dans la même base que le reste. Ça fait un service de moins à faire tourner.

Une seule stack pour mes sites

J’ai profité de la refonte pour aligner ce projet sur kevin-dev.com, le site que vous lisez. Les deux tournent sur AdonisJS, Inertia et React 19, avec PostgreSQL, dans une image Docker déployée par Dokploy, et avec les mêmes outils de lint et de format.

Je maintiens ces sites seul, sur mon temps libre. Deux projets qui se ressemblent, c’est une seule façon de faire à connaître, et un correctif qui passe de l’un à l’autre. La première version, en Next.js, marchait bien, mais elle ne ressemblait à aucun de mes autres projets.

L’interface, elle, n’a pas bougé, avec le même thème « kraft rustique » et la même police manuscrite, pour que ça ressemble toujours plus à une fiche cuisine qu’à un tableur.

Travailler avec Claude

Les deux versions ont été écrites avec Claude Code, la première assez vite. Pour la deuxième, j’ai d’abord répondu à une longue série de questions fermées, sur les comptes, la base, le MCP et le déploiement, jusqu’à ce qu’il n’y ait plus rien à trancher. Le code a suivi, par couches, chacune déployable.

Où en est le projet

L’application est en ligne, et son code est public sur GitHub. Maintenant que l’assistant parle directement au garde-manger, mon inventaire est à jour.

Technologies utilisées