260913-recettes de Joplin vers MEALIE par Claude Mise en place le 2026-09-13. Mealie est utilisé tous les jours par toute la famille, mais renseigner une recette à la main est fastidieux : sections d'ingrédients, étapes, catégories, tags, photo. La procédure confie ce travail à Claude à partir d'une simple note Joplin. 1. La procédure, côté Julien Capturer la recette dans une note Joplin, dans le carnet « A transcrire dans Mealie » — texte libre, copié-collé d'un site, clip web, réponse d'un assistant, dictée, photos du téléphone. Aucune mise en forme n'est exigée. Publier la note : clic droit sur la note → Publier la note → copier le lien ( https://joplin.juxjux.ovh/shares/xxxxxxxx). Coller le lien à Claude. C'est tout. Le carnet est le garde-fou (demandé par Julien le 2026-09-13) : publier une note ne vaut pas consigne, seul le carnet le fait. Une note publiée pour une autre raison — un résumé de match de hockey, une liste, un article — est refusée par le script même si Claude se trompe sur son contenu. La page publiée ne dit pas dans quel carnet vit la note ; la base Joplin Server sur le VPS le sait ( items.jop_parent_id, interrogée par SSH). Si la base est injoignable, le doute vaut refus. Claude lit la note, la structure, crée la recette avec sa photo, et rend le lien Mealie. En retour il signale ce qu'il a dû décider seul (catégorie ou tag créé, quantités absentes, photo de remplacement), pour que Julien puisse corriger d'un mot. Où est le travail de Claude Une note de recette est rarement au carré : un copié-collé de site mêle recette et bavardage ; une réponse d'assistant argumente (« je choisirais l'espadon… ») au lieu de lister ; une photo de carnet manuscrit ne dit rien à un parseur. Un script ne peut pas trier ça. Claude, lui, lit la note comme un lecteur et en tire : Champ Mealie Ce que Claude en fait Nom reformulé en titre de recette (le titre Joplin est souvent une note de travail) Description l'esprit du plat, les choix qui comptent — pas les étapes Personnes, temps repris s'ils sont dans la note, estimés sinon (et signalés comme estimés) Ingrédients listés en sections ( Marinade, Sauce, Riz coco…) — Mealie les affiche titrées Étapes rédigées à l'impératif, titrées, sans le bavardage Notes ce qui ne rentre ni dans les ingrédients ni dans les étapes : variantes, choix du poisson, conseils Catégories cuisine / pays / type de plat — c'est la convention de la base (Turquie, Italia, Poisson, Dessert…) Tags ingrédients principaux — c'est l'autre convention de la base (Courgettes, Feta, Lait de coco…) Source l'URL de la note Joplin, dans le champ URL d'origine de Mealie Image la première vraie photo de la note ; les autres en photos secondaires Claude réutilise les catégories et tags existants avant d'en créer, et signale toute création. Les temps sont en minutes nues (« 30 »), comme le reste de la base. 2. L'outillage Tout est dans Jux-scripts/Mealie-Recettes/ et Jux-scripts/MCP/, stdlib Python seule — rien à installer, réplicable sur toutes les machines par Syncthing. joplin_mealie.py — la mécanique py -3.12 joplin_mealie.py lire # texte + images, avec verdict "photo ou pas" py -3.12 joplin_mealie.py creer fiche.json [--simulation] # creation, image, photos secondaires py -3.12 joplin_mealie.py image # poser / remplacer l'image principale py -3.12 joplin_mealie.py organiseurs # categories et tags existants py -3.12 joplin_mealie.py supprimer lire annonce d'abord le carnet de la note ( A TRANSCRIRE ou PAS a transcrire), puis transforme le bloc
de la page publiée en texte proche du markdown (titres, listes, gras, tableaux), remplace chaque image par un marqueur [image N] et les liste à part avec leurs dimensions. Une image de moins de 200 px de côté est déclarée PAS une photo : c'est un favicon ou une vignette, jamais un plat. creer prend une fiche JSON (celle que Claude rédige), refuse si la note de source n'est pas dans le carnet attendu ( --forcer uniquement sur demande explicite), puis fait le reste : POST /api/recipes (nom) → PUT /api/recipes/{slug} (corps complet) → PUT /api/recipes/{slug}/image (multipart) → POST /api/recipes/{slug}/assets pour les photos secondaires. Catégories et tags sont résolus par nom, insensible à la casse et aux accents, créés s'ils manquent. Refuse un doublon de nom sauf --doublon-ok. --simulation montre le corps sans rien écrire. Le carnet se lit par plink (Windows, clé d'hôte épinglée) ou ssh (Linux, clé attendue) : psql dans le conteneur joplin-db, jointure shares → items (note) → items (carnet), titre dans le JSON de content. Nom du carnet surchargeable par MEALIE_CARNET. Fiche JSON minimale : { "nom": "Brochettes d'espadon satay, riz coco", "description": "…", "personnes": 4, "temps_preparation": "25", "temps_cuisson": "20", "temps_total": "60", "categories": ["Asiatique", "Poisson"], "tags": ["Espadon", "Lait de coco", "Cacahouetes"], "ingredients": [{"titre": "Marinade", "items": ["2 c. à soupe de sauce soja", "…"]}, "600 g d'espadon"], "etapes": [{"titre": "Marinade", "texte": "…"}, "Servir avec le riz."], "notes": [{"titre": "Quel poisson ?", "texte": "…"}], "source": "https://joplin.juxjux.ovh/shares/…", "image": "https://joplin.juxjux.ovh/shares/…?resource_id=…", "images_secondaires": ["https://…"] } mcp_mealie.py — les mêmes gestes en outils MCP Enregistré le 2026-09-13 dans ~/.claude.json du poste julie (projet Claude-pcelio+jux), comme les autres MCP Python : command = chemin absolu de python.exe, args = chemin du script. 13 outils : Joplin → Mealie : lire_note_joplin, creer_recette, poser_image, poser_photo_secondaire consultation : lister_recettes, lire_recette, lister_organiseurs, supprimer_recette au quotidien : plan_repas, ajouter_au_plan, listes_courses, ajouter_courses, recette_vers_courses Le MCP importe joplin_mealie.py depuis le dossier voisin : une seule implémentation, deux façons de l'appeler (le CLI reste utile quand le MCP n'est pas chargé, ou depuis Ubuntu / la VM). 3. Première recette réelle — l'exemple du 2026-09-13 Note : https://joplin.juxjux.ovh/shares/EqODt1SvmX6OKzdr867bpZ — Brochette de poisson Satay sauce. Une réponse d'assistant collée telle quelle : classement de cinq poissons avec des étoiles, « je choisirais l'espadon », marinade en liste, sauce satay sans quantités, riz coco et accompagnement en prose. Résultat : Brochettes d'espadon satay, riz coco — 5 sections d'ingrédients, 5 étapes titrées, 2 notes, catégories Asiatique + Poisson, 8 tags dont un créé ( Espadon), photo. Le classement des poissons est allé dans une note, pas dans les étapes. Ce qu'a révélé ce premier passage : La seule image de la note faisait 16 × 16 px : le favicon d'un site cité par l'assistant, pas une photo. Sans le contrôle des dimensions, Mealie aurait reçu un carré illisible. D'où la règle des 200 px. Sans photo dans la note, Claude en cherche une libre de droits sur Wikimedia Commons (API commons.wikimedia.org, licence lue dans les métadonnées). Ici : Brochette d'espadon à Georgioúpoli (Crète), CC0. Elle est signalée comme provisoire dans une note de la recette, à remplacer par une photo du plat. Wikimedia refuse le User-Agent vide de urllib (HTTP 403) et n'accepte que des tailles de vignette fixes ( 1280px-, pas 800px- → HTTP 400 « Use thumbnail sizes listed »). Le script envoie un User-Agent nommé. La note de Julien n'avait ni temps ni nombre de personnes explicites hors « pour 4 personnes / 600–700 g » : les temps ont été estimés (25 + 20, total 60 marinade comprise) et le sont dits. Deuxième recette — un clip web (même jour) Note Uhp5DRRLdhLh2IlmAv8Bkg : la page entière du blog L'instant nordique clippée dans Joplin — menus, encarts, articles liés, formulaire de commentaire, pied de page, 19 images dont 3 fois le logo. La recette des köttbullar tient au milieu. Résultat : Köttbullar, boulettes de viande suédoises à la crème — 3 sections d'ingrédients, 7 étapes titrées, photo de la poêle en principale, l'assiette en photo secondaire. Ce que Claude a dû arbitrer, consigné dans une note « Incohérences de la source » de la recette : la liste du site dit « 5 ml de lait » mais l'étape en met 4 cuillères à soupe (retenu) ; la sauce soja apparaît à la dernière étape sans figurer dans la liste (ajoutée) ; « 2 piments » est reproduit tel quel mais signalé comme douteux dans une recette suédoise ; nombre de personnes absent (4 pour 450 g, estimé). Le contrôle du carnet a fonctionné dans les deux sens le même jour : la note du pâté Lamourette, dans « Trucs et astuces », est refusée par creer. 4. Pièges relevés Un clip web embarque tout le site : navigation, articles liés, formulaire, 19 images. La recette est au milieu ; tout le reste est à ignorer, et les images du site ne sont pas toutes des photos du plat (logo, vignettes d'autres articles, portrait de l'auteur). Regarder les candidates avant de choisir. Une note publiée est publique — l'URL suffit, sans identifiant. Ne pas y mettre autre chose que la recette. Le champ URL d'origine de Mealie la garde : dépublier la note casse ce lien, sans effet sur la recette. Les images de la note se téléchargent par ?resource_id= sur l'URL du partage, anonymement. Les photos de téléphone arrivent en pleine taille (1 920 × 1 440, 500 Ko à 800 Ko) — Mealie les redimensionne lui-même. Mealie n'analyse pas les ingrédients : ils sont stockés en texte libre ( note / display), comme les 141 recettes existantes. Le champ title du premier ingrédient d'une section porte le titre de section — c'est ainsi que Mealie fait ses en-têtes. POST /api/recipes ne prend que le nom et renvoie le slug ; tout le reste passe par un PUT du corps complet relu ( GET puis mise à jour), sinon l'API efface ce qu'on n'a pas renvoyé. Les temps sont des chaînes libres dans Mealie. La base utilise des minutes nues (« 60 », « 30 ») — 31 recettes sur 141 n'en ont aucun. S'y tenir. 59 recettes sur 141 n'ont pas de catégorie au 2026-09-13 : les plus récentes ont été saisies vite. Rien n'empêche de les reprendre une par une avec lire_recette + mise à jour — chantier possible. Le CLI claude n'est pas dans le PATH du poste (application de bureau) : le MCP a été inscrit à la main dans .claude.json, sauvegarde .claude.json.bak-260913-mealie. Il faut relancer la session pour qu'il soit chargé. Piège d'atelier, sans rapport avec Mealie : l'outil Bash de Claude Code abîme les \x.. dans un heredoc Python — deux fichiers réparés en cours de route. Écrire les scripts avec l'outil d'édition, les exécuter avec Bash. 5. Identifiants Mealie : jubertrand@gmail.com / mot de passe dans CLAUDE.md (OAuth2 password, POST /api/auth/token, formulaire username/ password, jeton valable 48 h). Surchargeables par MEALIE_URL, MEALIE_USER, MEALIE_PASS.