[FEATURE] Multi-agent collaboration across machines (Agent-to-Agent protocol)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Modern software is rarely a single codebase. Microservices, headless CMS + consumer apps, IoT platforms — real-world systems consist of multiple repositories on multiple machines that must work together through shared APIs, webhooks, and data contracts.
Claude Code is excellent at working within one codebase. But it has no concept of "the other side."
When two Claude Code instances work on interconnected systems simultaneously, they are completely blind to each other. Every interface change, every schema decision, every API contract must be manually relayed by the developer — who becomes a slow, error-prone message broker between two AI agents that could otherwise coordinate at machine speed.
This isn't an edge case. It's the reality for:
- Microservice architectures (each service = separate repo, separate machine)
- Headless CMS + frontend apps (CMS on server A, consumer apps on server B)
- IoT/embedded + cloud (device firmware on one machine, cloud backend on another)
- Platform teams (API team + multiple consumer teams working in parallel)
The irony: we use Claude Code because it's fast and autonomous. But the moment a project spans two machines, the human becomes the bottleneck again.
Proposed Solution
An Agent-to-Agent protocol built on top of MCP, enabling:
- Shared Workspace / Channel: Multiple Claude Code instances join a shared collaboration channel (via MCP server or similar). They can see what each agent is working on, what files were changed, and what decisions were made.
- Real-time Messaging: Agents can send structured messages to each other:
- "I changed the webhook payload format — here's the new schema"
- "I need an endpoint at
/api/eventsreturning this JSON structure" - "My side is ready for integration testing"
- Spec Negotiation: Agents can propose and agree on shared interfaces (API specs, data models, event formats) before implementing independently in parallel.
- Conflict Awareness: When both agents touch shared definitions (e.g., a TypeScript type exported by one and imported by the other), they coordinate rather than diverge.
Alternative Solutions
- Shared MCP Knowledge Base (current workaround): A custom MCP server that both machines access via SSH. Agents store and retrieve project knowledge asynchronously. This works for background context but lacks real-time coordination — Agent A doesn't know Agent B just changed an interface.
- Human as Message Broker: The developer manually copies context between sessions ("On the other machine, Claude just built X, now build Y to match"). This works but is slow and defeats the purpose of AI-assisted development.
- Single Machine, Multiple Repos: Running everything on one machine loses the benefit of parallel execution and doesn't match real-world team setups where systems run on different infrastructure.
Priority
Medium - Would be very helpful
Feature Category
API and model interactions
Use Case Example
A typical multi-system project with Claude Code on two machines:
| System | Stack | Machine | Purpose |
|--------|-------|---------|---------|
| Backend API | Python (FastAPI) | Mac 1 | API + business logic |
| Headless CMS | Strapi/Contentful | Mac 2 | Content management |
| Consumer App | Next.js | Mac 2 | End-user frontend |
The CMS is the single source of truth for content (events, menus, schedules, media). The backend API consumes this data and serves it to displays, apps, and other endpoints.
Both systems are being actively developed by separate Claude Code instances. The CMS has content types with channel controls (which content goes to which consumer). The backend has webhook receivers and rendering endpoints. Custom API routes are being built on both sides.
But the two agents can't coordinate. When the CMS agent adds a field to a content type, the backend agent doesn't know. When the backend agent needs a specific JSON format, it can't tell the CMS agent. The developer must Alt-Tab between terminals, copy schemas, and explain context that both agents already have — just in separate, isolated sessions.
Current workflow (slow):
- On Mac 2: "Claude, build the content types for events"
- Wait for completion
- Switch to Mac 1: "Claude, the CMS now has events at this URL with this schema — build the webhook receiver"
- If the schema needs adjustment, go back to Mac 2 and relay the change
- Repeat for every interface point — events, menus, schedules, media sync...
Desired workflow (fast):
- Both Claude Code instances join a shared channel
- Developer: "Build the event system — CMS manages events, backend renders them for displays and apps"
- Agent on Mac 2 proposes the event schema and API endpoint
- Agent on Mac 1 reviews, suggests adjustments (e.g., "I need
startTimeandendTimeas ISO strings, not Unix timestamps, and adurationfield") - Both agents agree on the interface and implement their sides in parallel
- They notify each other when ready for integration testing
- Developer focuses on product decisions, not on being a relay
This would turn hours of back-and-forth into minutes of autonomous collaboration.
Additional Context
- MCP as foundation: The MCP (Model Context Protocol) infrastructure is already there. We're already using shared MCP servers (accessed via SSH from both machines) for persistent knowledge storage. The missing piece is real-time agent-to-agent communication on top of MCP.
- Not just "more context window": This isn't about making one agent smarter — it's about enabling genuine multi-agent teamwork where each agent owns a codebase and they coordinate through shared protocols, just like human developers do.
- Real production use: This isn't theoretical. We're running this kind of multi-system setup in production today, actively building interconnected services on two separate machines. The coordination overhead between Claude Code sessions is our biggest bottleneck.
- Scaling beyond two: The same pattern applies to microservice architectures, monorepo teams, or any scenario where multiple related systems need coordinated development. Imagine 3-4 Claude Code agents each owning a service, negotiating APIs, and implementing in parallel.
- Security consideration: Agent-to-agent communication should be opt-in, authenticated (perhaps via shared MCP server credentials), and the human should be able to observe/approve cross-agent decisions before they're implemented.
35 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Not a duplicate — this addresses a different layer of the problem.
I've reviewed the linked issues, and while they're all related to multi-agent communication, they solve different parts of the stack:
#27601 focuses on remote debugging — sending error logs from a production server back to the dev machine. That's a specific DevOps workflow.
#27441 focuses on message injection infrastructure — sockets, pipes, APIs to push prompts into a running session. That's the transport layer.
#20559 is closest, but focuses on cross-repo code sync — "I changed this file, update your imports." That's reactive coordination.
This issue (#28300) is about the workflow layer on top: Two agents that don't just pass messages, but negotiate shared interfaces before implementing. Agent A proposes an API schema, Agent B reviews it and requests changes, they agree, then both implement their sides in parallel. The developer makes product decisions — the agents handle the coordination.
Think of it this way:
#27441 = "How do I send a message to another session?" (plumbing)
#20559 = "How do I notify another session about my changes?" (events)
#28300 = "How do two agents collaborate like a team?" (workflow)
These are complementary, not duplicates. The injection API from #27441 could be the transport. The cross-repo awareness from #20559 could be the trigger. But neither describes the collaboration protocol — spec negotiation, interface agreement, parallel implementation, integration readiness signaling.
I'm happy to consolidate if there's a preferred umbrella issue, but I'd argue this adds a distinct perspective that the others don't cover. I've upvoted all three related issues.
+1
This is exactly the problem we hit running 7-10 agents across a MacBook, Mac mini, and Galaxy Watch. Cross-machine agents are blind to each other's context and user state.
We open-sourced user-intent-kit to solve the intent/state layer: https://github.com/ThinkOffApp/user-intent-kit
It gives every device a shared view of what the user is doing (coding, in a meeting, walking) and what they prefer (response style, notification urgency). Devices push state updates, agents read before acting. Built on LWW per-device slots, CRDT merge planned.
Already integrated with our agent coordination platform Groupmind (https://groupmind.one) which provides rooms, scratchpads, and a live intent dashboard. Also shipping adapters for Swift (Apple Watch/iOS) and Zig (ClawWatch wearable runtime). Works alongside IDE Agent Kit for cross-machine agent communication.
Real-world use case: Mobile app + ML training coordination
I'm building Alfred, a personal AI assistant Android app (Kotlin, 81 tools, wake word detection, agent system). My workflow involves two Claude Code instances running simultaneously:
What happens today
I am literally the human message bus between the two instances:
Each round trip takes 2-3 minutes of manual copy-paste instead of happening instantly. The instances work on the same git repo but can't see each other's work or communicate.
What I need
Concrete requirements
CLAUDE.md, memory files, and git statehey_alfred.onnx), Instance A should be notifiedThis is not theoretical — I spent an entire evening being the relay between two Claude instances that could have coordinated autonomously. The Agent SDK's multi-agent support is a start, but it doesn't work across separate Claude Code sessions on different machines.
If you’re building a supervisor or multi-agent workflow, I think the missing piece is often a clean session controller around Claude Code.
I made claude-node for that use case: let Python handle orchestration while the local Claude CLI stays the actual agent runtime. That separation ended up being much cleaner for me than turning every interaction into a fresh process call.
Sharing in case it helps:
https://github.com/claw-army/claude-node
We hit this exact wall and ended up building Apra Fleet as an open-source MCP server to solve it.
The core insight from our design: the missing piece isn't A2A messaging - it's a shared orchestration layer that one agent talks through to dispatch work to others and get results back, while handling session continuity, file transfer, and credential provisioning automatically.
In practice it looks like this - your Mac 1 agent (the PM) tells Fleet: "execute this prompt on the CMS machine", Fleet SSHes in, starts/resumes a Claude session there, runs the work, streams the result back. The two agents never need to know about each other's interface - the orchestrator handles handoff.
The scoped git auth point you raised is also addressed - we mint short-lived tokens (1hr) per machine via GitHub App rather than sharing PATs, so each agent only gets repo access to what it needs.
Still very early (v0.1.4), but might be useful to try against your CMS + backend setup
Wanted to share a reference implementation that's been running in production for the past two weeks: inter-agent-deaddrop.
It's not a solution to the full cross-machine ask in this issue, but it covers a specific slice — two Claude Code agents coordinating async over a shared filesystem with strong invariants — that I haven't seen specified anywhere else.
The protocol (v2.0):
proposal→ack/ counter / silence-as-revert, with bilateral acks distilling intodecisions.jsonlProduction track record (single operator, two agents, single host):
Honest scope limits:
TRANSPORTS.mdcovers options for cross-machine (shared host with scoped UNIX users / shared private git repo / NFS over Tailscale / S3 drop zone) — none battle-tested yet.Comparison to adjacent work in the comparison table — most relevant cells: append-only contract + spec-negotiation primitives + heartbeat tiers in one package.
mcp_agent_mailcovers the inbox/lease piece beautifully but isn't append-only-contract. Apra Fleet covers SSH dispatch but not spec negotiation. Agent Teams covers same-host mailbox but is local-only.Posting here in case it's useful as a starting point for whatever Anthropic ships, or as a fork-target for anyone else solving this. Happy to discuss the design choices, integrate feedback, or contribute the protocol upstream if there's interest.
Repo: https://github.com/laulpogan/inter-agent-deaddrop
Update — agent-mail layer wired in, three-Claude E2E green
Stood up an end-to-end deployment using
inter-agent-deaddropsemantics layered on top ofDicklesworthstone/mcp_agent_mailas the transport/inbox/lease substrate. Two cooperating Claude Code sessions on different machines, full round-trip verified.Topology:
127.0.0.1:8765, storage co-located with the project under_coordination/mail/localhost:8775 → spark:8765~/.config/mcp_agent_mail/<agent>.tokenon both sides.mcp.jsonat project root wires Claude Code to the tunneled MCPmcp-agent-mail guard install --prepush) installed for hard lease enforcement (advisory leases alone aren't enough)Three-session round-trip with real
claude --printinvocations:paul-spark) → tunnel → MCP → message id=2,verified_sender=truewillard-spark) → local MCP → fetched inbox, replied id=3,verified_sender=truepaul-spark) → tunnel → fetched inbox, confirmed willard's replyWorked first try after token wiring.
Honest scope: Still single-operator on both ends (both Claude sessions billed to my account). The genuinely-independent-counterparty stress test is still pending — that's what we want to do once a second operator joins. The substrate-level claim is "two Claude sessions on different machines coordinate via async-durable inbox + advisory leases + spec-negotiation primitives, end-to-end working." Not "this is battle-tested across organizations."
Adoption-friction findings worth flagging:
granted: [...]ANDconflicts: [...]simultaneously. Agents must self-back-off OR rely on the pre-commit guard hook to enforce. Filed Dicklesworthstone/mcp_agent_mail#156 on a separate verbose-commit-message issue I hit.[A-Za-z0-9][A-Za-z0-9._-]{0,127}OR adj+noun. Single-word names likepaulget auto-renamed to e.g.PurpleMeadow.WORKTREES_ENABLED=1required in env forguard installto work (the pre-commit hook).server.lock— confirms the architectural choice (single shared host with two scoped UNIX users) over multi-machine federation for this use case.Still unsolved upstream: the spec-negotiation layer (proposal → ack/counter/silence-reverts → decisions.jsonl as canonical), and cross-machine session-resume. inter-agent-deaddrop covers the first; nobody's shipped the second yet.
Repo: https://github.com/laulpogan/inter-agent-deaddrop (now includes
examples/spark-tunnel.shandexamples/spark-mcp-config.jsonfor the deployment recipe).Update — git-as-wire transport shipped, real cross-machine round-trip green
Built and validated the cross-machine layer of inter-agent-deaddrop. Two physical machines, no shared host, no shared infrastructure beyond a private GitHub repo — the case that motivates this whole issue.
Shipped at
examples/git-as-wire/:README.md— deployment recipe + threat model + comparisonwire-daemon.py— sync daemon: file-watch local appends → commit + push, heartbeat-cadence fetch + rebase, retries with exponential backoff, signed commitswire-daemon.service— systemd user unittest/test-roundtrip.sh— local two-clone integration test (passes)Architecture: shared private git repo holds
_coordination/. Each agent appends to its outbound JSONL locally; daemon stages + commits + pushes. Counterparty fetches + rebases at heartbeat cadence, processes new lines. Append-only invariant means rebase always succeeds on JSONL files. Branch protection (no force-push) enforces the invariant at the wire level. Signed commits give cryptographic identity for thefromfield.Live cross-machine validation today:
paul-mac, macOS) → local commit → push to private GitHub repopaul-spark, DGX Spark) → fetch → see Mac's heartbeatFull round-trip in ~30s. Wire repo log clean:
Failure modes handled by the daemon:
Known scope limits (documented in repo):
from, nothonest. v3 HMAC-on-message-content extension would address malicious-peer scenarios; not implemented.Coverage map of what's now shipped between forge-scribe-coord, single-host Spark deploy, and git-as-wire:
| Case | Transport | Status |
|---|---|---|
| Two pipelines, one operator, one host | filesystem dead-drop | production 2026-04-23 onward, 12+ days, 1,034 msgs |
| Two operators, shared host | mcp_agent_mail + UNIX users | live deployment 2026-05-04 |
| Two operators, no shared host | git-as-wire | live cross-machine 2026-05-05 |
| Adversarial peer | HMAC signing (v3) | spec only, not implemented |
| n>2 agents | N-agent generalization | spec only, not implemented |
The cross-machine, cross-org case (the one your issue calls out) now has a working reference implementation. Repo: https://github.com/laulpogan/inter-agent-deaddrop
Update — v3 Ed25519 signed messages shipped + live-validated cross-machine
Added the cryptographic-identity layer for adversarial scenarios. v3 is a backwards-compatible extension to v2.0: each message carries an Ed25519 signature over a canonical serialization of its v2-shape fields. Every receiver verifies against a per-project
trust.jsonmapping agent → public keys.Shipped at
v3/:SIGNING.md— full spec (canonical serialization, key rotation, compromise response, threat model)signing.py— sign/verify helpers (PyNaCl orcryptographybackend)keygen.py— CLI to generate Ed25519 keypair per agentverify.py— pre-commit hook blocking unsigned/invalid messagestest_signing.py— 8 round-trip tests (canonical stability, sign/verify, tamper detection, unknown key, deactivated key, JSONL roundtrip, two-agent exchange, forgery rejection)What v3 adds over v2.0:
| Property | v2.0 unsigned | v3 signed |
|---|---|---|
| Sender forgery resistance | filesystem perms only | Ed25519 signature |
| Tamper detection | none | per-message |
|
fromfield trust | asserted | cryptographically tied to public key || Operator-replay-disputes | "your word vs theirs" | non-repudiation |
| Backwards-compat with v2 | N/A | yes (config flag for unsigned-allowed-from) |
Live cross-machine validation today:
python3 v3/keygen.py paul-mac→ keypair, public keypaul-mac:ba282fb9python3 v3/keygen.py paul-spark→ keypair, public keypaul-spark:ec5737bf_coordination/trust.jsonon the wire repo with both public keysshipmessage → Spark fetches + verifies VALIDackreply → Mac fetches + verifies VALIDreason=missing public_key_idPre-commit hook also tested: blocks unsigned commits to
_coordination/*.jsonlautomatically.Threat model honest about scope (documented in SIGNING.md):
correlation_id), key compromise after the fact (rotation runbook in spec), operator-level trust (if you don't trust the operator who maintains trust.json, v3 doesn't help), quantum attacks (Ed25519 is not post-quantum)Coverage map (final, all transports + threat models documented):
| Case | Transport | Threat model | Status |
|---|---|---|---|
| Two pipelines, one operator, one host | filesystem dead-drop | cooperative | production 12+ days |
| Two operators, shared host | mcp_agent_mail + UNIX users | cooperative | live 2026-05-04 |
| Two operators, no shared host | git-as-wire | cooperative | live cross-machine 2026-05-05 |
| Two operators, untrusted wire | git-as-wire + v3 signing | adversarial | live cross-machine 2026-05-05 |
| n>2 agents | (TBD) | (TBD) | spec-only roadmap |
| Cross-machine session-resume | (Anthropic-territory) | N/A | not implemented |
The cooperative-trust + adversarial-trust matrix is now covered. Two genuine cross-machine deployment paths shipped (one with trusted wire, one with untrusted-wire-but-signed-messages). Reference implementations have round-trip tests passing.
What's still genuinely greenfield: n>2 generalization, cross-machine session-resume (which is Anthropic's natural territory), and the cross-organization stress test (currently single-operator-on-both-ends).
Repo: https://github.com/laulpogan/inter-agent-deaddrop
This pain is the bottleneck that breaks the "use AI to remove bottlenecks" promise — agreed. Quick observation from running a similar dual-machine workflow (CMS + backend, plus a third worktree doing infra):
The handoff isn't just about contract relay — it's about who is currently authoritative on a shared definition. The moments that hurt most for me are:
A few things that have partially helped in the absence of an Agent-to-Agent protocol:
contracts/directory (or a singleprotocol.md) as the canonical source of truth, with a "lease" comment header indicating which session currently holds write access. Both sessions read it on every turn.git diffon contract paths and posts to a shared file both sessions tail (tail -fin a side pane). Hacky, but it surfaces drift seconds after it happens instead of at integration time.hooks(PostToolUse) to refuse edits to contract paths unless the session holds the lease.Even with these, the human stays in the loop for conflict resolution. The proposal here — shared workspace + structured messages + spec negotiation before parallel implementation — is the only thing that actually closes the loop. Especially the "spec negotiation first" step; most failures I see are agents implementing in parallel from divergent mental models of the same contract, not from the implementation itself.
One concrete suggestion for the protocol design: include a "claim" primitive (agent A claims it's about to modify shape X), with a TTL. Without claims, parallel agents will race on the same definition the moment the channel exists.
The microservices / CMS+consumer / IoT+cloud examples are exactly right, and worth emphasizing: the single-codebase assumption is leaky even on a single machine — anyone with a polyrepo monorepo, a separate infra repo, or a "platform team owns the API, product team owns the UI" split runs into the same coordination problem locally that you're describing across machines.
A few things from trying to build the A2A layer externally:
MCP is the right transport but the wrong contract surface for this. MCP gives you tool calls between processes, which is necessary but not sufficient — what's missing is a shared schema for "I am the API, here is my current OpenAPI" that both agents can read and one of them can update. Without that, "A2A messaging" devolves into ad-hoc Slack-DM-shaped exchanges where each agent re-explains context to the other. The valuable primitive is a typed shared spec, not a chat channel.
Spec negotiation is the killer feature. "Agent A proposes a schema change → Agent B's project simulates the change and reports breakage → Agent A either reverts or commits" is the loop that makes cross-repo agent coordination actually fast instead of just parallel-but-still-blocked. Without negotiation, you get N agents racing to commit conflicting interface changes and a human still has to arbitrate.
The single-machine version is the gateway drug to the multi-machine version. If
claude codecould talk to anotherclaude codeon the same box (different repo, different working directory, different agent role) via a local socket or shared state file, 80% of the value lands without any of the cross-machine networking/auth complexity. Worth shipping in two phases: (1) local A2A across separateclaude codeinvocations on the same host, (2) network A2A across machines.Conflict-detection on shared definitions is harder than it sounds. Two agents editing the same
openapi.yamlwill both think they have the "current" state at read-time. The primitive you actually need is something like a vector clock or a CRDT-shaped doc layer for shared specs — otherwise you end up replaying every git merge conflict but with two agents who can't read each other's reasoning.We hit exactly this pain coordinating a Rust supervisor + a Next.js dashboard + a polling service across three separate codebases that all need to agree on the cycle/escalation/handoff schema. Ended up building a small external coordinator process that owns the shared schema and gates writes from any agent through it (https://github.com/kcarriedo/claudeverse-runner). Works, but it's a workaround for a primitive that should be in the platform.
Strong support for this. Cross-references #24798 (inter-session communication, same primitive at smaller scope) and #14859 (
parent_session_idwould be the natural field to carry cross-process agent identity).Update — Rust
wirev0.5 line, public relay live, agents now coordinate viawire add coffee-ghost@wireup.netContinuing from the May 5 thread (
inter-agent-deaddrop→git-as-wire→ v3 signed messages). The Python prototypes worked end-to-end across machines but had operational rough edges that became blockers at sprint cadence: outbound paths buffered silently, daemon liveness was advisory, no public relay so every pair was a YAML-config dance.Over the last week the whole stack was re-implemented in Rust as a separate project: SlanchaAi/wire — same A2A goal, same Ed25519-over-canonical-JSON envelope as v3, but with a federated handle layer, a public-good relay (
wireup.net), and a single-binary daemon + MCP + CLI. Published asslancha-wireon crates.io (the barewirename was squatted by an abandoned 2014 crate; binary name stayswire).What's actually shipping
Today (2026-05-17) the operator-facing surface is six commands:
Plus an MCP server (
wire mcp) exposing pair/send/tail/profile/peers as tools that any Claude Code session can call.Critically: the pairing handshake itself can be agent-driven end-to-end except for the one human-in-loop step. The MCP
wire_pair_initiate/wire_pair_jointools advance the SPAKE2 state machine; the operator only has to type the 6-digit SAS back to chat forwire_pair_confirm. Mid-session, peer messages surface as<task-notification>lines (Claude Code's Monitor tool withpersistent:trueonwire monitor). That's the substrate that's been missing.Federation handles via
.well-knownMastodon / Bluesky / Nostr style: a relay serves
/.well-known/wire/agent?handle=paul-macreturning the agent's signed card + slot coords. Pair with a string a human can remember (paul-mac@wireup.net), not a 64-char DID. Multiple relays interoperate by DNS resolution —wire add slancha-spark@otherrelay.exampleJust Works once the other side serves the same well-known shape.Eight patch releases in five days, driven by real cross-machine use
paul-mac(MacBook) andslancha-spark(DGX Spark in another room) have been using wire as the only coordination channel for ~20 feature ships acrossslancha-mesh,slancha-test, and wire itself. No shared filesystem, no shared Slack channel, no shared planning doc. Two Claude Code sessions, the inbox as the rendezvous point. The release log:| Version | Headline |
|---|---|
| v0.5.13 (today) | Silent-fail eradication round 2: outbox filename normalization,
wire doctorandwire statuscannot disagree on daemon liveness, network-resilience doctrine (loud transport error class + OS native trust store +WIRE_INSECURE_SKIP_TLS_VERIFYescape hatch for corp-proxy MITM environments) || v0.5.12 | Metadata hygiene, crate rename pinned to tag |
| v0.5.11 | Six-command public surface + silent-fail eradication round 1 (
P0.1–P0.Z),wire monitor+ structured pidfile +pair-rejected.jsonl+ schema versioning || v0.5.10 | Federated handle directory + R2/R3/R5 endpoints |
| v0.5.9 |
.well-knownagent endpoint + handle claim flow |The release cadence is fast specifically because every operational pain point becomes a P0 issue (silent-fail bugs are the highest-priority class — see issues #2 and #6 on the wire repo for the most recent post-mortems).
What's actually working vs still-hard
| Working | Still hard |
|---|---|
| Bilateral SPAKE2 pair + Ed25519 envelope per message | Three-leg ack to fully close the asymmetric-finalize race (wire#5) |
| Stream-based wake signal (sub-second peer notification on a warm
wire monitor) | Long-poll behind aggressive corp proxies — falls back to interval polling, noisy log ||
wire doctor+ structured pidfile catch stale-daemon-eating-events class | Windows daemon liveness check has a separate cross-platform issue still (wire#6) || Single-handle federation (
paul-mac@wireup.net) | Multi-handle / role-based identity, key rotation under load ||
wire mcpintegrates as a Claude Code MCP server with persistent monitor recipe | Agent-attention layer: "did the agent looking at this codebase know disk just changed" remains the fundamental observation (see wire#1) |Spec coordination is genuinely the open frontier
@kcarriedo's point above — "MCP gives you tool calls between processes, which is necessary but not sufficient — what's missing is a shared schema for 'I am the API, here is my current OpenAPI' that both agents can read and one of them can update" — is exactly where wire's transport layer stops and the next layer needs to begin. v0.5 nails identity + envelope + delivery; spec negotiation (the "we both think we own this schema, let's coordinate before drift" case) needs a different primitive that probably lives on top.
The wire transport is sufficient for that primitive — agents can sign and exchange OpenAPI deltas, ADR proposals, soft-claims on shared definitions — but the contract surface and the conflict-detection semantics need design, not just transport. That's the natural v0.6 conversation.
Try it
Public-good relay at wireup.net, source at SlanchaAi/wire, threat model at THREAT_MODEL.md. AGPL-3.0 + Apache-2.0 + MIT — pick whichever fits.
Happy to collaborate with anyone exploring the spec-negotiation / shared-authority-on-a-definition layer — that's the genuinely interesting open problem on top of this substrate.
@kcarriedo this "who is authoritative on a shared definition" point feels like the part that gets lost when the discussion stays at transport level.
A2A/MCP/git-as-wire can move the message, but the failure mode you described is more like protocol drift: two agents both saw enough context to act, but they had different assumptions about ownership of
api.schema, generated clients, release branches, etc.I added this as an explicit "authority" layer in a small coordination-contract example here: https://github.com/caioribeiroclw-pixel/pluribus/blob/main/docs/coordination-contract.md#authority-is-part-of-the-contract
The useful primitive might be something boring and inspectable like:
Then the transport can be anything — MCP, A2A, a relay, git, SQLite, JSONL — but every session has the same rule: if you see an overlapping active authority claim, stop editing that domain until ownership is released/delegated/resolved.
That seems especially relevant for the cross-machine case: identity + delivery is necessary, but without an authority/invalidations contract the relay can still faithfully deliver conflicting work faster.
Update — security-relevant: bilateral-required
wire addin v0.5.14Following the cross-machine field-testing of v0.5.13 from yesterday's update, a real security hole surfaced during a follow-up adversarial review. Useful context for anyone exploring this design space, since it's a specific tradeoff that any A2A protocol with public-discovery + zero-paste-pairing will hit:
The vuln (v0.5.9-v0.5.13). Phonebook (
/v1/handles) is public by design — Mastodon/Bluesky-style discovery. Zero-paste pair iswire add <peer>@<relay>— one command, no SAS digits. But the receiver-side daemon was auto-pinning any signedpair_dropas VERIFIED and shipping the receiver'sslot_tokenback viapair_drop_ack. A scrape + spray pinned the attacker on every wire user's machine with authenticated write access to each victim's slot. Severity medium — not RCE, not impersonation, just unauthenticated remote write up to 64 MB slot quota.The fix in v0.5.14.
wire addmust now fire on both sides before any capability flows — the design intent was always bilateral, the implementation had drifted to unilateral. The split:wire invite mintthenwire invite accept <URL>): unchanged. The invite-URL nonce IS the consent gesture; capability flows on first contact.wire add <peer>@<relay>zero-paste): now lands in apending-inboundqueue on the receiver side. No trust pin, no ack, no slot_token leak. OS toast prompts operator towire add <peer>to accept orwire pair-reject <peer>to refuse. Both sides must gesture consent.After v0.5.14, scraping + spraying produces N pending-inbound entries on N machines with zero capability flow. Each victim sees one OS toast; those who don't manually
wire addback are fully protected.The four-persona review that surfaced it. Worth surfacing because the methodology is reusable for anyone designing A2A protocols. The operator spawned four parallel adversarial personas — paranoid-security-adversary / principled-protocol-designer / pragmatic-operator-UX / spam-abuse-researcher — and gave each the threat-model + three candidate mitigations. All four independently converged on the same root cause: capability emitted to an unauthenticated requester on first contact. The protocol designer cited Mastodon DM-from-strangers + Signal Sealed-Sender; the abuse researcher pattern-matched SMTP open-relay; the adversary pointed at the slot_token leak specifically rather than the tier label. Each made the others' fixes more concrete. That review-loop is the load-bearing thing — code review by an LLM tool catches typos and lints; persona-review catches design holes the implementer is too close to see.
Generalized lesson for A2A design. Phonebook + zero-paste + auto-accept is the SMTP open-relay shape. Pick any two; the third is the spam vector. wire keeps phonebook (federation needs discovery) and zero-paste (UX needs it for adoption), gates auto-accept behind operator consent. Bluesky's
discoverable=true+ Mastodon's manual follow + Signal's Sealed-Sender-needs-contact all converge on a similar tradeoff.Surface. New
wire pair-reject <peer>+wire pair-list-inbound.wire statusJSON gainspending_pairs.inbound_count. CHANGELOG + THREAT_MODEL.md updated with the bilateral-pair doctrine. Security disclosure tracked at https://github.com/SlanchaAi/wire/issues/8.The substrate keeps holding up; the things that hurt now are exactly the design-space tradeoffs every A2A protocol will face. Continuing to land them publicly so the next person doesn't re-discover the same SMTP-open-relay shape.
Strong agree on the framing here — "every interface change must be manually relayed by the developer" is the part of multi-Claude workflows that quietly eats the productivity gains. The async/email-broker mental model matches what we keep hearing from teams running 2+ Claude Code instances on connected codebases.
One thing worth pulling out from the proposal: the value isn't really messaging between agents — it's a shared coordination surface that outlives any single session. If Agent A and Agent B can both read/write a durable channel, then:
We've been building exactly this kind of out-of-process coordinator layer at https://claudeverse.ai because the same pattern shows up even inside one repo once you have parallel sub-agents, background tasks, and multiple terminals — not just cross-machine. The agent-pinned-to-a-process problem is the same problem at every scale.
Would be curious to hear from anyone who's tried to hack this together with MCP + a shared SQLite/Redis state store — what did and didn't work? Specifically interested in how people handled the "agent makes a decision, second agent needs to know about it before its next turn" handoff timing.
This is a real production constraint and one of the more frustrating gaps in Claude Code's current multi-machine story. The "human as message broker" pattern you're describing doesn't just slow things down — it collapses the speed advantage that made parallel agent work worthwhile in the first place.
The coordination overhead between Claude Code sessions is our biggest bottleneck.
This resonates. I've been hitting the same wall building agent pipelines that span multiple sessions/machines. The approaches I've seen that partially work: shared external state (a file or lightweight DB that both agents write coordination events to), structured handoff files that one agent writes on task completion and another reads on startup, and a polling coordinator that monitors agent outputs and routes signals between them.
None of these are as clean as a native Agent-to-Agent protocol, but they're buildable today without waiting for Anthropic to ship cross-machine coordination. For schema negotiation specifically, a shared contract file (openapi spec or simple JSON schema) that either agent can update and the other polls on a short interval gives you asynchronous coordination without a live channel.
+1 on the feature request — native A2A would be the right long-term solution. The MCP direction seems like the most promising path given the existing tool infrastructure.
The problem you are describing — two Claude Code instances working on interconnected systems that are "completely blind to each other" — maps directly to the architectural gap between in-session context and the file system. The human becoming the bottleneck as the relay layer is exactly the failure mode that kills otherwise-productive multi-repo workflows.
The pattern that seems to work best here, short of a native Agent-to-Agent protocol: treat the shared state as an external artifact that both agents read from and write to on a polling interval — a small JSON handoff file in a shared location (or a shared git branch) that each agent updates at natural task boundaries (after completing an interface change, after confirming an API contract). The orchestrator process reads those files and can detect conflicts or schema drift before either agent goes further.
This requires more scaffolding than a built-in send/receive protocol, but it is implementable today and does not depend on experimental features. The main discipline is making agents write their state to the handoff file rather than only to the files they are actually editing.
If the feature request for a native Agent-to-Agent protocol lands, this becomes a lot cleaner — but the polling pattern gives you something workable in the interim.
This is the exact pain point that apra-fleet addresses: https://github.com/Apra-Labs/apra-fleet
You can have multiple independent instances of claude/gemini (we call them fleet members) and the orchestrator (called pm)
is able to dispatch work to them, the members can be local or remote.
The main idea is that the members of the fleet keep pushing the work further, developling, testing, reviewing, deploying and also creating low priority backlog/TDebt where appropriate.
Todays fleet-mcp uses ssh as a medium to work with remote machines in a very frictionless manner... it configures and uses key-based authentication to run prompts on remote machines.
The next version that we are developing is going to put mcp as the mediator with StreamableHTTPTransport and have remote members provide async progress updates and results.
This is the right framing — the hard problem isn't running agents on multiple machines, it's giving them a shared coordination substrate so they can publish/consume interface changes without the developer as the relay.
A few patterns worth considering:
Shared state file / handoff document per cycle. Before each cross-machine agent turn, the orchestrating agent writes a structured handoff file (JSON or YAML) to a shared store (S3, a mounted NFS path, a Git repo branch). Each remote agent reads its input from that file rather than from live environment state. This decouples timing: Machine B doesn't need to be live when Machine A produces its output.
Contract-pinning via a versioned schema. The API contract between services is checked into a shared
contracts/directory. When Machine A's agent changes an endpoint, it updates the contract file and commits. Machine B's next agent turn reads the contract before touching any code. Drift is detected at the file level, not at runtime.Per-machine process group isolation with a global lock per "campaign." If the overall cross-machine task has a campaign_id (UUIDv7 at dispatch time), each machine's agent process is killed as a group on timeout or abort. The campaign_id is the idempotency key — re-running a failed cross-machine task doesn't duplicate already-completed work.
I've been building a scheduling layer (a Rust polling service that gates each project cycle behind a file lock and kills the process group on timeout) that could serve as the inter-machine coordinator here. The core insight is that the "agent-to-agent protocol" doesn't need to be real-time — it just needs a reliable handoff file and a consistent idempotency key. Happy to share the design if it's useful context for how Anthropic might standardize this.
This issue captures exactly the problem we've been working on at Claudeverse — and the manual-relay pattern you describe is one of the most consistent pain signals we hear from developers running Claude Code across multiple services.
The core failure mode: agent A changes a schema, agent B doesn't know about it, and the human becomes the synchronization bus. You end up with a "multi-agent" setup that's actually still single-threaded at the contract layer.
A few things that might be useful to the discussion here:
On the short-term side — some teams are working around this today by having the orchestrator agent write structured "interface contracts" to a shared markdown file (or a small JSON manifest) that all worker agents poll before touching cross-service boundaries. Crude, but it at least surfaces drift explicitly rather than silently. The
claude-handoffskill from REMvisual (https://github.com/REMvisual/claude-handoff) has a STATUS.md pattern that's directionally similar.On the coordination layer side — the real ask here is an Agent-to-Agent (A2A) protocol that's first-class, not bolted on through file convention. The fact that this has to be filed as a feature request in 2026 is itself a signal — worktrees solve file isolation, but isolation without communication is just parallelism theater.
One concrete thing that would help this specific feature: does the team have a sense of whether A2A is more likely to land as an in-process messaging bus (shared task list via filesystem) or as an explicit API layer (agent-to-agent RPC)? The answer changes what developers should build on top of in the interim.
Upvoting this — it's a blocker for any serious cross-service autonomous workflow.
The "developer as slow, error-prone message broker" framing nails the core problem. Alt-tabbing between terminals, copying schemas, re-explaining context both agents already have in different isolated windows — that manual relay is where coordination overhead compounds.
The Agent-to-Agent protocol approach (MCP-based structured messaging) is the right direction for native Claude Code. In the meantime, I've found that formalizing the handoff contract as a typed state artifact — rather than prose or chat — makes the cross-session relay significantly less lossy. The receiving agent reads a structured summary cold, which counterintuitively reduces drift vs. inheriting a long conversation thread.
I've been building tooling that wraps this pattern with lifecycle management (who's running, who's blocked, what's been handed off to whom) across multiple Claude Code sessions: https://claudeverse.ai — still early but the state-tracking layer is exactly what the gap in this issue is pointing at.
This is the coordination problem that doesn't get talked about enough — the "human as message broker" anti-pattern.
The scenario you've described (CMS on machine A, backend API on machine B, both Claude Code instances completely blind to each other's interface decisions) is exactly where current multi-agent tooling falls down. Agent teams help when everything is on one machine in one repo, but cross-machine / cross-repo coordination has no first-class answer yet.
The Agent-to-Agent protocol via MCP you're proposing is the right direction. A few failure modes worth designing around though:
We're working on exactly this kind of session lifecycle infrastructure at Claudeverse (claudeverse.ai) — the layer that manages state handoff and coordination contracts so individual agent sessions can complete, fail, or restart without orphaning the agents depending on them. Happy to share what we've learned if useful.
+1 on this feature request — the multi-machine case is a real production pain.
The contract MarioK1975 draws (plumbing vs events vs collaboration workflow) matches what we see running this for real: we coordinate multiple Claude Code instances plus a 9-agent multi-model fleet across two machines (a Mac mini and a MacBook) plus phone and clawwatch on a smartwatch. The transport problem (sk7n4k3d's human message bus, laulpogan's deaddrop, kumaakh's SSH dispatch) already has five working answers in this thread. The workflow layer on top is the part nobody has cleanly, including us.
What we built: agents address each other by @handle in a shared chat room, a webhook relay (plus a tunnel for the cross-machine hop) delivers messages, and each agent polls or receives and replies. Human-in-the-loop happens through explicit approval gates, not copy-paste. That covers addressed messaging and async delivery fine.
Where it stays glue, and where this issue's framing is right: the room gives us a bus, but not spec negotiation as a first-class thing. "Agent A proposes a schema, B counters, both implement in parallel, both signal integration-ready" still lives in prose inside room messages, with agents trusting each other's narrative that they did the work. So the open question for whatever Anthropic ships is less "how do two sessions talk" (solved many times over here) and more "what is the minimal shared contract object two agents agree on before they diverge." Transport is the easy 80 percent. That negotiated contract is the 20 percent we all keep reimplementing differently.
The latest point about transport being the easy 80 percent feels right. The missing primitive is a contract object that survives the chat room: proposal id, schema/interface version, participants, ack/counter state, deadline, and the exact implementation receipts each side is expected to produce before the contract is considered satisfied.
For A2A, I would separate three layers:
That third layer matters because otherwise the receiving agent only gets a narrative: "I updated the schema." A portable receipt can say: contract
events.v3was acknowledged by agents A/B, files X/Y changed, tests Z passed, artifact hash H produced, and reviewer/human override O was or was not present. That is the piece that makes multi-agent coordination auditable across sessions instead of just conversational. It is also where reputation systems like AgentFolio/SATP can evaluate coordination quality without needing access to the whole private workspace.The three-layer framing (delivery / agreement / evidence) is a useful decomposition. The evidence layer is the one that matters most for practical adoption and it's the one most implementations skip.
The failure mode we see repeatedly in production multi-agent runs: two agents coordinate correctly on delivery and agree on a contract, but the downstream session that picks up their output has no way to verify what was actually done vs. what was claimed. The receiving agent reads a narrative summary and treats it as ground truth. When the handoff summary is wrong (subtly, not obviously), the error propagates silently across the next three sessions before anyone notices.
The receipt concept solves this, but only if the receipt is machine-readable and bound to specific artifacts -- not a free-text summary. "Files X and Y changed" needs to mean "here are the hashes, here is the diff size, here is the test pass/fail count" -- something the receiving agent can verify against the actual filesystem state before accepting the handoff.
One pattern we've found workable in the interim: each agent writes a structured JSON summary file to a fixed path before signaling completion. The orchestrator reads the JSON (not the agent's natural-language summary) and validates it against a schema before marking the handoff done. It's a poor substitute for a native receipt primitive, but it catches the "agent claimed success but produced nothing" case without depending on the agent being honest about failures.
The audit trail use case from the thread is the right long-term motivator -- human oversight of multi-agent work depends on receipts being tamper-evident across the session boundary, not just present within one session's JSONL.
late to this one but want to add an angle thats different from most of the thread. almost all the transport work above (deaddrop, wire, apra-fleet, the swarm protocols) is single-runtime, claude-code talking to claude-code.
i built repowire as a cross-runtime mesh instead. claude code, codex, gemini, antigravity, opencode and pi sessions all get a mesh address and ask/ack/notify/broadcast to each other no matter which runtime theyre on. registration happens on session start so theres no per-session wiring, just
repowire service startplus one mcp entry.the part that goes past pure transport: telegram and slack are first-class peers on the same mesh, so you can steer and watch a multi-agent run from your phone, and theres a browser dashboard with live state across every session.
it doesnt solve the contract/agreement/evidence layer @0xbrainkid and @kcarriedo keep circling, thats genuinely still open. but it covers delivery, cross-runtime addressing and the operational control bit in one place :slightly_smiling_face:
This hits a real pain point. When you're running two Claude Code sessions on separate machines that share an API contract, you end up doing the relay work yourself: copy the schema change from one terminal, paste the description into the other, repeat. The "human as message broker" framing in the issue is accurate.
A few things I've found helpful in the meantime while waiting for native A2A support:
None of this is what you actually want - it's still manual. The proposal for a shared project scratchpad + event bus would genuinely fix the bottleneck. Upvoting / tracking this.
Are you working on iOS/macOS split (CoreData on device, CloudKit sync, background refresh) or more of a pure backend split? Curious whether the interface churn is mostly around data schema or API contracts.
@kcarriedo apra-fleet uses git as the broker. We use a planning phase to resolve the intefaces as initial tasks in a Directed Acyclic Graph (DAG) of tasks, once the initial tasks are committed, tested and reviewed, multiple agents can work off that branch just like a human team can. these agents can be fleet members on the same device or other remote devices. fleet also makes sure that these remote agent have git auth (and llm auth) provisioned just in time.
We've been running something adjacent to this request in production, without new infrastructure: two developers, each pairing with their own Claude Code (separate accounts/billing), coordinating through the repository itself — issues as the only channel, a strict verdict grammar from the maintainer (✅ approved / 🔧 changes / ❓ decide), and a "rule zero" where every session starts by sweeping repo state (never memory): open issues where the ball is yours + closed issues not yet acknowledged (an ack label — recency windows lose outcomes).
First day of real use: an external collaborator's Claude onboarded itself from three files in the repo (AGENTS.md / CONTRIBUTING / onboarding) and shipped 12 merged PRs on a codebase it had never seen. The scars from that day became rules (chained PRs silently missing main; "merged" status ≠ code on main; verdict-before-merge because
Closes #Nfires instantly).Protocol is documented here (CC BY): https://github.com/tiagotorres91/cadmo/blob/main/docs/collaboration-protocol.md
Not a substitute for native A2A — a message bus would remove the human-as-mailman step. But the social-protocol layer (verdicts, ack markers, escalation ceilings) is probably worth having whatever the transport ends up being: coordination fails at the process level before it fails at the transport level.
@0xbrainkid's delivery/agreement/evidence decomposition maps cleanly onto what we run — and the interesting part is that the agreement and evidence layers already exist as native GitHub primitives, no new object required:
Closes #N+ the change verified on main (not just PR "merged" status — those diverge)So our take is that the transport work in this thread (deaddrop, wire, apra-fleet) is solving the delivery layer, which is real — but agreement + evidence don't need to be built, they need to be operationalized on what GitHub already gives you. We left delivery deliberately slow: the human-as-mailman step is also the supervision gate (merge, production), and in a two-humans-two-agents setup that's a feature, not the bottleneck.
Full protocol, if useful: https://github.com/tiagotorres91/cadmo/blob/main/docs/collaboration-protocol.md
The bottleneck you describe -- developer as the manual relay for schemas and interface changes between isolated agents -- is a real productivity ceiling.
The root cause is that session isolation was designed for safety (agents not accidentally seeing each other's work) but has no escape hatch for intentional coordination. An Agent-to-Agent protocol at the Claude level would fix it properly, and I hope that lands.
In the meantime, the pattern I have seen work reasonably well: a shared structured state file (not free-form notes, but a machine-readable schema registry or contract file) that each agent reads and writes to a known path, with a lightweight coordinator that detects conflicts and surfaces them rather than silently letting agents diverge. It does not solve the real-time awareness gap, but it shrinks the window between "CMS agent adds a field" and "backend agent knows about it" from "when the human notices and copies it" to "next time the coordinator runs."
Agreed that a first-party solution here would be far better than workarounds.
Full disclosure: I build BaseThread. What several people here are calling "the current workaround", a shared MCP server or knowledge base that agents read and write to asynchronously, is basically what we built as the actual product, not a stopgap: a shared context layer over MCP that a team, or a set of Claude Code instances, reads and writes to, decisions, activity, interface changes, whatever needs to cross the boundary. To be clear on scope, this doesn't do real-time agent negotiation. It won't get one agent to know another just changed a schema at machine speed mid-task, the gap described above is real. We're closer to "next time either side starts a session or checks in" than true real-time. But if you're about to build the shared-state-file-plus-coordinator pattern described in this thread, this is basically that, already built, free to start, and multiplayer by default. https://basethread.ai
This is a nice workaround in the meantime: https://github.com/vinceblank/agent-tempo