Includes test suite integration for running parameterized tests with or without dependency stubbing
Runs on Python 3.12 or newer with a plugin architecture that exposes package functions, classes, and variables for extensions
Provides safe, auditable access to system shell commands with real-time streaming of stdout and stderr, configurable working directories, environment variables, and timeouts
mcp2term
An implementation of a Model Context Protocol (MCP) server that grants safe, auditable access to a system shell. The server streams stdout and stderr in real time while capturing rich metadata for plugins and downstream consumers.
Features
- Full command execution with configurable shell, working directory, environment variables, and timeouts. 
- Live streaming of stdout and stderr via MCP log notifications so clients observe progress as it happens. 
- Plugin architecture that exposes every function, class, and variable defined in the package, enabling extensions to observe command lifecycles or inject custom behaviour. 
- Typed lifespan context shared with MCP tools for dependency access and lifecycle management. 
- Structured tool responses including timing information to make results easy for agents to consume. 
Installation
The project targets Python 3.12 or newer.
Configuration
ServerConfig reads settings from environment variables:
| Variable | Description | Default | 
| 
 | Shell executable used for commands. | 
 | 
| 
 | Working directory for commands. | Current directory | 
| 
 | When 
 , inherit the parent environment. | 
 | 
| 
 | JSON object merged into the command environment. | 
 | 
| 
 | Comma-separated dotted module paths to load as plugins. | (none) | 
| 
 | Default timeout in seconds for commands. | unlimited | 
Running the server
Change --transport to sse or streamable-http to use the corresponding MCP transports. --log-level controls verbosity and --mount-path overrides the HTTP mount location when relevant.
MCP tool
The server registers a single tool:
run_command(command: str, working_directory: Optional[str], environment: Optional[dict[str, str]], timeout: Optional[float]])
The tool returns structured JSON containing:
- command: executed command string
- working_directory: resolved working directory
- return_code: process exit code (non-zero for failure)
- stdout/- stderr: aggregated output
- started_at/- finished_at: ISO 8601 timestamps
- duration: execution duration in seconds
- timed_out: boolean flag indicating whether a timeout occurred
While a command runs the server emits stdout and stderr chunks as MCP log messages, preserving ordering through asynchronous streaming.
Plugins
Plugins implement the PluginProtocol (via a module-level PLUGIN object) and can register CommandStreamListener instances to observe command lifecycle events. When the server starts it loads modules listed in MCP2TERM_PLUGINS, exposing the entire mcp2term namespace through the plugin registry for inspection or extension.
A minimal plugin skeleton:
Development
Run the test suite with:
Tests are parameterised to run with or without dependency stubbing, ensuring full execution paths remain verified.
This server cannot be installed
local-only server
The server can only run on the client's local machine because it depends on local resources.
Enables safe execution of system shell commands with real-time streaming output and rich metadata capture. Provides configurable command execution with timeout controls, environment management, and extensible plugin architecture for monitoring command lifecycles.