Skip to main content
Glama

Quick start

1. Person requesting help: connect your agent

Add this MCP service to an agent that supports Streamable HTTP:

https://agenterm.net/mcp

See configuration examples. Describe your task, ask the agent to create an invitation, and privately share the generated connection command with the person at the target computer.

2. Person at the target computer: connect and authorize

Run the invitation command for your operating system, read the notice, and authorize access. The client displays connection status, commands, and output. You do not need to configure MCP or a server.

3. Both: complete the task and disconnect

Keep the agent conversation active while the device connects, then start the task. The target computer can disconnect at any time; close the client when finished.

Invitations are single-use by default and expire after 15 minutes. Connections grant terminal access with the current user's permissions. Share invitations and tokens only with people you trust.

Related MCP server: Codex SSH Terminal MCP

What you can do

  • Troubleshoot development environments: “Help my colleague check their Python setup and find why the project won't start.”

  • Inspect system status: “Check this server's disk usage and application logs.”

  • Work across computers: “Connect several test machines, check their environments, and summarize the results.”

Interactive terminal tasks are supported. Use the CLI or GUI on the target computer to follow progress; the client automatically attempts to reconnect after temporary network failures.

How it works

The server forwards commands and results. The client runs on the target computer, initiates its server connection, and executes tasks through the local shell. Both the agent and target need access to the server; the target needs no inbound port.

Use the hosted service or deploy your own server.

FAQ

Check that both sides can reach the server. Ask the agent for a new invitation if one has expired, been used, or the server has restarted. For version mismatches, use server and client binaries from the same release. Connection troubleshooting.

The client attempts to reconnect but does not replay commands. Ask the agent to check the device and task state. Connecting a device does not wake an agent conversation that has already ended.

Agenterm provides terminal assistance, not a remote desktop. Ask the agent for a multi-device invitation to work across computers. Windows supports simple interactive prompts; full-screen programs requiring a real terminal may not work.

Management access currently requires no authentication. Up to four devices can be online per invitation creator's public IP; people on the same network share that allowance. The agent, server, and target client can see commands and output, so keep invitations and tokens private. Use HTTPS when self-hosting publicly.

User guide · Deployment and source builds · Report an issue · Apache-2.0

Available Tools

7 tools
create_clientA

Create a client connection token and a 15-minute invitation. Set multi_device=true for multiple simultaneous devices and a reusable invitation; otherwise the invitation is single-use and only one device may connect. First show display_text including both platform commands in a progress message, then follow next_action: call list_clients with client_token and wait_ms=20000 repeatedly until a device connects, the invitation expires, or the user cancels. Do not end the turn after showing the invitation or after an empty result. Immediately notify the user when a device connects. Use client_id to target devices for multi-device tokens. Session tools use session_id after starting a session. Treat tokens and commands as credentials and share privately. Saying you are waiting is insufficient: the same response must actually call list_clients; invitation creation alone does not complete this task.

NameRequiredDescriptionDefault
multi_deviceNoTrue permits multiple simultaneous devices and reuses the invitation until expiry. False allows one device and a single-use invitation.

Output Schema

NameRequiredDescription
expires_atYesInvitation expiry deadline as a UTC RFC 3339 timestamp.
invitationYesPrivate invitation credential for target-client authorization; expires at expires_at.
next_actionYesNext step to perform. Invitation creation returns the exact tool call and deadline; other tools return human-readable guidance.
client_tokenYesPrivate credential for this target group. Pass as client_token with management access (including stdio and no-password mode) or as the MCP bearer token for device-scoped access.
display_textYesUser-facing invitation text including credentials and both platform commands. Display before waiting for the device to connect.
multi_deviceYesTrue permits multiple simultaneous devices and reuses the invitation until expiry. False allows one device and a single-use invitation.
macos_linux_commandYesOne-command macOS/Linux installer containing private invitation access. Show to the target user privately.
windows_powershell_commandYesOne-command Windows installer containing private invitation access. Show to the target user privately.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses the 15-minute invitation lifetime, single-use versus reusable invitation semantics, polling behavior with list_clients, and the fact that tokens and commands are credentials to be shared privately. It also states that invitation creation alone does not complete the task and that the agent must actually call list_clients rather than merely saying it is waiting.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, but the description is quite long and contains repeated workflow warnings, such as 'Do not end the turn' and 'Saying you are waiting is insufficient,' plus a tangential note about session_id. The complexity partly justifies the length, but it could be tightened without losing required guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with a defined workflow and an output schema, the description is complete enough to call and operate correctly: it explains creation semantics, the required progress message, the polling loop, notification timing, and credential handling. The output schema can cover return structure, so the description does not need to duplicate it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter has 100% schema description coverage, and the description largely restates the schema’s explanation of multi_device. It does not add syntax or edge-case detail for that parameter beyond what the schema already provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Create a client connection token and a 15-minute invitation.' It also clarifies the multi_device behavior and contrasts the client-token workflow with session tools that use session_id, making the tool’s role clear relative to siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit conditions for multi_device=true versus the default single-use/single-device case, then prescribes the follow-up sequence: show display_text, call list_clients repeatedly with client_token and wait_ms=20000, and continue until a device connects, the invitation expires, or the user cancels. It also warns not to end the turn after showing the invitation or an empty result.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

execute_commandA
Destructive

Run a non-interactive shell command on the selected authorized target device and wait for completion. This can modify or delete files and perform any operation allowed to the target user; obtain user approval for destructive commands. client_token is required with management access (including stdio and no-password mode); client_id is required for multi-device tokens. Each call starts a fresh shell: set cwd and env explicitly; changes do not persist between calls. timeout_ms defaults to 60000 (60 seconds), 0 disables the timeout, and the maximum is 86400000 (24 hours). Captured stdout and stderr share a 1 MiB limit; excess output is discarded and truncated=true. The result contains stdout, stderr, exit_code, timed_out, canceled, truncated and optional error; a nonzero exit, timeout, cancellation or execution failure sets isError. Canceling the MCP request sends a best-effort cancellation request; it does not undo effects already performed. Commands are not automatically retried. Use session_start/read/write/stop for prompts, incremental output or long-running jobs.

NameRequiredDescriptionDefault
cwdNoWorking directory on the target device. Each command starts a fresh shell; use cwd for subsequent commands instead of relying on a previous cd.
envNoEnvironment overrides for this command, merged with the client environment. Values must be strings.
commandYesShell command
client_idNoSix lowercase letters or digits from list_clients. Required for multi-device tokens, even when only one device is online; optional for single-device tokens.
timeout_msNoExecution timeout in milliseconds, up to 86400000 (24 hours). 0 disables the timeout. Default: 60000 for execute_command, 0 for session_start.
client_tokenYesTarget client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token.

Output Schema

NameRequiredDescription
errorNoOptional execution or connection error. A disconnect does not prove the remote process completed successfully.
stderrYesCaptured standard error, sharing a 1 MiB combined limit with stdout.
stdoutYesCaptured standard output, sharing a 1 MiB combined limit with stderr.
canceledYesTrue only when the target reported cancellation; a disconnect alone does not confirm cancellation.
exit_codeYesReported process exit code: 0 means success; -1 means execution failed, was interrupted, or the device disconnected before a normal exit report.
timed_outYesTrue if the target reported that the process execution timeout elapsed.
truncatedYesTrue if output exceeded the 1 MiB retention limit. Commands discard excess captured output; sessions discard older buffered bytes.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond annotations: warns that commands can modify/delete files and require user approval for destructive ones, that each call starts a fresh shell with no persistence, documents timeout defaults/limits, the 1 MiB shared stdout/stderr cap with truncation, the result field set, error semantics, and that cancellation is best-effort and does not undo effects. These are real operational constraints an agent cannot infer from destructiveHint/openWorldHint alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose and danger warning, then proceeds through auth, shell semantics, timeout, output limits and result shape. Dense but well ordered; the result-field enumeration is borderline verbose given an output schema exists, which costs a point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers everything an agent needs for a destructive, open-world, non-idempotent tool: approval guidance, auth requirements per token type, non-persistence of shell state, timeout bounds, output truncation, error signaling, cancellation limits, no retry, and sibling routing. The output schema's existence makes the brief result listing sufficient rather than redundant.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage the baseline is 3, but the description adds cross-parameter meaning: client_token is required with management access (including stdio/no-password mode), client_id is required for multi-device tokens, and cwd/env must be set per call because shells are fresh. These reinforce and contextualize the schema rather than merely restating it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Run a non-interactive shell command') plus the scope ('on the selected authorized target device and wait for completion'). It explicitly distinguishes itself from the session_* siblings by naming them as the alternative for prompts, incremental output and long-running jobs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The last sentence explicitly routes agents to session_start/read/write/stop for interactive or long-running scenarios, which is a clear use-vs-alternative rule. It gives no explicit exclusions for execute_command itself beyond the 'non-interactive' framing, so it falls short of a full when/when-not treatment.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_clientsA
Read-onlyIdempotent

List online devices belonging to this client_token. Set wait_ms=20000 to wait server-side while no device is online; a connection returns immediately. After creating an invitation, show display_text in a progress message and keep calling with wait_ms=20000 until the target connects, the invitation expires, or the user cancels. An empty result is only a wait timeout: continue waiting without ending the turn or asking the user to check. Immediately notify the user when connected. With wait_ms omitted or 0, return a snapshot immediately. Use client_id to execute commands or start sessions. For multi-device tokens, any online device completes the wait; use snapshots to discover additional devices.

NameRequiredDescriptionDefault
wait_msNoWait up to this many milliseconds while no device is online (0-20000, default 0). After creating an invitation, use 20000 and repeat empty results until connection, invitation expiry, or user cancellation.
client_tokenYesTarget client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token.

Output Schema

NameRequiredDescription
statusNoConnection wait status: waiting or connected. Session-stop status: stopping, stopped or finished.
clientsYesOnline devices owned by this token; an empty array means none are currently online.
next_actionNoNext step to perform. Invitation creation returns the exact tool call and deadline; other tools return human-readable guidance.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive, closed-world, so the safety bar is met. The description then adds non-obvious behavior: long-poll semantics, the fact that an empty result means timeout rather than no devices, and that notification should fire on connect. This is real added context beyond the annotations, though it does not cover limit/output shape (an output schema exists).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then the wait/snapshot distinction, then the workflow loop. Nearly every sentence carries operational instruction. It runs long and partially restates the wait_ms schema text, which keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value documentation is not required. Given a 2-parameter long-poll tool, the description covers purpose, polling cadence, empty-result interpretation, termination conditions, and the follow-up tool — everything an agent needs to call it correctly inside a multi-turn flow.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description goes further by explaining the polling loop pattern for wait_ms and its interaction with invitation expiry, and by noting that for multi-device tokens any online device completes the wait. The client_token access-model caveat is left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource: 'List online devices belonging to this client_token.' It is immediately distinguishable from siblings like create_client, execute_command, and session_start, and the scope (online devices only, scoped by token) is explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit branching guidance: use wait_ms=20000 to block after creating an invitation, omit or use 0 for an immediate snapshot. It also states what to do on an empty result (keep waiting, do not end the turn) and names the downstream handoff ('Use client_id to execute commands or start sessions'), leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_readA
Read-onlyIdempotent

Read incremental output and terminal state for an owned session. This does not send input or stop the process. Start with cursor=0, then use the returned next_cursor on each read; cursors are byte offsets, not character counts. wait_ms is 0-20000 (default 0): return immediately for new output or a terminal state, otherwise wait up to that many milliseconds. Empty output with done=false is only a polling timeout; continue polling. If older output was dropped from the 1 MiB buffer, truncated=true and reading resumes at the earliest retained byte; a cursor beyond available output is an error. done=true means a terminal result or a closed connection; only then are exit_code, timed_out, canceled and optional error included. A disconnect error is not proof of a remote command's success or confirmed cancellation. Use session_stop to terminate and session_write to supply input. Finished records expire after 30 minutes and server restarts invalidate them.

NameRequiredDescriptionDefault
cursorNoByte cursor, initially 0
wait_msNoWait up to this many milliseconds for output
session_idYesSession identifier
client_tokenYesTarget client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token.

Output Schema

NameRequiredDescription
doneYesWhether the session has reached a terminal state. When false, keep polling session_read.
errorNoOptional execution or connection error. A disconnect does not prove the remote process completed successfully.
outputYesCombined terminal output from the requested cursor; may contain echoed input.
canceledNoTrue only when the target reported cancellation; a disconnect alone does not confirm cancellation.
exit_codeNoReported process exit code: 0 means success; -1 means execution failed, was interrupted, or the device disconnected before a normal exit report.
timed_outNoTrue if the target reported that the process execution timeout elapsed.
truncatedYesTrue if output exceeded the 1 MiB retention limit. Commands discard excess captured output; sessions discard older buffered bytes.
session_idYesIdentifier of the owned session; retain it for subsequent read, write and stop calls.
next_cursorYesOutput byte offset to pass as cursor on the next session_read.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, and the description adds behavior well beyond them: 1 MiB buffer truncation with truncated=true, cursors as byte offsets, out-of-range cursor is an error, done=true gating which fields appear, and that a disconnect error is not proof of success or confirmed cancellation. Lifecycle constraints (30-minute expiry, restart invalidation) are also disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but essentially waste-free, and front-loaded with the purpose and the negative boundary before the cursor/wait mechanics. It is a long single paragraph, so the polling, truncation, and expiry rules run together; light structuring would make it easier to scan, but no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be enumerated, yet the description still explains when exit_code/timed_out/canceled/error appear. For a 4-parameter, stateful read tool with cursor and timeout subtleties, everything needed to call it correctly and interpret edge cases is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description genuinely adds meaning: cursor is a byte offset not a character count, must start at 0 and be chained from next_cursor, and an over-range cursor errors. wait_ms gains the 0-20000 range, default 0, and the semantic distinction between immediate return and waiting for new output or a terminal state.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read incremental output and terminal state for an owned session') and immediately draws the boundary against siblings: 'This does not send input or stop the process.' An agent can distinguish it from session_write and session_stop without inspecting any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit invocation protocol: 'Start with cursor=0, then use the returned next_cursor on each read', plus the polling rule ('Empty output with done=false is only a polling timeout; continue polling'). It also names the alternatives and when to use them: 'Use session_stop to terminate and session_write to supply input.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_startA
Destructive

Start a new interactive terminal process on an authorized target device. The command can change files or system state with the target user's permissions. Supply client_id for multi-device tokens; set cwd and env for this new process. timeout_ms defaults to 0 (no timeout), with a maximum of 86400000 (24 hours). Returns session_id and the initial byte cursor 0, not command completion. Repeated calls start separate processes. Use session_read with the last next_cursor to collect incremental output until done=true, session_write to answer prompts (include a newline), and session_stop to cancel. Each token retains up to six sessions, and only the latest 1 MiB of each session's output is retained. Finished history expires after 30 minutes or can be evicted by later sessions; keep the session_id and poll promptly. Server restarts invalidate sessions. For a short non-interactive command with a final stdout/stderr result, use execute_command instead.

NameRequiredDescriptionDefault
cwdNoWorking directory on the target device. Each command starts a fresh shell; use cwd for subsequent commands instead of relying on a previous cd.
envNoEnvironment overrides for this command, merged with the client environment. Values must be strings.
commandYesShell command
client_idNoSix lowercase letters or digits from list_clients. Required for multi-device tokens, even when only one device is online; optional for single-device tokens.
timeout_msNoExecution timeout in milliseconds, up to 86400000 (24 hours). 0 disables the timeout. Default: 60000 for execute_command, 0 for session_start.
client_tokenYesTarget client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token.

Output Schema

NameRequiredDescription
cursorYesInitial output byte cursor, always 0 for a new session.
session_idYesIdentifier of the owned session; retain it for subsequent read, write and stop calls.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true, openWorldHint=true, and idempotentHint=false, so the safety profile is largely covered, but the description still adds real context: the return is session_id plus cursor 0 rather than command completion, repeated calls fork separate processes, six sessions per token, only the latest 1 MiB retained, 30-minute expiry, and server restarts invalidate sessions. That is substantive beyond annotations, though pagination/streaming mechanics remain implied rather than spelled out.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and permission implication, then lifecycle and constraint details in a logical order. Some sentences restate schema-level facts (timeout_ms default/max, cwd/env) that could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, open-world, stateful tool, the description covers lifecycle (read/write/stop), resource limits (six sessions, 1 MiB buffer), expiry, and restart invalidation. With an output schema present, it need not specify return field shapes, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents command, client_id, cwd, env, timeout_ms, and client_token with the same details the description repeats (multi-device client_id requirement, timeout default of 0 with 24h cap). The description adds only light cross-parameter workflow framing (cwd/env apply to this new process) and does not compensate with anything the schema lacks, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Start a new interactive terminal process") plus a scope qualifier ("authorized target device"). The closing sentence explicitly contrasts it with execute_command for non-interactive commands, so an agent can distinguish it from the closest sibling without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent across the whole workflow: session_read with next_cursor to collect output until done=true, session_write to answer prompts with a newline, session_stop to cancel, and execute_command for short non-interactive commands. Both the when-to-use and the when-to-use-something-else conditions are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_stopA
DestructiveIdempotent

Request termination of a terminal session created by session_start. Requires its session_id and, with management access (including stdio and no-password mode), its owning client_token; it cannot stop a session owned by another token. Stopping can interrupt writes and lose unsaved work, and cannot undo completed side effects. wait_ms defaults to 1000 and can be 0-20000: 0 returns immediately after sending the request, otherwise wait up to that many milliseconds for a terminal result. accepted=true means a stop request was sent or is already pending, not that termination is confirmed. status=stopping and done=false require polling session_read until done=true; use its output/cursor to collect final output. status=stopped requires a terminal canceled=true report. status=finished means the session ended for another reason; inspect canceled, timed_out, exit_code and error, especially on disconnect. Repeating a stop is safe: an already-ended session returns already_done=true and accepted=false without sending another request. Unknown or unauthorized session IDs are errors. Use session_read to observe progress and session_write for input; stopping does not revoke the device token or disconnect other sessions.

NameRequiredDescriptionDefault
wait_msNoHow long to wait for a terminal result after requesting cancellation (0-20000 ms, default 1000). 0 returns a status snapshot immediately; stopping requires subsequent session_read polling.
session_idYesSession identifier
client_tokenYesTarget client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token.

Output Schema

NameRequiredDescription
doneYesTrue once this session has a terminal result or its device connection closed. Check status, canceled and error to distinguish confirmed cancellation from other endings.
errorNoOptional execution or connection error. A disconnect does not prove the remote process completed successfully.
statusYesstopping: request pending; poll session_read. stopped: terminal cancellation confirmed. finished: ended for another reason; inspect terminal fields and error.
acceptedYesTrue if a cancellation request was sent or is pending. False for a session already ended before this call. This alone never confirms termination.
canceledNoTrue only when the target reported cancellation; a disconnect alone does not confirm cancellation.
exit_codeNoReported process exit code: 0 means success; -1 means execution failed, was interrupted, or the device disconnected before a normal exit report.
timed_outNoTrue if the target reported that the process execution timeout elapsed.
session_idYesIdentifier of the owned session; retain it for subsequent read, write and stop calls.
next_actionNoNext step to perform. Invitation creation returns the exact tool call and deadline; other tools return human-readable guidance.
already_doneYesTrue if the session was already ended when this stop call began; no new cancellation request is sent.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Although annotations already flag destructive/idempotent/non-readOnly, the description adds substantial context they cannot convey: stopping can interrupt writes and lose unsaved work, side effects are irreversible, accepted=true only means a request was sent or pending, and status=stopping/done=false requires polling. It also spells out the already_done=true/accepted=false repeat-call behavior, which directly explains the idempotentHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then requirements, risks, wait_ms behavior, and status semantics in a logical order. It is dense but long, and the wait_ms explanation partially duplicates the schema property description, costing a bit of efficiency.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, open-world mutation tool this covers everything an agent needs: preconditions, side-effect risk, timeout behavior, the meaning of each status/accepted combination, and the required follow-up call. Even though an output schema exists, the description adds interpretive value about status transitions rather than restating field shapes.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description goes further by explaining the ownership rule for client_token ('cannot stop a session owned by another token') and the wait_ms trade-off between 0 and a blocking wait. These are semantic consequences not derivable from the schema's type/range constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Request termination of a terminal session') and ties it to the sibling that creates such sessions (session_start). It also implicitly separates itself from session_read and session_write by stating their roles at the end, so an agent can place it precisely among the six siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when it applies (session created by session_start, owned by the calling token), when it will fail (unknown/unauthorized IDs, sessions owned by another token), and how to retry ('Repeating a stop is safe'). It routes the agent to session_read for polling and session_write for input, and clarifies it does not revoke tokens or disconnect other sessions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

session_writeA
Destructive

Send text to the stdin of an owned running terminal session. Include a newline (for example, "yes\n") to submit an answer or command. Input can trigger destructive operations and may be echoed in session output, including secrets; only send input the user authorized. accepted=true confirms the input was sent to the device connection, not that the program consumed it or completed an action. Use session_read afterward to observe the response. Repeating a write sends the input again, so do not retry blindly. Unknown, unauthorized or ended sessions are errors. This does not start a session or cancel it; use session_start or session_stop for those operations.

NameRequiredDescriptionDefault
inputYesInput bytes as text, e.g. yes\n
session_idYesSession identifier
client_tokenYesTarget client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token.

Output Schema

NameRequiredDescription
acceptedYesWhether the action was sent to the device connection; this does not confirm it was consumed or completed.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the destructive/non-idempotent annotations: that input can trigger destructive operations, that input may be echoed in output including secrets, that repeating a write resends input, and that unknown/ended sessions error. The key disclosure that accepted=true only means the input reached the device connection, not that the program consumed it, is genuinely useful and not derivable from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Long but front-loaded: the core action comes first, then caveats, then lifecycle exclusions. Nearly every sentence carries a distinct rule, though the secrets/echo warning and the accepted=true caveat could be tightened slightly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, yet the description still clarifies what the accepted flag does and does not confirm, and covers authorization, error conditions, and follow-up reads. Nothing an agent needs before calling this destructive tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description still adds real semantics by explaining that a newline is what submits a command or answer, which is behavioral meaning the schema's 'Input bytes as text, e.g. yes\n' only implies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: send text to the stdin of an owned running terminal session. It also fences itself off from siblings by naming session_start and session_stop and by pointing to session_read for observing output.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit routing: use session_read afterward to observe the response, and use session_start/session_stop for lifecycle operations since this tool does not start or cancel a session. It even covers the retry case ('do not retry blindly') and the error case for unknown or ended sessions.

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.

  1. 7 tool updatesv0.3.1-stdio.2
    • Changedcreate_client4 fields changed
      • addedInput schema / properties / multi_device / description
        Added value: +"True permits multiple simultaneous devices and reuses the invitation until expiry. False allows one device and a single-use invitation."
      • changedOutput schema / additionalProperties
        Previous value: -trueNew value: +false
      • addedOutput schema / properties
        Added value: +{
        +  "client_token": {
        +    "description": "Private credential for this target group. Pass as client_token with management access (including stdio and no-password mode) or as the MCP bearer token for device-scoped access.",
        +    "type": "string"
        +  },
        +  "display_text": {
        +    "description": "User-facing invitation text including credentials and both platform commands. Display before waiting for the device to connect.",
        +    "type": "string"
        +  },
        +  "expires_at": {
        +    "description": "Invitation expiry deadline as a UTC RFC 3339 timestamp.",
        +    "type": "string"
        +  },
        +  "invitation": {
        +    "description": "Private invitation credential for target-client authorization; expires at expires_at.",
        +    "type": "string"
        +  },
        +  "macos_linux_command": {
        +    "description": "One-command macOS/Linux installer containing private invitation access. Show to the target user privately.",
        +    "type": "string"
        +  },
        +  "multi_device": {
        +    "description": "True permits multiple simultaneous devices and reuses the invitation until expiry. False allows one device and a single-use invitation.",
        +    "type": "boolean"
        +  },
        +  "next_action": {
        +    "additionalProperties": false,
        +    "description": "Next step to perform. Invitation creation returns the exact tool call and deadline; other tools return human-readable guidance.",
        +    "properties": {
        +      "arguments": {
        +        "additionalProperties": false,
        +        "description": "Arguments to pass unchanged to the next tool call.",
        +        "properties": {
        +          "client_token": {
        +            "description": "Private credential for this target group. Pass as client_token with management access (including stdio and no-password mode) or as the MCP bearer token for device-scoped access.",
        +            "type": "string"
        +          },
        +          "wait_ms": {
        +            "description": "Server-side polling duration in milliseconds; repeat waits until the action deadline or a terminal result.",
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "client_token",
        +          "wait_ms"
        +        ],
        +        "type": "object"
        +      },
        +      "instructions": {
        +        "description": "Workflow guidance for completing the next action.",
        +        "type": "string"
        +      },
        +      "tool": {
        +        "description": "Name of the next MCP tool to call.",
        +        "type": "string"
        +      },
        +      "until": {
        +        "description": "UTC RFC 3339 deadline for following this action.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "tool",
        +      "arguments",
        +      "until",
        +      "instructions"
        +    ],
        +    "type": "object"
        +  },
        +  "windows_powershell_command": {
        +    "description": "One-command Windows installer containing private invitation access. Show to the target user privately.",
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "client_token",
        +  "multi_device",
        +  "invitation",
        +  "expires_at",
        +  "next_action",
        +  "macos_linux_command",
        +  "windows_powershell_command",
        +  "display_text"
        +]
    • Changedexecute_command8 fields changed
      • changedInput schema / properties / client_token / description
        Previous value: -"Target client connection token (required when authenticated with the management key)"New value: +"Target client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token."
      • addedOutput schema / properties / canceled / description
        Added value: +"True only when the target reported cancellation; a disconnect alone does not confirm cancellation."
      • addedOutput schema / properties / error / description
        Added value: +"Optional execution or connection error. A disconnect does not prove the remote process completed successfully."
      • addedOutput schema / properties / exit_code / description
        Added value: +"Reported process exit code: 0 means success; -1 means execution failed, was interrupted, or the device disconnected before a normal exit report."
      • addedOutput schema / properties / stderr / description
        Added value: +"Captured standard error, sharing a 1 MiB combined limit with stdout."
      • addedOutput schema / properties / stdout / description
        Added value: +"Captured standard output, sharing a 1 MiB combined limit with stderr."
      • addedOutput schema / properties / timed_out / description
        Added value: +"True if the target reported that the process execution timeout elapsed."
      • addedOutput schema / properties / truncated / description
        Added value: +"True if output exceeded the 1 MiB retention limit. Commands discard excess captured output; sessions discard older buffered bytes."
    • Changedlist_clients4 fields changed
      • changedInput schema / properties / client_token / description
        Previous value: -"Target client connection token (required when authenticated with the management key)"New value: +"Target client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token."
      • changedOutput schema / additionalProperties
        Previous value: -trueNew value: +false
      • addedOutput schema / properties
        Added value: +{
        +  "clients": {
        +    "description": "Online devices owned by this token; an empty array means none are currently online.",
        +    "items": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "client_id": {
        +          "description": "Six-character device identifier. Required to select a device for multi-device tokens.",
        +          "type": "string"
        +        },
        +        "connected_at": {
        +          "description": "UTC connection time in RFC 3339 format.",
        +          "type": "string"
        +        },
        +        "hostname": {
        +          "description": "Device-reported hostname for display only, not authentication.",
        +          "type": "string"
        +        },
        +        "platform": {
        +          "description": "Device-reported operating system and architecture.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "client_id",
        +        "hostname",
        +        "platform",
        +        "connected_at"
        +      ],
        +      "type": "object"
        +    },
        +    "type": [
        +      "null",
        +      "array"
        +    ]
        +  },
        +  "next_action": {
        +    "description": "Next step to perform. Invitation creation returns the exact tool call and deadline; other tools return human-readable guidance.",
        +    "type": "string"
        +  },
        +  "status": {
        +    "description": "Connection wait status: waiting or connected. Session-stop status: stopping, stopped or finished.",
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "clients"
        +]
    • Changedsession_read4 fields changed
      • changedInput schema / properties / client_token / description
        Previous value: -"Target client connection token (required when authenticated with the management key)"New value: +"Target client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token."
      • changedOutput schema / additionalProperties
        Previous value: -trueNew value: +false
      • addedOutput schema / properties
        Added value: +{
        +  "canceled": {
        +    "description": "True only when the target reported cancellation; a disconnect alone does not confirm cancellation.",
        +    "type": [
        +      "null",
        +      "boolean"
        +    ]
        +  },
        +  "done": {
        +    "description": "Whether the session has reached a terminal state. When false, keep polling session_read.",
        +    "type": "boolean"
        +  },
        +  "error": {
        +    "description": "Optional execution or connection error. A disconnect does not prove the remote process completed successfully.",
        +    "type": "string"
        +  },
        +  "exit_code": {
        +    "description": "Reported process exit code: 0 means success; -1 means execution failed, was interrupted, or the device disconnected before a normal exit report.",
        +    "type": [
        +      "null",
        +      "integer"
        +    ]
        +  },
        +  "next_cursor": {
        +    "description": "Output byte offset to pass as cursor on the next session_read.",
        +    "type": "integer"
        +  },
        +  "output": {
        +    "description": "Combined terminal output from the requested cursor; may contain echoed input.",
        +    "type": "string"
        +  },
        +  "session_id": {
        +    "description": "Identifier of the owned session; retain it for subsequent read, write and stop calls.",
        +    "type": "string"
        +  },
        +  "timed_out": {
        +    "description": "True if the target reported that the process execution timeout elapsed.",
        +    "type": [
        +      "null",
        +      "boolean"
        +    ]
        +  },
        +  "truncated": {
        +    "description": "True if output exceeded the 1 MiB retention limit. Commands discard excess captured output; sessions discard older buffered bytes.",
        +    "type": "boolean"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "session_id",
        +  "output",
        +  "next_cursor",
        +  "truncated",
        +  "done"
        +]
    • Changedsession_start4 fields changed
      • changedInput schema / properties / client_token / description
        Previous value: -"Target client connection token (required when authenticated with the management key)"New value: +"Target client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token."
      • changedOutput schema / additionalProperties
        Previous value: -trueNew value: +false
      • addedOutput schema / properties
        Added value: +{
        +  "cursor": {
        +    "description": "Initial output byte cursor, always 0 for a new session.",
        +    "type": "integer"
        +  },
        +  "session_id": {
        +    "description": "Identifier of the owned session; retain it for subsequent read, write and stop calls.",
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "session_id",
        +  "cursor"
        +]
    • Changedsession_stop5 fields changed
      • changedInput schema / properties / client_token / description
        Previous value: -"Target client connection token (required when authenticated with the management key)"New value: +"Target client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token."
      • addedInput schema / properties / wait_ms
        Added value: +{
        +  "default": 1000,
        +  "description": "How long to wait for a terminal result after requesting cancellation (0-20000 ms, default 1000). 0 returns a status snapshot immediately; stopping requires subsequent session_read polling.",
        +  "maximum": 20000,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • changedOutput schema / additionalProperties
        Previous value: -trueNew value: +false
      • addedOutput schema / properties
        Added value: +{
        +  "accepted": {
        +    "description": "True if a cancellation request was sent or is pending. False for a session already ended before this call. This alone never confirms termination.",
        +    "type": "boolean"
        +  },
        +  "already_done": {
        +    "description": "True if the session was already ended when this stop call began; no new cancellation request is sent.",
        +    "type": "boolean"
        +  },
        +  "canceled": {
        +    "description": "True only when the target reported cancellation; a disconnect alone does not confirm cancellation.",
        +    "type": [
        +      "null",
        +      "boolean"
        +    ]
        +  },
        +  "done": {
        +    "description": "True once this session has a terminal result or its device connection closed. Check status, canceled and error to distinguish confirmed cancellation from other endings.",
        +    "type": "boolean"
        +  },
        +  "error": {
        +    "description": "Optional execution or connection error. A disconnect does not prove the remote process completed successfully.",
        +    "type": "string"
        +  },
        +  "exit_code": {
        +    "description": "Reported process exit code: 0 means success; -1 means execution failed, was interrupted, or the device disconnected before a normal exit report.",
        +    "type": [
        +      "null",
        +      "integer"
        +    ]
        +  },
        +  "next_action": {
        +    "description": "Next step to perform. Invitation creation returns the exact tool call and deadline; other tools return human-readable guidance.",
        +    "type": "string"
        +  },
        +  "session_id": {
        +    "description": "Identifier of the owned session; retain it for subsequent read, write and stop calls.",
        +    "type": "string"
        +  },
        +  "status": {
        +    "description": "stopping: request pending; poll session_read. stopped: terminal cancellation confirmed. finished: ended for another reason; inspect terminal fields and error.",
        +    "enum": [
        +      "stopping",
        +      "stopped",
        +      "finished"
        +    ],
        +    "type": "string"
        +  },
        +  "timed_out": {
        +    "description": "True if the target reported that the process execution timeout elapsed.",
        +    "type": [
        +      "null",
        +      "boolean"
        +    ]
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "session_id",
        +  "accepted",
        +  "done",
        +  "status",
        +  "already_done"
        +]
    • Changedsession_write4 fields changed
      • changedInput schema / properties / client_token / description
        Previous value: -"Target client connection token (required when authenticated with the management key)"New value: +"Target client connection token, required with management access (including stdio and no-password mode). Device-scoped bearer access implicitly selects its own token."
      • changedOutput schema / additionalProperties
        Previous value: -trueNew value: +false
      • addedOutput schema / properties
        Added value: +{
        +  "accepted": {
        +    "description": "Whether the action was sent to the device connection; this does not confirm it was consumed or completed.",
        +    "type": "boolean"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "accepted"
        +]
  2. 7 tool updatesv0.3.1-stdio.1
    • First observedcreate_client
    • First observedexecute_command
    • First observedlist_clients
    • First observedsession_read
    • First observedsession_start
    • First observedsession_stop
    • First observedsession_write

TDQS

A4.5/5.0

Scored across 7 tools

Disambiguation5/5

Each tool targets a distinct part of the remote-terminal workflow: client onboarding, device listing, non-interactive command execution, and session start/read/write/stop. The only possible overlap is execute_command versus session_start, but the descriptions clearly separate short non-interactive commands from interactive long-running sessions.

Naming Consistency4/5

The session tools consistently use resource-prefixed action names (session_start, session_read, session_write, session_stop), while client and command tools use verb_noun names (create_client, list_clients, execute_command). This is readable and predictable overall, but the mixed prefix convention keeps it from being perfectly uniform.

Tool Count5/5

Seven tools is well-scoped for a remote terminal/device management server. The set covers client setup, device discovery, command execution, and the full interactive session lifecycle without redundant tools.

Completeness4/5

Core workflows are covered: creating invitations, waiting for devices, executing commands, and managing interactive sessions. Minor lifecycle gaps remain, such as revoking client tokens or listing existing sessions, but agents can largely work around these.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    MCP server for SSH and local terminal access. Supports interactive commands, long-running processes, and TUI apps like tmux/zellij
    6
    4
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Agent-native SSH control plane with a local Web Terminal, human-in-the-loop secret input, keychain-backed profiles, and user-confirmed uploads for Codex, Claude Code, and MCP-compatible coding agents.
    18
    1
    Apache 2.0