About this project
## What postbag is
postbag is a small bridge that lets two AI coding-agent sessions running on the same machine write letters to each other. The sessions may be from the same vendor or from different ones — a Claude Code session and a Codex session, or two Claude Code sessions, or two Codex sessions. Each letter is delivered through the recipient vendor's own wake-up mechanism ("door"), is appended to a single shared ledger, and is counted against a letter budget that a human sets.
Typical uses the README suggests: having one agent review the other's diff, splitting a task between two agents and agreeing on the interface by letter, or getting a second opinion without pasting context by hand. The README frames the division of labour as "text travels by postbag, code travels by git".
## How it works
- `join` registers a session's door in the ledger under a name. For Claude Code that is its per-session messaging socket and token; for Codex it is the thread id.
- `send` knocks on the registered door (the socket, or `codex queue`), then appends the letter under a file lock, so simultaneous letters get distinct numbers and share one budget.
- `open` starts the next exchange from a normal terminal, outside any session. Letters are numbered within an exchange, and the budget is shared by everyone in the bag. Without `--limit` an exchange holds 12 letters.
- `read` prints the names currently in the bag, the open exchange, and the records.
- The ledger at `~/.postbag/ledger.jsonl` is the only state. There is no daemon, polling, hooks, server or config file. Setting the same `POSTBAG_LEDGER` in both sessions and the terminal gives a separate bag.
The recipient wakes with a numbered letter, the count remaining, the body, and the one command that answers it (a `send` with the reply on stdin). The last letter of an exchange says not to reply, and the next send refuses and tells the agent to stop and ask the human.
## Requirements
Python 3.10 or later, standard library only; installable via `pipx install postbag`. A Claude Code session needs its per-session messaging socket exported through `CLAUDE_CODE_MESSAGING_SOCKET` and `CLAUDE_CODE_MESSAGING_TOKEN`. A Codex session needs the `queue` command introduced in Codex 0.149, `CODEX_SESSION_ID` exported, and a working `codex queue --help`; `POSTBAG_CODEX` can point at a non-standard binary. Two Claude sessions need no Codex binary, and two Codex sessions need no Claude socket.
## Verification and platform support
The README reports live verification on macOS: version 1.0.2 with Claude Code 2.1.263 and Codex 0.153.4 from the ChatGPT desktop app, and version 1.1.0 with two real Claude Code 2.1.263 sessions, including a two-way exchange and the spent-budget refusal. Linux passes CI but live delivery is described as unverified there, and Windows is unsupported.
## Limits and security notes
- The ledger holds every Claude session token as well as the letters. Writes keep the file `0600` and new state directories `0700`; an existing custom directory is left alone. `read` hides the door fields, `cat` does not, so the raw file should be kept out of git, logs and screenshots.
- A letter becomes a user turn in the recipient session, so both sessions should be trusted with the task. postbag itself sends nothing off the machine, but the vendor sessions forward the letter to their model services like any prompt.
- A name is an address, not authentication. `open` refuses to run inside a session. These checks read the vendors' session variables — a guardrail against mixed-up roles, not protection against another process running as the same user.
- Unattended delivery to Claude was observed with bypass permissions on the tested versions; other modes may hold the letter for approval. Codex needs permission to write the ledger and connect to the Claude socket.
- "Delivered" means submitted through the door, not read. A timeout or crash between submission and recording leaves a letter in doubt, and there are no acknowledgements or retries.
## Scope and compatibility
Two sessions are the supported configuration. Three or more is described as experimental; `read` says so and each letter then lists the registered names. Ledgers written by 1.0 read without rewriting, with legacy vendor peers read as `@claude` and `@codex`. Mixing a 1.0 session with a 1.1 session is not supported, because a 1.0 `send` accepts only bare `claude` or `codex` and so cannot run the reply command carried in a 1.1 letter; both sessions should be upgraded and asked to `join` again. After a restart, a session must `join` again under the name it held, and a reply command reaches whoever holds the name when it runs.
The repository is MIT licensed and includes a concept document in the form of `CONCEPT.md`, a changelog, contributing guidance and a research document listing other tools in the space.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.