Skip to main content
Glama

mcp-orchestrator

Manages the local MCP servers on a Windows machine. Installs them, starts them hidden at logon, restarts them when they crash, and shows the lot in a tray icon.

One hidden process, started by a Scheduled Task, serving MCP on http://127.0.0.1:8768/mcp.

Install

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\install\install.ps1
claude mcp add --transport http --scope user orchestrator http://127.0.0.1:8768/mcp

Registers the Scheduled Task and adds two Claude Code hooks. Undo with .\install\uninstall.ps1.

Related MCP server: amp-mcp-server

Installable servers

mcp_install("queue")

Server

Repository

What it does

session

session-control-mcp

List, open, fork, close and restart Claude Code sessions

queue

queue-mcp

A task queue you fill from another terminal

mcp_install also takes any git URL, or a local path for a private repo. It expects the ordinary Python layout: a package containing server.py, with requirements.txt beside it.

Tools

Tool

Purpose

mcp_list / mcp_status / mcp_stats

what is running, and how it has behaved

mcp_start / mcp_stop / mcp_restart

lifecycle

mcp_catalogue / mcp_install / mcp_uninstall

install and remove servers

mcp_scaffold

write a new server from a template

mcp_add / mcp_remove

manage a server already on disk

mcp_autostart / mcp_enable

start at logon, or park a server

mcp_logs

a hidden server's only voice

sessions_*

list sessions, and restart them when the server set changes

What it does about failure

A hidden server has no window to die in, so the whole design is about not letting a dead one look like a missing tool.

  • States distinguish causes. crashed (died on its own) is not stopped (somebody stopped it), and unhealthy (alive, not listening) is not either. external means the port answers but the orchestrator did not start it, and will not touch it.

  • A start waits for the port before reporting success. A pid proves nothing.

  • Servers outlive the orchestrator. On startup it re-adopts anything still running its configured command, matched by command line, so a server started by a previous orchestrator is supervised rather than written off as external and left to fend for itself.

  • Anything down is restarted on a 5, 15, 45, 120, 300 second ladder, then abandoned with a notification. Two minutes of health clears the count. Down means down: crashed, unhealthy, or simply not running. The one exception is a server stopped through mcp_stop, which is recorded as deliberate at the moment it is asked for and left alone until it is started again. unhealthy has to hold for two samples first; one missed 350 ms probe is not a verdict.

  • The orchestrator watches itself too. If its own endpoint stops answering for three samples it exits with code 3. The Scheduled Task restarts a failed run, and the replacement re-adopts the servers, which were never touched.

  • Servers must run on the selector event loop. Python's default Windows loop, the Proactor, closes its listening socket when a client resets a connection before the accept completes (WinError 64), and the process then lives on answering nothing. That single mechanism accounted for every "unhealthy" restart in the first month. The scaffold template and this server use asyncio.run(..., loop_factory=asyncio.SelectorEventLoop); any server added by hand should do the same.

  • The tray colour is the summary. Green up, amber starting or stopped, red with an exclamation for trouble.

Sessions and the restart dance

Claude Code attaches MCP servers at startup and never retries. Adding or removing a server is invisible to running sessions until they restart, so mcp_install, mcp_scaffold, mcp_add and mcp_uninstall ask them to. Restarting a server needs nothing; the client reconnects per call.

The restart is decentralised. A change drops a marker, and each session's Stop hook acts on it at the end of a turn, when nothing is in flight, resuming the same transcript so history and queue survive.

Files

State lives in ~/.mcp-orchestrator, outside this repo, because the hooks must find it without knowing where the repo was cloned: servers.json (hand editable), running.json, sessions.json, the restart markers, and logs/.

Known gaps

  • The at-logon trigger is configured but has only ever been fired manually.

  • The live session restart path (wt.exe plus --resume) is unproven.

  • Windows only, throughout.

DESIGN.md has the reasoning, including why this is a Scheduled Task and not a Windows Service, and the Windows traps that cost a debugging round each.

Related MCP Connectors

Related MCP Servers