convoy
OfficialAllows Convoy to onboard Hermes CLI sessions as neurons, manage resume tokens, and send headless synapses to Hermes for tasks on a shared thread.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@convoybring up an isolated Windows Terminal window with split panes for threads T0, T1, and T2"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Convoy
Convoy is shared project memory for Grok Bot: attach one MCP endpoint, route work to your existing CLIs, and keep every neuron grounded in one durable thread state.
Public MCP remains one root: https://convoy.bot/mcp. A named thread is a --root binding, not a second MCP URL.
Install
Python >= 3.11, standard library only (no runtime dependencies).
git clone https://github.com/Deploy-Forward/convoy.git
cd convoy
python -m pip install .
convoy --helpAlternative: pipx install . (not verified on Windows in this pass).
The convoy console script and python -m convoy both work only after
install. To run from a checkout without installing, put src on the path:
PYTHONPATH=src python test/run.py on bash, or
$env:PYTHONPATH='src'; python test/run.py in PowerShell.
Related MCP server: wmux
CLI reference
One line per verb; flags shown are the ones you will reach for (see
convoy <verb> --help for the full set). Every verb accepts a global
--root <thread-root> before the verb name.
Read (no writes to thread state):
threads— every Convoy thread this machine knows.panes— every body of every neuron on this thread, from the OS process table; never a token.whoami— which chair is this process? Walks process ancestry to the harness.graph [--neuron <chair>] [--html [--out <file>]]— read-only ontology of the thread.seats [--convoy-id <id>]— seat rows.feed --since <ts>— events since a timestamp.context [--instance-id <chair>]— pointer pack for a neuron.glance [--thread <name>] [--tray]— one-screen status.resume --neuron <chair>— dry: prints native argv + cwd, spawns nothing.choices— installed harnesses, known worktrees, chairs, terminal adapter; no resume tokens.probe --to <harness>,id,terminals.
Write (thread state):
init— create the thread layer at--root.bind --thread <name>— bind this root to a named thread.onboard --to <harness> [--to ...] [--thread <name>]— name installed harnesses and bind.seat --to <harness> --session-id <chair> [--worktree <path>] [--model M] [--resume <vendor-id>] [--title T] [--effort E]— register a seated neuron.join --to <harness> [--worktree <path>] [--title T] [--as <chair>] [--launch] [--consent <id>]— register one fresh chair.swap --seat <chair> --to <harness> --handoff <.ola/*handoff*> --as <chair>— replace the occupant, keep the chair.seated --seat <chair> --token <token>— proof-of-life echo from the new occupant.lead --to <chair> --as <you>— pass lead to a chair.hook note "<text>" [--as-me] --to <chair>— leave a note for a chair (orgrok-bot).stamp "<summary>" [--agent A] [--model M] [--effort E] [--transcript <pointer>]— conductor stamp.send --to <harness> "<body>" [--live] [--dry-run] [--instance-id <chair>]— synapse; default runner records a feed row (delivery: recorded);--liveruns a fresh headless vendor session (executed); a named live seat queues (delivery: queued,delivered: false).inbox [--seat <chair>] [--drain | --hook-pretooluse]— list or drain the live-seat inbox. The hook command is alwaysconvoy inbox --hook-pretooluse(never a baked interpreter path).install --to <harness> --opt-in [--live]— cataloged installer; dry-run by default.
Launch / panes:
choices— see above; run it first.launch --seat <chair> [--dry-run] [--consent <id>]— split one already-joined fresh chair into the active pane host.consent --grant <request-id>— grant a prior consent request after the user explicitly approves it.close --seat <chair> [--consent <id>]— request closure of one Convoy-managed pane.bring-up/open [--thread <name>] [--dry-run]— bulk show of seated neurons in one new terminal window.hide/minimize/background [--dry-run]— bulk hide.resume --neuron <chair> --go— spawn once in the chair's worktree; refuses when a live body holds the chair.
MCP:
mcp [--root <thread-root>] [--host 127.0.0.1] [--port 8788]— serve the MCP endpoint for one root.
Run your own MCP
convoy mcp --root <thread-root> --port 8788Then attach http://127.0.0.1:8788/mcp in your MCP client. Write tools are
off by default on the RPC layer: set CONVOY_MCP_WRITE_TOOLS=1 on a
gated/loopback deploy to expose stamp, note, and resume with go=true.
The public https://convoy.bot/mcp is bound to one root; a different thread
means running your own server with your own --root.
Names you will see
Grok Bot — the xAI desktop conductor chat that attaches the MCP; not a neuron.
ola-brain — a private predecessor wrapper; refused by
install, not needed.Deploy-Forward/platform — a closed sibling repo; not needed to run this repo.
Aether — an internal demo host; not needed.
Terms
Grok Bot: the conductor in this chat; not a neuron and not a window.
neuron: one BYO harness session (
grok,claude,codex,cursor-agent,agy/antigravity,hermes, orpi) on a thread.synapse: a native Convoy
sendinto one neuron; one harness, one meter, compact card back.Convoy: source of truth (
feed, seats,convoy_id).thread: durable circuit keyed by
convoy_id.named thread: a
--rootbinding (not a second MCP URL).grok-bot-local vs grok-bot-cloud: neuron host (user machine vs cloud agent), not a second source of truth.
Product wording retires hop in favor of neuron/synapse/thread.
The problem
Single-harness chat is weak project memory: context windows bloat, meter state drifts, and another agent cannot safely rehydrate shared state without copy/paste loss.
Wrapper stacks (one vendor CLI inside another) add indirection and contention instead of shared truth.
The solution
Convoy keeps a slim pointer/stamp layer while Grok Bot remains conductor. Synapses run on native vendor CLIs, return compact cards, and keep session ownership separated.
Contract: feed + seats + convoy_id. Unknown values stay JSON null; no invented usage/session numbers.
Machine-readable contract: src/convoy/harness_effort.json (loaded by MCP-facing code).
Keyed effort language (locked)
Effort keys are harness-scoped and must not be merged. The locked key space
lives in CANON.md ("Effort keys are harness-scoped") and the
machine-readable source of truth is src/convoy/harness_effort.json — this
README deliberately does not restate the table, so there is exactly one place
for it to drift from the code: none.
Supported neurons (code-true contract)
grok, claude, codex, cursor-agent, and agy have a cataloged installer
(convoy install --to); hermes and pi are BYO-only (install refuses them)
and their direct-id resume is unverified.
Harness |
|
|
|
|
|
|
| Writes PATH ungate block; installs | Native CLI on PATH. Named live seats queue ( |
|
|
| Writes PATH ungate block; installs | Native CLI on PATH. Named live seats queue ( |
|
|
| Writes PATH ungate block; installs | Native CLI on PATH. Named live seats queue; may |
|
|
| Writes PATH ungate block; installs | Native CLI on PATH. Named live seats queue ( |
|
|
| Writes PATH ungate block; installs | Native CLI on PATH. Named live seats queue ( |
|
|
| Writes PATH ungate block; installs | Native CLI on PATH. Named live seats queue ( |
|
|
| Writes PATH ungate block; installs | Native CLI on PATH. Named live seats queue ( |
Notes tied to code/tests:
seat.session_idandseat.resumeare distinct: session key vs vendor resume token.First-run seats can omit vendor resume; then no resume token is passed.
Live
sendis headless and never steals an active interactive neuron; refusal cards ask users tobring_up/ open a pane or write.ola/*handoff*.context.packoverlays home-layerconvoy_id+thread_keyonto seat-worktree pointers when present.bring_up/openare the bulk show commands; targetedjoin --launchis the explicit one-chair exception described below.
Bring-up and pane invariants
Isolated WT only: one
wt --window newspawn, one tab, split panes joined with literal";"argv elements.Bulk bring-up never uses
-w 0or-w <thread>; targeted launch may use-w 0only after the user explicitly requests--launchfrom an active Windows Terminal session. Never--before harness exe; never per-seatCREATE_NEW_CONSOLE; never close on fail withWM_CLOSE.Two same-harness seats on different worktrees are two panes; duplicates collapse by worktree/resume/session key.
Ctrl+Shift+Wshould only drop one split pane at a time (or no-op when there is no split pane left).Codex TUI conflict: while a Codex pane is focused,
Shift+Up/Shift+Downcan change reasoning level and fight pane navigation. Do not use those shortcuts for pane selection in that focus state.
Targeted one-chair launch
Full contract and DoD: docs/targeted-launch.md.
convoy choices lists installed harnesses, known Git/registered worktrees,
existing chair identifiers, and the detected terminal adapter. It deliberately
omits every vendor resume token. A model or user can then invoke:
convoy join --to <harness> --worktree <path> --launchThis registers and launches exactly one fresh chair. Harness argv construction is independent of terminal placement, so all harnesses use the same terminal adapter contract. A persistent atomic launch claim refuses duplicate launchers; existing/resumable chairs are not eligible and a failed terminal spawn leaves the fresh chair pending for an explicit retry.
Supported active-pane adapters:
Host | Detection | Targeting |
Windows Terminal | Windows, |
|
tmux on macOS/Linux |
|
|
Other terminal hosts fail closed with a manual-pane instruction. Convoy never
injects keystrokes or guesses an iTerm, Terminal.app, WezTerm, kitty, or shell
API. Source installs currently require Python 3.11+; the project exposes a
cross-platform convoy console entry point, but a machine without Python still
needs a packaged executable/runtime before a skill can invoke it.
Creation and closure are separate capabilities. The Windows Terminal CLI can
create a split but does not expose its closePane action. A killed TUI may leave
an exited pane visible under graceful closeOnExit, so absent process IDs are
not pane-close proof. New targeted launches therefore use a Convoy lifecycle
host: after a separate, scoped close-chair consent it terminates only its owned
child tree and exits zero. Legacy panes still require Ctrl+D or the configured
closePane binding. First-run harness trust prompts are also user decisions;
Convoy returns an awaiting-user-consent card and never auto-accepts them.
How it works
Attach
https://convoy.bot/mcp.Run
onboardwith harnesses you already installed.Bind one thread at
--root; Convoy writes/reads one durableconvoy_id.Use
sendfor synapses. A send that names a live seat queues the body (delivery: queued,delivered: false); it does not type into the TUI and does not spawn a second--resume. Codex may usecodex queue. Drain withconvoy inbox --drainor the project hookconvoy inbox --hook-pretooluse(Grok PreToolUse, Claude PreToolUse + UserPromptSubmit). Hook files never bake an absolute interpreter path.Use
bring_up/openonly when you want visible interactive TUIs for seated neurons.
End-to-end example
# (after `python -m pip install .`, see Install)
# 1) Name installed harnesses and bind this root to one thread
convoy onboard --to grok --to claude --to codex --thread demo
# 2) Register seated neurons (session key + optional vendor resume token)
convoy seat --to grok --session-id seat-grok --worktree ../wt-grok --model gpt-5.6-sol --resume vendor-grok-uuid
convoy seat --to codex --session-id seat-codex --worktree ../wt-codex --resume vendor-codex-uuid
# 3) Dry-run bring-up shows native argv (Codex uses "resume" subcommand)
convoy bring-up --dry-run
# 4) Headless synapse (safe default)
convoy send --to claude "Summarize open payment retry bugs and propose a fix plan."
# 5) Optional live headless run in a fresh native session (no resume token)
convoy send --to codex --live "Draft unit tests for the retry planner."Development: PYTHONPATH=src python test/run.py (discovers test/demo/*_test.py).
License: MIT.
Cloudflare split hosting (static site + MCP proxy)
This repo includes a Cloudflare Worker config that serves the landing page/static files at the edge while preserving the existing Python MCP transport.
Config:
wrangler.jsoncWorker entry:
workers-site.mjsStatic assets directory:
src/convoy/site
Routing behavior:
/mcpand/mcp/*are proxied byte-for-byte toMCP_ORIGIN(the current Python MCP origin).all other paths are served from Worker static assets (
env.ASSETS.fetch(request)).
Deploy steps (from an authenticated environment):
Set
MCP_ORIGINinwrangler.jsonc(or with environment-specific vars) to the current Python MCP origin URL.Run
wrangler deploy.Attach the
convoy.bot/*route to this Worker in Cloudflare.
This repo does not assume that Cloudflare Worker routing is live until those steps are completed.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
Develop, manage, and debug Railway projects, services, and deployments from within agents.
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Build, test, deploy, and operate Connic agents.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables management of visible, interactive terminal sessions across platforms (macOS, Windows, Linux, WSL). Supports creating, executing commands, capturing output, and managing multiple terminal windows simultaneously.51MIT
- AlicenseNot gradedqualityAmaintenanceA native Windows terminal multiplexer with MCP bridge for AI agents, enabling browser automation, multi-agent coordination, and terminal control.365MIT
- AlicenseBqualityCmaintenanceEnables stateful subprocess sessions (REPLs) and tmux-backed TUI program control for interactive tools like Python, r2, or shells.13AGPL 3.0
- FlicenseNot gradedqualityDmaintenanceEnables orchestration of multiple AI coding agents (Claude Code, Gemini CLI, etc.) in isolated Wezterm panes, allowing one agent to spawn, monitor, and communicate with others across projects.101
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Deploy-Forward/convoy'
If you have feedback or need assistance with the MCP directory API, please join our Discord server