terminal-mcp
README.md
# terminal-mcp
**An agent-capable MCP server with terminal access, filesystem control, and persistent memory.** Built-in sandboxing, access control, activity logging, and a file-backed memory store — so Claude can run commands, manage files, and remember context across conversations.
---
## What it does
`terminal-mcp` provides **10 tools** across two categories:
### Terminal Tools
| Tool | Access Scope | Description |
|------|-------------|-------------|
| `run_command` | Full ROOT_DIR | Execute shell commands with dangerous-command blocking |
| `read_file` | Allowed dirs only | Read files from whitelisted paths |
| `write_file` | Allowed dirs only | Write/overwrite files in whitelisted paths |
| `list_files` | Full ROOT_DIR | Browse directory contents (recursive supported) |
| `run_workflow` | Full ROOT_DIR | Named workflows: `npm_install`, `npm_run`, `python_run`, `shell_script` |
### Memory Tools
| Tool | Description |
|------|-------------|
| `memory_store` | Save a memory with name, type, tags, and content |
| `memory_recall` | Retrieve a specific memory by name |
| `memory_search` | Search all memories by keyword and/or type |
| `memory_delete` | Remove a memory |
| `memory_list` | List all stored memories (returns the MEMORY.md index) |
## Memory System
The memory system gives Claude persistent context that survives across conversations. Memories are stored as individual markdown files with YAML frontmatter inside `claude_playground/memory/`, with an auto-maintained `MEMORY.md` index.
### Memory Types
| Type | Purpose | Example |
|------|---------|---------|
| `user` | Who the user is, their preferences, expertise | "Senior backend engineer, prefers Go" |
| `feedback` | How to approach work (corrections + confirmations) | "Don't mock the database in integration tests" |
| `project` | Ongoing work context, goals, deadlines | "Auth rewrite driven by compliance, due March 15" |
| `reference` | Pointers to external resources | "Pipeline bugs tracked in Linear project INGEST" |
| `note` | General-purpose memory | Anything that doesn't fit above |
### How it works
```
claude_playground/
└── memory/
├── MEMORY.md # Auto-generated index (grouped by type)
├── user_role.md # Individual memory files
├── feedback_testing.md
├── project_auth_rewrite.md
└── ...
```
Each memory file looks like:
```markdown
---
name: testing preferences
type: feedback
tags: [testing, database]
created: 2025-01-15T14:30:00
updated: 2025-01-20T09:15:00
---
Integration tests must hit a real database, not mocks.
**Why:** Prior incident where mock/prod divergence masked a broken migration.
**How to apply:** Any test touching the data layer should use the test database.
```
The `MEMORY.md` index is automatically rebuilt whenever a memory is stored or deleted:
```markdown
# Memory Index
## User
- [user role](user_role.md) — Senior backend engineer, prefers Go
## Feedback
- [testing preferences](feedback_testing.md) — Integration tests must hit a real database
```
### Usage
Claude can use memory tools naturally in conversation:
- *"Remember that I prefer concise responses with no trailing summaries"*
- *"What do you know about the auth rewrite?"*
- *"Search your memory for anything about testing"*
- *"Forget the note about the old API endpoint"*
- *"What's in your memory?"*
## Safety Features
- **Path sandboxing** — `read_file` and `write_file` restricted to allowed directories
- **Dangerous command blocking** — `rm -rf /`, `mkfs`, disk overwrites, fork bombs blocked
- **Dynamic access control** — edit `path.txt` to grant access without restarting
- **Activity logging** — every action (including memory operations) logged with timestamps
- **Configurable root** — restrict the entire server to a specific directory tree
## Installation
```bash
pip install terminal-mcp
```
Or from source:
```bash
git clone https://github.com/koushikmaji/terminal-mcp.git
cd terminal-mcp
pip install -e .
```
## Setup
### Configure Claude Desktop
```json
{
"mcpServers": {
"terminal": {
"command": "terminal-mcp"
}
}
}
```
To restrict the root directory:
```json
{
"mcpServers": {
"terminal": {
"command": "terminal-mcp",
"env": {
"TERMINAL_MCP_ROOT": "/Users/you/projects"
}
}
}
}
```
### Granting File Access
By default, `read_file` and `write_file` only work inside `$ROOT/claude_playground/`. To grant access to additional paths, add them to `claude_playground/path.txt`:
```
# One absolute path per line
/Users/you/projects/my-app
/Users/you/Documents/notes
```
Changes take effect immediately — no restart needed.
## Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `TERMINAL_MCP_ROOT` | `$HOME` | Base directory for all operations |
| `TERMINAL_MCP_PLAYGROUND` | `claude_playground` | Playground subdirectory name |
| `TERMINAL_MCP_SHELL` | `/bin/zsh` (macOS) or `/bin/bash` | Shell for command execution |
| `TERMINAL_MCP_TIMEOUT` | `30` | Default command timeout (seconds) |
## Architecture
```
run_command / list_files / run_workflow
┌─────────────────────────────────────────┐
│ Full ROOT_DIR │
│ │
│ read_file / write_file │
│ ┌──────────────────────────┐ │
│ │ claude_playground/ │ │
│ │ + paths in path.txt │ │
│ │ │ │
│ │ memory_* │ │
│ │ ┌────────────────┐ │ │
│ │ │ memory/ │ │ │
│ │ │ MEMORY.md │ │ │
│ │ │ *.md files │ │ │
│ │ └────────────────┘ │ │
│ └──────────────────────────┘ │
└─────────────────────────────────────────┘
```
## Logging
All actions are logged to `claude_playground/terminal.log`:
```
[2025-01-15 14:32:01] [RUN] CMD: ls -la | CWD: /Users/you
[2025-01-15 14:32:05] [READ] FILE: /Users/you/projects/app/config.json
[2025-01-15 14:33:00] [MEMORY] STORE: user role (user)
[2025-01-15 14:33:10] [MEMORY] SEARCH: q=testing type=None hits=2
```
## Requirements
- Python 3.10+
- MCP-compatible client (Claude Desktop, Claude Code, etc.)
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues