# Mattermost Proxy Mirror Local read-only Mattermost Desktop mirror for AI workspace context. This is for **raw evidence only**. It writes under `ai/inbox/mattermost-mirror/`; durable project memory still belongs in `project-knowledge/` after normal promotion rules. ## Why this exists Mattermost Team Edition 11.4.2 exposes normal `/api/v4` REST and WebSocket traffic. When Mattermost Desktop is launched with Chromium/Electron's `--proxy-server` flag, `mitmproxy` can capture only that app without changing the macOS system proxy. ## Setup 1. Install `mitmproxy`. 2. Trust the mitmproxy certificate if HTTPS interception is not already working: - Start `scripts/mattermost-proxy/run-mirror.sh` - Open `http://mitm.it` - Install/trust the certificate in Keychain. 3. Optional: copy `.env.example` to `.env` and set `MATTERMOST_MIRROR_HOST_ALLOW` to the exact Mattermost host. ## Run day to day Terminal 1: ```bash scripts/mattermost-proxy/run-mirror.sh ``` Terminal 2: ```bash scripts/mattermost-proxy/launch-mattermost.sh ``` This launches Mattermost Desktop through macOS LaunchServices with: ```bash --proxy-server=http://127.0.0.1:8080 ``` No global macOS proxy is required. The helper intentionally uses `open -n /Applications/Mattermost.app --args ...` instead of invoking `/Applications/Mattermost.app/Contents/MacOS/Mattermost` directly. Direct binary launch can crash sandboxed Electron apps with Mach rendezvous errors because their expected app/container parent process is missing. ## Output layout ```text ai/inbox/mattermost-mirror/ latest.jsonl # bounded AI-readable window latest.md # bounded Markdown view state.json # last seen by channel and user cache index.json # date/channel file map messages/YYYY/MM/YYYY-MM-DD.jsonl raw/YYYY/MM/YYYY-MM-DD-websocket.jsonl # only if MATTERMOST_MIRROR_WRITE_RAW=1 raw/YYYY/MM/YYYY-MM-DD-rest-flows.jsonl # only if MATTERMOST_MIRROR_WRITE_RAW=1 ``` Use `latest.md` or `latest.jsonl` for quick AI context. Use date-rotated `messages/...` files for previous-workday or channel/date-specific analysis. The mirror writes any post payload it sees, including older messages returned when the desktop app loads channel history or a thread. It dedupes by `post_id`, so scrolling back through useful history is a safe way to backfill missing local evidence without creating repeated entries. ## Normalized message schema Each line in the normalized JSONL contains: ```json { "source": "websocket|rest", "captured_at": "2026-05-19T...Z", "created_at": "2026-05-19T...Z", "created_at_ms": 1779190000000, "channel_id": "...", "channel_name": "fidelity-preguntas", "post_id": "...", "root_id": "...", "thread_id": "...", "user_id": "...", "username": "jeff", "message": "...", "type": "channel_post|thread_reply", "raw_event": "posted|posts|post" } ``` ## Safety rules - The addon allowlists Mattermost hosts and `/api/v4` traffic only. - Headers such as `Authorization`, `Cookie`, `Set-Cookie`, and CSRF are redacted in optional raw output. - Optional raw output is disabled by default to prevent large files. - Attachments are not downloaded by this mirror. - The mirror is evidence, not canonical memory. ## Useful environment variables - `MATTERMOST_MIRROR_HOST_ALLOW`: exact host or parent domain to capture. - `MATTERMOST_MIRROR_DIR`: output directory, default `ai/inbox/mattermost-mirror`. - `MATTERMOST_MIRROR_LATEST_LIMIT`: number of messages in `latest.*`, default `200`. - `MATTERMOST_MIRROR_CHANNEL_IDS`: optional comma-separated channel ID allowlist. - `MATTERMOST_MIRROR_WRITE_RAW`: set to `1` to save compact raw REST/WebSocket evidence. - `MATTERMOST_APP_PATH`: Mattermost Desktop `.app` bundle path.