Docs Core
Planning
Install the MCP server, then let a lead session open the day's terminals itself: each in the right repo, each seeded with its own prompt.
On this page12
All pages12
The broadcast bar is one command → many terminals. This is the other half: many different jobs → many terminals.
Keep one session as the lead: a tile you talk to rather than work in. Tell it what your morning looks like and it opens the terminals itself. Any agent that speaks MCP can be the lead. The tools below are a normal MCP server, and nothing in them is particular to one CLI.
I’ve got BUG-114 in vantage, BUG-118 in Aura-Tycoon, and two chores in meme-factory. Set them up.
They come up armed: the command is typed into each shell and left sitting at the cursor, not run. You read down the row, see exactly what each one is about to do, and press Enter on the ones you agree with. Armed tiles glow amber, the same as a completion ping.
Ask for mode: "fired" when you’d rather they run on their own.
What each tile runs
The tile’s startup command: the one you set for that project, or the app-wide one if
you have not set a per-project one, or claude if you have set neither. A plan can name a
command per tile to override it, which is how you send one ticket to codex and the next
to claude in the same breath, or add flags and a model to a single tile.
See Getting started for where those are set.
Setting it up
Dispatch is its own MCP server: the same executable, launched with --mcp-stdio, speaks
JSON-RPC on stdio and forwards to the running window. There is no separate server to install
and no node runtime to have on the machine, so registering it is one stdio entry in whichever
client you use.
The one-click install (Claude Code)
Open the Marketplace chip at the right-hand end of the top bar, press AI tools, and
Install the Claude Code integration. It writes a dispatch entry into your user config
(the same one claude mcp add --scope user writes) pointing at the copy of the server inside
the build you installed it from, so a checkout and an installed copy each register themselves
correctly with no path to type.
This button knows Claude Code’s config file and no other, which is the only part of planning that is specific to one CLI. Every other client is the two lines below.
Then the sidebar carries the status. An MCP button appears at the bottom of it once the integration is in place: green once it’s registered; amber if the entry survives but points at a server somewhere else, which is what a moved or reinstalled Dispatch leaves behind. Click it to repoint.
Clients read their config at startup, so sessions already running won’t see the tools until they restart.
By hand, for any MCP client
# running from a checkout
claude mcp add dispatch --scope user -- H:\path\to\terminal-dispatch\target\debug\Dispatch.exe --mcp-stdio
# or against an installed build
claude mcp add dispatch --scope user -- "$env:LOCALAPPDATA\Programs\Dispatch\Dispatch.exe" --mcp-stdio
For anything other than Claude Code, give your client the same two facts in whatever form it
takes them: the command is the path to Dispatch.exe and the single argument is --mcp-stdio.
A JSON-configured client wants
{ "type": "stdio", "command": "…\\Dispatch.exe", "args": ["--mcp-stdio"] }
Either way Dispatch must be running. The tools talk to the live window over a local named pipe, and that window is the only thing that knows what is open. When it isn’t running, every tool says so rather than guessing.
The tools
Eleven, and they divide into three jobs: find out what exists, open things, and supervise what you opened.
dispatch_projects- Every project it can open, with path, group, type and git branch. The lead calls this first to map tickets to repos.
dispatch_plan- Opens a set of terminals in one go. A tile can carry a
docinstead of a prompt, so a planned workspace comes up with its plan already open beside the work, and abranchto put it on its own worktree. dispatch_doc- Opens a markdown file as a tile. See Documents.
dispatch_list- What’s open right now: project, title, still-armed, waiting-on-you, exited, plus each terminal’s
status(needs-you/done/working/exited) and how long it’s been quiet. Alsocwdandbranchon every terminal, and astudioorrojoblock on the tiles that have one. dispatch_send- Types into an open terminal; multi-line text is pasted as a block.
submit: truepresses Enter afterwards. dispatch_read- Reads a terminal’s text back out: the tail of what’s on screen and above it. How the lead finds out what a session answered.
face: "studio"reads Roblox Studio’s Output pane instead. dispatch_wait- Blocks until a session rings, exits or goes quiet, then says which and why. How the lead supervises without polling.
dispatch_studio- Starts and stops a playtest in the Studio linked to a tile, from inside Studio, so it needs no window focus and no keystrokes. See Studio and Rojo.
dispatch_rojo- The sync switch from a session, so an agent can check sync before it edits.
dispatch_workspace- Switches to, renames, or closes a workspace.
dispatch_close- Closes a tile and ends its shell.
Every one of them takes a tile id from dispatch_list, except the three that do not need
one: dispatch_projects, dispatch_plan and dispatch_list itself. There is no separate
handle to keep: the id in the list is the id everything else takes.
What a tile can carry
dispatch_plan takes a list of tiles. Only project is required; everything else narrows
what that tile is.
project- An absolute path, or a project name from
dispatch_projects. A name matching more than one project is refused rather than guessed at. prompt- What the session starts on, normally the ticket in full. Multi-line is preserved. Leave it out for a terminal that opens in the right place and nothing more.
command- What the prompt is an argument to. Defaults to that project’s configured startup command, or
claude. Set it for a different tool, or a different Claude invocation. modearmedtypes the command and waits for Enter;firedruns it. Omitted, the tile does whatever this Dispatch is set to, which by default is fired.title- The tile header and the workspace tab, usually the ticket id.
doc- Makes the tile a document rather than a terminal. The file must already exist;
prompt,commandandmodeare ignored. branch- Opens the tile on a git branch, backed by its own worktree, rather than in the project’s own checkout.
And two on the plan itself: workspace, which names the new tab or takes "current" to add
to the one on screen, and columns, a grid width from 1 to 4.
A plan is all-or-nothing
Every project reference is resolved before anything is created, so a plan naming a repo that can’t be found opens no terminals rather than half of them.
A name matching more than one project is an error listing the candidates, never a guess.
Where the tiles land
By default they land in a new workspace, so a plan never disturbs what you’re already
doing. Pass workspace: "current" to add them to the one on screen.
Supervising without polling
dispatch_wait is the piece that makes a lead session practical: it blocks until a session
rings, exits or goes quiet, then reports which and why. Combined with dispatch_read, a lead
can set up five jobs, wait for whichever finishes first, read what it said, and decide what
to do next, without a loop that burns tokens asking “are you done yet”.
What counts as something happening is the until argument, and picking the wrong one is
the usual way this goes quiet for two minutes and returns nothing:
idle- The terminal has printed nothing for
idle_sseconds, 20 by default. This is the one that means “is it done”. attention- The session rang its bell. Claude Code rings when it wants an answer from a human (a permission prompt) and not merely on finishing a turn.
exited- The shell ended.
studio- A new error in the linked Roblox Studio’s output, counted from when the wait starts.
any- The default: attention or exited. It does not match
idle, so a terminal that is merely sitting quiet never wakes it.
So: wait on idle for work you dispatched, and on attention for work you expect to be
interrupted by. A session that never asks anything times out on attention, which is not an
error: it comes back woke: false and is called again.
Pass lines and the transcript for whichever terminal woke the wait comes back with it,
saving the dispatch_read that would otherwise always follow. A terminal still sitting armed
never counts as idle: nothing has been run in it yet.
Done is inferred, not reported
status: "done" in dispatch_list means printed something, then went quiet for 20 seconds.
A model thinking hard for half a minute reads the same way, so quiet_s comes with it, and
dispatch_wait answers “has it finished” more precisely than sampling the list does.
Reading Studio back
A tile whose project has Roblox Studio linked has a second face. dispatch_read with
face: "studio" returns Studio’s Output pane for that place (prints, warnings, and the
stack traces from a failed playtest) rather than the shell transcript. Warnings and errors
come marked [warn] and [error]; anything unmarked is a plain print.
The two faces are independent, so a playtest that threw is on the Studio face while the shell face shows nothing at all. Studio output survives Studio being closed, so this still answers after a test that ended badly.
That is the loop dispatch_studio completes: start a test with it, wait with
until: "studio", read the trace. See Studio and Rojo for what a tile
linked to a Studio window can do.
Removing it
Remove is on the same Marketplace card, not on the sidebar button. Nothing outside the
dispatch entry is touched: the file is parsed, modified and written whole, a
.dispatch-backup is kept beside it, and a config that doesn’t parse is refused rather than
rewritten.