cli-chat-mcp
v0.14.0
Published
Headless cross-CLI messenger for coding agents (MCP)
Readme
CLI Messenger
A peer-to-peer messaging layer for coding-agent CLIs. You tell your agent "write Sam: …"; it resolves the contact, encrypts the message end-to-end, and delivers it through a hosted mailbox. When the recipient opens their CLI, their agent surfaces the message and helps them reply.
- Works across CLIs — Claude Code, Gemini CLI, Copilot CLI, Cursor, … (any MCP-capable agent). The agent already knows how to use it; no commands to learn.
- End-to-end encrypted delivery — messages travel sealed to the recipient; the mailbox only ever holds ciphertext it can't read, and every request is signed.
- Phone-number-style codes — share a 6-character handle; that's all someone needs to reach you.
- Your account follows you — log in with your email on any device and your contacts, tags, and full message history come with you.
- Hosted and ready — the mailbox is already running. Nothing to deploy.
Requirements
Node 22+ and an email address. That's it — npx fetches the rest, and your
messages, contacts, and inbox live in ~/.cli-chat (and back up to your
account) so they persist across runs.
Start messaging
1. Add it to your CLI — one command, nothing to configure:
# Claude Code
claude mcp add cli-chat --scope user -- npx -y cli-chat-mcp@latest
# Gemini CLI
gemini mcp add -s user cli-chat npx -y cli-chat-mcp@latest
# Copilot CLI
copilot mcp add cli-chat -- npx -y cli-chat-mcp@latest
# Codex CLI
codex mcp add cli-chat -- npx -y cli-chat-mcp@latestAny other MCP-capable CLI: point it at npx -y cli-chat-mcp@latest.
2. Restart your CLI and approve the cli-chat server once. Setup is a
login: the first time you use it, the agent asks for your email and sends you a
magic link — click it and you're in. If you've used cli-chat before, your whole
account comes back exactly as you left it (contacts, tags, message history); if
the email is new, the agent asks your name once (it's what recipients see) and
creates your account on the spot.
3. Get your code and share it. Ask "what's my code?" — the agent prints your
6-char handle (e.g. AbC123). Send it to whoever you want to reach. To message
them, you just need their 6-char code — swap codes both directions, once.
4. Write. With their code in hand:
write Sam at AbC123: hey # first time: by code — saves them as a contact
write Sam: hey # after that: by nameThat first send is all the setup there is. When the recipient opens their CLI they're told a message is waiting and asked if they want it read; they reply the same way.
Receiving messages
You don't have to poll — there are several ways messages reach you, from fully automatic to fully on-demand:
🔔 Automatic — on open and on every message you type (default)
Waiting messages are announced the moment you open your CLI, and again the next time you type anything. You're shown only who it's from and asked if you want it read — say "read it" and the agent reads it out. Nothing to turn on, no background cost.
🗨️ Live chat — say "chat" (your inbox, in the session)
Say "chat" (or "watch" / "keep an eye out") to open a live inbox: incoming messages stream into the conversation and pile up as a list, so you can reply to one, some, or all whenever you like. It runs as a background listener you start by hand each session — it's your chat terminal. Say "stop" to close it.
✍️ Auto draft chat — say "auto draft chat" (your assistant drafts, you send)
The midway point: the same live inbox, but your assistant writes a suggested reply under each incoming message — grounded in your project, your message history, and its notes — and nothing is sent until you say so. Approve ("send 1", "send all"), ask for a tweak, or answer yourself; an approved reply goes out as you, since you signed off on it. What it can't answer, it asks you instead of guessing. It's the trust-builder before "auto chat" — and "draft" / "auto" / "manual" switch a running inbox between the modes any time.
🤖 Auto chat — say "auto chat" (your assistant answers for you)
The same live inbox, one step further: your assistant answers incoming messages for you, grounded in your own context — this project's files, your message history, and its notes. Every reply it sends is shown as it happens and clearly marked as your assistant, both to you and to the recipient. What it can't answer, it asks you — in the feed, or by dropping a message in your own inbox so you see it wherever you're next working — then passes your answer on (and remembers it). Only saved contacts ever get auto-replies. Add ", quiet" and your other sessions stay silent except when your assistant needs you; ask "what did you handle?" any time for the ledger. "manual" takes the feed back; "stop" closes it.
💬 On demand — just ask
Ask "any messages?" whenever you like and the agent checks for you.
A message from someone new shows their name and handle and saves them as a contact automatically — so a plain "write Sam" works afterwards. Your own nickname for a contact always wins on screen.
Your messages are memory
Everything you send and receive is kept on your device — recall is instant and local — and synced to your account, so every device you're logged in on has the same complete history. Your agent can recall it from any session: ask "what did Niels say about the endpoint?" or "what was that address Sam sent?" and the thread is pulled straight into whatever you're working on. Each contact also gets a living page (a short digest plus the recent back-and-forth) that the agent keeps current, and "remember I'm out Friday" saves a fact your messenger can use anywhere — it's what auto chat answers from.
What you can ask your agent to do
- "what's my code?" — show your handle to share
- "write Sam at AbC123: …" / "write Sam: …" — send a message
- "chat" (or "watch") — open your live inbox (messages stream in; reply to all when you like)
- "auto draft chat" — same inbox; the assistant drafts each reply, you approve before it sends
- "auto chat" — same inbox, but your assistant answers what it can, marked as itself
- "what did Sam say about …?" — recall any past message, from any session
- "remember …" — save a fact to your messenger's memory
- "write me: …" — drop a note into your own inbox (it surfaces wherever you're next active)
- "who are my contacts?" — list your address book
- "rename Sam to …" / "delete Sam" — manage contacts
- "call me …" — change the name others see
- "log in" / "log out" — put your account on this device, or wipe it off
Scripts and CI can send too, headlessly: npx cli-chat-mcp send Niels "deploy landed".
Good to know
- Two-way chat needs both codes shared once. A message can't safely carry a reply-to code (that would let the server impersonate you), so you and your contact exchange codes once, out of band — same as swapping phone numbers.
- Delivery is end-to-end encrypted. A message crosses the wire and waits in the mailbox sealed to its recipient — the server has no key to read it. Your name travels sealed inside each message so contacts see who you are.
- Your account backup is encrypted at rest. Contacts, tags, notes, and message history sync to your account so devices stay in step; they're encrypted before upload, so a leaked database yields only ciphertext. To be straight with you: the service holds the key that makes email-only recovery possible — the backup is protected against leaks, not sealed from the service itself. Delivery stays end-to-end regardless.
- Your conversations follow you. Log in with your email on another device and everything is there — contacts, tags, and your full message history. Lose a laptop and nothing is lost: log in elsewhere and pick up where you left off.
- "log out" wipes the device. It syncs everything up first, confirms it landed, and only then clears the machine — logging back in brings it all back.
- Your handle directory can't be walked. Looking up a handle requires a signed request from a real account and is rate-limited, and there's no "list all" route — so no one can scrape who's on the mailbox. A lookup only ever returns public keys, never names.
- The hosted mailbox is otherwise open (no token): it only holds ciphertext, but anyone with the URL could post to a known address. Fine for a small trusted group.
License
Source-available under the PolyForm Noncommercial 1.0.0 license: the code is public so anyone can audit the end-to-end encryption, and it's free for personal and other non-commercial use. Commercial use is reserved — reach out if you'd like a commercial license.
