Skip to main content
Glama
README.md
> โšก Published on PyPI and compatible with MCP clients that support the stdio transport.

# Smart Terminal MCP

A lightweight **Model Context Protocol (MCP)** server built with **FastMCP** that lets AI assistants work with files, git and Python on your local machine, **inside a protected workspace folder**.

Giving an AI agent a raw terminal is risky: it could delete files, read secrets or run commands you never intended. This project explores how to expose useful local tools to MCP clients **with safety nets built in**.

---

## โœจ Features

- List, read, write and search files (`glob`, `grep`, `read_file`, `write_file`)
- Create and (softly) delete folders
- Run a small allowlist of safe commands: `ls`, `pwd`, `echo` and **read-only git** (`status`, `log`, `diff`, `show`)
- Run Python code and Python files (**opt-in**, off by default)
- Every file operation is confined to one workspace folder
- Works on Windows, macOS and Linux (developed and tested on Windows)
- One command to run: `uvx smart_terminal_mcp`

---

## ๐Ÿ›ก๏ธ Security Model

| Safety net | What it does |
|------------|--------------|
| **Workspace jail** | Every path is resolved to its real location (`../` and symlinks included) and must stay inside the workspace folder |
| **Secrets blocklist** | `.env*`, `.git`, `.ssh`, `*.pem`, `*.key` and `.trash` cannot be read, written or listed |
| **No raw shell** | `bash` never uses a shell. It runs only allowlisted commands, and `;` `&` `\|` `>` `<` `` ` `` `$` are rejected |
| **Read-only git** | Only `status`, `log`, `diff`, `show`; risky flags like `--output` and `--no-index` are blocked |
| **Limits** | 20 s timeout, 20,000-character output cap, 1 MB file-size cap |
| **Clean environment** | Launched programs only receive `PATH` and `SYSTEMROOT`, so your API keys are not exposed to them |
| **No accidental overwrite** | `write_file` refuses to replace an existing file unless `overwrite=True` |
| **Soft delete** | `delete_folder` moves folders to `.trash/` instead of destroying them; the workspace root can never be deleted |
| **Friendly errors** | Anything blocked returns a readable `Blocked/Error: ...` message so the agent can adjust |
| **Python is opt-in** | `python_code` / `python_file` are disabled unless you set `SMART_TERMINAL_ALLOW_PYTHON=1` |

### โš ๏ธ Important limitation

The folder jail protects the **file, search and git tools**. **Python execution is not sandboxed**: when enabled, Python code can access anything your user account can. Enable it only with agents you trust, or run the server inside Docker (on the roadmap).

---

## ๐Ÿ“ฆ Installation

### Using uv (Recommended)

Run it directly without installing:

```bash
uvx smart_terminal_mcp
```

Or add it to a project:

```bash
uv add smart_terminal_mcp
```

### Using pip

```bash
pip install smart_terminal_mcp
```

---

## ๐Ÿš€ MCP Server Configuration

You need an MCP client (Claude Desktop, Claude Code, Cursor, VS Code, Codex, or your own LangGraph app) and [`uv`](https://docs.astral.sh/uv/) installed.

### Claude Desktop / Cursor style

```json
{
  "mcpServers": {
    "smart_terminal": {
      "command": "uvx",
      "args": ["smart_terminal_mcp"],
      "env": {
        "SMART_TERMINAL_ROOT": "C:\\Users\\me\\projects\\my-app"
      }
    }
  }
}
```

### LangChain MCP adapters style

```json
{
  "smart_terminal": {
    "transport": "stdio",
    "command": "uvx",
    "args": ["smart_terminal_mcp"],
    "env": {
      "SMART_TERMINAL_ROOT": "/path/to/workspace"
    }
  }
}
```

### Claude Code

```bash
claude mcp add smart_terminal -- uvx smart_terminal_mcp
```

### Settings (environment variables)

| Variable | Default | Meaning |
|----------|---------|---------|
| `SMART_TERMINAL_ROOT` | current folder | The workspace folder every tool is confined to. **Set this explicitly.** |
| `SMART_TERMINAL_ALLOW_PYTHON` | off | Set to `1` to enable `python_code` and `python_file` |

---

## ๐Ÿ“‚ Available Tools

| Tool | Description |
|------|-------------|
| `bash` | Run one allowlisted command: `ls`, `pwd`, `echo`, or read-only `git` |
| `python_code` | Run a Python snippet (opt-in, 20 s timeout) |
| `python_file` | Run a `.py` file from the workspace (opt-in, 20 s timeout) |
| `read_file` | Read a text file in the workspace (max 1 MB) |
| `write_file` | Create a file; overwrites only with `overwrite=True` |
| `glob` | List files matching a pattern such as `**/*.py` |
| `grep` | Search for text inside a file |
| `create_folder` | Create a folder in the workspace |
| `delete_folder` | Move a folder to `.trash/` (recoverable) |

---

## ๐Ÿ”„ How It Works

```
LLM  โ‡„  MCP client (Claude, Cursor, ...)  โ‡„  smart_terminal_mcp  โ‡„  workspace folder
 (cloud)        (on your computer)        (started by uvx, stdio)     (your files and git)
```

1. Your MCP client starts the server with `uvx smart_terminal_mcp`.
2. The LLM asks the client to call a tool; the client forwards it over stdio.
3. The server validates the request (path jail, allowlist, limits) and only then runs it.
4. The result, or a `Blocked/Error` message, goes back to the LLM.

The server runs entirely on your own machine. Nothing is hosted.

---

## ๐Ÿงช Testing

```bash
uv run python test.py
```

Or open the MCP Inspector against the server:

```bash
npx @modelcontextprotocol/inspector uv run smart_terminal_mcp
```

Things worth trying: `ls; whoami` (blocked), reading `../anything` (blocked), reading `.env` (blocked), writing to an existing file without `overwrite=True` (refused).

---

## ๐Ÿ“ Project Structure

```
smart_terminal_mcp/
โ”‚
โ”œโ”€โ”€ src/
โ”‚   โ””โ”€โ”€ smart_terminal_mcp/
โ”‚       โ”œโ”€โ”€ main.py
โ”‚       โ””โ”€โ”€ tools.py
โ”‚
โ”œโ”€โ”€ test.py
โ”œโ”€โ”€ pyproject.toml
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ LICENSE
```

---

## ๐ŸŽฏ Motivation

The goal of this project was to gain hands-on experience with the **Model Context Protocol (MCP)** by building a practical server, and to learn why **safety design matters** when AI agents can touch a real machine.

It helped me understand:

- MCP architecture and the stdio transport
- Tool registration with FastMCP
- Path traversal and why paths must be resolved before checking
- Why raw `shell=True` is dangerous, and allowlisting as an alternative
- Python packaging and PyPI publishing
- Honest threat modelling: what a safeguard does and does not protect

---

## ๐Ÿ”ฎ Roadmap

- Docker mode for a true sandbox (including Python execution)
- `delete_file`, `edit_file` (partial edits), `move` and `copy` operations
- More read-only commands and richer `ls` options
- Git actions with explicit approval (add, commit)
- Tool execution audit log
- More testing on macOS and Linux

---

## โš ๏ธ Disclaimer

This project is intended for educational and development purposes. Even with the safety nets above, only connect it to agents and clients you trust, and point `SMART_TERMINAL_ROOT` at a dedicated project folder, never at your home directory or system folders.

---

## ๐Ÿ“œ License

MIT License

---

## ๐Ÿ‘จโ€๐Ÿ’ป Author

**Mohd Bilal**

If you found this project interesting, feel free to star the repository.

TDQS

B3.2/5.0

Scored across 9 tools

Disambiguation3/5

Most tools have distinct purposes, but 'bash' overlaps with many others (can create files/folders, run python), and 'python_code' vs 'python_file' are similar. Descriptions help, but boundaries are somewhat blurry.

Naming Consistency3/5

All names use lowercase with underscores, but the pattern is mixed: 'read_file' and 'create_folder' follow verb_noun, while 'bash', 'python_code', 'glob', and 'grep' do not. Consistent style, but not a uniform convention.

Tool Count5/5

9 tools is a well-scoped set for a terminal/file manipulation server, covering core operations without being excessive or too sparse.

Completeness4/5

The domain is file and terminal operations, and the set covers read/write, directory create/delete, glob, grep, and execution via bash/python. Missing a direct delete_file or list_directory, but bash can handle those, so gaps are minor and workable.

Maintenance

ActivityMaintained
ResponsivenessNo issues