Skip to main content
Glama
stuck1a

terminal-mcp

by stuck1a
README.md
# Terminal MCP

A lightweight Model Context Protocol (MCP) server providing controlled terminal access for AI agents and coding assistants.

Terminal MCP is designed to give an AI agent access to selected local command-line tools while keeping the available executables explicitly configurable.

Compatible with MCP clients such as:

- LM Studio
- Claude Desktop
- Cursor
- Windsurf
- Continue
- Other MCP-compatible clients

---

## Features

- Execute explicitly allowlisted executables
- Configure the whitelist through CLI arguments and whitelist files
- Combine multiple whitelist files
- Configurable working directory
- Configurable process timeout
- Configurable stdout/stderr output limits
- Asynchronous process execution
- Windows and Linux support
- MCP compliant

---

## Installation

### Requirements

- Python 3.11+
- pip

Install the project:

```bash
py -m pip install -e .
```

Or install it as a regular package when published.

---

## Running

The server can be started directly:

```bash
terminal-mcp
```

or:

```bash
py -m terminal_mcp
```

With no whitelist configured, **no executable is allowed to run**.

For example:

```bash
py -m terminal_mcp --whitelist py python git
```

allows only `py`, `python`, and `git`.

---

## Command-line options

### `--whitelist`

Adds one or more executable names directly to the whitelist:

```bash
--whitelist py python pip pytest
```

The option accepts multiple command names and can be followed by another `--...` option.

For example, both forms are valid:

```bash
terminal-mcp --timeout 60 --whitelist py python git
```

```bash
terminal-mcp --whitelist py python git --timeout 60
```

The whitelist contains **executable names**, not complete commands or argument combinations.

---

### `--whitelist-file`

Loads executable names from one or more text files:

```bash
--whitelist-file examples/whitelist-python.txt
```

Multiple files can be supplied:

```bash
--whitelist-file examples/whitelist-python.txt examples/whitelist-python-tools.txt
```

All entries are merged into one whitelist.

Whitelist files use a simple one-entry-per-line format:

```text
# Python
py
python
pip

# Testing
pytest
```

Empty lines are ignored. Lines beginning with `#` are comments.

`--whitelist` and `--whitelist-file` can also be combined. Their entries are merged.

---

### `--timeout`

Sets the maximum process runtime in seconds:

```bash
--timeout 120
```

`-1` means unlimited runtime:

```bash
--timeout -1
```

The default is:

```text
-1
```

---

### `--max-output-size`

Sets the maximum amount of **stored output per stream**, in MiB:

```bash
--max-output-size 1
```

This means up to 1 MiB of stdout **and separately** up to 1 MiB of stderr can be stored.

The two streams therefore have independent limits.

`-1` means unlimited output. The default is:

```text
-1
```

---

## MCP configuration

A minimal configuration:

```json
{
  "mcpServers": {
    "terminal": {
      "command": "terminal-mcp"
    }
  }
}
```

A Windows configuration using Python:

```json
{
  "mcpServers": {
    "terminal": {
      "command": "py",
      "args": [
        "-m",
        "terminal_mcp",
        "--timeout",
        "120",
        "--max-output-size",
        "1",
        "--whitelist",
        "py",
        "python",
        "pytest"
      ]
    }
  }
}
```

### 1. Direct `--whitelist`

Useful for small, self-contained configurations:

```json
{
  "mcpServers": {
    "terminal": {
      "command": "terminal-mcp",
      "args": [
        "--timeout",
        "120",
        "--max-output-size",
        "1",
        "--whitelist",
        "py",
        "python",
        "pytest",
        "git"
      ]
    }
  }
}
```

### 2. One whitelist file

For larger or project-specific configurations:

```json
{
  "mcpServers": {
    "terminal": {
      "command": "terminal-mcp",
      "args": [
        "--timeout",
        "120",
        "--max-output-size",
        "1",
        "--whitelist-file",
        "examples/whitelist-ai-workspace.txt"
      ]
    }
  }
}
```

The path may be relative or absolute, depending on how the MCP client starts the server.

For example:

```text
examples/whitelist-ai-workspace.txt
```

or:

```text
D:/Programming Workspace/FooProject/.terminalmcp
```

### 3. Multiple whitelist files

Whitelists can be composed from several files:

```json
{
  "mcpServers": {
    "terminal": {
      "command": "terminal-mcp",
      "args": [
        "--whitelist-file",
        "examples/whitelist-python.txt",
        "examples/whitelist-python-tools.txt"
      ]
    }
  }
}
```

The resulting whitelist is the union of both files.

### 4. Combining CLI and file-based whitelists

Direct entries and file entries can be combined:

```json
{
  "mcpServers": {
    "terminal": {
      "command": "terminal-mcp",
      "args": [
        "--timeout",
        "120",
        "--max-output-size",
        "1",
        "--whitelist",
        "git",
        "ping",
        "--whitelist-file",
        "examples/whitelist-python.txt",
        "examples/whitelist-python-tools.txt"
      ]
    }
  }
}
```

This allows a small number of additional commands to be added without modifying an existing whitelist file.

### 5. Project-local `.terminalmcp`

A project can maintain its own whitelist file:

```text
FooProject/
+-- .terminalmcp
+-- pyproject.toml
+-- src/
+-- ...
```

For example:

```text
# Project development tools
py
python
pytest
ruff
black
mypy
uv
```

The MCP configuration can then reference it:

```json
{
  "mcpServers": {
    "terminal": {
      "command": "terminal-mcp",
      "args": [
        "--whitelist-file",
        "D:/Programming Workspace/FooProject/.terminalmcp"
      ]
    }
  }
}
```

Automatic discovery of a `.terminalmcp` file in the current working directory is planned for a future release.

---

## Example whitelists

The repository contains several example whitelist files in [`examples/`](examples/):

### Python development

```text
examples/whitelist-python.txt
```

Contains the basic Python execution and package-management commands.

### Python tooling

```text
examples/whitelist-python-tools.txt
```

Contains common Python testing and code-quality tools.

### AI development workstation

```text
examples/whitelist-ai-workspace.txt
```

Contains a broader development/AI-oriented selection, including tools such as:

```text
py
python
pip
pytest
uv
ruff
black
mypy
node
npm
npx
ping
ollama
lms
```

The AI workspace example is intentionally illustrative rather than a recommended universal whitelist.

---

## Security model

Terminal MCP uses an **executable allowlist**.

Before starting a process, the server extracts the executable name and checks it against the configured whitelist. Commands that are not allowlisted are rejected.

The whitelist is loaded **once when the server starts**. It cannot be modified through an MCP tool while the server is running.

This distinction is important:

```text
python
```

allows the executable `python`, but it does **not** restrict Python to a particular Python command or module.

Likewise:

```text
bash
```

allows Bash itself and therefore potentially everything that the Bash process can execute.

The same applies to powerful executables such as:

```text
cmd
python
node
bash
powershell
```

Allowlisting one of these should therefore be treated as granting the capabilities exposed by that executable, not as granting access to one narrowly defined operation.

The whitelist is consequently **not a complete sandbox** and does not attempt to understand the semantics of individual command arguments.

For example, allowing:

```text
curl
```

does not mean "allow HTTP GET requests only". It allows the `curl` executable with whatever arguments the client supplies.

Likewise, an entry such as:

```text
curl fetch
```

does not create a restriction to the `fetch` subcommand. The whitelist operates on executable names, so the executable `curl` itself would not match that entry.

The security boundary is therefore intentionally simple:

> **Which executables may this MCP server launch?**

More restrictive argument-level policies would require command-specific validation and are outside the scope of the current design.

---

## Why allow redundant executables?

It can be useful to allow multiple executable names that provide essentially the same capability.

For example, both:

```text
py
python
```

may be included.

A skill, README, generated instruction, or development guide might use:

```bash
python -m pytest
```

while another uses:

```bash
py -m pytest
```

Allowing both improves compatibility with such instructions without materially expanding the intended capability.

The same principle can apply to other platform- or environment-specific executable names.

---

## A universal terminal MCP?

Terminal MCP is deliberately general-purpose, but a universal MCP should not necessarily replace every specialized MCP server.

A dedicated filesystem MCP, for example, can expose operations such as moving or editing files with well-defined semantics. A terminal MCP can technically perform many of the same operations through commands such as `python`, `node`, `cmd`, or other tools, but doing so provides a much broader capability surface.

Specialized MCP tools generally offer:

- clearer semantics
- more predictable parameters
- narrower capabilities
- easier reasoning for an AI agent
- potentially stronger security boundaries

For that reason, Terminal MCP works well as a **complement** to specialized MCP servers rather than necessarily replacing them.

Giving an agent both a filesystem MCP and Terminal MCP is not inherently problematic. The specialized tool can be preferred for operations it explicitly supports, while Terminal MCP can provide controlled access to development tools and command-line workflows that have no dedicated MCP equivalent.

---

## Experimental AI tooling

A particularly interesting use case is allowing local AI tooling such as:

```text
ollama
lms
```

An agent could potentially inspect available local models or start a model through commands such as:

```bash
ollama list
```

or:

```bash
ollama run <model>
```

This is an experimental example of how Terminal MCP could expose capabilities beyond traditional development tooling. Whether an AI agent can use such functionality effectively depends on the agent, its tool descriptions, and the surrounding MCP environment.

---

## Working directory

Terminal MCP maintains a configurable working directory.

The directory is validated before use and must:

- exist
- be an actual directory
- resolve to a normalized path

The working directory can also be changed through the MCP tool provided by the server.

---

## Example prompts

Once the appropriate executables have been allowlisted, an AI agent can perform tasks such as:

```text
Run the Python test suite.
```

```text
Run Ruff and Black on the project.
```

```text
Check which local Ollama models are available.
```

```text
Run the project's Node.js build.
```

The exact capabilities available to the agent depend entirely on the configured whitelist.

---

## Roadmap

Planned improvements include:

- Automatically detect a `.terminalmcp` whitelist file in the current working directory and merge it with explicitly configured whitelists.
- Add support for command based argument whitelisting and blacklisting
- Further refine configuration and usability based on real-world MCP client behavior.

---

## License

MIT