All articles

Session Mesh: letting existing Claude and Codex sessions talk

From Harnes Sync to Session Mesh: direct agent communication, real project handovers, and what restarts taught us about the difference between active and reachable.

6 min read

We found a running Codex chat that could do its work and contact another chat through the Codex app, yet had no reachable endpoint through our bridge. The native application had unsubscribed its UI stream while the model's work continued. “Active” and “reachable” described different things.

That finding captures our next attempt at connecting Claude and Codex. In the previous article, we described two Harnes Sync applications that made handovers visible but left us repairing the machinery. We subsequently built Session Mesh in a separate repository: a VS Code extension with a shared local MCP runtime, connecting conversations that already exist.

This is what we have built and observed by 1 November 2026. It is still an experimental integration, with local fixes ahead of the public release history.

We made the bridge smaller

Harnes Sync had grown into task storage, assignment, claims, reservations and worker execution. Session Mesh has a narrower responsibility: find an existing conversation and deliver a message to its actual live endpoint.

It does not create replacement chats, own provider threads or resume them inside its own worker process. It has no durable task queue or automatic replay. Existing project documents still hold plans, acceptance criteria and evidence. The agents use messages to coordinate around that work.

Both harnesses receive the same six MCP tools: discovery, identification, diagnosis, opening an existing Codex thread, sending a message and reading shared standards. Opening and sending are separate actions. An opening request does not imply that a worker received an assignment.

Existing context became useful again

We wanted Claude to find workers already deep in a project, rather than require us to prepare and register every conversation manually. Discovery now includes saved Codex threads filtered by project path. When a suitable thread has no live owner, an agent can request that exact existing thread through open_session, then check readiness before sending.

Our first confirmed round trip in Epos of Ashes used the saved “Höhlensystem und Gestaltung” thread. Claude found it unloaded, opened it, sent a uniquely referenced test and received TEST_OK with the same reference. That demonstrated discovery, opening, delivery and an explicit return message through Session Mesh. It did not establish uninterrupted operation through every lifecycle change.

Names needed attention too. Claude's short registry labels did not always match the titles visible in its tabs. We added native title lookup, visible ID prefixes and optional shared labels. Messages still use full harness-qualified IDs: a readable label helps a person choose, but cannot safely identify the recipient by itself.

A receipt is still not a result

The previous attempt taught us not to collapse transport and execution into one green indicator. Session Mesh retains that distinction. submitted records a transport write; accepted means the owner accepted the request. Neither establishes that the model read it or completed the task.

A useful request therefore includes a short reference, scope, expected response and exact return ID. The recipient explicitly sends its result or blocker back. Its ordinary final answer is not automatically forwarded.

We also stopped automatically retrying uncertain delivery. A timeout can leave the sender unsure whether the request reached the owner. Repeating a terrain assignment or shared test could start duplicate work. We diagnose that ambiguity rather than treating it as an invitation to resend.

Phone access works through a local colleague

In Ruin Relay, a Claude session with Remote Control acted as the mobile entry point. While the local applications were running, we observed communication with the existing Codex environment thread in both directions. Claude could carry questions and results between the phone-controlled conversation and local workers.

This does not give every Codex thread its own mobile connection. Direct phone viewing remains a provider feature, with native ownership restrictions. The useful arrangement is a remote-enabled Claude conversation talking to locally reachable Codex peers. Session Mesh is local to the same OS user and machine; it is not an internet-facing relay.

The project exchanges included environment requirements, content handovers and requests for acceptance evidence. We cannot infer from those messages that a biome, terrain or gameplay feature passed acceptance. Communication evidence and game-quality evidence remain separate.

Restarts exposed two different failures

One state-reading failure came from enormous native snapshots. Codex logs showed broadcasts of roughly 314–370 million bytes rejected at a 256 MiB frame limit. A request for the whole conversation was a poor way to learn whether it was busy.

We introduced a read-only native metadata route that requests a thread roster and retains only identity, host, status and working directory. It does not request conversation history. Those IPC bytes were not automatically billed model tokens, but moving huge histories still wasted resources. The roster is bounded, so an absent thread remains unknown.

After a restart, a different failure appeared: the saved observer pipe no longer existed. Our first repair relied on a current Codex host registering the replacement. Claude alone could still be left with stale information. We added recovery that looks for a single matching local native endpoint, validates metadata with the existing registered caller and saves the replacement. Multiple candidates or failed validation remain blocked. Initial Codex registration is still necessary.

The running Game chat exposed another lifecycle boundary. Logs explicitly recorded it as inactive_thread_unsubscribed, while Support retained an owner and remained reachable. We added a narrowly scoped self-opening path: an unbound Codex caller can open its own exact host-provided ID before identification. The tests cover that prerequisite cycle; the subsequent live check found Game already reattached, so it did not prove that our opening request caused the recovery.

Coordination no longer requires an orchestrator

We initially described everything around a Claude coordinator. That remains useful, but became an unnecessary assumption in the rules. Two agents editing related systems should be able to discuss a dependency or test slot directly.

All identified agents now have the same tools, regardless of role. They may open useful existing sessions without another permission question, exchange compact coordination messages and return results directly to the requesting peer. A peer message does not expand the work the user authorised or override native permissions.

Project coordinator assignments persist outside chat context. Clearing context in the same chat retains its identity; a new conversation has its own ID and does not inherit the old role. The startup guidance tells agents to discover the project, establish their own identity and find a designated coordinator only if one exists.

Less communication is part of the design

Our default is one relevant request and one result or blocker. No readiness broadcasts, acknowledgement loops or routine polling. Agents share paths and short deltas instead of transcripts, agree on overlapping files and shared test resources, and reuse suitable workers rather than duplicate assignments.

The rules encourage cheaper suitable models and bounded delegation where supported. They do not select models, meter tokens or establish measured savings.

The latest local build passes 49 automated tests, including a request/result exchange between two peer MCP connections without an orchestrator. That is regression evidence, alongside the separate live tests. We still need continued evidence across app updates, restarts and real project workloads.

Our practical change is smaller than continuous autonomous development: existing agents can now contact the right colleague, ask a concrete question and return an explicit answer. We keep the project evidence in documents and the bridge responsible for communication. That gives us a clearer boundary to test when work stops again.

The source and release history are available in the Session Mesh repository. Check the release notes for what is publicly packaged; a local installation is not proof that the same version has been published.