diff --git a/README.MD b/README.MD
index 4ae118d..f5dd531 100644
--- a/README.MD
+++ b/README.MD
@@ -1,133 +1,216 @@
-# 🤐 CMD-CHAT
+# CMD-CHAT
-### encrypted terminal chat. no servers. no logs. ram only.
+### end-to-end encrypted terminal chat with file transfer
[](https://opensource.org/licenses/MIT)
-[](https://www.python.org/downloads/)
+[](https://www.python.org/downloads/)
---
-peer-to-peer encrypted chat that runs in your terminal. you host, you control. close the window — everything's gone.
+Encrypted chat that runs in your terminal. You host the server, you control the room. Close the window — everything's gone. Messages and files are encrypted client-side before the server ever sees them.
-## why
+## Features
-every "secure" messenger still stores metadata somewhere. this doesn't. it's just two terminals talking over an encrypted tunnel. nothing written to disk, ever.
+- **End-to-end encrypted** — messages encrypted with Fernet (AES-128-CBC + HMAC) before leaving your machine
+- **TLS by default** — auto-generated self-signed certs, or bring your own
+- **SRP authentication** — password never sent over the network (zero-knowledge proof)
+- **Encrypted file transfer** — `/send`, `/accept`, `/reject` with SHA-256 verification
+- **RAM only** — nothing written to disk on the server
+- **Rate limiting** — brute-force protection on auth endpoints
+- **No IP leaks** — client IPs never broadcast to other users
+- **Password hidden** — prompted securely via `getpass`, never visible in `ps` or shell history
-## how it works
-
-```
-┌──────────────────────────────────────────────────────────────────┐
-│ SRP AUTHENTICATION │
-├──────────────────────────────────────────────────────────────────┤
-│ │
-│ CLIENT SERVER │
-│ │ │ │
-│ │─────── POST /srp/init {username, A} ───────► │ │
-│ │ (A = client public ephemeral) │ │
-│ │ │ │
-│ │◄──── {user_id, B, salt, room_salt} ───────── │ │
-│ │ (B = server public ephemeral) │ │
-│ │ (room_salt = E2E key derivation) │ │
-│ │ │ │
-│ │ [client derives room_key via HKDF: │ │
-│ │ room_key = HKDF(password, room_salt)] │ │
-│ │ │ │
-│ │ [both sides compute SRP session key │ │
-│ │ using password + ephemeral values] │ │
-│ │ │ │
-│ │─────── POST /srp/verify {user_id, M} ──────► │ │
-│ │ (M = client proof) │ │
-│ │ │ │
-│ │◄────────── {H_AMK, session_key} ──────────── │ │
-│ │ (H_AMK = server proof) │ │
-│ │ │ │
-│ │ [password never transmitted] │ │
-│ │ [MITM can't derive session key] │ │
-│ │ │ │
-├──────────────────────────────────────────────────────────────────┤
-│ E2E ENCRYPTED CHAT │
-├──────────────────────────────────────────────────────────────────┤
-│ │ │ │
-│ │═══════ WebSocket /ws/chat?user_id ═════════► │ │
-│ │ (authenticated session) │ │
-│ │ │ │
-│ │ │ │
-│ ┌─┴─┐ ┌──┴──┐ │
-│ │ C │──── encrypt(msg, room_key) ───────────►│ S │ │
-│ │ L │ │ E │ │
-│ │ I │◄─── ciphertext (broadcast) ────────────│ R │ │
-│ │ E │ │ V │ │
-│ │ N │ decrypt(ciphertext, room_key) │ E │ │
-│ │ T │ │ R │ │
-│ └─┬─┘ └──┬──┘ │
-│ │ │ │
-│ │ [server stores ONLY ciphertext] │ │
-│ │ [server CANNOT read messages] │ │
-│ │ [all clients with same password │ │
-│ │ derive identical room_key] │ │
-│ │ │ │
-│ │ Encryption: Fernet (AES-128-CBC + HMAC) │ │
-│ │ Key derivation: HKDF-SHA256 │ │
-│ │ │ │
-│ │ [on disconnect: keys wiped from RAM] │ │
-│ │ │ │
-└──────────────────────────────────────────────────────────────────┘
-
-┌──────────────────────────────────────────────────────────────────┐
-│ KEY HIERARCHY │
-├──────────────────────────────────────────────────────────────────┤
-│ │
-│ password ──┬──► SRP ──► session_key (per-user, auth only) │
-│ │ │
-│ └──► HKDF(password, room_salt) ──► room_key (shared) │
-│ │
-│ room_salt: generated once at server start │
-│ room_key: deterministic, same for all clients with same pwd │
-│ │
-└──────────────────────────────────────────────────────────────────┘
-```
-
-**SRP (Secure Remote Password)** — password is never sent over the network. both sides prove they know it via zero-knowledge proof, then derive identical session keys.
-
-## install
+## Install
```bash
-python -m venv venv && source venv/bin/activate && pip install -r requirements.txt
+git clone https://github.com/diorwave/cmd-chat.git
+cd cmd-chat
+pip install -r requirements.txt
```
-windows:
+## Quick Start
+
+**Host a chat room:**
```bash
-python -m venv venv ; .\venv\Scripts\activate ; pip install -r requirements.txt
+python3 cmd_chat.py serve 0.0.0.0 3000
```
-## usage
+You'll be prompted for a room password (hidden input). An admin token and TLS cert path will print to the console.
-start server:
+**Connect to a chat room:**
```bash
-python cmd_chat.py serve 0.0.0.0 3000 --password mysecret
+python3 cmd_chat.py connect SERVER_IP 3000 yourname --insecure
```
-connect:
+`--insecure` is needed for self-signed certs. You'll be prompted for the room password.
+
+## Securing Your Connection
+
+### Tailscale (recommended)
+
+Both parties install [Tailscale](https://tailscale.com). Traffic goes through an encrypted WireGuard tunnel. No port forwarding, works across NATs.
```bash
-python cmd_chat.py connect SERVER_IP 3000 username mysecret
+# Host
+python3 cmd_chat.py serve 0.0.0.0 3000
+
+# Friend connects using your Tailscale IP
+python3 cmd_chat.py connect 100.x.x.x 3000 theirname --insecure
```
-
+Find your Tailscale IP: `tailscale ip -4`
-## features
+### LAN (same network)
-- **ram only** — nothing touches disk
-- **rsa + aes** — key exchange + symmetric encryption
-- **no central server** — direct p2p connection
-- **srp auth** — password never sent over network
+Use your local IP. Both devices must be on the same WiFi/network.
-## license
+```bash
+python3 cmd_chat.py connect 192.168.1.x 3000 theirname --insecure
+```
+
+### Public Internet
+
+Requires port forwarding on your router (TCP port 3000 to your machine). Use `--cert` and `--key` with a real certificate for production use.
+
+```bash
+python3 cmd_chat.py connect PUBLIC_IP 3000 theirname --insecure
+```
+
+Find your public IP: `curl ifconfig.me`
+
+## Sharing the Room Password
+
+The password must be shared outside the chat. Never send it over an unencrypted channel.
+
+1. **In person** — tell them verbally
+2. **Signal** — disappearing message set to 30 seconds
+3. **One-time link** — [onetimesecret.com](https://onetimesecret.com) (self-destructs after one view)
+4. **Split it** — send half via Telegram, half via SMS
+
+## Chat Commands
+
+| Command | Action |
+|---------|--------|
+| `/send ` | Propose a file transfer to the room |
+| `/accept` | Accept a pending file offer |
+| `/reject` | Decline a pending file offer |
+| `q` | Disconnect |
+
+### File Transfer
+
+Files are chunked (64KB), encrypted with the room key, and relayed through the server as opaque ciphertext. The server never sees file names, contents, or metadata.
+
+```
+alice> /send report.pdf
+bob> "alice wants to send report.pdf (1.2 MB) — /accept or /reject"
+bob> /accept
+ Receiving: 100% (1.2 MB/1.2 MB)
+ File saved: ./downloads/report.pdf — SHA-256 verified
+```
+
+- Max file size: 50 MB
+- Files saved to `./downloads/` relative to where the client was launched
+- SHA-256 integrity check on every transfer
+
+## CLI Reference
+
+### Server
+
+```bash
+python3 cmd_chat.py serve [options]
+```
+
+| Flag | Purpose |
+|------|---------|
+| `--password`, `-p` | Room password (prompted if omitted) |
+| `--cert` | Path to TLS certificate |
+| `--key` | Path to TLS private key |
+| `--no-tls` | Disable TLS (local dev only) |
+
+### Client
+
+```bash
+python3 cmd_chat.py connect [options]
+```
+
+| Flag | Purpose |
+|------|---------|
+| `--password`, `-p` | Room password (prompted if omitted) |
+| `--insecure`, `-k` | Skip TLS cert verification (self-signed certs) |
+| `--no-tls` | Connect without TLS |
+
+### Environment Variable
+
+Set `CMD_CHAT_PASSWORD` to skip the password prompt for both server and client.
+
+## Helper Scripts
+
+### `./lab/host-chat.sh`
+
+One-command server setup. Detects your IPs (Tailscale, LAN, public), prints the exact connect command your friend needs, then starts the server.
+
+```bash
+./lab/host-chat.sh # TLS on port 4000
+./lab/host-chat.sh --port 5000 # custom port
+./lab/host-chat.sh --no-tls # disable TLS
+```
+
+### `./lab/setup-lab.sh`
+
+Spins up a tmux session with the server and two chat clients side-by-side for local testing.
+
+```bash
+./lab/setup-lab.sh # default lab
+./lab/setup-lab.sh --no-tls --port 4001 # plain HTTP
+./lab/setup-lab.sh --user1 alice --user2 bob
+./lab/setup-lab.sh --teardown # clean up
+```
+
+Attach with `tmux attach -t cmd-chat-lab`. Switch panes with `Ctrl+B` then arrow keys.
+
+## How It Works
+
+```
+CLIENT SERVER CLIENT
+ │ │ │
+ │── POST /srp/init {A} ──────────► │ │
+ │◄── {B, salt, room_salt} ──────── │ │
+ │ │ │
+ │ derive room_key = HKDF(password, room_salt) │
+ │ │ │
+ │── POST /srp/verify {M} ────────► │ │
+ │◄── {H_AMK, ws_token} ─────────── │ │
+ │ │ │
+ │══ WSS /ws/chat?ws_token ════════► │ ◄══════════════════════════════│
+ │ │ │
+ │ encrypt(msg, room_key) ────────► │ ──── ciphertext ────────────► │
+ │ │ decrypt(ciphertext, room_key)
+ │ │ │
+ │ server stores ONLY ciphertext │ │
+ │ server CANNOT read messages │ │
+```
+
+**SRP (Secure Remote Password)** — both sides prove they know the password without transmitting it. A network observer learns nothing.
+
+**Room Key** — derived independently by each client via `HKDF(password, room_salt)`. All clients with the same password get the same key. The server never has the key.
+
+**WebSocket Auth** — HMAC-SHA256 token issued after SRP verification. Prevents session hijacking.
+
+## Admin
+
+The server prints an admin token at startup. Use it to clear message history:
+
+```bash
+curl -k -X DELETE https://SERVER:3000/clear \
+ -H "Authorization: Bearer "
+```
+
+## License
MIT