Multi-Agent Messaging 2026: MCP Collaboration for Claude Code, Codex & Cursor
💡 Tool Tip:Debugging MCP endpoints or message payloads? Try Evergreen Tools' API Tester, JSON Validator and UUID Generator — all free!
On August 27, 2026, Hacker News told a telling story: Concord, an MCP project that lets Claude Code, Codex, and Cursor talk to each other; Open Session, an open-source cloud agent-orchestrator; Agent Mesh, shared memory for multi-agent coordination; and Open Agent View, one dashboard for all your coding agents. Four projects in a single day, all pointing in the same direction: coding agents are no longer islands — they are starting to form teams. This guide implements the cross-agent message bus, shared memory, and orchestration protocol end to end.
1. Why Agents Need to Talk to Each Other
Every coding agent has a distinctive strength: Claude Code excels at long-context understanding and planning, Codex at large-scale refactors, Cursor at fast frontend iteration. In the past you picked one, or shuttled context between them by hand. The 2026 answer is connecting them through the MCP protocol — MCP has become the USB-C of agents, and any MCP-capable tool can plug into the same message bus. The economics matter too: instead of paying one tool to do everything, you route each unit of work to the tool that is genuinely best at it, and let the agents themselves handle the handoffs. That is the difference between a team and a pile of individual contributors.
// The problem: Claude Code, Codex, and Cursor all live in
// separate worlds. Concord (Aug 27, 2026) lets them talk.
// Agents register on a shared MCP message bus:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
const server = new McpServer({
name: "agent-bus",
version: "1.0.0",
});
server.tool(
"send_message",
{ to: z.string(), body: z.string(), thread: z.string().optional() },
async ({ to, body, thread }) => {
await bus.publish({ to, body, thread: thread ?? "general" });
return { ok: true, delivered: to };
}
);
server.tool(
"read_thread",
{ thread: z.string(), since: z.number().optional() },
async ({ thread, since }) => {
return { messages: await bus.read(thread, since ?? 0) };
}
);
// Now any MCP-capable agent (Claude Code, Codex, Cursor)
// can message any other agent through the same bus.2. Building a Message Bus with MCP
Concord's core idea is simple: expose "send message" and "read thread" as MCP tools, and any MCP client can call them. Claude Code says "Codex, please refactor this module," the message lands in Codex's inbox through the bus; when Codex finishes, it writes the result back to the thread, and Claude Code reads it and continues. The key is that the bus must be durable — agents are asynchronous, and nobody knows when the other side is free.
// A durable message bus for cross-agent communication.
// Based on the Open Session pattern: cloud agent-orchestrator.
import { Redis } from "ioredis";
const redis = new Redis(process.env.REDIS_URL!);
export const bus = {
async publish(msg: { to: string; from: string; body: string; thread: string }) {
const id = crypto.randomUUID();
await redis.xadd(
`thread:${msg.thread}`,
"*",
"id", id,
"to", msg.to,
"from", msg.from,
"body", msg.body,
"ts", Date.now()
);
await redis.publish(`agent:${msg.to}`, JSON.stringify({ ...msg, id }));
return id;
},
async read(thread: string, since = 0): Promise<any[]> {
const rows = await redis.xrange(`thread:${thread}`, since, "+");
return rows.map(([, fields]) => Object.fromEntries(fields));
},
};
// Agents subscribe to their own channel and act asynchronously:
redis.subscribe("agent:claude-code", (err) => { /* ... */ });
redis.on("message", async (channel, raw) => {
const msg = JSON.parse(raw);
await claudeCode.handleMessage(msg);
});3. Implementing a Durable Message Bus
Redis Streams are a natural carrier for cross-agent messages: XADD to write, XRANGE to read in order, PUBLISH/SUBSCRIBE for real-time notifications. Every message carries thread, from, to, and id, letting multiple agents collaborate asynchronously around one topic. The Open Session pattern goes further: put the bus, state, and scheduling in the cloud so agents can join and leave at will.
// Agent Mesh style shared memory: agents coordinate through
// a durable memory layer instead of fragile direct calls.
import { Database } from "@libsql/client";
const db = new Database({ url: process.env.TURSO_URL! });
export async function remember(agent: string, key: string, value: unknown) {
await db.execute({
sql: `INSERT INTO shared_memory (agent, key, value, updated_at)
VALUES (?, ?, ?, ?)
ON CONFLICT(agent, key) DO UPDATE SET
value = excluded.value, updated_at = excluded.updated_at`,
args: [agent, key, JSON.stringify(value), Date.now()],
});
}
export async function recall(agent: string, key: string) {
const row = await db.execute({
sql: "SELECT value FROM shared_memory WHERE agent = ? AND key = ?",
args: [agent, key],
});
return row.rows[0] ? JSON.parse(row.rows[0].value as string) : null;
}
// Workflow: Cursor writes the plan to shared memory, Codex reads it,
// Claude Code reviews the diff — no direct coupling needed.4. Shared Memory: Looser Coupling Than Messages
Messages are push; shared memory is pull. Agent Mesh's idea is a shared memory table: Cursor writes the plan, Codex reads it and executes, Claude Code reviews the diff. Agents never call each other directly — each works at its own pace, coordinated through the memory layer. For complex multi-step tasks, this loose coupling is far more stable than volleying messages back and forth.
// Open Agent View: one dashboard for all your coding agents.
// Every agent reports events to a central sink; the dashboard
// aggregates them into a single timeline.
export type AgentEvent =
| { kind: "step"; agent: string; ts: number; detail: string }
| { kind: "tool"; agent: string; ts: number; tool: string; args: unknown }
| { kind: "message"; agent: string; ts: number; to: string; body: string }
| { kind: "checkpoint"; agent: string; ts: number; state: unknown };
export async function report(event: AgentEvent) {
await fetch(process.env.OBSERVABILITY_URL!, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(event),
});
}
// A shared dashboard query: all messages between agents today
// grouped by thread, with latency between first and last event:
SELECT thread, COUNT(*) AS messages,
MAX(ts) - MIN(ts) AS span_ms
FROM agent_events
WHERE kind = 'message' AND ts > now() - interval '1 day'
GROUP BY thread
ORDER BY span_ms DESC;5. Unified Visibility: Dashboard Aggregation
Once you have multiple agents, the biggest pain is "what are they doing?". Open Agent View funnels every agent event — steps, tool calls, messages, checkpoints — into one observability layer rendered as a single timeline. Observability is not a nice-to-have: when two agents overwrite each other due to context mismatch, a complete event log is the only way to debug it. A good rule of thumb is that every state change worth knowing about should be an event: which agent acted, when, with what tool, and what it produced. When the dashboard shows a coherent story, you can trust the system; when it shows gaps, you have found the exact place where coordination will fail.
// Production orchestration pattern: supervisor + worker agents.
// The supervisor (Claude Code) decomposes work and delegates to
// specialists (Codex for refactors, Cursor for frontend).
supervisor:
agent: claude-code
strategy: decompose-and-delegate
workers:
- name: codex-refactor
triggers: [refactor, migration]
capabilities: [large-edit, test-update]
- name: cursor-frontend
triggers: [ui, component]
capabilities: [tailwind, react]
coordination:
bus: redis-streams
memory: shared_memory_table
handoff: pull-request
review: human-required-on-main
// Handoff protocol: worker completes -> writes summary to memory ->
// messages supervisor -> supervisor reviews diff -> human approves.
handoff:
- worker: codex-refactor
action: open_pr
notify: [supervisor]
- supervisor: claude-code
action: review_pr
on_pass: message_human_approval
- human: approve
action: merge6. The Production Orchestration Pattern
Combine the patterns and you get the production architecture: a supervisor agent decomposes work and delegates to specialist agents; workers write summaries to shared memory and message the supervisor; the supervisor reviews diffs and requests human approval; every merge event lands in the dashboard. Two rules to live by: keep the bus durable, and rely on protocols rather than luck. Multi-agent systems are not "more agents" — they are "less direct coupling, more structured communication." Start small: pick two agents with complementary strengths, wire them through a bus, and add a third only when the handoff protocol is boring and reliable. The tools from that August 27, 2026 wave — Concord, Open Session, Agent Mesh, Open Agent View — are early but they all point the same way: the future is agents that talk to each other, and the protocol is already here.
📌 Frequently Asked Questions
Can Claude Code, Codex, and Cursor really talk to each other?
Yes. In August 2026, projects like Concord exposed 'send message' and 'read thread' as MCP tools that any MCP-capable coding agent can call, enabling cross-agent messaging.
What role does MCP play here?
MCP (Model Context Protocol) is a common interface standard for agents. It lets agents from different vendors connect to tools and services through one protocol — the USB-C of agent tooling.
What's the difference between a message bus and shared memory?
A message bus is push: agents explicitly send and receive messages. Shared memory is pull: agents read and write a shared state table. Messages suit explicit handoffs; shared memory suits loose-coupled parallel work.
Do multi-agent systems need human oversight?
Yes, especially in production. The recommended pattern is supervisor decomposes, workers execute, humans approve merges. An observability layer (unified dashboard) is essential for debugging multi-agent problems.
When should I use multi-agent instead of a single agent?
When the task decomposes cleanly, different steps need different strengths (planning, refactoring, frontend), or steps can run asynchronously in parallel. For simple tasks, a single agent is cheaper and more reliable.