terminal-emulator-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., "@terminal-emulator-mcpStart a terminal, run 'npm test', and show the result."
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.
terminal-emulator-mcp
A headless, interactive terminal MCP server for shells, REPLs, and TUIs. Agents can launch commands, inspect screen text and formatting, send keyboard or mouse input, resize terminals, and close sessions. Each session owns a real pseudoterminal and a headless xterm emulator.
Install
Requires Node.js 22 or newer on macOS or Linux. Install a released version from npm:
npm install --global --allow-scripts=node-pty terminal-emulator-mcp@0.9.0
terminal-emulator-mcp --versionThe examples explicitly approve node-pty's native installation scripts on npm versions that support --allow-scripts. This approval is not a blanket deny policy for other packages. Older npm versions without the option can omit it.
Related MCP server: Interactive Terminal MCP Server
Add to Claude Code
claude mcp add --scope user --transport stdio terminal-emulator-mcp -- terminal-emulator-mcp
claude mcp get terminal-emulator-mcpThe user scope makes the server available across projects.
Add to Codex CLI
codex mcp add terminal-emulator-mcp -- terminal-emulator-mcp
codex mcp get terminal-emulator-mcpStart a new harness session and use /mcp to check the connection. The executable must be on the harness's PATH; an absolute executable path also works. An existing registration with the same name may need to be removed before changing its launch command.
Run through npx
For an npx-based setup, use these add commands instead of the global-install configuration above:
claude mcp add --scope user --transport stdio terminal-emulator-mcp -- \
npx --yes --allow-scripts=node-pty terminal-emulator-mcp@0.9.0
codex mcp add terminal-emulator-mcp -- \
npx --yes --allow-scripts=node-pty terminal-emulator-mcp@0.9.0The version pin makes startup reproducible. A first npx run may need to download packages or compile native code; a global installation completes that work before the harness starts its MCP connection.
Native binaries
The pinned node-pty dependency ships prebuilt binaries for macOS x64/ARM64 and glibc-based Linux x64/ARM64. A compatible prebuild avoids a local compiler requirement. Other environments, including musl-based Linux distributions, may need an explicit source build with Python 3, make, a C/C++ compiler, and suitable Node headers. macOS source builds use Xcode Command Line Tools.
npm_config_build_from_source=true npm install --global --allow-scripts=node-pty \
terminal-emulator-mcp@0.9.0The server uses stdin/stdout for MCP messages and stderr for diagnostics. With no arguments it starts the stdio server; --help and --version print their output and exit. Commands run with the server's local permissions and inherited environment.
Tools and a typical session
Tool | Required arguments | Result |
|
| Initial snapshot and |
|
| Current snapshot; optional |
|
|
|
|
| Snapshot at the applied size |
| None |
|
|
|
|
For example, start Claude Code in a 120×40 terminal:
{"command":"claude","cols":120,"rows":40,"cwd":"/absolute/path/to/project"}terminal_start runs [shell, "-l", "-c", command] by default, loading the shell's login startup files while executing a noninteractive command. Pass login:false to use [shell, "-c", command]. The -l flag is supported by common shells such as Bash, Zsh, Dash, and Fish; it is a convention rather than a universal POSIX requirement. Login startup does not force interactive mode or guarantee that interactive-only files such as .zshrc are read.
Commands support the selected shell's quoting, pipelines, and redirection. The shell defaults to the server's nonempty SHELL variable, then /bin/sh; pass shell to override it. The initial working directory defaults to the server's directory. env overrides inherited variables, with null deleting a variable; login startup files can further change the environment or directory. TERM is fixed to xterm-256color and cannot be overridden through env.
Use the returned session ID to submit input:
{
"sessionId": "<returned ID>",
"actions": [
{"type":"text","text":"Explain this repository"},
{"type":"key","key":"Enter"},
{"type":"wait","durationMs":500}
]
}Inspect the screen, send any follow-up actions, and close the session when finished. Batches preserve action order and share a per-session queue with resize operations. They do not automatically wait for the application to respond between actions; add a wait action or use separate calls when needed. Snapshots can run while a batch waits.
Input actions
Action | Fields | Behavior |
|
| Send the exact Unicode string |
|
| Normalize line endings to carriage returns; use bracketed-paste markers when enabled |
|
| Send a named key or one printable ASCII character |
|
| Send a press and, where supported, release |
|
| Send one wheel report per step |
|
| Pause for a fixed duration |
| Optional | Wait for screen settlement |
|
| Notify the application when focus reporting is enabled; otherwise no output |
|
| Send integers from 0 through 255 without text encoding |
Named keys are Enter, Tab, Backspace, Escape, Space, Up, Down, Left, Right, Home, End, PageUp, PageDown, Insert, Delete, and F1–F12. Keys and modifiers are case-sensitive. Unicode input belongs in text or paste.
Modifiers are Ctrl, Alt, and Shift, with no duplicates:
Key family | Supported modifiers |
Navigation and function keys | Any subset of the three modifiers |
|
|
|
|
|
|
Printable ASCII | Optional |
Ctrl with ASCII | Letters, space, |
Unsupported combinations fail before any batch input is sent. Traditional terminal encodings cannot distinguish all physical keys: Ctrl+I and Tab send the same byte. There are no key-up events, platform shortcuts, keypad modes, or extended keyboard protocols; raw provides explicit byte access.
Mouse coordinates are 1-based cells within the terminal. Buttons are left (default), middle, and right. Wheel count defaults to one and accepts 1–100. Mouse reporting must be enabled by the application. Legacy mouse encoding supports coordinates through 223; SGR cell encoding supports the configured screen dimensions. Pixel mode is rejected. X10 supports unmodified click presses only, without release or wheel reports. Dragging, pointer motion, clipboard access, and window-system shortcuts are outside scope. Wheel reports are application input; they do not scroll the emulator's history.
Encoding follows the application's modes at each action. Paste control characters remain unchanged, and focus actions count as complete even when reporting is disabled.
Screens and formatting
Every snapshot has exactly rows screen strings, a cursor, a style legend, and spans over nondefault cells. Tool results include both structured data and readable text with numbered screen rows. Coordinates and span endpoints are 1-based; endpoints are inclusive. String offsets are not cell coordinates, particularly for wide or combining characters.
Readable spans use row: column[-column]=styleId, for example 1: 1-5=s1 8=s2. Structured content retains the full span objects. The complete encoded result has an 8 MiB limit, including structured data and readable text. If a screen or requested history cannot fit, the tool returns RESULT_TOO_LARGE with no screen instead of truncating its styles or disconnecting the client.
An example snapshot at 8×2:
{
"sessionId":"<ID>",
"status":"running",
"cols":8,
"rows":2,
"buffer":"normal",
"screen":["READY",""],
"cursor":{"row":2,"column":1,"visible":true},
"styles":{"s1":{"foreground":{"kind":"palette","index":2},"bold":true}},
"spans":[{"row":1,"startColumn":1,"endColumn":5,"styleId":"s1"}],
"mouse":{"tracking":"none","encoding":"legacy"},
"settled":true
}Colors use palette indices or RGB values such as {"kind":"rgb","value":"#00ff80"}. Other attributes include background, dim, italic, underline, blink, inverse, invisible, strikethrough, and overline. Missing attributes mean terminal defaults. Style IDs belong to one snapshot and may change between snapshots.
Leading whitespace and blank rows are preserved. Trailing unstyled spaces can be omitted; styled blank cells retain their spans. Concealed characters are represented as spaces. Styles report visual facts without labeling application semantics such as selection or errors.
terminal_snapshot accepts scrollbackLines: 0–2000 (default zero). Requested history is returned separately as {lines, availableLines}, in chronological order, from the normal buffer even while an alternate screen is active. History is bounded and is not a complete process transcript.
Settlement and recovery
Start, snapshot, input, and resize accept optional settleMs and settleTimeoutMs. Each observation begins a fresh quiet interval:
Timing | Meaning |
Omitted | Wait for 250 ms of visible quiet, capped at 1,000 ms; return |
| Request N ms of quiet within the deadline |
| Require settlement within T ms; otherwise return |
| Flush received output when possible and capture without a quiet wait |
Visible text, styles, cursor position/visibility, active buffer, and size affect quiet detection. Identical repaints and changes confined to history do not reset it. Pending parsing and an application's synchronized redraw prevent settlement. At a deadline, the latest complete parsed screen is returned with settled:false. A zero quiet interval with a strict deadline still waits for parsing and synchronized redraw completion.
Quiet intervals and explicit delays accept integer milliseconds from 0–60,000. Strict deadlines accept 1–60,000 and must be at least the quiet interval (250 ms if omitted). Without a strict deadline, a quiet interval above 1,000 ms cannot finish before the default cap. The input operation's final-observation deadline begins after its batch completes; each observation-style wait has its own independent timing.
Settlement measures observed inactivity, not application completion. On a strict timeout, input and resize effects remain applied, and a newly started session remains available. MCP tool errors include a stable code, readable message, sessionId when allocated, and latestSnapshot when available.
An input result or operational failure includes actionsCompleted and inputSent. Completed actions include waits and no-op focus actions. inputSent:true means bytes were submitted to the terminal, not that the application consumed them. A failure inside an action also includes zero-based failedActionIndex. Check these fields and the latest screen before retrying; resending an already-submitted batch can repeat its effects. Invalid schema arguments can be rejected by MCP before reaching the tool handler.
RESULT_TOO_LARGE preserves the session ID, dimensions, process status, and any input progress, along with resultBytes and limitBytes. Applied input and resize effects remain in place. Recover by resizing the terminal or requesting fewer scrollback lines; the connection and session stay available. If an underlying operation also failed, originalError retains its code and message (up to 1,024 characters, with messageTruncated:true when needed). Error responses omit oversized snapshots explicitly. Missing-session input reports zero completed actions and no submitted input.
Tool argument objects are strict: unknown top-level fields, unknown action fields, and invalid timing relationships are rejected before mutation.
Limits and cleanup
The server retains at most eight sessions, including exited sessions. Supported dimensions are 2–500 columns and 1–200 rows. Each batch contains 1–256 actions and at most 1 MiB of UTF-8 text, paste, and raw payload combined. Output parsing uses backpressure to bound its pending queue while preserving the process output stream.
A command's exit is a successful observation with status:"exited" and available exitCode or signal, including nonzero exits. Its final screen remains inspectable until close. Input and resize reject exited sessions. Unknown or already-closed IDs return closed:false from terminal_close.
Close cancels pending work, terminates the launched process group, allows a bounded grace period, escalates to SIGKILL when necessary, and disposes terminal resources. Ordinary descendants sharing the group are included; deliberately detached processes are outside session ownership. Disconnect, SIGHUP, SIGINT, and SIGTERM close all sessions. Abrupt server termination such as SIGKILL cannot run cleanup. Canceling an individual MCP request releases its wait without closing the session or retracting submitted input.
Development
From a source checkout:
npm ci
npm run build
npm run typecheck
npm test
npm pack --dry-runThe project records a version-specific installation-script approval for node-pty through allowScripts. Consumer installations use their own npm policy.
npm pack builds an artifact containing compiled runtime modules, package metadata, this README, and LICENSE. The executable is dist/src/index.js; installed packages do not require TypeScript or the source tree. CLI and MCP versions are read from the package manifest.
CI is configured for macOS and Linux with Node 22 and 24, including real terminal-process tests and package checks.
License
Available Tools
6 toolsterminal_closeADestructiveIdempotent
Close a terminal, cancel pending work, terminate its process group, and release its screen. Returns {sessionId,closed}; an unknown or already-closed ID returns closed:false.
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive=true and idempotent=true, and the description adds valuable behavioral detail beyond those hints: it explicitly states that pending work is canceled, the process group is terminated, the screen is released, and that unknown or already-closed IDs return closed:false. This tells the agent exactly what will be destroyed and how idempotency manifests, which is strong disclosure.
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 two sentences with zero filler. The first sentence front-loads the primary action and its immediate consequences, and the second sentence precisely documents the return value and the failure/idempotent case. Every clause earns its place.
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 tool with rich annotations already covering destructiveness and idempotency, the description is complete. It specifies the return shape ({sessionId, closed}), the behavior for invalid IDs, and the side effects on the terminal's process and screen. No output schema exists, so documenting the return contract here is essential and is handled well.
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?
The schema only provides sessionId as a string with minLength 1? sub>1, and schema description coverage is 0%. The description compensates by discussing the behavior of 'an unknown or already-closed ID', which clarifies the semantic meaning of sessionId as the terminal identifier and describes an edge case. It does not elaborate on format requirements, but for a single self-descriptive parameter this is adequate.
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 opens with a specific verb and resource combination: 'Close a terminal', and it distinguishes this operation from the siblings by enumerating the concrete effects: 'cancel pending work, terminate its process group, and release its screen.' This clearly identifies what the tool does and why it is distinct from terminal_list, terminal_start, and the other siblings.
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 intended usage is clearly implied: use this tool when you need to shut down a terminal and clean up its associated process state. The description does not explicitly name alternatives or say 'when not to use', but the action word 'Close' plus the detailed effects provide enough context to select it over siblings. It lacks an explicit exclusion statement, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
terminal_inputADestructive
Send an ordered batch of actions and return its styled screen, actionsCompleted, and inputSent. text sends exact Unicode; paste normalizes newlines and honors bracketed-paste mode. key sends named keys or printable ASCII with supported modifiers. mouse clicks/wheels require application reporting and cell coordinates; disabled reporting, pixel mode, and unsupported X10 actions fail. focus is a no-op unless reporting is enabled. raw sends bytes. wait delays with durationMs or observes with timing options. Example actions: [{type:"key",key:"F2"},{type:"wait"},{type:"key",key:"Down"}]. Modes are checked per action; response waits are explicit. A settling error does not undo input; inspect inputSent, actionsCompleted, and zero-based failedActionIndex before retrying.
| Name | Required | Description | Default |
|---|---|---|---|
| actions | Yes | ||
| settleMs | No | ||
| sessionId | Yes | ||
| settleTimeoutMs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations mark the tool as destructive and non-idempotent, but the description adds substantial behavioral detail: paste normalization, modifier support, mouse reporting requirements, no-op focus, per-action mode checks, and the fact that settling errors do not undo input. This is exactly the kind of context an agent needs before sending input.
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 dense but perfectly structured: core contract first, then per-action semantics, an illustrative example, and failure/retry guidance. No sentence is filler, and the most important information 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 complex input tool with no output schema, the description names the return fields, explains failure modes, gives a runnable example, and warns that a settling error does not undo input. Nothing essential for correct invocation appears to be missing.
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?
Since schema description coverage is 0%, the description carries the full burden, and it delivers: it explains what each action type does, the meaning of modifiers, why mouse actions need coordinates, what wait options exist, and the raw byte behavior. The example also clarifies the expected action array shape.
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?
Opens with a specific verb ('Send') and clear resource ('ordered batch of actions'), and names exactly what is returned: styled screen, actionsCompleted, and inputSent. The per-action detail makes it unmistakably distinct from sibling tools like terminal_snapshot or terminal_resize.
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?
Provides clear operational context for each action type, including when mouse actions fail, when focus is a no-op, and how modes are checked per action. It stops short of explicitly naming alternatives such as terminal_snapshot for read-only inspection, so it lacks a formal when-to-use versus alternative statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
terminal_listARead-only
List retained terminal sessions with IDs, commands, working directories, dimensions, and process status. Exited sessions count toward the eight-session limit until closed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description consistently describes a read-only listing operation. It adds meaningful behavioral context beyond the annotations by noting that exited sessions still count toward the eight-session limit until closed, which is important for capacity planning and not inferable from the annotations alone.
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 a single sentence that front-loads the core action and output fields, then attaches a relevant capacity-limit note. Every clause earns its place with no filler or redundancy.
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?
Since there is no output schema, the description shoulders the burden of describing return values and does so by listing all key fields (IDs, commands, working directories, dimensions, and process status). It also covers the important boundary condition about exited sessions and the eight-session limit, making the tool fully usable without external context.
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?
The tool takes zero parameters, so the input schema carries no parameter documentation burden. The description appropriately focuses on what is listed rather than on inputs; with no params, a baseline of 4 is appropriate and the description does not need to add parameter meaning.
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 uses a specific verb ('List') with a specific resource ('retained terminal sessions') and enumerates the exact data returned (IDs, commands, working directories, dimensions, process status). This clearly distinguishes it from the sibling tools, which start, snapshot, input, resize, or close sessions.
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 makes the tool's purpose obvious and implies use when an agent needs to inspect existing terminal sessions, but it does not explicitly state when to prefer this over alternatives or what conditions might exclude its use. There are no exclusions or alternative routing, so usage guidance is only implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
terminal_resizeADestructiveIdempotent
Resize the child terminal and emulated screen, then observe the result. The child receives its terminal-size notification. A strict timeout retains the applied dimensions in latestSnapshot; it does not undo the resize.
| Name | Required | Description | Default |
|---|---|---|---|
| cols | Yes | ||
| rows | Yes | ||
| settleMs | No | ||
| sessionId | Yes | ||
| settleTimeoutMs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=false, destructiveHint=true, and idempotentHint=true. The description adds useful behavioral context: the child receives its terminal-size notification, and a timeout retains the applied dimensions rather than rolling back. It does not contradict the annotations.
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 sentences, with the primary verb and object front-loaded and no filler. Every sentence adds behavioral or side-effect information.
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?
The core behavior and side effects are covered well, and no output schema exists, so return-value description is unnecessary. However, with five parameters and no parameter documentation, the description leaves the optional timing semantics underspecified for correct invocation.
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 0% and the description does not explain the five parameters. cols, rows, and sessionId are inferable from names, but settleMs and settleTimeoutMs are ambiguous and never addressed, so the description does not compensate for the missing schema documentation.
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 names a concrete action ('Resize the child terminal and emulated screen') and the observable outcome ('observe the result'), which clearly separates it from sibling tools like terminal_input and terminal_snapshot.
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?
There is no explicit statement about when to use terminal_resize versus terminal_start, terminal_input, or terminal_snapshot. The phrase 'then observe the result' implies a follow-up observation, but it does not name alternatives or give decision criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
terminal_snapshotARead-only
Observe the current terminal screen, styles, cursor, and process status without sending input. Optionally request up to 2,000 normal-buffer scrollback lines. settleMs:0 captures without a quiet wait. An exited process keeps its final screen until the session is closed.
| Name | Required | Description | Default |
|---|---|---|---|
| settleMs | No | ||
| sessionId | Yes | ||
| scrollbackLines | No | ||
| settleTimeoutMs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds meaningful behavioral detail: 'settleMs:0 captures without a quiet wait' and 'An exited process keeps its final screen until the session is closed.' These reveal timing and lifecycle behavior an agent could not infer from annotations alone.
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?
Three sentences with no filler: the main purpose is front-loaded, then scrollback scope, then the two behavioral exceptions. Every sentence adds information needed to call the tool correctly.
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?
The description covers the tool's content (screen, styles, cursor, process status), optional scrollback, quiet-wait behavior, and exit-state behavior. Since there is no output schema, exact return formatting is left unspecified, but an agent has enough context to invoke the snapshot correctly and interpret its purpose.
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 0%, so the description must compensate. It does explain scrollbackLines ('up to 2,000 normal-buffer scrollback lines') and settleMs ('0 captures without a quiet wait'), but settleTimeoutMs is never mentioned and sessionId is only inferable from its name and required status. This is partial but not complete compensation for the absent schema descriptions.
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 opens with a specific verb and resource: 'Observe the current terminal screen, styles, cursor, and process status without sending input.' This clearly distinguishes the tool from siblings like terminal_input (sends input) and terminal_list (lists sessions), and it names the core read-only operation precisely.
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 implies when to use the tool by emphasizing 'without sending input' and by explaining optional scrollback and settle behavior, but it never explicitly names alternatives, excludes them, or states conditions such as 'use this instead of terminal_input when you need to inspect state.' Usage context is present but left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
terminal_startADestructive
Run command through shell -l -c in a new terminal and return its styled screen and sessionId. Example: {command:"claude",cols:120,rows:40}. shell defaults to SHELL or /bin/sh; cwd defaults to the server directory. login defaults to true; false skips -l. The shell is not made interactive. Use a shell supporting -l -c, such as bash, zsh, dash, or fish. env overrides inherited variables; null deletes a variable. TERM is fixed to xterm-256color. A strict observation timeout retains the allocated session for inspection.
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No | ||
| env | No | ||
| cols | Yes | ||
| rows | Yes | ||
| login | No | ||
| shell | No | ||
| command | Yes | ||
| settleMs | No | ||
| settleTimeoutMs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the annotations (readOnlyHint=false, destructiveHint=true) by detailing shell invocation specifics (shell -l -c), non-interactive shell behavior, env variable semantics (null deletes), TERM fixed to xterm-256color, and the observation timeout retaining the session. It also clarifies that 'strict observation timeout' preserves the session for inspection, adding operational nuance. No contradictions with annotations.
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 dense yet concise, with every sentence adding unique value. It is front-loaded with the primary action and example, followed by defaults and behavioral nuances. There is no redundancy or fluff; the structure is logical and easy to parse.
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 the tool's complexity (9 parameters, nested env, no output schema), the description is thorough. It explains the core behavior, defaults, env handling, TERM, and timeout behavior. However, it does not describe the response format in detail beyond 'styled screen and sessionId', leaving some ambiguity about the exact structure of the returned data. Also, it does not mention error handling or exit codes. These gaps are minor given the absence of an output schema, but a fuller description would improve completeness.
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?
With 0% schema coverage, the description carries the full burden. It explains shell, cwd, login, env, and TERM behavior, and the example clarifies command, cols, rows. However, it does not directly describe settleMs and settleTimeoutMs, though 'strict observation timeout' hints at them. It also omits explicit explanation of cols/rows beyond the example. Overall, it covers most parameters meaningfully.
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-resource pair: 'Run command through shell -l -c in a new terminal' and explicitly mentions the return value (styled screen and sessionId). It clearly distinguishes itself from siblings like terminal_list (which lists sessions) and terminal_snapshot (which captures output) by focusing on starting a new session. The example adds concrete context.
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 explains how to invoke the tool (shell defaults, cwd, login, env) but provides no guidance on when to choose this tool over its siblings. It does not mention alternatives or when not to use it. For a tool that starts a session, an agent might benefit from knowing it should be used before terminal_input or terminal_resize, but this is absent.
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.
6 tool updates
v0.9.0- First observed
terminal_close - First observed
terminal_input - First observed
terminal_list - First observed
terminal_resize - First observed
terminal_snapshot - First observed
terminal_start
TDQS
Scored across 6 tools
Each tool targets a distinct operation on terminal sessions: listing, starting, observing, sending input, resizing, and closing. There is no overlap or ambiguity between them, and the descriptions clearly differentiate read-only vs. write operations.
All tools follow a consistent verb_noun pattern with a common 'terminal_' prefix (e.g., terminal_start, terminal_snapshot, terminal_close). The naming is uniform and predictable, making it easy for agents to infer tool purpose from the name.
With 6 tools, the server is well-scoped for a terminal emulator. Each tool covers a core aspect of terminal lifecycle management without unnecessary bloat or redundancy, fitting the typical sweet spot for tool count.
The tool surface covers the full lifecycle: create (terminal_start), observe (terminal_snapshot), interact (terminal_input), resize (terminal_resize), destroy (terminal_close), and manage sessions (terminal_list). There are no obvious gaps for the stated purpose.
Maintenance
Related MCP Connectors
- TabfleetOAuthcom.tabfleet
Launch, inspect, control, and share isolated cloud browsers for your agents.
Securely control computers you explicitly pair through files, terminals, processes, screenshots, desktop UI/input, clipboard, browser automation, diagnostics, and document tools.
Scoped, audited SSH exec, sessions, and SFTP on your saved servers without exposing credentials
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to programmatically control interactive terminal applications through HT sessions, supporting session management, key sending, snapshots, and command execution.1MIT
- AlicenseNot gradedqualityCmaintenanceProvides AI agents with fully interactive terminal sessions, including TUI support, keyboard control, and screen capture across Windows, Linux, and Mac.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to interact with interactive CLI processes via a real PTY, allowing them to send keystrokes, read screen output, and handle interactive prompts.1 npm1MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to spawn and interact with real terminal sessions, capturing screenshots of rendered TUI output and sharing live sessions for debugging.4 npm1MIT