← Retour au blog
Guide

Comment les agents de code IA lisent-ils et modifient-ils les fichiers de configuration JSON ?

Publié le 16/09/2026 Dernière mise à jour le 16/09/2026 Environ 15 min Boîte à outils JSON

Comment lire cet article

« Ajoute-moi un script dans package.json » sonne comme une opération sur objet. Ce n'est pas le cas. L'Agent de Claude Code, Codex ou Cursor lit d'abord le fichier comme du texte dans le contexte, puis cherche un ancien fragment unique à remplacer par un nouveau ; si le match n'est pas unique, si le dialecte est faux, si un tableau est écrasé d'un bloc, la config casse. Ce texte est daté du 2026-09-16 : d'abord la boucle de lecture / écriture commune aux trois, puis le settings.json strict de Claude Code, le TOML de Codex plus le JSON du dépôt, le JSONC et les checkpoints de Cursor, enfin un échantillon de config MCP branché sur les outils de ce site. Comment les Skills se chargent à la demande : Pourquoi les Agents ont besoin de Skills ; pourquoi le bus est le JSON : Pourquoi l'IA aime le JSON.

En 2026, un Coding Agent sait déjà modifier un dépôt, lancer les tests, ouvrir une PR. Au quotidien, ce qu'il modifie le plus — et casse le plus facilement — n'est souvent pas le code métier, mais la config : package.json, tsconfig.json, settings.json, manifestes MCP. Les fichiers sont petits, les clés denses, les dialectes pas unifiés : certains interdisent les commentaires, d'autres vivent grâce à eux ; certains tableaux sont des ensembles, d'autres des étapes ordonnées. L'Agent n'a pas d'API objet officielle stable du type « changer une clé par chemin ». Ce qu'il voit, c'est du texte. Un correctif texte qui dérive, et l'éditeur ou le runtime sort un Settings Error à la seconde suivante — ou, pire, jette silencieusement vos hooks d'origine.

Pourquoi réécrire une config est la première leçon de l'Agent

Le code métier se trompe, les tests crient. Une config se trompe, et c'est souvent « le démarrage échoue » ou « ça a l'air bon, le tableau des permissions a déjà été écrasé ». Trois duretés :

  • Le dialecte. JSON strict, JSONC (commentaires //, virgule finale), et parfois quelqu'un jette du JSON5 ou du faux JSON à apostrophes simples dans le dépôt.
  • La sémantique de fusion. Ajouter un élément à permissions.allow ou scripts doit être un ajout ; remplacer l'objet d'un bloc, c'est effacer les règles des collègues.
  • Le périmètre. Global utilisateur, partagé projet, surcharge locale : trois fichiers. Le mauvais fichier, au mieux ça ne vous touche que vous ; au pire un chemin de secret entre dans le dépôt à commiter.

Donc « savoir modifier du JSON » n'est pas un cours de syntaxe, c'est un cours de flux Agent : d'abord lire, puis le plus petit correctif, puis valider. Le Skill lui dit quand suivre ces étapes ; le Schema lui dit si l'objet modifié est encore légal. La division du travail : Agent Skills et Structured Output.

En une phrase. Pour modifier une config, ce qui manque à l'Agent n'est pas « mieux comprendre le JSON », c'est « cet ancien texte est-il unique, ce fichier accepte-t-il les commentaires, ce tableau peut-il être remplacé d'un bloc ».

La boucle commune : découvrir → lire → correctif → valider

Les trois produits n'ont pas la même marque. Au niveau fichier, c'est la même boucle. Une fois le dessin clair, les écarts se retiennent.

Les quatre étapes pour qu'un Coding Agent modifie du JSON Découvrir le chemin, lire le fichier entier ou un extrait, appliquer un correctif par chaîne exacte ou réécrire le fichier, puis parser et valider. 1 Découvrir Glob / Grep 2 Lire Read → contexte 3 Correctif Edit / Write 4 Valider parse / Schema
L'index passe par la recherche, le corps par Read, le changement par un match unique. Valider n'est pas de la politesse, c'est la boucle fermée.
  1. Découvrir. Glob cherche **/settings.json, **/mcp.json ; Grep cherche les noms de clés. D'abord confirmer quel fichier, quel périmètre.
  2. Lire. Read envoie le texte avec numéros de lignes dans le contexte. Modifier sans avoir lu, c'est l'opération que les trois produits empêchent : le contenu peut être périmé, le correctif vise une hallucination.
  3. Correctif. Par défaut Edit / StrReplace : old_string doit apparaître dans le fichier de façon exacte et unique. Le Write du fichier entier se réserve à la création, ou quand l'ancienne structure ne se remplace plus localement.
  4. Valider. JSON.parse, diagnostics de l'éditeur, Schema, commandes liées (npm pkg get, claude /status). En cas d'échec, Read à nouveau, ne pas empiler les correctifs.

C'est le même budget que Function Calling / MCP : définition d'outil courte, résultat à valider ensuite. Le fichier de config est la forme disque du contrat d'outil.

Trois dialectes : JSON strict, JSONC, faux JSON

L'Agent ne trébuche le plus souvent pas sur « une clé oubliée », mais sur « quelle syntaxe ce fichier accepte vraiment ».

Dialecte Commentaires / virgule finale Fichiers courants Résultat typique quand l'Agent casse le fichier
JSON strict Ni l'un ni l'autre package.json, settings.json Claude Code, la plupart des manifestes MCP Settings Error au démarrage ; JSON.parse échoue
JSONC //, /* */ autorisés, souvent la virgule finale aussi settings.json VS Code / Cursor, certains tsconfig.json Réécriture du fichier entier en JSON strict : commentaires et ordre des clés effacés
Faux JSON / JSON5 Apostrophes simples, clés non quotées « Exemples » copiés depuis une doc ou un chat Ça ressemble à un objet, tout parseur strict refuse

Une même clé n'ouvre pas trois serrures. Avant de laisser l'Agent modifier un fichier, écrivez le dialecte dans le prompt ; après modification, recettez avec le parseur correspondant, pas avec « ça ressemble à du JSON ».

Claude Code : Read d'abord, puis Edit exact

Les outils fichier de Claude Code sont un trio : Read, Edit, Write. Le comportement officiel se referme en trois règles dures :

  • Sur un fichier déjà là, préférer Edit. Il ne soumet que le fragment changé, moins de risque d'écraser.
  • Edit est un remplacement littéral, pas une regex. Espaces, indentation, retours à la ligne doivent coller ; si old_string apparaît deux fois sans replace_all, ça échoue.
  • Dans la session, il faut d'abord Read ce chemin avant un Edit ou un Write d'écrasement. Si le disque a changé depuis la dernière lecture, l'outil refuse le correctif périmé.

La config elle-même est du JSON. Défaut utilisateur dans ~/.claude/settings.json, partagé projet dans .claude/settings.json, surcharge locale dans settings.local.json. Ces fichiers sont du JSON strict : une ligne // ou une virgule finale, au prochain démarrage c'est Settings Error. La doc officielle insiste encore : pour modifier les tableaux de permissions ou les hooks, fusionner les éléments déjà là, ne pas remplacer l'objet d'un bloc. Après modification, /status montre quelles couches sont chargées ; la plupart des clés se rechargent à chaud, pas besoin de redémarrer pour une règle allow.

{
  "permissions": {
    "allow": [
      "Bash(npm test *)",
      "Read(src/**)"
    ],
    "deny": [
      "Read(.env*)",
      "Edit(.env*)",
      "Write(.env*)"
    ]
  }
}

Les règles de permission sont aussi des chaînes structurées : Read(path), Edit(path), Write(path). Refuser Read bloque aussi Edit / Write sur le même chemin. C'est le fichier de config qui, en retour, contraint comment l'Agent modifie les autres configs — le JSON est à la fois l'objet modifié et le contrat des droits d'écriture.

Le prompt pour Claude Code peut être figé. « Read d'abord le settings cible ; Edit seulement les clés à changer ; fusionner les tableaux ; après modification, confirmer que c'est encore du JSON strict. » Le Skill communautaire update-claude-code-config, c'est à peu près ces phrases refermées en manuel.

Codex : sa propre config est du TOML, le dépôt reste du JSON

Le point qu'on mélange : Codex CLI / le Codex de ChatGPT, la config utilisateur n'est pas du JSON. Le global est dans ~/.codex/config.toml, un projet de confiance peut empiler .codex/config.toml ; le one-shot passe par -c key=value, valeur parsée en TOML. Les consignes de flux vont dans AGENTS.md, les étapes réutilisables dans le répertoire Skills. Le TOML projet ne peut pas changer les clés locales : identifiants, provider, notifications.

Mais une fois Codex dans le dépôt comme Coding Agent, il affronte encore du JSON :

  • package.json, tsconfig.json, configs de toolchain front ;
  • manifestes MCP / outils, OpenAPI, catalogues de modèles (ce que pointe model_catalog_json est bien un JSON) ;
  • la sortie structurée de l'Agent lui-même : le CLI peut viser un JSON Schema avec --output-schema, pour valider la forme de la réponse finale.

Le bac à sable décide par défaut s'il peut écrire : read-only en lecture seule, workspace-write pour modifier les fichiers de l'espace. Donc « comment Codex modifie du JSON » se découpe en deux couches — ses propres boutons sont dans le TOML, modifier votre dépôt passe encore par lire le fichier + poser un correctif. Ne prenez pas les tables de config.toml et les objets de package.json pour le même contrat.

Comme chez Claude Code, réécrire tout un JSON de dépôt est la mauvaise option. Codex a un crochet de recette en plus : vous pouvez écrire « après modification, ça doit passer la validation Schema » en Skill, ou donner directement la forme attendue à --output-schema. Côté outils : Structured Output et MCP Tool.

Cursor Agent : correctifs, checkpoints et settings.json

La boucle du Cursor Agent est la même : recherche → Read → remplacement exact / Write → recette par commande. Le bureau a deux choses de plus, particulièrement utiles pour la config :

  • Checkpoints. Instantané automatique avant une grosse modification, séparé de Git : adapté à « ce settings a explosé, revenir d'abord à la version précédente de la session ».
  • JSONC. Les settings.json utilisateur et espace de travail autorisent les commentaires. Un bon Skill (par exemple update-cursor-settings dans la communauté) exige : d'abord lire, garder les clés non concernées et les commentaires, ne modifier que le chemin nommé, après écriture confirmer que l'éditeur parse encore.

Au niveau projet, on trouve souvent aussi .cursor/mcp.json, .vscode/settings.json. Le premier va en général en JSON strict au runtime MCP ; le second est du JSONC. Si l'Agent réécrit les deux avec le même « stringify strict », il écrit le MCP correctement et efface les commentaires des settings d'espace — ou l'inverse, il ajoute des // au manifeste MCP, et le runtime refuse net.

Le CVE-2025-49150 de 2025 a poussé ça jusqu'à la couche sécurité : l'Agent peut lui-même modifier du JSON. Si json.schemaDownload.enable est true, le $schema du fichier lance un HTTP GET sortant sans confirmation. Cursor a donc désactivé par défaut le téléchargement distant de Schema. Un projet de confiance peut l'ouvrir seulement dans .vscode/settings.json, pas en global. Pour les lecteurs de ce site, la conclusion est concrète : $schema est aussi un champ que l'Agent peut écrire ; ce n'est pas seulement un hint d'éditeur, c'est une requête sortante.

Ask / Plan / Agent. Seulement comprendre pourquoi le tsconfig est écrit comme ça : Ask. Modifier plusieurs fichiers de config : Plan d'abord, puis laisser l'Agent poser les correctifs. Une tâche de config blesse plus facilement les clés voisines qu'une fonction isolée.

Structures de données : objets, tableaux, pointeurs, correctifs

L'Agent pose des correctifs texte ; dans la tête, mieux vaut encore penser données structurées. Quatre couches suffisent :

Couche Ce que c'est Comment s'en servir pour modifier une config
Objet Correspondance clé → valeur Fusionner les clés : laisser les champs non mentionnés
Tableau Liste ordonnée, parfois en réalité un ensemble Ajouter / dédupliquer ; ne pas remplacer tout le tableau, sauf si vous voulez vraiment vider
JSON Pointer Par ex. /permissions/deny/0 Dans le prompt, pointer « modifier ce chemin », moins de risque que l'Agent prenne une clé sœur
JSON Patch add / remove / replace de la RFC 6902 Modèle mental : une opération à la fois. La plupart des Agents n'émettent pas de Patch standard, mais vous pouvez recetter sur cette forme

Un « changement que je veux que l'Agent fasse » s'écrit d'abord en objet, pas en phrase :

{
  "file": ".claude/settings.json",
  "dialect": "strict-json",
  "op": "add",
  "path": "/permissions/deny/-",
  "value": "Read(.env*)",
  "merge_arrays": true
}

Le - en fin de path veut dire ajouter à la fin du tableau. C'est la sémantique JSON Patch. Vous pouvez d'abord refermer cette intention en Schema avec les outils de ce site, puis la coller dans la conversation comme contrat de recette. L'Agent atterrit encore par Edit texte, mais vous savez à quoi ressemble le succès.

Fusionner les clés, ou réécrire le fichier entier

L'outil Write écrase le fichier entier. Pour un manifeste MCP neuf de 20 lignes, c'est adapté. Pour un package.json qui vit depuis deux ans, c'est un accident.

  • Il faut Edit. Ajouter un script, ajouter une règle deny, changer un port, ajouter une clé à compilerOptions.
  • Il faut Write. Le fichier n'existe pas encore ; l'ancienne structure ne se remplace plus localement (par exemple une config plate migrée vers un schema imbriqué) ; vous exigez clairement « remplacer tout le fichier par cet échantillon », et vous avez déjà une sauvegarde.
  • Toujours Read d'abord. Write sans avoir lu, c'est écraser le disque avec la mémoire du modèle.

La fusion de tableaux est le mode d'échec le plus fréquent. À gauche, l'ajout correct ; à droite, les règles allow des collègues disparues :

// Ce qu'il faut : lire l'ancien tableau, n'ajouter qu'un élément
"allow": [
  "Bash(npm test *)",
  "Read(src/**)",
  "Bash(npm run lint *)"
]

// À éviter : remplacer tout le tableau par un tableau qui ne contient que le nouvel élément
"allow": [
  "Bash(npm run lint *)"
]

Écrire « merge arrays, do not replace » dans le prompt vaut mieux que « fais attention ». Ce qui se referme en Skill, ne le retapez pas à chaque fois.

Accidents fréquents

  • Correctif non unique. "strict": true apparaît deux fois dans le fichier : Edit échoue ou change le mauvais bloc. Emportez quelques lignes de contexte en plus.
  • Dialecte inversé. Ajouter des commentaires au settings Claude Code ; ou stringify tous les commentaires du settings Cursor.
  • Virgule finale. Le JSONC survit, package.json et les settings Claude non.
  • Ordre des clés et lignes vides. Une réécriture du fichier entier transforme le Diff en « tout le fichier est rouge » : la review ne voit plus ce qui a vraiment changé.
  • $schema sortant. Une URL de Schema que l'Agent peut écrire déclenche un téléchargement dans certains éditeurs. Dépôt non fiable : n'ouvrez pas le Schema distant en global.
  • Mauvais périmètre. Écrire un chemin absolu local dans le settings.json projet et le commiter ; ou modifier le global utilisateur, les collègues ne reproduisent rien.
  • Modifier sans valider. L'éditeur peut recharger à chaud une config cassée et revenir en silence. Après modification, parsez : ne vous fiez pas au seul « l'appel d'outil a réussi ».

Un échantillon de config MCP à recetter en local

L'objet ci-dessous joue deux rôles : l'« intention » et la forme une fois atterrie. D'abord parser, sortir un Schema, faire un Diff dans les outils locaux, puis donner ça à n'importe lequel des trois Agents pour modifier le vrai fichier du dépôt.

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "./data"],
      "env": {
        "MCP_LOG_LEVEL": "info"
      }
    }
  },
  "permissions": {
    "allow": [
      "Read(./data/**)",
      "Edit(./data/**)"
    ],
    "deny": [
      "Read(./data/secrets/**)",
      "Write(./data/secrets/**)"
    ]
  },
  "meta": {
    "dialect": "strict-json",
    "merge_arrays": true,
    "scope": "project"
  }
}

Selon les règles d'inférence actuelles du site, cet échantillon donne :

Champ Type inféré À faire après génération
mcpServers / env / meta object additionalProperties à trancher : un nouveau nom de server est ouvert, meta.dialect se referme en enum
command / MCP_LOG_LEVEL / scope string scope en user | project | local, ne laissez pas « juste de mon côté »
args / allow / deny array of string Déclarer « ajouter » ou « remplacer » ; par défaut, ajouter
merge_arrays boolean Doit être true / false, pas « garder autant que possible »

Prenez le même objet comme contrat de recette de l'Agent : une fois le fichier disque modifié, l'ensemble des clés, les éléments de tableau et le dialecte doivent encore coller. Échantillon prêt : ouvrez le formatage JSON pour confirmer que ça parse, puis JSON → Schema pour faire pousser le premier brouillon de contrat.

Recetter dans la Boîte à outils JSON

  1. Collez la config existante ou l'échantillon ci-dessus dans le formatage JSON. Le JSON strict ne passe pas : d'abord le Nettoyage JSON ; du JSONC, enlevez d'abord les commentaires puis parsez.
  2. Avec JSON → Schema ou Structured Output, générez le contrat de l'« objet d'intention » et de la « config atterrie ».
  3. Le second fichier après modification par l'Agent passe en validation Schema. Regardez surtout si les tableaux ont été ajoutés ou remplacés, si un enum a dérivé en langage naturel.
  4. Comparez avec la copie d'avant via la comparaison JSON. Le Diff idéal ne touche que les chemins que vous avez nommés ; tout le fichier rouge, c'est un Write de réécriture.
  5. Si la config part vers MCP / Function Calling, les mêmes champs passent respectivement par MCP Tool et Function Calling : ne copiez pas deux jeux de noms de clés.

Tout se traite dans le navigateur, rien n'est envoyé au serveur. L'Agent cloud ou local pose le correctif ; l'outil local, avant que le correctif entre dans Git, fige la forme et le contrat.

FAQ

L'Agent modifie-t-il le JSON comme un objet, ou comme du texte ?

Comme du texte. D'abord Read, puis remplacement de chaîne exacte ou Write du fichier entier. Pas d'API officielle stable « changer une clé via JSON Pointer ». Le correctif doit être unique, après modification ça doit parser.

Quelle différence entre Claude Code, Codex et Cursor pour modifier du JSON ?

La boucle est la même. Les settings Claude Code sont du JSON strict, et imposent Read puis modification. Les boutons de Codex sont dans le TOML ; modifier le JSON du dépôt passe encore par des correctifs fichier. Les settings Cursor sont du JSONC, avec checkpoints de session ; le téléchargement distant de Schema est désactivé par défaut.

Peut-on mettre des commentaires dans settings.json ?

Cursor / VS Code oui (JSONC). Les settings Claude Code non. Mauvais dialecte : soit le démarrage échoue, soit les commentaires disparaissent.

Pourquoi ne pas laisser l'Agent réécrire tout le package.json ?

Write écrase le fichier entier : scripts, overrides, ordre des clés et commentaires humains peuvent disparaître. Ne remplacer que le fragment unique, fusionner les tableaux, recetter au Diff.

Comment empêcher l'Agent de casser la config ?

Cadrer le périmètre ; Read puis modification ; interdire les Write inutiles ; après modification, parse / Schema / Diff ; chemins sensibles dans deny. Ce qui se referme en Skill et Schema, ne le laissez pas au seul « fais attention » oral.

En résumé

Un AI Coding Agent lit et modifie une config JSON non pas comme une base d'objets, mais via une boucle texte qu'on peut raconter : découvrir le fichier, le lire dans le contexte, poser un correctif sur un fragment unique, puis parser et valider. Claude Code inscrit « Read puis Edit » dans le contrat d'outil, et cloue les settings au JSON strict ; Codex range ses boutons dans le TOML, continue de modifier le JSON de votre dépôt avec le même type de correctif, et peut refermer la réponse finale avec un Schema ; Cursor ajoute les checkpoints et le JSONC, et la facture sécurité du $schema sortant. Pour le développeur, la suite n'est pas de faire « mieux comprendre le JSON » au modèle, c'est de refermer dialecte, périmètre et règles de fusion en objet validable — index court, correctif petit, contrat dur. Un seul échantillon MCP fait pousser le Schema, un Diff, puis atterrit chez n'importe lequel des trois.