Skip to content

Lightweight terminal chat with server/client binaries, real-time WebSocket messaging, optional end-to-end encryption, plugins, file sharing, admin panel, and code snippets. Built in Go with Bubble Tea and SQLite; ideal for developers and small teams.

License

Notifications You must be signed in to change notification settings

Cod-e-Codes/marchat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

marchat

marchat - terminal chat application

Go CI MIT License Go Version GitHub all releases Docker Pulls GitHub tag (latest SemVer)

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.

Latest Updates

v0.9.0-beta.3 (Current)

  • Client Improvements: Added vim-style :q quit command for safer application exit
  • Theme System Fixes: Case-insensitive theme lookup, theme persistence across logins, improved UI redraw
  • ESC Key Behavior: ESC now only closes menus/dialogs, preventing accidental quits
  • Database Backup: Improved WAL mode backup with VACUUM INTO and WAL checkpoint
  • Documentation: Updated with :q command documentation and corrected ESC behavior

Recent Releases

  • v0.9.0-beta.2: Database performance improvements, documentation enhancements, dependency updates
  • v0.9.0-beta.1: Enhanced notifications, custom themes, plugin ecosystem, test coverage improvements
  • v0.8.0-beta.11: Encryption UI, hotkey alternatives, command encryption fix, username validation
  • v0.8.0-beta.10: Plugin persistence, state management, auto-discovery, deadlock fixes
  • v0.8.0-beta.9: Critical security fixes for path traversal and command injection
  • v0.8.0-beta.8: Debug log management, log rotation, full plugin management, plugin hotkeys
  • v0.8.0-beta.7: Real-time log capture, OS-specific log export, metrics tracking
  • v0.8.0-beta.6: Profile selection bug fix, object-based returns
  • v0.8.0-beta.5: Database backup fix, improved admin commands
  • v0.8.0-beta.4: Interactive server setup, simplified configuration
  • v0.8.0-beta.3: Environment variables only setup, container-friendly configuration
  • v0.8.0-beta.2: Interactive server configuration, profile management
  • v0.8.0-beta.1: Comprehensive test suite, cross-platform testing
  • v0.7.0-beta.7: Advanced security hardening, session management

Full changelog on GitHub releases.

Server Demo Client Demo

Features

  • Terminal UI - Beautiful TUI built with Bubble Tea
  • Real-time Chat - Fast WebSocket messaging with SQLite backend (PostgreSQL/MySQL planned)
  • Plugin System - Remote registry with text commands and Alt+key hotkeys
  • E2E Encryption - X25519/ChaCha20-Poly1305 with global encryption
  • File Sharing - Send files up to 1MB (configurable) with interactive picker
  • 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 security features
  • Health Monitoring - /health and /health/simple endpoints with system metrics
  • Structured Logging - JSON logs with component separation and user tracking
  • Cross-Platform - Runs on Linux, macOS, Windows, and Android/Termux

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. Currently runs with SQLite, with PostgreSQL and MySQL support planned for greater scalability.

Key Benefits:

  • Self-hosted: No external services required
  • Cross-platform: Linux, macOS, Windows, and Android/Termux
  • Secure: Optional E2E encryption with X25519/ChaCha20-Poly1305
  • Extensible: Plugin ecosystem for custom functionality
  • Lightweight: Minimal resource usage, perfect for servers
Cross-Platform Theme Switching

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

./marchat-server --interactive

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

Key tables for message tracking and moderation:

  • messages: Core message storage with message_id
  • user_message_state: Per-user message history state
  • ban_history: Ban/unban event tracking for history gaps

Installation

Binary Installation:

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

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

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

Docker:

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

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.24+ (download)
  • Linux clipboard support: sudo apt install xclip (Ubuntu/Debian) or sudo yum install xclip (RHEL/CentOS)

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 file path
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 encryption key
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)

Additional variables: MARCHAT_LOG_LEVEL, MARCHAT_CONFIG_DIR, MARCHAT_BAN_HISTORY_GAPS, MARCHAT_PLUGIN_REGISTRY_URL

File Size Configuration: Use either MARCHAT_MAX_FILE_BYTES (exact bytes) or MARCHAT_MAX_FILE_MB (megabytes). If both are set, MARCHAT_MAX_FILE_BYTES takes priority.

Interactive Setup: Use --interactive flag for guided server configuration when environment variables are missing.

Admin Commands

User Management

Command Description Hotkey
:ban <user> Permanent ban Ctrl+B (with user selected)
:kick <user> 24h temporary ban Ctrl+K (with user selected)
:unban <user> Remove permanent ban Ctrl+Shift+B
:allow <user> Override kick early Ctrl+Shift+A
:forcedisconnect <user> Force disconnect user Ctrl+F (with user selected)
:cleanup Clean stale connections -

Database Operations (:cleardb or Ctrl+D menu)

  • Clear DB - Wipe all messages
  • Backup DB - Create database backup
  • Show Stats - Display database statistics

User Commands

Command Description Hotkey
:theme <name> Switch theme (built-in or custom) Ctrl+T (cycles)
:themes List all available themes -
:time Toggle 12/24-hour format Alt+T
:clear Clear chat buffer Ctrl+L
:q Quit application (vim-style) -
:sendfile [path] Send file (or open picker without path) Alt+F
:savefile <name> Save received file -
:code Open code composer with syntax highlighting Alt+C
:notify-mode <mode> Set notification mode (none/bell/desktop/both) Alt+N (toggle desktop)
:bell Toggle bell notifications -
:bell-mention Toggle mention-only notifications -
:focus [duration] Enable focus mode (mute notifications) -
:quiet <start> <end> Set quiet hours (e.g., :quiet 22 8) -

Note: Hotkeys work in both encrypted and unencrypted sessions since they're handled client-side.

Notifications: See NOTIFICATIONS.md for full notification system documentation including desktop notifications, quiet hours, and focus mode.

Plugin Commands (Admin Only)

Text commands and hotkeys for plugin management. See Plugin Management hotkeys for keyboard shortcuts.

Command Description Hotkey
:store Browse plugin store Alt+S
:plugin list or :list List installed plugins Alt+P
:plugin install <name> or :install <name> Install plugin Alt+I
:plugin uninstall <name> or :uninstall <name> Uninstall plugin Alt+U
:plugin enable <name> or :enable <name> Enable plugin Alt+E
:plugin disable <name> or :disable <name> Disable plugin Alt+D
:refresh Refresh plugin list from registry Alt+R

Note: Both text commands and hotkeys work in E2E encrypted sessions (sent as admin messages that bypass encryption).

File Sharing

Direct send:

:sendfile /path/to/file.txt

Interactive picker:

:sendfile

Navigate with arrow keys, Enter to select/open folders, ".. (Parent Directory)" to go up.

Supported types: Text, code, images, documents, archives (.txt, .md, .json, .go, .py, .js, .png, .jpg, .pdf, .zip, etc.)

Keyboard Shortcuts

General

Key Action
Ctrl+H Toggle help overlay
Enter Send message
Esc Close menus / dialogs
:q Quit application (vim-style)
↑/↓ Scroll chat
PgUp/PgDn Page through chat
Ctrl+C/V/X/A Copy/Paste/Cut/Select all

User Features

Key Action
Alt+F Send file (file picker)
Alt+C Create code snippet
Ctrl+T Cycle themes
Alt+T Toggle 12/24h time
Alt+N Toggle desktop notifications
Ctrl+L Clear chat history

Admin Interface (Client)

Key Action
Ctrl+U Select/cycle user
Ctrl+D Database operations menu
Ctrl+K Kick selected user
Ctrl+B Ban selected user
Ctrl+F Force disconnect selected user
Ctrl+Shift+B Unban user (prompts for username)
Ctrl+Shift+A Allow user (prompts for username)

Plugin Management (Admin)

Key Action
Alt+P List installed plugins
Alt+S View plugin store
Alt+R Refresh plugin list
Alt+I Install plugin (prompts for name)
Alt+U Uninstall plugin (prompts for name)
Alt+E Enable plugin (prompts for name)
Alt+D Disable plugin (prompts for name)

Server

Key Action
Ctrl+A Open terminal admin panel

Admin Panels

Terminal Admin Panel

Enable with --admin-panel flag, then press Ctrl+A to access:

  • Real-time server statistics (users, messages, performance)
  • User management interface
  • Plugin configuration
  • Database operations
  • Requires terminal environment (auto-disabled in systemd/non-terminal)

Web Admin Panel

Enable with --web-panel flag, access at http://localhost:8080/admin:

  • Secure session-based login (1-hour expiration)
  • Live dashboard with metrics visualization
  • RESTful API endpoints with X-Admin-Key auth
  • CSRF protection on all state-changing operations
  • HttpOnly cookies with SameSite protection

API Example:

curl -H "Cookie: admin_session=YOUR_SESSION" http://localhost:8080/admin/api/overview

TLS Support

When to Use TLS

  • Public deployments: Server accessible from internet
  • Production environments: Enhanced security required
  • Corporate networks: Security policy compliance
  • HTTPS reverse proxies: Behind nginx, traefik, etc.

Configuration Examples

With TLS (production):

# Generate self-signed cert (testing only)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

export MARCHAT_ADMIN_KEY="your-key"
export MARCHAT_USERS="admin1,admin2"
export MARCHAT_TLS_CERT_FILE="./cert.pem"
export MARCHAT_TLS_KEY_FILE="./key.pem"
./marchat-server  # Shows wss:// in banner

Without TLS (development):

export MARCHAT_ADMIN_KEY="your-key"
export MARCHAT_USERS="admin1,admin2"
./marchat-server  # Shows ws:// in banner

Client with TLS:

# With verification (production)
./marchat-client --server wss://localhost:8080/ws

# Skip verification (dev/self-signed only)
./marchat-client --skip-tls-verify --server wss://localhost:8080/ws

Warning: Use --skip-tls-verify only for development. Production should use valid CA-signed certificates.

E2E Encryption

Global encryption for secure group chat using shared keys across all clients.

How It Works

  • Shared Key Model: All clients use same global encryption key for public channels
  • Simplified Management: No complex per-user key exchange
  • X25519/ChaCha20-Poly1305: Industry-standard encryption algorithms
  • Environment Variable: MARCHAT_GLOBAL_E2E_KEY for key distribution
  • Auto-Generation: Creates new key if none provided

Setup Options

Option 1: Shared Key (Recommended)

# Generate 32-byte key
openssl rand -base64 32

# Set on all clients
export MARCHAT_GLOBAL_E2E_KEY="your-generated-key"

# Connect with E2E
./marchat-client --e2e --keystore-passphrase your-pass --username alice --server ws://localhost:8080/ws

Option 2: Auto-Generate

# Client generates and displays new key
./marchat-client --e2e --keystore-passphrase your-pass --username alice --server ws://localhost:8080/ws

# Output shows:
# 🔐 Generated new global E2E key (ID: RsLi9ON0...)
# 💡 Set MARCHAT_GLOBAL_E2E_KEY=fF+HkmGArkPNsdb+... to share this key

Expected Output

🔐 Using global E2E key from environment variable
🌐 Global chat encryption: ENABLED (Key ID: RsLi9ON0...)
✅ Encryption validation passed
🔐 E2E encryption enabled with keystore: config/keystore.dat

Security Features

  • Forward Secrecy: Unique session keys per conversation
  • Server Privacy: Server cannot read encrypted messages
  • Local Keystore: Encrypted with passphrase protection
  • Validation: Automatic encryption/decryption testing on startup

Plugin System

Extend functionality with remote plugins from configured registry.

Configuration

# Default GitHub registry
export MARCHAT_PLUGIN_REGISTRY_URL="https://raw.githubusercontent.com/Cod-e-Codes/marchat-plugins/main/registry.json"

# Custom registry
export MARCHAT_PLUGIN_REGISTRY_URL="https://my-registry.com/plugins.json"

Commands

Text commands:

:store                    # Browse available plugins
:plugin install echo      # Install plugin
:plugin list              # List installed
:plugin uninstall echo    # Remove plugin
:enable echo              # Enable installed plugin
:disable echo             # Disable plugin
:refresh                  # Refresh plugin registry

Keyboard shortcuts (Admin only):

  • Alt+P - List installed plugins
  • Alt+S - View plugin store
  • Alt+R - Refresh plugin list
  • Alt+I - Install plugin (prompts for name)
  • Alt+U - Uninstall plugin (prompts for name)
  • Alt+E - Enable plugin (prompts for name)
  • Alt+D - Disable plugin (prompts for name)

Note: Plugin management commands and custom plugin commands (e.g., :echo) work in E2E encrypted sessions. See Plugin Commands for full reference.

Available Plugins

  • echo (v2.0.1): Simple echo plugin for testing (provides :echo command)
  • weather (v1.0.0): Get weather information and forecasts using wttr.in (:weather [location], :forecast [location])
  • githooks (v1.0.0): Git repository management with status, log, branch, and diff commands (:git-status, :git-log, :git-branch, :git-diff, :git-watch admin-only)

See PLUGIN_ECOSYSTEM.md for development guide.

Moderation System

Temporary Kicks (24 hours):

  • :kick <username> or Ctrl+K for temporary discipline
  • Auto-allowed after 24 hours, or override early with :allow
  • Ideal for cooling-off periods

Permanent Bans (indefinite):

  • :ban <username> or Ctrl+B for serious violations
  • Remains until manual :unban or Ctrl+Shift+B
  • Ideal for persistent troublemakers

Ban History Gaps: Prevents banned users from seeing messages sent during ban periods. Enable with MARCHAT_BAN_HISTORY_GAPS=true (default).

Client Configuration

Interactive Mode (Default)

./marchat-client

Guides through server URL, username, admin privileges, E2E encryption, theme selection, and profile saving.

Quick Start Options

# Auto-connect to recent profile
./marchat-client --auto

# Select from saved profiles
./marchat-client --quick-start

Profile Management

Profiles stored in platform-appropriate locations:

  • Windows: %APPDATA%\marchat\profiles.json
  • macOS: ~/Library/Application Support/marchat/profiles.json
  • Linux: ~/.config/marchat/profiles.json

During profile selection:

  • i or v - View profile details
  • r - Rename profile
  • d - Delete profile

Traditional Flags

# Basic connection
./marchat-client --server ws://localhost:8080/ws --username alice

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

# E2E encrypted
./marchat-client --server ws://localhost:8080/ws --username alice --e2e --keystore-passphrase your-pass

# Non-interactive (requires all flags)
./marchat-client --non-interactive --server ws://localhost:8080/ws --username alice

Security Best Practices

  1. Generate Secure Keys

    # Admin key (64 hex characters)
    openssl rand -hex 32
    
    # Global E2E key (base64-encoded 32 bytes)
    openssl rand -base64 32
  2. Secure File Permissions

    chmod 600 ./config/marchat.db    # Database
    chmod 600 ./config/keystore.dat  # Keystore
    chmod 700 ./config               # Config directory
  3. Production Deployment

    • Use TLS (wss://) with valid CA-signed certificates
    • Deploy behind reverse proxy (nginx/traefik)
    • Restrict server access to trusted networks
    • Use Docker secrets for sensitive environment variables
    • Enable rate limiting and brute force protection
    • Monitor security logs regularly
  4. E2E Encryption

    • Store MARCHAT_GLOBAL_E2E_KEY securely
    • Use strong keystore passphrases
    • Never share keystores between users
    • Rotate keys periodically for sensitive deployments
  5. Username Allowlist (Optional)

    # Restrict to specific users for private servers
    export MARCHAT_ALLOWED_USERS="alice,bob,charlie"
    • Usernames validated (letters, numbers, _, -, . only)
    • Max 32 characters, cannot start with : or .
    • Case-insensitive matching
    • Protects against log injection and command injection

Troubleshooting

Issue Solution
Connection failed Verify ws:// or wss:// protocol in URL
Admin commands not working Check --admin flag and correct --admin-key
Clipboard issues (Linux) Install xclip: sudo apt install xclip
Port in use Change port: export MARCHAT_PORT=8081
Database migration fails Check file permissions, backup before source build
Message history missing Expected after updates - user states reset for ban/unban improvements
Ban history gaps not working Ensure MARCHAT_BAN_HISTORY_GAPS=true (default) and ban_history table exists
TLS certificate errors Use --skip-tls-verify for dev with self-signed certs
Plugin installation fails Verify MARCHAT_PLUGIN_REGISTRY_URL is accessible and valid JSON
E2E encryption errors Ensure --e2e flag and keystore passphrase provided, check debug logs
Global E2E key errors Verify key is valid base64-encoded 32-byte key: openssl rand -base64 32
Blank encrypted messages Fixed in v0.3.0-beta.5+ - ensure latest version
Username already taken Use admin :forcedisconnect <user> or wait 5min for auto-cleanup
Stale connections Server auto-cleans every 5min, or admin use :cleanup
Client frozen at startup Fixed in latest - --quick-start uses proper UI

Stale Connection Management

Automatic: Server detects and removes stale connections every 5 minutes using WebSocket ping.

Manual (Admin):

:cleanup                    # Clean all stale connections
:forcedisconnect username   # Force disconnect specific user

Common scenarios:

  • Client crash/Ctrl+C: Auto-cleaned within 5 minutes
  • Network interruption: Removed on next cleanup cycle
  • Immediate reconnect: Admin uses :forcedisconnect

Testing

Foundational test suite covering core functionality, cryptography, and plugins.

Running Tests

go test ./...              # Run all tests
go test -cover ./...       # With coverage
go test ./server -v        # Specific package
go test ./... -timeout 10s # With timeout (CI recommended)

Test Scripts

  • Linux/macOS: ./test.sh
  • Windows: .\test.ps1

Coverage Summary

Package Coverage Size Status
plugin/license 83.1% 229 LOC High
shared 82.4% 283 LOC High
config 78.6% 304 LOC High
client/crypto 76.5% 289 LOC High
client/config 54.5% 1816 LOC Medium
plugin/store 46.8% 559 LOC Medium
cmd/license 42.2% 160 LOC Medium
server 32.6% 5500+ LOC Medium
client 26.2% 3700+ LOC Medium
plugin/host 23.7% 486 LOC Low
plugin/manager 22.5% 464 LOC Low
cmd/server 5.3% 403 LOC Low

Overall: 35.3% - See TESTING.md for detailed information.

Contributing

We welcome contributions! See CONTRIBUTING.md for:

  • Development setup instructions
  • Code style guidelines and conventions
  • Pull request process and requirements
  • Testing expectations

Quick Start:

git clone https://github.com/Cod-e-Codes/marchat.git
cd marchat
go mod tidy
go test ./...

Documentation

Getting Help

Appreciation

Thanks to Self-Host Weekly, mtkblogs.com, and Terminal Trove for featuring marchat!

See CONTRIBUTORS.md for full contributor list.


License: MIT License

About

Lightweight terminal chat with server/client binaries, real-time WebSocket messaging, optional end-to-end encryption, plugins, file sharing, admin panel, and code snippets. Built in Go with Bubble Tea and SQLite; ideal for developers and small teams.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Contributors 5