À la fin, Codex CLI traite le canal de records "Bugs" de l'un de vos projets osFoundry. Il lit le schéma du canal, parcourt page par page les éléments encore marqués New, ouvre chacun d'eux et renseigne Status, Owner et Severity. Les modifications apparaissent dans l'onglet Data du canal comme celles de n'importe quel collègue, et chaque appel est listé dans le Recent activity (activité récente) de la connexion. Quand une valeur ne correspond pas à un champ, osFoundry refuse la modification, et Codex laisse ce champ à un humain au lieu de deviner.
Qui fait quoi
| Côté Codex | Côté osFoundry | |
|---|---|---|
| Connexion | Votre connexion Codex, inchangée. Codex conserve le token OAuth d'osFoundry | Une connexion approuvée pour un workspace |
| Quel canal | Codex le trouve avec list_project_resources
|
Uniquement les canaux de records des projets auxquels la connexion a été ajoutée |
| Règles des champs | Codex les lit dans le schéma que renvoie list_record_items
|
L'onglet Schema du canal : types de champ, Required, options des select |
| Écritures |
edit_record_item, après la demande d'approbation propre à Codex |
Les valeurs sont validées par rapport aux champs. Un mauvais type ou une option inconnue est refusé |
| Conflits | Codex relit l'élément et décide à nouveau |
expected_version doit correspondre à la version actuelle de l'élément |
| Lignes et champs | Codex peut modifier les valeurs d'éléments existants | Ajouter ou supprimer des éléments et modifier le schéma restent dans l'app |
Mise en place
On part du principe que Codex est déjà connecté : la table [mcp_servers.osfoundry] est dans ~/.codex/config.toml, et codex mcp login osfoundry est allé au bout. Les étapes ci-dessous sont ce qu'un canal de records ajoute par-dessus.
1. Placer le canal de records dans le projet connecté
Ouvrez Records dans la barre latérale et choisissez le canal. Un nouveau tracker se crée via Create Record Channel, Record Type Custom, qui demande un nom. Dans le canal, ouvrez l'onglet Settings. Le champ Project affiche "Add to project" tant que le canal n'est dans aucun projet. Choisissez le projet auquel appartient la connexion Codex.
La connexion accède à un canal de records par son projet. Si vous déplacez le canal dans un autre projet, l'appel suivant de Codex est refusé.
2. Vérifier le schéma que Codex devra respecter
L'onglet Schema ("Define the fields for this record channel.") fait office de contrat. Chaque champ a un type, un indicateur Required facultatif et, pour Select et Multi-Select, une liste d'options. Chaque option a une valeur stockée et un libellé. La grille affiche le libellé. Codex doit envoyer la valeur.
Example: the Bugs channel
ticket Text Required
title Text Required
status Select Required new · triaged · in_progress · fixed · wont_fix
owner Select aiko · mika · ren
severity Select s1 · s2 · s3 · s4
points Number min 0, max 13
area Multi-Select billing · auth · api · ui
due Date
age_days Formula computed
Exemple : L'onglet Schema du canal de records Bugs
Un champ Formula est calculé à partir de son expression. Personne ne l'écrit, Codex compris.
3. Ajouter la connexion au projet et vérifier ses outils
Cliquez sur l'icône de clé dans l'en-tête et ouvrez Connected. Sélectionnez la connexion Codex. Sous Projects, choisissez le projet et cliquez sur Add to project (ajouter au projet). Le contenu synchronisé du projet, canaux de records compris, est alors ouvert à cette connexion.
Plus bas, ouvrez Tools. La checklist affiche les noms d'outils avec des espaces, cherchez donc "list record items", "read record item", "edit record item" et "poll resource events". Tous les outils pris en charge sont activés par défaut. Si Codex ne doit que lire pour l'instant, décochez "edit record item" et cliquez sur Save tools (enregistrer les outils).
Exemple : La connexion Codex CLI avec le projet "Product" ajouté
4. Réduire ce qui est proposé à Codex
Codex filtre aussi les outils de son côté. Pour le tri, six suffisent :
[mcp_servers.osfoundry]
url = "https://api.osfoundry.io/api/v1/external-mcp"
scopes = ["osfoundry:read", "osfoundry:write"]
default_tools_approval_mode = "writes"
enabled_tools = [
"list_granted_resources",
"list_project_resources",
"list_record_items",
"read_record_item",
"edit_record_item",
"poll_resource_events",
]
list_record_items, read_record_item et poll_resource_events sont marqués en lecture seule sur le serveur, donc avec "writes" ils s'exécutent sans demande de confirmation. Codex demande avant chaque edit_record_item. Sur une passe de 40 éléments, cela fait 40 demandes. C'est aussi 40 occasions de l'arrêter.
5. Formuler la demande avec les règles explicites
In osFoundry, open the "Bugs" record channel in the Product project.
Go through every item with status "new", newest first.
For each one: read it, then set status to triaged, pick an owner by area
(billing → aiko, auth → mika, everything else → ren) and a severity.
Use the option values from the schema, not the labels.
If osFoundry rejects a value, don't guess. Leave that field and list the
item at the end.
Une vraie exécution
Codex n'est pas installé sur la machine où cet article a été écrit, la session ci-dessous est donc un exemple simulé. Les noms d'outils et les arguments sont ceux que le serveur réel liste dans tools/list. Codex présente les outils MCP au modèle sous la forme mcp__<server>__<tool>. Le canal, les éléments et la réponse sont du contenu de démonstration.
Example (simulated)
• mcp__osfoundry__list_project_resources {"project_id": "…", "resource_type": "record_channel",
"search": "Bugs"}
← record channel "Bugs", id 4127
• mcp__osfoundry__list_record_items {"record_channel_id": "4127", "limit": 50}
← schema: 11 fields · 50 item previews · more before item 9811
• mcp__osfoundry__list_record_items {"record_channel_id": "4127", "before_id": "9811", "limit": 50}
← schema · 23 item previews · no more pages
(38 of the 73 items have status "new")
• mcp__osfoundry__read_record_item {"record_channel_id": "4127", "item_id": "9874"}
← BUG-1873 "Invoice PDF shows last month's total", area ["billing"], version "…14.208311Z"
• mcp__osfoundry__edit_record_item {"record_channel_id": "4127", "item_id": "9874",
"values": {"status": "triaged", "owner": "aiko", "severity": "s2"},
"expected_version": "…14.208311Z", "idempotency_key": "triage-9874"}
[Codex asks: allow this tool call? → yes]
← saved
… 36 more items …
• mcp__osfoundry__edit_record_item {… "item_id": "9790",
"values": {"status": "triaged", "owner": "ren", "severity": "s3", "points": 20}, …}
← rejected: points must be between 0 and 13
• mcp__osfoundry__read_record_item {… "item_id": "9790"}
• mcp__osfoundry__edit_record_item {… "values": {"status": "triaged", "owner": "ren", "severity": "s3"}, …}
← saved
• mcp__osfoundry__edit_record_item {… "item_id": "9802", …, "expected_version": "…02.551904Z"}
← rejected: the item changed after that version
• mcp__osfoundry__read_record_item {… "item_id": "9802"}
← status "in_progress", owner "mika" (set by Mika in osFoundry a minute ago)
Triaged 37 of 38 new items. BUG-1791's description says "about 20 points",
but Points only goes to 13, so I left it empty. BUG-1805 was already
in progress with Mika, so I didn't touch it.
Ce sont deux refus qui ont fait le travail ici. Dans cet exemple, le champ Points est plafonné à 13, donc la modification qui contenait 20 a été rejetée en bloc. Codex a retiré ce seul champ et enregistré le reste. Il n'a pas ramené 20 à 13, parce qu'une estimation tronquée ressemble à une vraie. Le second refus vient du contrôle de version. Mika avait pris l'élément entre la lecture et l'écriture de Codex. Codex l'a relu, a vu le nouveau statut et le nouveau responsable, et n'y a pas touché au lieu d'écraser son travail avec son propre plan.
La pagination s'est faite par before_id. Chaque page se termine par l'élément le plus ancien qu'elle contient, et la page suivante demande les éléments antérieurs à celui-ci. Les bugs signalés pendant que Codex lit ne repoussent pas d'anciens éléments sur la page suivante, donc rien n'est lu deux fois.
Exemple : L'onglet Data après la passe, avec Status et Owner renseignés
L'onglet Data affiche le résultat comme la grille le fait d'habitude. Status s'affiche avec le libellé de l'option, "Triaged", dans la couleur de l'option si elle en a une, et non avec la valeur stockée triaged. Un élément modifié par quelqu'un d'autre garde les valeurs de cette personne.
Où passe la limite
Le schéma est la limite pour les valeurs. Codex ne peut mettre dans un champ que ce que le champ accepte, et les champs select acceptent les valeurs de leurs options. Les libellés "In progress" ou "Aiko Tanaka" sont refusés, pas convertis. Une conversion obligerait à deviner. "major" pourrait vouloir dire S2, et "Won't fix" et wont_fix ne se ressemblent que pour un humain. Si vous voulez que Codex arrête de poser des questions sur un champ, modifiez ce champ dans l'onglet Schema. Codex ne peut pas l'assouplir de l'extérieur.
Codex modifie des valeurs, rien d'autre. Via MCP, il n'existe aucun outil pour ajouter un élément, en supprimer un ou ajouter un champ. Fermer les doublons et remanier le tracker se fait dans l'app, où Versions et l'historique du canal montrent qui l'a fait.
Chaque appel est vérifié à son arrivée. Le statut de la connexion, le projet dans lequel se trouve actuellement le canal et vos propres droits dessus sont évalués à chaque appel. Un token émis plus tôt ne garde pas l'accès ouvert une fois le projet retiré ou après un clic sur Revoke connection (révoquer la connexion). Seuls les canaux synchronisés et hébergés sont accessibles. La réponse initialize du serveur indique "Local-only data is unavailable to cloud clients."
osFoundry voit les appels, pas la session. Recent activity liste le nom de l'outil, la décision d'accès et l'heure. Le raisonnement de Codex et votre dépôt restent sur votre machine.
Et ensuite
Relancez le même prompt le lendemain matin, mais commencez par poll_resource_events sur le canal de records à partir de la séquence que Codex a notée à la fin de la passe précédente. L'outil renvoie les événements du canal postérieurs à cette séquence, si bien que Codex ne relit que la poignée d'éléments qui ont bougé au lieu de tout le tracker. L'aspect d'un élément côté osFoundry, avec sa vue formulaire et son historique, est présenté sur la page de détail des records.



Top comments (0)