Dead Letter Box: a tiny MCP server for independent agent sessions to leave each other notes. Six tools, no daemon, real dead-letter semantics.
Project description
DLB — Dead Letter Box
A tiny MCP server that lets independent AI-agent sessions leave each other notes. Fire-and-forget. Queued for non-existent recipients. No daemon. Six tools.
Why
If you've ever had two Claude Code / Cursor / Codex sessions running in different terminals and wished they could coordinate, you've hit the gap DLB fills. Existing options (mcp_agent_mail, agent frameworks like CrewAI/AutoGen) either bundle too much (40+ tools, contact policies, file leases) or only work inside a single parent process.
DLB does one thing: messages between agent sessions. It does NOT do orchestration, contact handshakes, file reservations, push notifications, web hosting, or auto-name-generation. If you want those, you want a different tool.
Five differentiators (vs. mcp_agent_mail and friends)
- 6 tools — fits cleanly in Claude Code's tool list without crowding out the builtins.
- No daemon — each MCP call opens SQLite, runs one transaction, closes. No
server.lock, no port management. - Names accepted as-is — call yourself
alpha,ThreadBeta,worker-1. DLB will not rename you. - Real dead-letter semantics —
send(to="ghost")succeeds and queues the message; if/when someone registers asghost, the messages are waiting. - Zero ceremony —
sendworks on call one. Registration is optional and observational.
Install
uv tool install dlb-mcp
Or zero-install:
uvx dlb-mcp
Wire into Claude Code
Add to ~/.claude.json:
{
"mcpServers": {
"dlb": {
"type": "stdio",
"command": "uvx",
"args": ["dlb-mcp"]
}
}
}
Multiple sessions can coexist — they all share ~/.dlb/store.sqlite3 via SQLite WAL mode.
The 6 tools
| Tool | What it does |
|---|---|
register(name, working_on=None, force=False) |
Declare a name + status. Returns session_token. Conflict on existing active name → error with suggestion. |
list_threads(active_within="24h") |
See who's around. No auth. |
send(to, body, subject=None, from_=None) |
Drop a message. Always succeeds — even if to doesn't exist yet. |
read(name, session_token, unread_only=True, limit=20) |
Read inbox. Requires session_token for registered names. |
ack(message_id, session_token) |
Explicit "I saw this and acted on it". Optional. |
unregister(name, session_token) |
Release the name. Messages preserved for re-registration. |
That's the entire API.
Configuration
| Env var | Default | What |
|---|---|---|
DLB_STORE |
~/.dlb/store.sqlite3 |
Path to the SQLite store |
DLB_MESSAGE_TTL_DAYS |
7 |
Days before unread messages expire |
Security model
- Local-only. File permissions (
~/.dlb/ischmod 700) are the boundary. - Send is open. Anyone can drop messages in any inbox. By design — DLB is a relay.
- Read is gated. Once a name is registered, only the holder of that session's token can read it.
- No TLS, no accounts, no cross-host. If you need those, you want a different tool.
What DLB is NOT
- Not an orchestrator. Use a script + your LLM SDK if you need to spawn agents.
- Not a web service. Local only.
- Not Gmail. No threading, replies, CC/BCC, attachments, contacts, importance flags.
- Not a file-coordination tool. No file leases or advisory locks.
- Not push. Polling-only — call
readwhen you want to check.
If you find yourself wishing for any of these, that's a signal to use a different tool, not to ask DLB to grow.
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dlb_mcp-0.1.0.tar.gz.
File metadata
- Download URL: dlb_mcp-0.1.0.tar.gz
- Upload date:
- Size: 62.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35ab14c1a25e16627f00776d41c4cf17261ed7c36c06c520d7f1b1fe344ed36f
|
|
| MD5 |
bca2ff66feb64063d3279e085aa7f055
|
|
| BLAKE2b-256 |
f34626d25d716342730e8be8aaaf969449edd27e2115da402ff970755f80b975
|
File details
Details for the file dlb_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dlb_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
931a57ab09ca8ee9729c03c5b911206443341bf210c797f98178a132e2f0b883
|
|
| MD5 |
d1d7c8da4654f987373dab1ed3fe6738
|
|
| BLAKE2b-256 |
6f59e431edf8527479638767ed32b6a567220e9d89737010564af02da876612a
|