Skip to main content
Glama

πŸš€ 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


Related MCP server: Shell MCP Server

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.

A
license - permissive license
-
quality - not tested
D
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (12mo)
Commit activity

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/LeandroPG19/cuba-exec'

If you have feedback or need assistance with the MCP directory API, please join our Discord server