Cuba-Exec
Advanced shell command execution for AI agents β a Model Context Protocol (MCP) server with security policy engine, process lifecycle management, bounded output capture, POSIX signals, and token-efficient responses.
README
π Cuba-Exec
Advanced shell command execution for AI agents β A Model Context Protocol (MCP) server with security policy engine, process lifecycle management, bounded output capture, POSIX signals, and token-efficient responses.
6 tools. Zero configuration. POSIX-native. Security by default.
Why Cuba-Exec?
Existing command execution MCPs are thin wrappers over subprocess.run. Cuba-Exec solves the real problems:
| Problem | Existing MCPs | Cuba-Exec |
|---|---|---|
| Output overflow (cat /dev/urandom) | β OOM crash | β 64KB bounded |
| Background processes | β Sync only | β Start/status/signal |
| Kill child processes (npm run dev) | β Orphaned children | β Process group kill (setsid) |
| Send stdin (REPLs, prompts) | β Not supported | β Full stdin pipe |
| POSIX signals (SIGTERM, SIGKILL) | β Not supported | β 5 signals + graceful shutdown |
| Command allowlist/blocklist | β οΈ Some | β Both + shell operator validation |
| Directory restriction | β οΈ Rare | β Path-resolved anti-traversal |
| Audit logging | β None | β Structured JSON to stderr |
| Token-efficient output | β Verbose JSON | β TOON compact format |
| Idle process cleanup | β Resource leak | β 1-hour TTL auto-cleanup |
| Fork bomb protection | β None | β Semaphore(20) |
| Process discovery | β None | β List all managed processes |
Quick Start
1. Prerequisites
- Python 3.14+
- Linux/macOS (POSIX required for process groups)
2. Install
git clone https://github.com/LeandroPG19/cuba-exec.git
cd cuba-exec
uv venv && uv pip install -e .
3. Configure your AI editor
{
"mcpServers": {
"cuba-exec": {
"command": "/path/to/cuba-exec/.venv/bin/python",
"args": ["-m", "cuba_exec"]
}
}
}
Zero environment variables needed. Zero configuration files. It just works β with 25 dangerous commands blocked by default.
The 6 Tools
run β Execute and wait
run(command="ls -la", cwd="/tmp", timeout_ms=5000)
| Parameter | Type | Default | Description |
|---|---|---|---|
command |
string | required | Shell command |
cwd |
string | None | Working directory |
env |
dict | None | Environment variables (merged with current) |
timeout_ms |
int | 30000 | Timeout in milliseconds |
max_output |
int | 65536 | Output buffer size (bytes) |
shell |
string | /bin/sh | Shell executable |
Response:
[exit:0 time:12ms trunc:no]
total 156
drwxrwxrwt 22 root root 4096 Mar 8 2026 .
...
start β Background process
start(command="npm run dev", cwd="/app")
Response:
[pid:12345 state:running]
Background process started. Use status(12345) to check output.
status β Check background process
status(pid=12345, tail_bytes=4096)
Response:
[pid:12345 state:running exit:- time:5432ms bytes:8192 trunc:no]
Server running on http://localhost:3000
send_signal β POSIX signals
send_signal(pid=12345, sig="SIGTERM")
SIGTERM triggers graceful shutdown: SIGTERM β wait 5s β SIGKILL.
Valid signals: SIGTERM, SIGKILL, SIGINT, SIGHUP, SIGQUIT.
send_input β stdin pipe
send_input(pid=12345, stdin="print('hello')\n")
For interactive processes (Python REPL, bash prompt, etc.).
list_processes β Process discovery
list_processes()
Response:
[processes:2]
pid:12345 state:running exit:- time:5432ms bytes:8192 cmd:npm run dev
pid:12346 state:completed exit:0 time:1200ms bytes:256 cmd:echo done
π‘οΈ Security Policy Engine
Cuba-Exec includes a multi-layer security engine β the most comprehensive of any MCP command server.
Security Layers
| Layer | Description | Config |
|---|---|---|
| Command Allowlist | Only listed commands can execute | CUBA_EXEC_ALLOWED_COMMANDS |
| Command Blocklist | Dangerous commands always rejected | CUBA_EXEC_BLOCKED_COMMANDS |
| Shell Operator Validation | Validates each sub-command after ;, &&, ||, | |
Automatic |
| Directory Restriction | Restrict cwd to allowed paths (anti-traversal) |
CUBA_EXEC_ALLOWED_DIRS |
| Audit Logging | Structured JSON log of every execution | CUBA_EXEC_AUDIT |
Default Behavior (Zero Config)
Out of the box, Cuba-Exec blocks 25 dangerous commands:
rm, dd, mkfs, shutdown, reboot, halt, poweroff, init, systemctl,
passwd, chown, chmod, chgrp, mount, umount, fdisk, parted,
iptables, nft, ip6tables, crontab, at, useradd, userdel,
groupadd, groupdel, visudo
Production Hardening
export CUBA_EXEC_ALLOWED_COMMANDS="ls,cat,echo,grep,find,head,tail,wc,git,python3,node,npm"
export CUBA_EXEC_BLOCKED_COMMANDS="rm,dd,mkfs,shutdown"
export CUBA_EXEC_ALLOWED_DIRS="/home/user/project,/tmp"
export CUBA_EXEC_AUDIT=1
Shell Operator Bypass Prevention
ls && rm -rf / β the rm after && is validated against blocklist/allowlist too.
Operators parsed: ;, &&, ||, | β each sub-command checked independently.
Audit Log (stderr)
{"ts":"2026-03-08T15:00:00-0600","event":"exec","command":"ls -la","pid":12345,"exit":0,"ms":12,"ok":true}
Output Format (TOON)
All responses use Token-Oriented Object Notation β compact headers that save ~200 tokens per tool call vs verbose JSON.
[exit:0 time:1543ms trunc:no]
...output...
Error Codes
| Error | Exit Code | Field | Example |
|---|---|---|---|
| Command not found | 127 | ENOENT |
nonexistent_binary |
| Permission denied | 126 | EACCES |
cat /etc/shadow |
| Timeout | -1 | TIMEOUT |
sleep 60 with 1s timeout |
| Signal killed | -9 | SIGKILL |
Process killed by signal |
| Blocked by policy | β | BLOCKED |
rm -rf / |
Head+Tail Output Buffer β Shannon (1948)
Command output has high entropy at the extremes (preamble + results/errors) and low entropy in the middle (progress bars, repetitive logs).
βββββββββββββββ¬ββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ
β Head (25%) β Truncated middle β Tail (75%) β
β ~16KB β [... N bytes truncated ...] β ~48KB (ring buffer) β
βββββββββββββββ΄ββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββ
- Head: First 25% of buffer β captures headers, version info
- Tail: Last 75% via ring buffer β captures results, errors (highest entropy)
- Ring buffer: O(1) write, O(C) memory (Cormen et al., CLRS 4th ed.)
- Default: 64KB per process. Max memory: 20 Γ 64KB = 1.28MB
POSIX Process Groups β IEEE Std 1003.1
npm run dev spawns child processes. Sending SIGTERM to the parent doesn't kill children.
Cuba-Exec creates process groups via setsid:
asyncio.create_subprocess_exec(..., start_new_session=True)
os.killpg(os.getpgid(pid), signal.SIGTERM) # Kills entire tree
Graceful Shutdown
SIGTERM β wait 5s β SIGKILL (if still alive)
Two-phase shutdown (Stevens & Rago, 2013): SIGTERM allows cleanup, SIGKILL is uncatchable.
Configuration
All defaults work out of the box. Override via environment variables:
| Setting | Default | Env Var |
|---|---|---|
| Max concurrent processes | 20 | CUBA_EXEC_MAX_PROCS |
| Output buffer size | 64KB | CUBA_EXEC_BUFFER_SIZE |
| Idle process TTL | 1 hour | CUBA_EXEC_TTL |
| Shutdown timeout | 5s | CUBA_EXEC_SHUTDOWN_TIMEOUT |
| Allowed commands | β (all) | CUBA_EXEC_ALLOWED_COMMANDS |
| Blocked commands | 25 defaults | CUBA_EXEC_BLOCKED_COMMANDS |
| Allowed directories | β (all) | CUBA_EXEC_ALLOWED_DIRS |
| Audit logging | off | CUBA_EXEC_AUDIT |
Architecture
cuba-exec/
βββ pyproject.toml # 1 dependency: fastmcp
βββ src/
βββ cuba_exec/
βββ __init__.py
βββ __main__.py # Entry point
βββ server.py # FastMCP 6 tool definitions (~105 LOC)
βββ security.py # SecurityPolicy engine (~135 LOC)
βββ process_manager.py # Lifecycle FSM + signals + TTL (~520 LOC)
βββ output_buffer.py # Head+Tail ring buffer (~110 LOC)
Total: ~880 LOC. FastMCP SDK handles protocol boilerplate.
Dependencies (1 total)
| Package | Purpose |
|---|---|
fastmcp |
MCP protocol server β auto tool schemas from type hints, Pydantic validation |
Everything else is Python stdlib: asyncio, os, signal, time, json, re, pathlib.
Part of the Cuba Ecosystem
| Project | Purpose |
|---|---|
| Cuba-Memorys | Persistent memory β knowledge graph, Hebbian learning |
| Cuba-Thinking | Sequential reasoning β cognitive engine, NLI, MCTS |
| Cuba-Search | Web search β research, scraping, validation, documentation lookup |
| Cuba-Exec | Shell execution β process lifecycle, security, bounded output, POSIX signals |
Together: memory + reasoning + search + execution β the four pillars of capable AI agents.
Academic References
| # | Citation | Used For |
|---|---|---|
| 1 | Yang et al. (2024). "SWE-agent: Agent-Computer Interfaces." NeurIPS | ACI design, output truncation, guardrails |
| 2 | Shannon (1948). "A Mathematical Theory of Communication" | Information-theoretic output strategy |
| 3 | IEEE Std 1003.1-2024. "POSIX.1: System Interfaces" | Process groups, setsid, signals |
| 4 | Cormen et al. (2022). "Introduction to Algorithms." 4th ed. | Ring buffer O(1) analysis |
| 5 | Dijkstra (1965). "Cooperating Sequential Processes" | Semaphore concurrency limiting |
| 6 | Stevens & Rago (2013). "APUE" 3rd ed. | Process lifecycle, graceful shutdown |
| 7 | TOON (2025). "Token-Oriented Object Notation" | 95-97% token reduction |
| 8 | OWASP (2025). "Top 10 for Agentic Applications" | Security policy design, allowlist/blocklist |
License
CC BY-NC 4.0 β Free to use and modify, not for commercial use.
Author
Leandro PΓ©rez G.
- GitHub: @LeandroPG19
- Email: leandropatodo@gmail.com
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.