Mac Terminal is a small protected local web app for running short macOS shell commands through a local controller. It was split out from the AI Chat project as an independent open-source tool.
- Admin-protected login with JWT authentication.
- Short command execution through a local macOS controller.
- Working directory tracking for
cd. - Command history with Up/Down arrow navigation.
- Copy and clear terminal output.
- Safety blacklist for destructive command patterns in the controller.
- macOS
- Node.js 18+
- Python 3
- Python packages from
mac-controller/requirements.txt
Optional controller tools depend on macOS command availability. Terminal execution itself uses Python's standard library.
One-command local deployment:
./deploy.shThis installs Node dependencies, creates a local .env with generated secrets when needed, prepares the Python controller virtual environment, runs checks, and starts the app.
Manual setup:
npm install
cp .env.example .envEdit .env and set a strong JWT_SECRET. The first registered user whose username matches ADMIN_USERNAME becomes an admin.
To install controller Python dependencies:
python3 -m venv mac-controller/.venv
mac-controller/.venv/bin/pip install -r mac-controller/requirements.txtnpm startOpen http://localhost:3301, create the admin account, then sign in.
After signing in as admin, open Settings from the top bar. The panel can edit local deployment settings such as port, admin username, database path, controller host/port, and controller auto-start.
Secrets are never displayed in the browser. Use the rotate checkboxes to generate new values for JWT_SECRET or CONTROL_INTERNAL_TOKEN. Restart the app after saving server-level settings.
- Keep this app bound to localhost unless you fully understand the risk.
- Set
CONTROL_INTERNAL_TOKENso only the Node app can call the controller API. - Do not expose this app directly to the public internet.
- The controller blocks common destructive command patterns, but it is not a full sandbox.
npm run check
npm run smoke:startup
npm run smoke:auth