Contexte et évolution de MCP
Jusqu'à récemment, le site pi.dev affichait clairement que le protocole MCP (Model‑Chain Protocol) n'était pas supporté. Des podcasts et des posts d'entreprise confirmaient cette position. Au cours de l'année passée, les développeurs d'Earendil ont suivi les évolutions de MCP : la version actuelle propose des mécanismes de découverte d'outils et de retour de données structurées, plus proches d'OpenAPI que des implémentations antérieures qui se contentaient de renvoyer du texte brut. Cette modernisation a motivé la réintégration de MCP dans le noyau de Pi.
Architecture de l’intégration MCP dans Pi
Pi expose désormais les outils MCP via un sandbox JavaScript similaire à celui utilisé par les harnesses Codex. Le système charge les métadonnées d'outil de façon différée, ce qui permet aux modèles LLM de récupérer les définitions d'outils au besoin, sans gonfler le contexte initial. Les messages système intermédiaires et les changements de niveau de raisonnement sont également pris en charge, offrant une flexibilité accrue pour les conversations longues. Cette architecture repose sur une couche d'abstraction qui différencie les outils disponibles pour le LLM de ceux réservés au mode Codemode, évitant ainsi les conflits de disponibilité.
Rôle de Codemode et du sandbox JavaScript
Codemode est un mécanisme d'orchestration qui s'exécute dans le même environnement de confiance que le harness, contrairement aux outils qui s'exécutent dans un sandbox isolé. En pratique, Codemode utilise JavaScript – souvent compilé en WASM – pour combiner plusieurs appels d'outils, conserver l'état dans la transcription de session et optimiser l'usage du contexte. L'activation de Codemode se fait automatiquement lorsqu'MCP est configuré, mais il peut aussi être ajouté comme outil par défaut. L'exemple suivant montre comment Pi combine le MCP de Linear avec le modèle de classification Jev pour analyser le ton des commentaires :
const { issues } = await tools.mcp__linear__list_issues({ team: "Pi", state: "open", limit: 250, });
const jev = await models.getModelOfType(
"classifier", "cloudflare-workers-ai", "typesafe/jev"
);
const questions = {
frustration: {
type: "choice",
instructions: "Judge ONLY the emotional tone of the people writing. " +
"Ignore how severe the bug is.",
criteria: {
none: "Neutral, factual, or friendly, even about a serious bug",
mild: "Explicit annoyance, impatience, or disappointment",
high: "Clearly angry, exasperated, sarcastic, or fed up",
},
},
};
const results = [];
let next = 0;
async function worker() {
while (next < issues.length) {
const issue = issues[next++];
const { comments } = await tools.mcp__linear__list_comments({ issueId: issue.identifier });
const c = await models.classify(jev, { state: { ...issue, comments }, questions });
results.push({ id: issue.identifier, title: issue.title, ...c.answers.frustration });
}
}
await Promise.all([worker(), worker(), worker(), worker()]);
store("frustration", results);
Analyse des impacts et limites
L'intégration native de MCP simplifie le développement d'agents capables de composer plusieurs appels d'outils sans recourir à des extensions tierces. Le fait que les outils retournent des données structurées améliore la fiabilité du chaînage et réduit les besoins en post‑traitement. Cependant, la composition reste difficile : les serveurs MCP existants sont souvent optimisés pour la token‑efficiency et ne fournissent pas toujours les métadonnées nécessaires à une orchestration fine. De plus, la dépendance à JavaScript/WASM impose des contraintes de performance sur les environnements à ressources limitées. Enfin, la séparation entre les outils « déférés » et ceux réservés à Codemode nécessite une configuration explicite, ce qui peut introduire des erreurs si les développeurs ne maîtrisent pas pleinement le nouveau modèle de charge d'outils.