Exploitation OpenClaw 25 avril 2026

2026 : tamponnage stdio OpenClaw, arrêts JSON-RPC MCP et contre-pression de tube sur un Mac mini ProxyMac loué

Équipe d’ingénierie ProxyMac 25 avril 2026 ~11 min de lecture

Sur un ProxyMac Mac mini à Hong Kong, au Japon, en Corée, à Singapour ou aux États-Unis, OpenClaw enregistre souvent des serveurs MCP via stdio : la passerelle lance un processus enfant, parle JSON-RPC sur stdin/stdout et attend que chaque message arrive vite. La signature d’échec est d’un calme agaçant : le premier appel d’outil fonctionne, puis l’enfant cesse d’émettre alors que top montre du CPU au repos. Neuf fois sur dix ce n’est pas « de mauvais modèles », mais le tamponnage stdio plus la contre-pression de tube : l’enfant passe en mode entièrement tamponné par blocs car il ne voit plus de TTY ; des réponses partielles restent dans libc jusqu’à remplir un tampon. Le parent peut bloquer sur read() en attendant un délimiteur qui n’arrive jamais, ou l’enfant bloque sur write() car le parent n’a pas vidé le tube. Ce guide explique l’architecture, oppose tampon ligne vs bloc avec une matrice de symptômes, compare enveloppes PTY vs tubes bruts sous launchd, liste des atténuations pour Python (PYTHONUNBUFFERED=1, python -u), filtres POSIX (stdbuf -oL) et flux Node (garder stdout en mode flux), puis propose un triage en cinq étapes relié à déploiement MCP, redémarrage passerelle, dépannage déploiement et ulimits quand la cause réelle est la famine de descripteurs déguisée en « blocages ».

Architecture MCP stdio sur macOS (ce qui doit rester vrai)

Imaginez trois processus coopératifs : (A) la passerelle OpenClaw, (B) le binaire ou script serveur MCP, (C) des filtres optionnels (jq, runtimes). Tout participant qui bloque en écriture pendant qu’un autre attend la lecture pour la même dépendance circulaire crée un interblocage. Les transports stdio héritent aussi d’une discipline stderr : des bibliothèques bavardes qui crachent des barres de progression sur stderr peuvent remplir les tampons de tube du noyau si personne ne lit.

  • Un message JSON par vidage est irréaliste — libc ne connaît pas les frontières JSON.
  • Les grosses réponses exigent des lecteurs en flux ; si la passerelle tamponne toute la charge en RAM, vous ressentirez des « pauses » sans lien avec la sémantique MCP.
  • launchd ne source pas vos rc de shell interactif — l’alignement d’environnement est manuel ; voir les motifs upgrade/rollback pour des redémarrages ordonnés après changement d’env.

Tampon ligne vs bloc (pourquoi le Terminal « marche »)

Beaucoup de CLI utilisent le tampon ligne quand isatty(stdout) est vrai, et le tampon bloc (souvent des multiples de 4–8 KiB) quand stdout est un tube. Sous un LaunchAgent sans interface, votre serveur MCP devient soudain écrivain de tube — les journaux « live » au Terminal sont groupés jusqu’à remplir le tampon. Ce délai ressemble à « le modèle s’est arrêté » alors que le LLM a fini il y a des secondes.

Astuce d’instrumentation : enveloppez les commandes suspectes avec stdbuf -oL -eL uniquement pendant le triage — mesurez la latence avant de figer des enveloppes dans des plists de prod.

Matrice des symptômes MCP bloqué

SignalPlus probable qu’un bug MCPProuver / infirmerLien suivant
Premier RPC OK, le second bloque pour toujoursstdout tamponné par blocsMême binaire sous script -q /dev/null (fumée PTY)Cet article
CPU saturé, RAM plateBoucle serrée sur fd videÉchantillonner avec sample pid 5 -file /tmp/st.txtDépannage
Too many open filesUlimits, fan-out MCPlaunchctl limit maxfiles vs limite souple du processusUlimits
Par intermittence après rotation des logsGestion SIGHUP / fds rouvertsCorréler horodatages avec newsyslogJournaux

Enveloppes PTY vs tubes bruts sous LaunchAgents

Des équipes enveloppent les serveurs MCP avec script, unbuffer ou des parents PTY maison pour que les enfants se croient interactifs. Compromis : les PTY ajoutent du CPU et du coût de copie mais retirent une classe de surprises de tampon. Les tubes bruts restent moins chers mais exigent un vidage discipliné dans l’enfant ou des cales stdbuf. Choisissez consciemment — mélanger les styles entre serveurs embrouille l’astreinte.

Sécurité : les PTY n’accordent pas la confiance — appliquez toujours les listes d’outils du déploiement MCP et l’hygiène des secrets du durcissement Keychain.

Atténuations toolchain (copier dans EnvironmentVariables du LaunchAgent)

Python : exporter PYTHONUNBUFFERED=1 ou appeler python3 -u ; pour les CLI packagées, préférer un point d’entrée qui invoque sys.stdout.reconfigure(line_buffering=True) sur les versions supportées. Node : consommez stdout en mode flux — les flux en pause sont un piège classique entre processus enfants. Go / Rust : videz explicitement après chaque trame JSON-RPC si vous contrôlez le code. Filtres shell : pensez à grep --line-buffered pour du tail via tubes en automatisation.

<key>EnvironmentVariables</key> <dict> <key>PYTHONUNBUFFERED</key> <string>1</string> <key>NODE_OPTIONS</key> <string>--max-old-space-size=4096</string> </dict>

Triage stdio en cinq étapes avant de réécrire l’agent

  1. Reproduire sous ssh en collant les mêmes ProgramArguments du plist dans un shell interactif — si ça marche soudain, vous avez un delta env/TTY.
  2. Équivalent strace sur macOS : sudo fs_usage -w -f filesys | grep mcp brièvement pour voir des écritures bloquées (avec parcimonie en prod).
  3. Séparer stderr vers un fichier rotatif pour que le spam de debug ne rivalise pas avec le JSON-RPC sur stdout.
  4. Test de trempage avec de grosses charges synthétiques après activation des atténuations.
  5. Choisir le transport : si stdio reste fragile, planifier du MCP HTTP selon le guide de déploiement.

FAQ

Augmenter le sysctl du tampon de tube règle-t-il le problème ? Dernier recours — la cause est souvent un rythme lecteur/écrivain désaccordé, pas seulement la taille du tampon.

Les serveurs MCP doivent-ils journaliser sur stdout ? Réservez stdout au JSON-RPC uniquement ; poussez les journaux humains vers stderr ou des fichiers structurés.

Apple Silicon change-t-il le tamponnage ? Non — le M4 vous fait juste toucher le bug plus vite, pas immuniser contre les défauts de libc.

Pourquoi le Mac mini ProxyMac est le bon endroit pour durcir le MCP stdio

Les mini Apple Silicon M4 en HK / JP / KR / SG / US offrent du métal toujours allumé pour rejouer chaque nuit les mêmes graphes stdio, accrocher de la capacité régionale à côté des API SaaS que vous appelez et garder des liens aide près du dépôt LaunchAgent. Quand des humains doivent valider des invites TCC, basculez sur VNC ; quand le réseau hésite, lisez IPv6 Happy Eyeballs SSH sur la même ligne de release.

Lancer OpenClaw sur du métal que vous pouvez stracer calmement

HK / JP / KR / SG / US · automatisation compatible stdio