hyperpanes-mcp
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., "@hyperpanes-mcplaunch a workspace with two panes, one for code and one for terminal"
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.
hyperpanes-mcp
An MCP server for hyperpanes — the Electron terminal-workspace app (one window of tiled, labeled, color-framed terminal panes). It lets an agent compose and launch workspace layouts and drive a running instance — read, spawn, and arrange panes, stream their output, and (guarded) type into live shells — from Claude, Cursor, or any MCP client.
It works at two levels, and you can use either without the other:
Level | Needs a running app? | What it does |
Compose & launch | No | Generate/validate a workspace config and shell out to |
Live control | Yes | Talk to the app's loopback control API to inspect/drive panes and stream output. |
Live control is off by default. The app's control API is a loopback (
127.0.0.1), token-authenticated server that only listens once you enable Preferences → "Allow agent control" in hyperpanes. Typing into shells (send_input) is gated further still — see the send_input safety model.
Tools
Compose & launch (no running app needed)
Tool | Description |
| List the tab layouts ( |
| Validate a workspace spec against the schema. Returns |
| Validate + return canonical workspace JSON; optionally write it to a |
| Launch |
Inspect a running instance
Tool | Description |
| Is the control API reachable? Reports app pid/version, whether the app allows input, the bridge-side |
| All panes across windows/tabs, with status, activity (busy/idle/exited), org metadata, tab/window context, and each pane's output-resource URI. |
| A pane's terminal output. |
| Drain a pane's durable message inbox past a cursor ( |
| Identify the pane this bridge is running inside ( |
Drive panes
Tool | Description |
| Open a new pane in a window's active tab (defaults to the first window). Returns the new |
| Set a tab's tiling layout (defaults to the first window's active tab). |
| Focus a pane (and its tab/window). |
| Close a pane, terminating its shell. |
| Kill and respawn a pane's shell. |
| Change a pane's label and (optionally) subtitle, live. |
| Change a pane's frame color, live (any CSS color). |
| Attach/update a pane's free-form metadata (merge; |
Send input
All three type into a live shell — they run whatever you send in a real terminal. Triple-gated and never on by default. See the safety model.
Tool | Description |
| Type text. |
| Send named keys as the right terminal bytes: |
| One full turn in one call: type → submit → wait for the pane to settle → return the rendered transcript + whether it's now |
Driving an interactive TUI agent
Two supported patterns for talking to an agent running inside a pane (e.g. a live claude):
Structured bus (preferred when the agent is MCP-capable). If the pane-agent also has the hyperpanes MCP, converse over its inbox (
send_message/send_to_parent/read_messages) — a clean, structured channel, no screen-scraping. Run such workers with an inbox-poll loop ("listening agent") so they pick messages up unprompted.TUI scrape (for any agent, incl. an interactive
claudethat won't poll its inbox). Drive the terminal directly. The one-call path isprompt_pane; under the hood that'ssend_input({ submit:true })to type a line,read_pane({ waitForIdle:true })to block until the reply lands, andread_pane({ mode:"screen" })to read it back cleanly. Usesend_keys(["enter"])to clear a first-run trust dialog, and watchawaitingInputon the result to know when the agent is blocked on a prompt rather than done.
Agent orchestration
Turn the control plane into a substrate for an LLM agent org — one orchestrator driving
worker panes, or a recursive manager→worker tree. Hierarchy is data (meta.parent), the
message bus is hierarchy-agnostic, and tokens scope what a child can reach.
Tool | Description |
| Enqueue a structured message to a pane's durable inbox (at-least-once delivery). |
| Message this pane's org parent (resolved from |
| Message every pane in an org subtree (all panes whose |
| Mint a subtree-scoped control token (no escalation) to hand a child via |
| Take an advisory write lock so only the holder can |
| Release an advisory write lock you hold. |
Work queue
A durable, SQLite-backed job queue behind the control server — fan work out to competing
workers with at-least-once delivery and leases. A claim returns each task's fencingToken;
every ack/nack/extend must carry it (lease fencing, so a reaped worker can't clobber a
task another worker now owns).
Tool | Description |
| Every queue and its per-state depth. |
| Append a task ( |
| Claim the next task(s) for a |
| Complete a claimed task (carry the |
| Fail a task — re-queued until |
| Heartbeat a long task: extend its lease so it isn't reaped. |
| Fetch one task (state, payload, attempts, lease, timestamps). |
| List/inspect a queue's tasks with a |
| Drop terminal tasks (done/failed/dead) for cleanup. |
Related MCP server: cmuxlayer
Resources
Pane output and inboxes are exposed as subscribable MCP resources — read for a snapshot,
subscribe for a live stream (the bridge consumes the app's /events WebSocket and emits
resources/updated / resources/list_changed notifications):
Resource URI | Content |
| Terminal output — scrollback on read, deltas on subscribe ( |
| The pane's durable message inbox — JSON on read, live deliveries on subscribe. |
Installation
The server runs over stdio and is launched by your MCP client.
Claude Desktop / generic MCP config
{
"mcpServers": {
"hyperpanes": {
"command": "npx",
"args": ["-y", "hyperpanes-mcp"],
"env": {
"HYPERPANES_BIN": "C:/path/to/hyperpanes.exe"
}
}
}
}HYPERPANES_BIN is only needed for launch_workspace; the live-control tools find the app
via its control.json (see Configuration).
Claude Code
claude mcp add hyperpanes -- npx -y hyperpanes-mcpInstall globally
npm install -g hyperpanes-mcp
hyperpanes-mcp # runs the stdio serverAlso published to GitHub Packages as @eyalm321/hyperpanes-mcp.
Configuration
All variables are optional. launch_workspace needs a launcher; the live-control tools need
the app running with "Allow agent control" enabled.
Env var | Purpose |
| Path to the hyperpanes executable (for |
| Whitespace-separated leading args for the launcher (e.g. a dev runner). |
| Override the path to the app's |
| Override just the userData dir; |
| A scoped control token + port for a child pane (set automatically by |
| The pane this bridge runs inside — enables |
|
|
| Comma-separated pane ids or labels allowed to receive input. |
Default control.json locations:
Windows:
%APPDATA%\hyperpanes\control.jsonmacOS:
~/Library/Application Support/hyperpanes/control.jsonLinux:
$XDG_CONFIG_HOME/hyperpanes/control.json(or~/.config/hyperpanes/…)
send_input safety model
send_inputtypes into live shells — it runs whatever you send in a real terminal. It is the sharp edge of this server and is never on by default. Three independent gates, all required:
App-side (enforced by hyperpanes): the control server is loopback + token, disabled by default, and
send_inputreturns 403 unless "Allow agent control → input" is on. The bridge cannot bypass this.Bridge opt-in: refused unless
HYPERPANES_ALLOW_INPUT=1is set in this server's environment. OptionallyHYPERPANES_INPUT_ALLOWLISTrestricts which panes accept input.Per-call confirmation: every call must pass
confirm: true.
control_status surfaces all three (appAllowsInput + inputGate) so a refusal is always
explainable.
Workspace schema
A faithful mirror of the app's WorkspaceFile. The canonical shape is nested; the legacy
single-window fields are kept for back-compat, and everything normalizes through one
windowsOf funnel (windows[] verbatim → groups[] as one window → panes[] as one window/tab).
WorkspaceFile { name?, layout?, panes?, groups?, active?, windows? }
WindowSpec { title?, active?, bounds?, groups[] }
GroupSpec { title?, layout?, panes[], sizes?, mainFraction?, focused?, zoomed? } // a tab
PaneSpec { label?, subtitle?, color?, command?, cwd?, shell?, fontSize? }
Layout = auto | single | columns | rows | grid | main-stackLaunch modes.
launch_workspacedefaults to writing a temp.json(lossless).mode:"cli"compiles to--window/--tab/-c …flags — convenient but lossy: window bounds, the active-tab index, pane subtitle, split sizes, and command-less panes are JSON-only and reported inlossy.Relative
cwd. In a workspace file, relativecwdresolves against the file's dir. Inline specs are written to a temp file — prefer absolutecwdfor inline specs.Strict validation. Unknown keys are rejected (typo guard),
layoutmust be a known id,fontSizea positive integer, and a workspace must declare at least one pane.
See examples/dev.workspace.json for a full two-window spec.
Development
npm install
npm run build # tsc -> dist/
npm test # vitest (pure units; no running app needed)
npm run test:watch
npm run dev # tsx src/index.ts
node scripts/smoke.mjs # end-to-end stdio check (no app needed)The unit tests mirror the app's own workspace.test.ts / control read-model cases, so a
contract drift in the app surfaces here as a test failure.
Architecture
src/
index.ts # stdio entrypoint
server.ts # creates the MCP server; registers compose/launch tools + wires control tools
schema.ts # workspace schema (zod) + windowsOf/summarize — mirrors the app's workspace.ts
compile-cli.ts # WorkspaceFile -> hyperpanes CLI argv (inverse of the app's parseCli)
launch.ts # launcher resolution + launch planning/execution
control-tools.ts # live-control + orchestration tools, and the subscribable pane resources
control/
discovery.ts # locate + parse control.json (and scoped-token env)
client.ts # HTTP client for the control API (state/output/input/command/messages/tokens/locks)
model.ts # read-model types + pure helpers (flatten, resolve, URIs, whoami, subtree)
subscriptions.ts# /events WebSocket -> MCP resource notifications
input-gate.ts # send_input gating (opt-in + confirm + allowlist)
scripts/smoke.mjs # end-to-end stdio check
examples/ # sample workspace filesReleasing
CI runs the build + tests on every push and PR to main (Node 20 & 22). Publishing is
triggered by creating a GitHub Release, which publishes to both registries:
npm as the unscoped package
hyperpanes-mcpGitHub Packages as
@eyalm321/hyperpanes-mcp
One-time repo setup
Add an
NPM_TOKENrepository secret (an npm automation token).GITHUB_TOKENis provided automatically for GitHub Packages.To release:
npm version <patch|minor|major>, push with--follow-tags, then create a GitHub Release for the tag (e.g.v0.1.1). Thepublishworkflow builds, tests, and publishes to both registries.
License
MIT © Eyalm321
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.
Latest Blog Posts
- 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/Eyalm321/hyperpanes-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server