Local stdio MCP server giving Claude Work (Cowork) a full terminal toolkit: one-shot commands, persistent PTY sessions, and path-jailed file access with command guardrails.
Strong foundation with 13 well-named tools following verb_noun convention (term_exec, term_start, term_send, etc.). All tools have descriptions (avg ~150 chars, within baseline 194). Input schemas present with type definitions and parameter descriptions. However, output schemas are not documented in the visible code, LLMs cannot predict return structures. Error handling is minimal; no recovery guidance or actionable error messages visible. Security is well-considered (path jailing, command policy, audit logging) but not surfaced in tool descriptions. File tools (term_read_file, term_write_file, term_edit_file) lack explicit encoding/format constraints in descriptions.
Run self-checks and report whether the terminal server is healthy. Use this FIRST when a terminal tool is misbehaving, or to confirm the server is wired up correctly. It verifies the shell is runnable, the node-pty native module can actually spawn a PTY, the allowed directories are readable/writable, and (if configured) the audit log is writable. It also returns usage metrics (call counts, errors, active sessions).
Replace an exact substring in a file. Mirrors a precise find-and-replace edit. By default old_string must appear exactly once (include enough surrounding context to make it unique). Set replace_all to replace every occurrence.
Execute a shell command once and return its output. Runs the command in a subprocess (not a persistent session), captures stdout/stderr separately, and enforces a per-command timeout. The command is subject to the safety policy (blocks sudo, rm -rf /, etc. unless dangerous mode is enabled).
Terminate a running PTY session. Sends SIGTERM by default; pass signal='SIGKILL' to force-kill.
List all active PTY sessions. Returns session IDs, commands, working directories, and running status.
Output schemas not documented. LLMs cannot predict return structures (e.g., what fields term_output returns, what term_list returns). This forces agents to guess and risks parsing failures.
Error handling lacks recovery guidance. No visible error messages that tell LLMs what to do next (e.g., 'Path outside allowed roots. Allowed: /home, /tmp' or 'Command blocked by safety policy. Use TERM_DANGEROUS=1 to override'). Agents cannot self-correct.
File encoding parameter (term_read_file) lacks constraint documentation. Description says 'use base64 for binary' but does not explain when to choose utf8 vs base64 or what happens if encoding mismatches file content.
Inferred effective spec: 2025-06-18+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 71 | 2025-06-18+ | v2 |
List the entries of a directory inside the allowed roots. Returns entries with their type (dir / file / symlink), directories first.
Read new output from a PTY session since a given byte cursor. Supports incremental reads: pass since=0 to read from the start, or pass the cursor from a previous call to read only new bytes. Returns the output chunk, the new cursor position, and the session's running/exit status.
Read a file's contents from within the allowed roots. Supports optional byte limit and encoding selection (UTF-8 or base64 for binary files).
Resize a running PTY session to new dimensions. Returns the updated session info.
Send raw data (keystrokes, command text, control characters) to a running PTY session. Use this to interact with the session started by term_start.
Start a persistent interactive PTY session. Returns a session ID that can be used with term_send, term_output, term_resize, term_wait, and term_kill. The session runs the specified command (or an interactive shell if no command is given) and retains output in a ring buffer.
Wait for a PTY session to produce output or reach an idle state. Blocks until either new data arrives, the session exits, or a timeout is reached. Useful for synchronizing with long-running commands.
Create or overwrite a file inside the allowed roots. Optionally creates missing parent directories. Overwrites existing files — read first if you need to preserve content.
term_wait and term_resize descriptions lack clarity on blocking behavior and side effects. Does term_wait block indefinitely if no output arrives? Does term_resize affect running commands?
Security constraints (path jailing, command policy, dangerous mode) are not surfaced in tool descriptions. LLMs cannot reason about what operations are blocked or how to work around them.