MCPcopy Index your code
hub / github.com/Cod-e-Codes/marchat

github.com/Cod-e-Codes/marchat @v1.3.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.3.0 ↗ · + Follow
1,418 symbols 5,639 edges 104 files 527 documented · 37%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

marchat

marchat - terminal chat application

Go CI MIT License Go Version GitHub all releases Docker Pulls Version

A lightweight terminal chat with real-time messaging over WebSockets, optional E2E encryption, and a flexible plugin ecosystem. Built for developers who prefer the command line.

Quick start: QUICKSTART.md for a single-page walkthrough (install, server, client, and where to read next).

E2E in one sentence: Optional chat encryption uses a shared symmetric key (ChaCha20-Poly1305) distributed out of band (MARCHAT_GLOBAL_E2E_KEY, keystore, or equivalent). It is not pairwise Signal-style key exchange: anyone who holds the key can decrypt message and file payloads. See SECURITY.md and PROTOCOL.md.

Good fit: self-hosted teams, terminal-first chat, SQLite or Postgres/MySQL, and optional plugins. Poor fit: hosted SaaS you do not run, or a threat model that requires per-user forward secrecy without a shared secret.

If you are... Start here
Trying marchat QUICKSTART.md
Running a server in production QUICKSTART.md, deploy/CADDY-REVERSE-PROXY.md, PACKAGING.md
Writing a plugin PLUGIN_ECOSYSTEM.md, plugin/README.md
Contributing code CONTRIBUTING.md, TESTING.md, ARCHITECTURE.md
Reviewing security SECURITY.md, PROTOCOL.md
Prefer a graphical client marchat_flutter, marchat-gui

Optional graphical clients

marchat stays terminal-first in this repository, with the TUI as the reference client.

  • marchat_flutter: Recommended GUI path and the main graphical client focus.
  • marchat-gui: Go and Fyne companion client for desktop use.

Both clients follow the same wire format documented in PROTOCOL.md.

Release notes

Latest tagged release: v1.3.0 (2026-07-06). Narrative history: CHANGELOG.md. Assets and tags: GitHub releases.

main branch: may include changes not yet in that tag (for example items under Unreleased in CHANGELOG.md). Feature descriptions elsewhere in this README match the tree you build from source; compare your binary’s -doctor / -version output to the release page when in doubt.

Demos

Screen recordings of a current build (GIF autoplay depends on the viewer).

Server: startup banner and web admin panel

Server startup and web admin panel

Server: diagnostics (marchat-server -doctor)

Server diagnostics (doctor)

Client: reactions and help

Client reactions and help

Client: theme switching (:theme)

Client theme switching

Client: diagnostics (marchat-client -doctor)

Client diagnostics (doctor)

Features

  • Terminal UI - Beautiful TUI built with Bubble Tea
  • Real-time Chat - Fast WebSocket messaging with SQLite, PostgreSQL, or MySQL backends
  • Message Management - Edit, delete, pin, react to, and search messages
  • Direct Messages - Private DM conversations between users, persisted server-side and replayed on reconnect for sender and recipient
  • Channels - Multiple chat rooms with join/leave, persisted channel metadata on messages, and fast local channel switching with filtered transcript history
  • Typing Indicators - Channel and DM typing indicators are scoped to the active view
  • Read Receipts - Server stores per-user read rows; the reference client sends debounced read_receipt when the transcript is scrolled to the newest messages
  • Plugin System - Remote registry with text commands and Alt+key hotkeys
  • E2E Encryption - ChaCha20-Poly1305 with a shared global key (MARCHAT_GLOBAL_E2E_KEY), including file transfers
  • File Sharing - Send files up to 1MB (configurable) with interactive picker and optional E2E encryption
  • Admin Controls - User management, bans, kick system with ban history gaps
  • Smart Notifications - Bell + desktop notifications with quiet hours and focus mode (guide)
  • Themes - Built-in themes + custom themes via JSON (guide)
  • Docker Support - Containerized deployment with docker-compose.yml for local dev; optional TLS reverse proxy via Caddy (guide)
  • Health Monitoring - /health and /health/simple endpoints with system metrics
  • Structured Logging - JSON logs with component separation and user tracking
  • UX Enhancements - Stable status footer (connection, unread for others' new chat lines when scrolled above the tail, optional E2E and channel), banner for command feedback, tab completion for @mentions, multi-line input, chat export
  • Cross-Platform - Runs on Linux, macOS, Windows, and Android/Termux
  • Diagnostics - marchat-client -doctor and marchat-server -doctor (or -doctor-json) summarize environment, resolved paths, and configuration health

Overview

marchat started as a fun weekend project for father-son coding sessions and has evolved into a lightweight, self-hosted terminal chat application designed specifically for developers who love the command line. It supports SQLite by default and can also run against PostgreSQL or MySQL for larger deployments.

Key Benefits: - Self-hosted: No external services required - Cross-platform: Linux, macOS, Windows, and Android/Termux - Secure: Optional E2E encryption with ChaCha20-Poly1305 (global symmetric key) - Extensible: Plugin ecosystem for custom functionality - Lightweight: Minimal resource usage, perfect for servers

Quick Start

1. Generate Admin Key

openssl rand -hex 32

2. Start Server

Option A: Environment Variables (Recommended)

export MARCHAT_ADMIN_KEY="your-generated-key"
export MARCHAT_USERS="admin1,admin2"
./marchat-server

# With admin panel
./marchat-server --admin-panel

# With web panel
./marchat-server --web-panel

Option B: Interactive setup (first run, missing required config)

./marchat-server --interactive

Runs a guided wizard only when MARCHAT_ADMIN_KEY or MARCHAT_USERS is not set. If they are already in the environment or config/.env, the server starts normally and --interactive does nothing extra.

3. Connect Client

# Admin connection
./marchat-client --username admin1 --admin --admin-key your-key --server ws://localhost:8080/ws

# Regular user
./marchat-client --username user1 --server ws://localhost:8080/ws

# Or use interactive mode
./marchat-client

Database Schema

Tables created by the server (dialect-aware DDL for SQLite, PostgreSQL, and MySQL): - messages: Core message storage with message_id, encryption fields, edit/delete/pin flags, recipient, and persisted channel - user_message_state: Per-user last_seen timestamp after handshake (last_message_id column is legacy/unused for replay) - ban_history: Ban/unban event tracking for history gaps - message_reactions: Durable emoji reactions (unique per message + user + emoji) - user_channels: Last channel per user, persisted across reconnects - read_receipts: Per-user read receipt state tracking

Installation

Binary Installation:

# Linux (amd64)
wget https://github.com/Cod-e-Codes/marchat/releases/download/v1.3.0/marchat-v1.3.0-linux-amd64.zip
unzip marchat-v1.3.0-linux-amd64.zip && chmod +x marchat-*

# macOS (amd64)
wget https://github.com/Cod-e-Codes/marchat/releases/download/v1.3.0/marchat-v1.3.0-darwin-amd64.zip
unzip marchat-v1.3.0-darwin-amd64.zip && chmod +x marchat-*

# Windows - PowerShell
iwr -useb https://raw.githubusercontent.com/Cod-e-Codes/marchat/main/install.ps1 | iex

Package managers:

# Homebrew (macOS / Linux): https://github.com/Cod-e-Codes/homebrew-marchat
brew tap cod-e-codes/marchat
brew install marchat
# Scoop (Windows): https://github.com/Cod-e-Codes/scoop-marchat
scoop bucket add marchat https://github.com/Cod-e-Codes/scoop-marchat
scoop install marchat

winget: winget install Cod-e-Codes.Marchat (listed on winget). Maintainer notes and checksum alignment: PACKAGING.md.

See PACKAGING.md and packaging/ for Homebrew, Scoop, winget, Chocolatey, and AUR: canonical manifest templates here, installs available on those ecosystems, and how each release lines up with downstream publishes.

Docker:

docker pull codecodesxyz/marchat:v1.3.0
docker run -d -p 8080:8080 \
  -e MARCHAT_ADMIN_KEY=$(openssl rand -hex 32) \
  -e MARCHAT_USERS=admin1,admin2 \
  codecodesxyz/marchat:v1.3.0

Docker Compose (local development):

The server service loads config/.env first, then a project-root .env (both optional and gitignored). Put MARCHAT_ADMIN_KEY and MARCHAT_USERS in either file (see Essential Environment Variables). Compose also sets MARCHAT_DB_PATH=/data/marchat.db so SQLite uses the attached volume.

Example snippet for config/.env or .env (generate a strong key for anything reachable from a network):

MARCHAT_ADMIN_KEY=your-secret-here
MARCHAT_USERS=admin1,admin2

Then:

docker compose up -d

TLS reverse proxy (Caddy, optional): To terminate TLS in front of a host-native marchat-server (plain HTTP on port 8080), use docker-compose.proxy.yml, deploy/caddy/Caddyfile, and deploy/caddy/proxy.env.example plus optional gitignored deploy/caddy/proxy.env for MARCHAT_CADDY_EXTRA_HOSTS (public IP/DNS on tls internal). Published port 8443 maps to HTTPS/WebSocket inside the container; clients use wss://localhost:8443/ws (with --skip-tls-verify while using Caddy’s internal CA). The proxy stack must be running whenever you use that URL. Full steps, helper scripts (scripts/build-windows.ps1 / scripts/build-linux.sh, scripts/connect-local-wss.ps1 / scripts/connect-local-wss.sh), source changes, and breaking notes: deploy/CADDY-REVERSE-PROXY.md.

From Source:

git clone https://github.com/Cod-e-Codes/marchat.git && cd marchat
go mod tidy
go build -o marchat-server ./cmd/server
go build -o marchat-client ./client

Prerequisites for source build: - Go 1.25.11 or later (download) - Linux clipboard support: sudo apt install xclip (Ubuntu/Debian) or sudo yum install xclip (RHEL/CentOS)

Terminal colors: The server startup banner and the client’s pre-chat output (connection, E2E status, profile picker tags such as [Admin] / [E2E], and auth prompts) use Lip Gloss v2 (charm.land/lipgloss/v2) for emphasis. Set NO_COLOR=1 (or NO_COLOR) in the environment to disable colors on plain stdout/stderr.

Configuration

Essential Environment Variables

Variable Required Default Description
MARCHAT_ADMIN_KEY Yes - Admin authentication key
MARCHAT_USERS Yes - Comma-separated admin usernames
MARCHAT_PORT No 8080 Server port
MARCHAT_DB_PATH No ./config/marchat.db Database path/DSN. Supports SQLite file path, postgres://..., or mysql:...
MARCHAT_TLS_CERT_FILE No - TLS certificate (enables wss://)
MARCHAT_TLS_KEY_FILE No - TLS private key
MARCHAT_GLOBAL_E2E_KEY No - Base64 32-byte global E2E key (server and/or client). On the client, if set, it overrides the key from keystore.dat for that run only; the keystore file is not updated. See E2E Encryption.
MARCHAT_MAX_FILE_BYTES No 1048576 Max file size in bytes (1MB default)
MARCHAT_MAX_FILE_MB No 1 Max file size in MB (alternative to bytes)
MARCHAT_ALLOWED_USERS No - Username allowlist (comma-separated)
MARCHAT_ALLOWED_ORIGINS No - Extra WebSocket Origin values (comma-separated URLs or hostnames)
MARCHAT_TRUSTED_PROXIES No - Reverse-proxy IPs/CIDRs; when set, X-Forwarded-For / X-Real-IP are honored for client IP and admin login rate limits

Additional variables: MARCHAT_LOG_LEVEL, MARCHAT_CONFIG_DIR, MARCHAT_BAN_HISTORY_GAPS, MARCHAT_PLUGIN_REGISTRY_URL

Database backend setup

MARCHAT_DB_PATH accepts either a SQLite pa

Extension points exported contracts — how you extend this code

Plugin (Interface)
Plugin is the main interface that all marchat plugins must implement [1 implementers]
plugin/sdk/plugin.go
PluginHost (Interface)
PluginHost provides methods for plugins to interact with the host
plugin/sdk/plugin.go
CommandFunc (FuncType)
CommandFunc handles chat commands from the host (PluginRequest with Type "command"). Return the full PluginResponse; for
plugin/sdk/stdio.go

Core symbols most depended-on inside this repo

Error
called by 276
client/websocket.go
Error
called by 205
server/logger.go
Close
called by 148
plugin/manager/manager.go
Run
called by 102
server/hub.go
String
called by 89
cmd/server/main.go
appendCheck
called by 64
internal/doctor/doctor.go
CreateSchema
called by 46
server/handlers.go
InsertMessage
called by 41
server/handlers.go

Shape

Function 865
Method 413
Struct 118
TypeAlias 17
FuncType 2
Interface 2
Class 1

Languages

Go100%
Ruby1%

Modules by API surface

server/admin_panel.go63 symbols
client/main_test.go57 symbols
server/admin_web.go56 symbols
client/config/interactive_ui.go54 symbols
client/main.go49 symbols
plugin/manager/manager.go42 symbols
client/render.go38 symbols
server/handlers.go36 symbols
plugin/manager/manager_test.go36 symbols
client/config/config.go31 symbols
plugin/store/store.go29 symbols
client/websocket.go28 symbols

Datastores touched

(mysql)Database · 1 repos
marchatDatabase · 1 repos
marchatDatabase · 1 repos
dbDatabase · 1 repos

For agents

$ claude mcp add marchat \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact