visible-terminal-mcp
Click on "Deploy 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., "@visible-terminal-mcpOpen a terminal, run npm init -y, then read what's on screen"
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.
visible-terminal-mcp
An MCP server that gives an AI agent control of a genuinely visible Windows terminal window — the agent spawns it, types into it, reads back exactly what's rendered on screen, and closes it, while a human watches the real window the whole time.
The problem this solves
Most ways an AI agent can drive a terminal are headless: the agent spawns a process behind a pseudo-terminal (ConPTY / node-pty), types into it, and reports back what happened. That's fast and works well for scripted automation — but it gives a human nothing to look at. You're asked to trust that the agent did what it says it did, with no independent way to verify it in real time.
This project exists because that trust gap caused a real problem: an agent was asked to drive a second interactive CLI session on behalf of a user. Using a headless approach, the agent reported success — but the session had silently failed to persist its work, and there was no way for the user to have caught this while it was happening, because there was nothing to watch. See docs/motivation.md for the full incident this project was built to prevent from recurring.
The fix: don't hide the terminal. Spawn a real, classic Windows console window — the same kind you'd open yourself — and drive it with the same two things a human uses: a keyboard and a pair of eyes.
Related MCP server: com-use-mcp
What it actually gives you
Capability | Mechanism | Why it's different from a headless approach |
Spawn a real terminal window |
| It's an actual OS window, not a virtual buffer — the user can see it exists |
Type into it | Windows | Real keystrokes, including special keys (arrows, Enter, Esc, Tab) for navigating interactive menus/pickers |
Read what's on screen | Win32 Console API ( | Reads the actual character buffer the window is displaying — not a screenshot, not a guess, the same content the human sees |
Close it |
| Clean teardown when done |
Because reading goes through the real console buffer, the agent and the human are looking at the same ground truth — there's no second, hidden copy of "what happened" that only the agent has access to.
Use cases
Supervised automation of interactive CLIs — anything that only shows its full behavior when it detects a real terminal (confirmation prompts, TUI pickers, tools that disable prompts when piped), with a human able to watch it happen.
Driving a second instance of an interactive agent/CLI session on behalf of a user, transparently — the motivating case for this project.
Reproducing and debugging terminal-dependent bugs that don't manifest the same way under a headless PTY, with a human verifying each step as the agent takes it.
Teaching or demoing what an agent is doing step by step, rather than presenting only a final summary.
Requirements
Windows (uses Win32 Console API and PowerShell
SendKeys— this is not cross-platform)Node.js >= 18
PowerShell available on
PATH
Installation
git clone https://github.com/Sanjay-dev22/visible-terminal-mcp.git
cd visible-terminal-mcp
npm installUsing it as an MCP server
Register it with your MCP-compatible client. For Claude Code, add this to your mcpServers config (e.g. ~/.claude.json):
{
"mcpServers": {
"visible-terminal-control": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/visible-terminal-mcp/src/server.js"],
"env": {}
}
}
}Restart your MCP client, and four tools become available. The server also declares MCP instructions — a usage guide (workflow, pacing, focus requirements) that a compliant client surfaces to the agent automatically on connect, the same way tool descriptions are surfaced. You don't need to paste anything from this README into a prompt for the agent to know how to use the server correctly.
vterm_spawn
Opens a new, visible PowerShell window.
Param | Type | Required | Description |
| string | no | Working directory to start in |
Returns { pid } — the process id used by every other tool.
vterm_send
Sends keystrokes to a window, exactly as if typed on a keyboard.
Param | Type | Required | Description |
| string | yes | From |
| string | no | Literal text to type |
| boolean | no | Press Enter after the text |
| array | no | Named keys sent in order: |
Why each key is its own process call internally: sending multiple
SendKeyscalls within a single PowerShell invocation is not reliably delivered — confirmed empirically, only the first of several queued keys would land, even with delays in between.vterm_sendissues one PowerShell process invocation per discrete key/text/enter action, which is reliable 100% of the time in testing. This makes each call slightly slower than a naive batched version, but correct — seedocs/motivation.mdfor how this was diagnosed.
vterm_read
Reads exactly what's currently rendered in the window.
Param | Type | Required | Description |
| string | yes | From |
Returns the visible screen content as text.
vterm_close
Terminates the window's process.
Param | Type | Required | Description |
| string | yes | From |
Example
See examples/basic-spawn-type-read.js for a minimal spawn → type → read → close cycle, and examples/menu-navigation.js for using special keys to navigate a TUI/history menu (PowerShell command-history recall, as a stand-in for any arrow-key-driven picker).
npm run example:basic
npm run example:menu-navigationRelying on focus, not stealing it
vterm_send does not forcibly steal window focus (no SetForegroundWindow call). It relies on the target window already having focus — true immediately after vterm_spawn creates it, or after a human last interacted with it. This is a deliberate choice: combining forced focus-stealing with synthetic keystroke injection is a recognized pattern for malicious input automation, and this project avoids it even though it means the caller is responsible for not clicking elsewhere mid-sequence.
Known limitations
Windows only. The console-reading mechanism and
SendKeysare both Win32-specific.Reads text, not pixels.
vterm_readreturns the character buffer, not colors, fonts, or a literal screenshot.Can't reach an IDE's own integrated terminal panel (e.g. VS Code's) directly — that would require an IDE-extension-based tool, which this is not. It controls independent OS-level console windows.
One key per process call. See the note under
vterm_sendabove — this is intentional, not a missing optimization.Relies on the target window keeping focus between calls — if something else is clicked in between, keystrokes go to the wrong place, same as a real human would need to refocus.
License
Available Tools
4 toolsvterm_closeA
Close a visible terminal window (terminates the process).
| Name | Required | Description | Default |
|---|---|---|---|
| pid | Yes | Process id returned by vterm_spawn |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden, and it does earn credit for disclosing the key consequence: the underlying process is terminated, not merely detached or hidden. It still omits failure modes — what happens with an invalid or already-dead pid, whether the call is idempotent, and whether in-flight work is lost.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no waste; the most important fact, that the process dies, is included. It is arguably under-specified rather than bloated, but nothing in it is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter lifecycle tool with full schema coverage and no output schema, the essential facts — action and side effect — are present. What is missing, error behavior on stale pids, is minor at this complexity level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the sole parameter is documented as the process id returned by vterm_spawn, which even cross-references the sibling that produces it. The description adds nothing beyond that, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (close) and resource (a visible terminal window), with a parenthetical that disambiguates what closing means: the process is terminated. That distinguishes it cleanly from vterm_spawn, vterm_send and vterm_read, which create, write to, and read terminals.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the verb-resource pair and the sibling set, but there is no explicit when-to-use or when-not-to-use statement, no mention of cleanup duties, and no declaration that this is the counterpart to vterm_spawn. An agent must infer that from tool names alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vterm_readB
Read exactly what is currently rendered on screen in a visible terminal window, via the real Windows Console API (not a screenshot) — the same thing the user sees if they look at that window.
| Name | Required | Description | Default |
|---|---|---|---|
| pid | Yes | Process id returned by vterm_spawn |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden, and it does valuable work by clarifying this reads the console buffer rather than capturing pixels. However, it omits key behavior an agent needs: whether the window must be foregrounded/visible for the read to succeed, what happens for an invalid or closed pid, and whether only the viewport (not scrollback) is returned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence with the core action front-loaded ('Read exactly what is currently rendered') and the parenthetical qualifiers each eliminating a plausible misinterpretation (screenshot, other windows). Nothing is padded or repeated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool, the description covers what is read and from where, but with no output schema it should say more about the returned shape (plain rendered text? whitespace/ANSI preserved? viewport-only vs scrollback) and about failure modes. It is minimally sufficient rather than complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single pid parameter is already documented as 'Process id returned by vterm_spawn', so the schema does the heavy lifting. The description adds no further parameter meaning, which is exactly the baseline 3 case for high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource ('read exactly what is currently rendered on screen') plus the mechanism ('real Windows Console API, not a screenshot'), which makes the operation unmistakable. It never names vterm_spawn/vterm_send/vterm_close, so routing is inferred from the operation described rather than explicitly stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description never says when to call this versus waiting, re-sending input, or checking a different window; only the phrase 'in a visible terminal window' hints at a precondition. An agent must derive the usage pattern (e.g. read after vterm_send to verify output) entirely on its own.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vterm_sendA
Send keystrokes to a visible terminal window, exactly as if typed on a keyboard. Relies on the window having focus (true right after vterm_spawn, or after the user last interacted with it — does not forcibly steal focus from other windows). Does not wait for a response — call vterm_read afterward.
| Name | Required | Description | Default |
|---|---|---|---|
| pid | Yes | Process id returned by vterm_spawn | |
| text | No | Literal text to type (e.g. a command or a chat message). | |
| enter | No | Press Enter after the text. | |
| special | No | Special keys to send in order, e.g. ["UP","UP"] to navigate a menu, before any text/enter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose key behavior: focus dependency, no focus stealing, and non-blocking execution. However, it does not explain what happens if the window lacks focus or what the immediate return value is, leaving some failure-mode and response behavior unspecified.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tight sentences, front-loads the core action, then gives focus constraints and the required follow-up. There is no redundant or filler text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given full parameter schema coverage and no output schema, the description provides the essential operational context: focus requirements and the need to call vterm_read afterward. It is complete enough for correct invocation, though failure behavior when unfocused is not fully specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents pid, text, enter, and special keys in detail. The description adds only general context about keystrokes and does not supplement parameter semantics beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: send keystrokes to a visible terminal window. It clarifies the action as equivalent to typing on a keyboard, which clearly distinguishes it from sibling tools like vterm_spawn, vterm_read, and vterm_close.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states the focus prerequisite (true right after vterm_spawn or after user interaction), warns that it does not forcibly steal focus, and directs the agent to call vterm_read afterward. This gives clear when-to-use context and sequencing relative to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vterm_spawnA
Open a brand-new, genuinely visible PowerShell console window the user can watch on their own screen. Returns the process id (pid) to use with vterm_send / vterm_read / vterm_close.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | Working directory to start in. Defaults to the current directory. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose the key behavioral fact: this creates a real, user-visible window on their screen — an observable side effect an agent must not trigger casually. It also implies a lifecycle requiring vterm_close. It does not cover failure modes (e.g., headless/no interactive session) or whether the window steals focus, keeping it below a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the first defines the action and its visible-window nature, the second gives the return value and the follow-up tools. No filler, and the most decision-relevant fact (a visible window appears) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter spawn tool with no output schema, the description supplies the birth-to-death lifecycle (spawn → send/read → close) and explicitly states the pid return, which substitutes for the missing output schema. Minor gap: no note on environment prerequisites or whether multiple windows are permitted.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single optional cwd parameter is fully documented in the schema, so baseline 3 applies. The description adds no information about cwd semantics (e.g., whether it must exist or how paths are resolved) beyond what the schema already says.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (open/spawn) and resource (a PowerShell console window) plus the distinguishing trait that it is 'genuinely visible' to the user, which separates it from any hypothetical headless execution. It also declares the return value (pid) and maps it to the sibling tools that consume it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly establishes the workflow: spawn first, then use the returned pid with vterm_send / vterm_read / vterm_close, naming all three siblings. It stops short of explicit when-not guidance (e.g., when to reuse an existing session rather than spawn a new window), so it is clear context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v1.0.0- First observed
vterm_close - First observed
vterm_read - First observed
vterm_send - First observed
vterm_spawn
TDQS
Scored across 4 tools
Each tool maps to a distinct lifecycle action on a visible terminal: spawn, send, read, and close. There is no overlap in purpose, and the descriptions make the boundaries between input, output, and process management clear.
All tools use a consistent vterm_verb pattern: vterm_spawn, vterm_send, vterm_read, vterm_close. The shared prefix and short action verbs are predictable and readable.
Four tools are well-scoped for a focused visible-terminal controller. Each tool earns its place in the create/send/read/close lifecycle, with no redundant operations.
The core lifecycle for a visible terminal is covered: opening, typing into, reading from, and closing a window. Minor gaps exist, such as explicit waiting for command completion or listing active terminal windows, but agents can work around them with repeated reads.
Maintenance
Related MCP Connectors
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Control a real browser from AI agents: navigate, click, type, screenshot, read the page.
Give your AI hands on every computer you own. Remote control of your Windows, Mac and Linux machines from one ChatGPT, Claude or Cursor chat — even from your phone. Ask it to find out why the office server is crawling, update every PC in the house, sort out your mom's laptop from another city, or ship the site from your work machine while you're on a train. It runs commands, reads files and takes a screenshot when it needs to see the screen. You decide what each computer allows, and you can cut any of them off in a second.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceProvides AI agents with fully interactive terminal sessions, including TUI support, keyboard control, and screen capture across Windows, Linux, and Mac.MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to see and operate a Windows PC through mouse, keyboard, screenshots, OCR, window control, and shell commands.-
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to drive native Windows apps and headed browsers inside a hidden child desktop session with its own screen, pointer and keyboard focus. Provides tools for screenshots, mouse/keyboard input, accessibility inspection, UI waits, display changes, Android emulators, application launches and cancellable command jobs, so the user's own desktop stays free.3MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI models to control a local Windows desktop by moving the cursor, clicking, scrolling, typing Unicode text, sending key chords, and capturing screenshots. Runs natively on Windows with minimal latency and no heavy dependencies such as Python, PyAutoGUI, or Docker.58 npm1MIT