Aller au contenu

Développement

  • Répertoireavenir_mcp/ — le serveur (voir Architecture)
    • …
  • Répertoiretests/ — tests unitaires, tests du protocole, de la documentation et d’hygiène
    • …
  • Répertoireevals/ — le plan de démonstration, une doublure de l’API YNAB, l’évaluation par agent
    • …
  • Répertoiredocsgen/ — génère la référence des outils, le catalogue des erreurs et les exemples
    • …
  • Répertoiredocs/ — ce site (Astro Starlight, anglais, français, espagnol, allemand, néerlandais)
    • …
  • AGENTS.md — le contrat des contributeurs, humains ou non
  • justfile — toutes les commandes ci-dessous
  • pyproject.toml, uv.lock — le projet Python, verrouillé
Fenêtre de terminal
git clone https://github.com/mathbeal/avenir-mcp && cd avenir-mcp
uv sync # Python 3.14 et les dépendances verrouillées
just check # tous les contrôles de la CI

just check lance, dans l’ordre de la CI :

Contrôle Commande Échoue quand
format ruff format --check un fichier n’est pas formaté
lint pylint la note est sous 10,00
ruff ruff check une docstring du paquet n’est pas au format Google ou omet un argument, la valeur de retour ou une exception levée ; les imports ne sont pas triés ; les contrôles de sécurité de bandit trouvent un motif risqué (TLS non vérifié, commande shell, mot de passe dans le code…)
docstrings pydoclint une docstring du paquet liste les arguments dans un autre ordre que la signature, donne un type que l’annotation donne déjà, ou se réduit à un résumé pour une fonction qui prend des arguments ou renvoie une valeur
Conditions de l’API YNAB pytest -m ynab_terms, python -m docsgen.terms une règle des conditions de l’API YNAB n’est pas respectée (nommage, mention mot pour mot, image officielle de YNAB, jeton réservé à son titulaire, limite de requêtes par heure), ou YNAB a changé ses conditions depuis la date vérifiée ; le badge du README l’affiche
dépendances deptry . le code importe un paquet que pyproject.toml ne déclare pas, ou en déclare un qu’il n’utilise pas
types mypy (strict) une erreur de type
tests pytest un test échoue, un avertissement est émis, ou la couverture des lignes ou des branches est sous 100 %
vocabulaire lexdrift check avenir_mcp --baseline lexdrift.lock un nouveau mot apparaît pour une idée déjà nommée
verrou uv lock --check uv.lock ne correspond pas à pyproject.toml

La CI lance aussi lychee sur chaque lien du README et de la documentation (just links, et chaque lundi, car une page ailleurs peut disparaître), gitleaks sur chaque commit de l’historique (just secrets, avec Docker), typos, zizmor sur les workflows, reuse lint (chaque fichier indique son copyright et sa licence), deux constructions du wheel et du sdist qui doivent être identiques au bit près (just reproducible), pip-audit sur les dépendances verrouillées, la construction de la documentation avec les tests de son propre code, CodeQL et l’OpenSSF Scorecard (une fois le dépôt public), une comparaison hebdomadaire de l’API YNAB avec son instantané (just api-drift), et le MCP Inspector officiel (just inspect), qui contrôle le serveur comme le voit un client, sur le plan de démonstration : ses listes, la portabilité des schémas de ses outils et un appel de chaque sorte. La suite de tests tourne sous Linux et macOS avec Python 3.12, 3.13 et 3.14, et sous Windows avec Python 3.14 (sur une pull request, macOS n’essaie que 3.14 : ses machines coûtent dix fois celles de Linux) ; la couverture est exigée sous Linux et macOS, où s’appliquent les vérifications de permissions de fichiers. Python 3.15 tourne aussi, à titre expérimental : un échec y est un avertissement, pas un contrôle en rouge. Sur une pull request, chaque commit doit porter un sign-off et le titre doit commencer par la nature du changement. Deux contrôles doivent être au vert : CI passed, qui résume tous les jobs du workflow de qualité, et MCP Inspector, un workflow à part pour que son badge le montre seul.

Renovate ouvre des pull requests chaque lundi matin :

Mise à jour Traitement
outils de développement, actions de la CI, site de documentation (mineures et correctifs) regroupées, fusionnées d’elles-mêmes une fois la CI au vert
fastmcp, httpx, pydantic — ils tournent devant les plans des utilisateurs une pull request chacune, relue à la main ; l’évaluation est lancée avant une mise à jour de fastmcp
toute version majeure une pull request chacune, relue à la main
une vulnérabilité connue aussitôt, quel que soit le jour

Une nouvelle version attend sept jours avant que Renovate la propose : une version cassée ou malveillante vite retirée n’atteint jamais le projet.

Sorte Fichiers Ce qu’ils vérifient
Unitaires test_classifier, test_triage, test_writes, test_reconcile, test_forecast, test_analytics, test_journal, test_client la logique pure et le client HTTP, sur des données inventées
Propriétés test_properties avec Hypothesis, des règles vraies pour toute entrée : aller-retour des montants, répartition sans perdre un centime, mois qui s’enchaînent, curseurs, texte bancaire, empreintes de confirmation
Protocole test_protocol*, test_context, test_policy les outils via un client MCP en mémoire : schémas, annotations, chemins de confirmation, annulation
Documentation test_docs les pages et exemples générés correspondent au code ; chaque page existe dans chaque traduction ; chaque variable d’environnement est documentée
Couverture de l’API test_api_coverage chaque opération de l’API YNAB est utilisée par un outil, prévue, ou écartée avec sa raison ; le client n’appelle que des chemins documentés
Hygiène test_hygiene ni IBAN, ni jeton, ni relevé, ni chemin personnel, ni copie du Finder dans le dépôt
Évaluation test_evals les vérifications de l’évaluation sont justes

Les tests sont écrits d’abord. Aucun test n’appelle YNAB.

just mutate lance les tests de mutation (mutmut) sur les modules de calcul : il modifie volontairement le code, quelque 1 500 fois, et vérifie qu’un test échoue à chaque fois. Les modifications qu’aucun test ne remarque désignent les tests à écrire ; beaucoup sont anodines, comme la formulation d’un message.

just bench mesure la durée des modules de calcul sur un plan généré de cinq ans, environ 9 000 transactions (pytest-benchmark). Sur un portable, l’opération la plus lente (préparer une page de suggestions) prend environ 30 ms : le temps d’un outil passe à attendre YNAB, pas à calculer.

just fuzz lance les propriétés Hypothesis avec 50 000 exemples chacune au lieu de 100 (quelques minutes ; just fuzz 200000 pour aller plus loin), sur ce qui vient de l’extérieur : libellés bancaires, journaux abîmés, en-têtes HTTP, montants, curseurs de pagination. Un échec est enregistré et rejoué, réduit au plus petit cas, au lancement suivant. La CI le fait chaque nuit avec 200 000. Le premier passage a trouvé un octet du journal qui n’était pas du texte (0x80) et remontait en erreur de codec brute au lieu de nommer la ligne à corriger.

Fenêtre de terminal
uv run python -m docsgen # pages des outils, catalogue des erreurs, exemples
just docs # construit le site dans toutes les langues ; un lien cassé échoue
just docs-serve # aperçu en direct sur http://localhost:4321/avenir-mcp/

docsgen fait tourner avenir-mcp sur le plan de démonstration et écrit ce qu’il répond réellement, date fixée et identifiants aléatoires remplacés. Les pages écrites à la main existent en anglais, en français, en espagnol, en allemand et en néerlandais ; un test échoue s’il en manque une.

Le site est publié sur GitHub Pages par le workflow docs, et sur Cloudflare Pages (avenir-mcp.pages.dev), qui le construit depuis le dépôt avec npm run build:cloudflare. Les deux le servent sous /avenir-mcp/ ; sur Cloudflare, la racine y redirige. GitHub Pages ne peut pas envoyer d’en-têtes de sécurité ; Cloudflare Pages envoie ceux de docs/cloudflare/_headers avec chaque fichier : une Content-Security-Policy, HSTS, X-Content-Type-Options: nosniff, X-Frame-Options: DENY, une politique de référent, une politique de permissions et une politique d’ouverture. La politique autorise les fichiers du site et chaque script ou style en ligne des pages construites par son SHA-256, calculé à la construction ; 'wasm-unsafe-eval' laisse la recherche exécuter son WebAssembly, et les attributs de style ne sont autorisés que par style-src-attr. La construction échoue, en CI aussi, si un en-tête requis manque ou est affaibli. La variable d’environnement DOCS_SITE fixe l’adresse des liens canoniques et du plan du site.

Fenêtre de terminal
just evaluate # toutes les tâches, Sonnet, environ 1 USD de votre forfait Claude
uv run python -m evals.run --task classify --model haiku

Voir Évaluation.

  • Les messages de commit commencent par un type — feat:, fix:, docs:, refactor:, test:, build:, ci:, chore: — car CHANGELOG.md en est généré par git-cliff.
  • Pour publier : just changelog, commit, étiquette vX.Y.Z égale à avenir_mcp.__version__, puis une release GitHub. Le workflow publish construit deux fois avec la date du commit étiqueté, s’arrête si les deux constructions diffèrent, lance twine check --strict et envoie sur PyPI par Trusted Publishing : aucun jeton n’est stocké.
  • Puis le registre MCP : server.json porte la même version (un test le vérifie) ; lancez mcp-publisher login github, puis mcp-publisher publish. La ligne mcp-name: du README prouve que le paquet PyPI vous appartient.

Projet non officiel. « We are not affiliated, associated, or in any way officially connected with YNAB or any of its subsidiaries or affiliates. The official YNAB website can be found at https://www.ynab.com. The names YNAB and You Need A Budget, as well as related names, tradenames, marks, trademarks, emblems, and images are registered trademarks of YNAB. » Nous ne sommes ni affiliés, ni associés, ni liés officiellement de quelque manière que ce soit à YNAB ou à ses filiales et sociétés affiliées. Le site officiel de YNAB se trouve à l’adresse https://www.ynab.com. Les noms YNAB et You Need A Budget, ainsi que les noms, dénominations commerciales, marques, emblèmes et images qui s’y rattachent, sont des marques déposées de YNAB. avenir-mcp est fourni tel quel, sans garantie, et n’est pas un conseil financier. Mentions légales · Confidentialité