Moonstone icon

Moonstone

Every Claude Code session on every machine you own, in one browser window. Approve steps, send the next instruction by voice, and hear the answer back. Local models sit right next to Claude.

MITmacOS + WindowsNode, zero dependencies127.0.0.1 only
Moonstone session list across three machines next to an open conversation
What it does

A control panel for a fleet of agents

One Node file and one HTML file. It reads Claude Code's own transcripts, runs sessions as headless claude -p processes, and links machines over SSH tunnels you already trust.

Every machine, one list

Sessions grouped by machine with GPU and RAM gauges, sorted so the ones waiting on you come first.

Real permission prompts

Runs with --permission-prompt-tool stdio. Allow or deny each step from the window; nothing is auto-approved.

Push to talk

Drives your OS's own dictation, falls back to browser speech or local Whisper. Enter while listening stops and sends.

Answers read aloud

Finished answers go to a local Kokoro voice. With windows open on several machines, only the last one you touched speaks.

Local models too

llama.cpp or MLX chat scripts over stdin, or OpenAI-style servers it starts on demand and stops after 30 idle minutes.

Picks the best machine

A launcher on several machines goes to the least busy one: fewest working sessions, then lowest GPU.

Sessions

Terminal or dock, it is the same conversation

  • Dock sessions are headless Claude Code processes Moonstone owns, so it can type into them and answer their prompts.
  • Terminal sessions already running show up too. Type into one and Moonstone stops the terminal copy and resumes it here with full history.
  • Warm spares keep a claude process ready per launcher, so a new session starts without the wait.
  • Machine chips pin a launcher to the Mac or PC you want; the star marks the suggestion.
Session list with three machines
Approvals

Say yes from anywhere in the house

  • Permission prompts become an Allow / Don't card with the exact command.
  • Questions Claude asks with options turn into buttons.
  • The tool calls behind every answer fold under a Show the work bar with step count and time.
A session waiting for permission to run a command
Voice

Talk to it. It talks back.

  • macOS: a small signed Swift helper clicks Edit > Start Dictation in the focused app and checks through CoreAudio that the mic really turned on or off.
  • Windows: presses Win+H for voice typing.
  • Fallbacks: browser speech recognition, then local Whisper (mlx_whisper, large-v3-turbo) on your own machine.
  • Narration: tap the speaker and new answers are read aloud by a local Kokoro server.
Conversation with narration on and the mic listening
Architecture

Your browser, your machines, nothing in between

Every machine runs the same server on 127.0.0.1:8899. The one you open polls its peers through SSH tunnels and forwards requests for their sessions.

You
Browserpublic/index.html
HTTP + SSE →
Moonstone serverserver.js · 127.0.0.1:8899
Runs
claude -pstream-json in / out
Local modelspipe scripts · llama-server · Ollama
Voicemlx_whisper · Kokoro · dictation helper
Peers
Second Macssh -R 18899:127.0.0.1:8899
Windows PCssh -R 18898:127.0.0.1:8899
Quick start

Running in a minute

Needs Node 18+ and Claude Code. No install step.

# get it
git clone https://github.com/nicedreamzapp/moonstone.git
cd moonstone
cp config.example.json config.json

# run it, then open http://localhost:8899
node server.js

# or look around with invented data on :8890
node tools/demo-server.js
Add launchersList your projects, local models and servers in config.json.
Link machinesRun it on each machine and add each one as a peer through an SSH tunnel.
Turn on voiceBuild the Mac helper with mac/build.sh and allow it under Accessibility.
Security

Boring on purpose

Loopback onlyListens on 127.0.0.1. Other machines come in through SSH tunnels, never an open port.
Host checkRequests not addressed to localhost get a 403, which stops DNS rebinding.
CSRF guardEvery POST needs an X-Dock header, which a cross-site page can't send without a preflight Moonstone never grants.
Audio stays homeTranscription and speech run on your machines. Temporary recordings are deleted right after.