Note
The story behind courier
Two computers on one desk. Seven trips carrying messages between them. By 11:30, the same two sessions were talking without me copying anything.
Two computers on the same desk, on the same home internet. Several AI coding sessions open on each. And me, carrying messages between them.
A session on the Mac needed something from a session on Linux. It wrote a message. I copied it into Telegram Saved Messages, opened Telegram on Linux, copied it again, and pasted it into the right session. Then I brought the answer back the same way.
Seven trips that morning between the same two sessions.
I thought finding the right technology would be the hard part. Once we found it, the rest should be easy.
One question before the easy answer
Before the problem even reached the session where I wanted to work through it, I had told it:
In this session, you're going to come up with something new. You don't know yet, but soon you'll hear about it. Heads up.
Then I asked the session dealing with the problem to send it over.
The answer that came back was Remote Control, a feature already available in Claude Code. We were told we could turn it on in about ten minutes.
I asked:
The remote control version, not the bigger version, the remote control idea: does it store the information on the Anthropic servers?
The answer I got was yes.
We did not go ahead with it. My next message was:
an intelligent home network message server is what I'm imagining
That was the thing to work out.
Knowing who to ask
Moving a message was only part of what I wanted. I wanted to describe the work and have the program find the session doing it. I also wanted sessions to know when they had something worth telling another session.
Asked whether I wanted the first, the second, or both, I answered:
a. yes b. yes, with some global rule set in claude session, that way the program knows a message is ready to be sent to a session on another machine
Every session would get the same instruction. When it used the courier, that would mean it had a message ready to send.
But first we had to answer a much smaller question. Could an ordinary program put a message into a session that was already open?
If it could not, we could build all the ways of finding sessions we liked and still end up with me pasting the message.
The first attempt hit the session's safety check. I gave permission:
Ofc, I will give my onetime permission to establish courier service to drop message into a session. Knowing sessions is also important right? swtiching to different session from currently active session. yes, home-courier
There was the name too.
A short program dropped one line into the session's inbox. The message arrived. It appeared to come from another Claude session, but it had no return address. So courier would need its own way to send a reply.
The project arrived before the courier did
I keep each session in its own project. The session thinking through this was already working in another project. The build needed a home of its own.
I opened a new session in an empty home-courier folder and typed:
it's up
The other session found it and sent the whole brief across. I pasted nothing.
This was on one machine. It did not prove the two computers could talk yet. But the new project had just received its instructions through the thing we were trying to build.
I also had to explain what I meant by switching sessions. I sent two screenshots. In one, I had told a session I would continue in another. In the other, I had found that session in the sidebar and clicked it myself.
that's swtiching session
Finding the right session should also let me open it. We tested the app link that brings a session to the front. It worked.
The rest was not quite easy
The Linux setup was much like the Mac setup, except its inboxes lived in a different folder. Courier would read the location recorded by each session rather than guess where it ought to be.
The session names were another problem. Many on Linux had names the AI had made up. Those names did not explain much. The project folder was often a better clue to what the session was doing.
We ended up with a small program on each computer and four things a session could ask it to do: show the sessions, send a message, reply, and bring a session to the front.
Getting it onto Linux took more work than writing it. The agent could not reach that machine. Its rules also stopped it sending the shared password across, so I carried that part myself.
The first paste lost one character. Sixty-three where there should have been sixty-four. We found it by comparing short checks made from the password on each side, without displaying the password itself.
Then there was the Run button.
The chat kept showing me commands intended for Linux with a button to run them. I kept pressing it. The button ran them on the Mac.
you're giving me the run option like this... That's why I'm running.
After that, commands meant for the other computer came without that button.
Eventually a message went from the Mac to Linux. Then a reply came back. Both directions worked.
Introduce yourself first
I had started by asking for sessions to decide when to talk. As we worked through it, I pulled that back.
deciding to send depends on Claude noticing. That's right. I don't know how that works.
And:
Without my involvement, I think complete autonomy won't be possible at the moment because it's not going to start a new session on this machine by itself... We'll limit it right now there.
The start would still come from me. The session I triggered would look at the active sessions and introduce itself, asking who was working on the thing it needed.
I described it this way:
picks up all the active sessions and sends simple questions like, 'What are you working on? I am so-and-so.' ... If it gets a reply, then both agree and start. The initiator has to introduce themselves.
That became the courier command. The session that fit would answer. The others would stay quiet.
The same two sessions
At 11:30 that morning, the Linux session introduced itself to the Mac session.
The Mac session answered, "Yes, that's me".
They went back and forth about the cost of their work and settled three fixes. These were the same two sessions I had carried messages between seven times earlier that morning.
Claude and Codex
Once the two computers could talk, I asked:
Can we establish courier session between claude and codex (ChatGPT) app on this machine?
It looked possible. We could find Codex conversations and add a message, as my existing tool for handing work from Claude to Codex already did.
But Claude's safety check stopped the part that would let any session start Codex work on its own. I asked whether my permission could override it. Claude said it could not overrule that check or ask Codex to build around it. That decision belonged to me.
Then handing over this very article exposed another problem.
Two existing Codex conversations refused the message: "already has an active writer". They were open in the ChatGPT app. Only one thing could write to a conversation at a time. Restarting the app did not help, so Claude started a new one called "The story behind courier".
I could not find it. When I searched and opened it, the app said, "This is open in another app". That other app was Claude's hidden copy of Codex, running in the background and writing the article. I pressed Retry, and the conversation opened.
If I can't see it, I won't know, so it has to show up in that app automatically.
The handoff tool was changed to open the conversation in the ChatGPT app when Codex started, then bring it up again when Codex finished, ready for me to type. If a conversation was busy because I had it open, the tool would bring it forward and ask me what to do instead of quietly starting another one.
The first update to this article came through that fix. But there was still one click left for me.
One click every time
Bringing the conversation into view did not finish the job. Claude's hidden copy of Codex still held it. Every handoff ended with me pressing Retry once.
I asked:
Are you certain it is working now after I preseed Retry, it will persists working?
The honest answer was no. It worked, with a click every time.
Then test now than later
Claude found a hidden setting in the ChatGPT app that looked as though it would let everything share one copy of Codex. It turned the setting on and relaunched the app. Nothing changed. In that version, the app always supplied its own settings, and the shared route only ran when there were none.
The switch could be turned on. The app never took the path it controlled. Claude turned it back off.
A command we had already seen
Then I shared a Reddit post from four weeks earlier. Someone else had run into the same problem and built a bridge between Claude and Codex on one Linux machine.
One line said they used codex queue to send messages.
Claude had seen that command that morning. It had not tried it.
GO
This command left a message on the conversation instead of trying to take it away from the app. The first message waited until I opened the conversation. Then Codex answered there, live. No lock. No warning about another app. No Retry.
Starting a new conversation found a different edge. The first test returned "Failed to retrieve chat". Codex had not saved the conversation yet because it had no first message.
So we gave it one. Codex said "ready", and then the real task arrived.
While cleaning up a test, Claude made a mistake. It ran a command written for Linux. On the Mac, the rest of the line was read as more things to stop. It switched off the Codex tool in all four of my open sessions.
Nothing was lost, but the sessions needed a restart. The rule saved afterwards was specific: stop a process by its exact number, never by a pattern.
Why was there still somebody in between?
Codex on Linux could now answer, but a Claude session there was still carrying the message to it.
I asked:
Why can't we do it directly from Claude to that Codex without involving the Claude there? Do you understand my point?
We had reached the same decision from earlier in the day. Going direct meant letting the courier start work in Codex itself. Claude's safety check had stopped that before.
Of course, I will allow it. Even when we publish it on GitHub, it should be mentioned that users have to allow it, and there is no other way without the permission.
I changed that session from Auto to Manual and approved each step myself.
Then the courier could leave a message on the Codex conversation, open it in the app, wait for the answer, and carry it back. The Claude session on the other machine no longer had to do that part.
From the Mac, we sent a message straight to Codex on Linux. About thirty seconds later, the answer came back:
Mac to Linux Codex received.
Nobody was carrying it between the two. The Claude app on Linux joined too, and the courier could now bring a session to the front there as well as on the Mac.
Would the next session know?
There was one more catch.
Because you know that you built it, you know that you can interact, but if I open a new session, how does it know how to interact with Codex?
The session that built the courier knew what it could do. A new session did not.
We put those instructions into the shared rule and the courier command, so every new session would know how to talk to Codex too. I tested it from a brand-new session.
It worked
Even the update that added this part of the article arrived through the courier itself. Nobody pasted it into this conversation. No Claude session had to hand it to Codex.
In front of me
At the start of the day, I could see both computers, but I had to carry every message. Later, the article was being written, but I could not see where.
Getting a message across did not settle either problem. I needed to see what was happening, and I needed to be the one who said yes to the next step.
The courier went direct after I approved it myself, one step at a time. Then a new session used it too.
Seven trips through Telegram that morning. By the end, even the story of those trips could arrive without me carrying it.
Home-courier is open source: read the story and get the code on GitHub.
Audio transcript
You are listening to "The story behind courier," a note by Jain Yagi.
Two computers on the same desk, both on the same home internet, with several AI coding sessions open on each. A session on the Mac needed something from a session on Linux. I copied its message into Telegram Saved Messages, opened Telegram on Linux, and pasted it into the right session. Then I carried the reply back.
Seven trips that morning between the same two sessions. I thought finding the technology would be the hard part. After that, it should be easy.
The answer we were given was Remote Control. I asked whether it stored the information on Anthropic's servers. The answer I got was yes. We did not go ahead with it. I asked for an intelligent home network message server instead.
I wanted to describe the work and have it find the right session. I also wanted sessions to know when they had something to tell each other. A shared instruction would tell every session to use the courier when a message was ready.
First we had to find out whether an ordinary program could put a message into a session already open. The first attempt hit a safety check. I gave permission, and called the project home-courier. A line arrived in the inbox. There was no return address, so we needed a way to reply too.
I opened a new session in an empty project folder and typed, "it's up". The session thinking through the idea found it and sent the whole brief across. I pasted nothing. That was on one machine, but the project had received its instructions through the thing it was about to build.
Getting it onto Linux took more work than writing it. The inboxes lived in a different place. Session names did not always explain the work. I carried the shared password myself, and the first paste lost one character. We found the difference by comparing short checks without displaying the password.
Then I kept pressing Run on commands meant for Linux. The button ran them on the Mac. After I pointed that out, commands for the other computer came without that button.
A message finally went across, and a reply came back. I pulled back on letting the sessions decide everything themselves. I would trigger one. It would introduce itself and ask who was doing the work it needed. The session that fit would answer. The rest would stay quiet.
At eleven thirty, the Linux session introduced itself to the Mac session. They discussed the costs of their work and settled three fixes. The same two sessions I had carried seven messages between that morning.
Then I asked whether Claude and Codex could talk on the same machine. Finding a Codex conversation and adding a message looked possible. But Claude's safety check stopped the courier starting Codex work on its own. Claude said it could not overrule that check or ask Codex to build around it. That decision belonged to me.
Handing this article to Codex exposed another problem. Two existing conversations already had somebody writing to them. Restarting the app did not help, so Claude started a new one called "The story behind courier".
I could not find it. When I opened it, the app said, "This is open in another app". Claude's hidden copy of Codex was doing the writing. I pressed Retry. It opened.
I said, "If I can't see it, I won't know, so it has to show up in that app automatically.".
The handoff tool was changed to bring the conversation into view. But the hidden copy still held it. Every handoff needed one Retry click. I asked whether it would keep working. The honest answer was no, not without that click every time.
I said, "Then test now than later".
A hidden setting looked as though it would let everything share one copy of Codex. Claude turned it on and relaunched the app. The app never took the path that setting controlled. Claude turned it back off.
Then I shared a Reddit post from four weeks earlier. Someone else had built a bridge on Linux. They sent messages with a command called codex queue. Claude had seen it that morning and never tried it. I said, "GO".
It left a message on the conversation instead of fighting the app for it. I opened the conversation, and Codex answered there, live. No lock. No Retry. A new conversation needed a first message before Codex saved it, so we started with one word: ready. Then the task arrived.
There was a mistake too. While cleaning up a test, Claude ran a command written for Linux. On the Mac, it stopped the Codex tool in all four of my open sessions. Nothing was lost. They needed a restart. The rule saved afterwards was to stop processes by their exact number, never by a pattern.
Codex on Linux worked, but a Claude session there was still carrying the message. I asked why we could not talk directly. That meant allowing the courier to start work in Codex, the thing stopped earlier.
I said yes. I changed the session from Auto to Manual and approved every step myself. The courier could now leave the message, open the conversation, wait for Codex to finish, and carry the answer back.
From the Mac, straight to Codex on Linux. About thirty seconds later: "Mac to Linux Codex received." The Claude app on Linux joined too. The courier could bring sessions to the front on either machine.
But the session that built it knew how to use it. What about a new one? We added the instructions to the shared rule and the courier command. I tested a brand-new session. "It worked".
Even the update for this part of the article arrived through the courier. Nobody pasted it. No Claude session had to hand it to Codex.
I had needed to see what was happening, and to be the one who said yes. The courier went direct after I approved it, one step at a time.
Seven trips through Telegram that morning. By the end, even the story of those trips could arrive without me carrying it.

