Skip to main content
Glama
claude-session-orchestrator

claude-session-orchestrator

by Nurhak

claude-session-orchestrator

An MCP server that lets you manage all your Claude Code sessions, on all your machines, from one place. That place can be the Claude mobile app (including voice mode), claude.ai, or another Claude Code session.

Ask "how are my projects doing?" while you're away from the keyboard. Then start a session on your GPU box, approve a pending permission prompt, or read what a session did. You never open a terminal.

  • Sessions run in tmux on your machines, reached over SSH (Tailscale works well). Each session starts with --remote-control, so it also shows up in the Claude app.

  • Hooks report state. Claude Code's Notification, Stop and SessionEnd hooks tell the server which sessions are waiting for input or approval.

  • Shared memory. A git repo of markdown notes ("the brain"), with shared knowledge and skills. It is injected into each new session through CLAUDE.md.

  • Local LLMs. Small jobs can go to OpenAI-compatible endpoints (Ollama, LM Studio, llama.cpp, vLLM), with routing that never uses a laptop running on battery.

  • No model calls of its own. The thinking stays in your Claude subscription; this server only forwards commands.

Status: early (0.1). Tested end to end against Claude Code 2.1.319 on Linux. The macOS and multi-machine paths are covered by tests but have had little real-world use. Issues and PRs are welcome.

How it works

 Claude app / voice ──HTTPS──▶ Cloudflare Tunnel + Access ──▶ orchestrator (/mcp) on an always-on "hub"
                                                                 │  SQLite: sessions, events, audit log
                                                                 │  ~/brain: shared memory (git)
                                                     SSH / local sh
                                          ┌──────────────────────┼──────────────────────┐
                                        hub                     gpu                   laptop
                                 tmux: cc-<project>-<id>   tmux: cc-…              tmux: cc-…
                                 claude --remote-control …
                                          └───── hooks POST /events (Bearer EVENTS_TOKEN) ─────┘

Related MCP server: claude-mux.mcp

Tools (22)

Tool

What it does

overview()

One line per session, plus what is waiting on you. "How are my projects doing?"

events_pending()

Sessions waiting for your input or approval, oldest first

machine_list() / machine_status(machine)

Reachability, session count, laptop power (AC or battery); CPU, RAM, disk, GPU/VRAM, link type, LLM endpoints

session_list(machine?)

Status: working, waiting_input, waiting_approval, idle or stopped

session_start(project, machine?, prompt?, remote_control=true, name?)

Refreshes the shared context, then starts Claude Code in tmux

session_read(session, mode=summary|tail, lines)

Last action, what it is waiting for, last error, files changed; or a cleaned tail of the output

session_send(session, message)

Types a message and presses Enter

session_approve(session, yes|no|always)

Answers the menu on screen (tool permissions, trust dialogs)

session_interrupt(session) / session_stop(session, graceful|kill, confirm?)

Esc / /exit, or kill (kill needs confirm=true)

memory_search / memory_read / memory_write / memory_append / memory_delete

The brain; every write is a git commit, and delete needs confirm=true

memory_link(project, shared_path) / project_context(project)

Link shared knowledge to a project / get everything a session on that project should know

llm_list() / llm_run(task, endpoint=auto, …)

Local models with auto routing

agent_run(agent, task) / agent_status(job_id)

Local agents (HTTP or CLI) as background jobs

Every result is JSON whose first field is a one-sentence summary, written for voice. Long diffs and logs are never dumped. Sessions can be named by project alias ("my app"), and every call goes into an audit log.

Quick start

Requirements: Node ≥ 24, plus tmux, git and Claude Code on each machine you want to manage. You also need key-only SSH from the hub to the other machines. jq is needed on each machine for the hook installer.

git clone https://github.com/Nurhak/claude-session-orchestrator && cd claude-session-orchestrator
npm ci
cp config/machines.example.yaml config/machines.yaml   # your machines
cp config/projects.example.yaml config/projects.yaml   # your projects and their spoken aliases
cp config/llm.example.yaml config/llm.yaml             # optional: local models and agents
cp .env.example .env                                   # set EVENTS_TOKEN and MCP_TOKEN: openssl rand -hex 32
npm start                                              # http://127.0.0.1:8787/mcp

Install the hooks on each machine. This adds Notification, Stop and SessionEnd hooks to ~/.claude/settings.json and keeps your existing hooks:

scripts/install-hooks.sh local hub http://127.0.0.1:8787
scripts/install-hooks.sh me@gpu gpu http://hub:8787

Use it from Claude Code right away:

claude mcp add -s user --transport http orchestrator http://127.0.0.1:8787/mcp

To use it from the Claude app or voice mode, publish /mcp through a Cloudflare Tunnel with Access in front, then add it as a custom connector. deploy/README.md covers that, plus systemd, skills, and Claude Code sessions as clients.

Configuration

  • machines.yaml: id, ssh_host, user, os (linux or macos), projects_root, local: true for the hub itself, and an optional claude_cmd.

  • projects.yaml: id, spoken aliases, default machine, path, and shared brain paths to always include.

  • llm.yaml: endpoints (id, machine, url including /v1, model, ctx, requires_ac), routing.order, and agents (url or cmd).

  • .env: EVENTS_TOKEN, MCP_TOKEN, PORT, HOST, DB_PATH, CONFIG_DIR, BRAIN_DIR, REMOTE_BRAIN_DIR, BRAIN_PUSH, LLM_TIMEOUT_S.

Shared memory layout

~/brain/                    git repo on the hub (BRAIN_DIR), created on first start
  index.md                  your map of projects, tags and relations
  shared/<topic>/           cross-project knowledge: deployment, branding, infra…
  projects/<p>/*.md         project notes and decisions
  projects/<p>/links.md     shared paths linked with memory_link
  projects/<p>/log.md       one entry per ended session
  projects/<p>/context.md   generated at session_start (gitignored)
  skills/<name>/            shared Claude Code skills; scripts/link-skills.sh symlinks them into ~/.claude/skills

At session_start, context.md is rebuilt from the project's notes, its linked shared files and related skills. It is copied to the target machine, and the project's CLAUDE.md gets @…/context.md once. On a project's first start, Claude Code asks "Allow external CLAUDE.md file imports?", and you can answer with session_approve.

Security model

  • /mcp trusts loopback callers only, meaning cloudflared on the same host behind Cloudflare Access. Everyone else needs Authorization: Bearer $MCP_TOKEN.

  • /events always needs EVENTS_TOKEN.

  • There is no general "run a shell command" tool; only the tools above. Every argument is shell-quoted, and session names are validated.

  • Destructive actions (session_stop kill, memory_delete) need confirm=true. Brain paths can't escape the repo or touch .git.

  • Use a dedicated, key-only SSH user. Secrets live in .env, which is gitignored.

Development

npm test            # unit tests + end-to-end: real HTTP server, private tmux server, fake claude, fake OpenAI endpoint
npm run typecheck

The TypeScript runs directly on Node (type stripping); there is no build step. src/summarize.ts reads Claude Code's terminal UI with regexes. When Claude Code changes its wording, add a captured pane to test/fixtures/ and adjust it.

Design notes and limits

  • Stateless MCP over HTTP. Each request gets a fresh server, and all state lives in SQLite (node:sqlite).

  • Status comes from hooks first. The pane is a fallback for prompts that fire no hook, and it only overrides on clear signals.

  • Approving prompts: numbered menus get the digit, and unnumbered dialogs get arrow keys plus Enter, based on the menu read off the screen.

  • Laptop power: nothing ever wakes a sleeping laptop. A Mac on battery counts as unavailable for requires_ac endpoints.

  • Planned: push notifications for pending approvals, and embedding search over the brain.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables Claude Desktop to interact with and view tmux session content, allowing AI assistants to read from, control, and observe terminal sessions.
    13
    224 npm
    306
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables Claude Code to launch and supervise multiple concurrent Claude Code sessions in tmux, sending them briefs, reading their progress, answering their prompts, and managing isolated git worktrees.
    20
    2
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables voice assistants to start, monitor, message, and approve local Claude Code sessions on your computer, including sessions already open in a terminal. It exposes session management, recaps, approvals, and history search as MCP tools.
    7
    GPL 3.0