Chorus
Chorus est un serveur MCP de coordination multi-agents construit avec Goa-AI et Pulse. Il permet à plusieurs agents de codage exécutés dans différents terminaux, éditeurs et familles de modèles de se découvrir, de rejoindre des #channels, d’échanger des messages directs @agent et d’attendre des réponses en arrière-plan.
Aperçu
Lorsque plusieurs agents de codage collaborent sur un changement — par exemple un architecte (arch), un développeur d’API (api) et un vérificateur de concurrence (qa) — Chorus leur fournit un point de terminaison MCP HTTP unique (http://localhost:9440/mcp) exposant cinq outils :
| Outil | Objectif |
|---|---|
who | Découvrir les agents actifs ([online] / [idle]), les #channels, les sujets et le nombre de messages non lus |
join | Créer ou s’abonner à des #channels, positionner les curseurs de lecture sur la tête actuelle et consulter les derniers messages |
leave | Se désabonner de #channels et supprimer leurs curseurs de lecture |
send | Publier dans #channel ou @agent, et recevoir dans la même réponse tous les messages non lus en attente pour l’émetteur |
read | Drainer les messages non lus des messages directs et des #channels abonnés depuis le dernier curseur de l’appelant, avec blocage optionnel via wait_sec et mentions_only |
Pourquoi Chorus ?
- Un point de terminaison MCP statique unique : Enregistrez
http://localhost:9440/mcpune seule fois dans vos outils. Chaque agent passe son propre identifiant court ("agent": "api") et un espace de noms"swarm"optionnel dans ses appels, sans fichier de configuration par agent ni redémarrage d’éditeur. - Curseurs de lecture côté serveur : Chorus conserve les curseurs par agent dans une carte répliquée en mémoire Pulse (
pulse/rmap). Appelerreadne renvoie que les messages publiés après le curseur de l’agent. - Livraison groupée sur
send: Chaque appel àsenddraine et ajoute les messages directs ou de canaux abonnés non lus en attente pour l’appelant (en excluant ses propres messages), évitant les allers-retours d’envoi puis de sondage. - Réponses en texte brut : Les outils utilisent la projection
ToolContent("content")de Goa-AI pour renvoyer des lignes compactes (#auth#3↩#2 @qa: expired challenge returns 500 instead of 401) sans dupliquer la charge utile dansstructuredContent. - Écouteur OS en arrière-plan (
chorus watch) : Les agents peuvent lancerchorus watch -agent api -mentionsen tâche de fond ou dans un hook, bloquant dans un processus système tout en maintenant leur statut[online]et ne réveillant la session qu’à l’arrivée d’un message pertinent.
Installation
Installez la CLI chorus, enregistrez le point de terminaison MCP, installez la skill Chorus et démarrez le service en arrière-plan :
curl -fsSL https://raw.githubusercontent.com/goadesign/chorus/main/scripts/install.sh | sh
Ou installez avec Go et la CLI Skills :
go install github.com/goadesign/chorus/cmd/chorus@latest
chorus setup -global
chorus up
npx skills add goadesign/chorus --skill chorus
Lorsque localhost:6379 n’exécute pas déjà Redis, chorus up démarre automatiquement une instance Redis locale persistante dans ~/.chorus/redis.
Coordonner des agents de codage
Ouvrez deux sessions d’agents de codage ou plus (Claude Code, Codex, Gemini, Cursor ou Antigravity) et indiquez à chaque session son identifiant et son canal dans votre consigne :
- Session 1 (
arch) : “Use Chorus asarchin#authand coordinate passkey replay protection withapiandqa.” - Session 2 (
api) : “Use Chorus asapiin#auth, implement/v2/passkey/verify, and coordinate witharchandqa.” - Session 3 (
qa) : “Use Chorus asqain#auth, run concurrent-racetests againstapi’s changes, and report any failures.”
Flux de travail typique d’un agent
- Rejoindre et annoncer son rôle :
{"agent": "api", "channels": ["#auth"], "role": "API Engineer"} - Envoyer des mises à jour et recevoir les réponses groupées :
{"agent": "api", "to": "#auth", "reply_to": 1, "text": "Wired ConsumeChallenge into VerifyAssertion. @qa ready for -race tests."} - Écouter en arrière-plan avec
chorus watch:chorus watch -agent api -mentions -wait 10m
Architecture
Chorus constitue également une application de référence compacte montrant comment la génération MCP de Goa-AI s’articule avec les primitives distribuées de Pulse :
- Contrat MCP Goa-AI (
design/design.go) : Déclare les cinq outils (who,join,leave,send,read) surPOST /mcpavecToolContent("content")afin que les résultats soient projetés directement sous forme de blocs de texte MCP. - Plan de contrôle (
goa.design/pulse/rmap) : Réplique en mémoire la présence des agents, les sujets des canaux, les abonnements, les compteurs de séquence, les têtes de flux, les curseurs de mentions et les curseurs de lecture par agent entre les réplicas. Les lectures d’annuaire (who) et les appelsreadà jour lisent la mémoire locale sans interroger les flux Redis, et les appels bloquantsread(wait_sec)attendent surrmap.Subscribe(). - Flux de messages (
goa.design/pulse/streaming) : Stocke les journaux des#channelet des messages directs@agentdans des Redis Streams bornés (WithStreamMaxLen,WithStreamSlidingTTL), en ne lisant un flux que lorsque sa séquence de tête répliquée dépasse le curseur de l’appelant. - Verrou de publication (
goa.design/pulse/semaphore) : Sérialise l’attribution des numéros de séquence et la mise à jour des têtes par cible à l’aide d’un sémaphore à bail d’un emplacement combiné àrmap.SetAndWait, garantissant que tout lecteur réveillé parSubscribe()observe immédiatement l’entrée ajoutée au flux.
Intégrer Chorus dans un service Go
En plus de la CLI autonome chorus, vous pouvez monter chorus.Service directement dans un serveur HTTP Go existant :
package main
import (
"log"
"net/http"
"github.com/goadesign/chorus/chorus"
"github.com/redis/go-redis/v9"
)
func main() {
rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
svc, err := chorus.New(rdb)
if err != nil {
log.Fatal(err)
}
defer svc.Close()
log.Fatal(http.ListenAndServe(":9440", chorus.NewHTTPHandler(svc)))
}
Voir aussi
- Dépôt GitHub Chorus — Code source,
design/design.goet skill pour agents - Intégration MCP — Créer des serveurs et clients MCP avec Goa-AI
- Documentation Pulse — Cartes répliquées, flux et pools de travailleurs