ubuntu-controller
Provides safe, policy-controlled access to an Ubuntu system, enabling file and directory operations, command execution, system information retrieval, and APT package listing/search.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ubuntu-controllershow me system uptime and current CPU load"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Hardened Model Context Protocol server · safe, controlled access to Ubuntu system operations
Give your AI assistant safe, audited, policy-controlled access to an Ubuntu machine — through the power of the standard Model Context Protocol.
┌───────────────────────┐ ┌───────────────────────────┐ ┌─────────────────────┐
│ AI Assistant (Claude │ ───▶ │ ubuntu-mcp-server │ ───▶ │ Ubuntu System │
│ Desktop, custom │ MCP │ stdio/stdin-stream │ safe │ files · commands · │
│ clients) │ │ SecurityChecker │Audit │ │ packages · system │
└───────────────────────┘ └───────────────────────────┘ └─────────────────────┘Never expose a raw shell. The server validates every path, command, and file against a configurable policy before it touches your system — and logs everything it does.
📑 Table of Contents
Related MCP server: MCP Process Server
✨ Key Features
Area | What you get |
🛡️ Security-first | Symlink-aware path resolution, |
🧱 Defense in depth | Multiple independent validation layers — a single bypass never grants system access |
📜 Full audit trail | Every command, file access, and violation logged with user attribution |
📦 Safe package ops | APT search & list only — no accidental installs unless you widen the policy |
🧪 Proven | Built-in security test suite ( |
🪶 Zero extra deps | Core security is pure-Python; only |
🚀 Quick Start
# 1. Clone & enter
git clone https://github.com/Serp3n7/secure-ubuntu-mcp.git && cd secure-ubuntu-mcp
# 2. Interactive setup (venv + deps + tests + Claude config) — recommended
python3 setup.py
# --- or, manually ---
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# 3. Verify
python main.py --test
python main.py --security-testRun it:
python main.py --policy secure # 🔐 production default
python main.py --policy dev # 🧪 more permissive, for development⚙️ CLI Reference
usage: main.py [options]
--policy secure|dev Security policy to use [default: secure]
--test Run functionality tests
--security-test Run the comprehensive security validation suite
--log-level LEVEL Logging level: INFO, DEBUG, WARNING, ERROR [default: INFO]🤖 Claude Desktop Integration
1. Install Claude Desktop (Linux)
Officially, Claude Desktop targets macOS/Windows — the community-published Debian package by @aaddrick fills the gap:
wget https://github.com/aaddrick/claude-desktop-debian/releases/latest/download/claude-desktop_latest_amd64.deb
sudo dpkg -i claude-desktop_latest_amd64.deb
sudo apt-get install -f2. Register the server
Edit ~/.config/Claude/claude_desktop_config.json — absolute paths required (the ~ shorthand is not expanded):
{
"mcpServers": {
"secure-ubuntu": {
"command": "/path/to/ubuntu_mcp_server/.venv/bin/python3",
"args": ["/path/to/ubuntu_mcp_server/main.py", "--policy", "secure"],
"env": { "MCP_LOG_LEVEL": "INFO" }
}
}
}💡
setup.pymerges this block for you automatically. Alternatively pointcommandat the bundledrun_mcp_server.shlauncher, which handles venv activation.
3. Verify
Restart Claude Desktop → confirm "secure-ubuntu" appears as a connected server → try:
"Check my system status and disk space"
Other MCP clients
The server speaks standard MCP over stdio — any compatible client works. See test_client.py for a reference client:
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def example():
params = StdioServerParameters(command="python3", args=["main.py"])
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
# ... call tools ...
asyncio.run(example())🛡️ Security Policies
Two ships-with-the-box policies plus a custom-policy API. Start with secure, widen deliberately.
🔐 Secure Policy — default, production
Control | Value |
Allowed paths |
|
Forbidden paths |
|
Command mode | Whitelist (deny-by-default) |
Allowed commands |
|
Forbidden commands |
|
File size / output | 1 MB / 256 KB |
Timeout / listing | 15 s / 100 items |
Sudo · shell | ❌ Disabled · ❌ Disabled (direct |
🧪 Development Policy — less restrictive
Control | Value |
Allowed paths | Secure + |
Command mode | Denylist (whitelist off — most tools allowed) |
File size / output | 10 MB / 1 MB |
Timeout / listing | 60 s / 500 items |
Sudo | ❌ Still disabled |
✍️ Custom Policies
from main import SecurityPolicy, SecureUbuntuController
policy = SecurityPolicy(
allowed_paths=["/your/custom/paths"],
forbidden_paths=["/sensitive/areas"],
allowed_commands=["safe", "commands"],
forbidden_commands=["dangerous", "commands"],
command_whitelist_mode=True, # True = deny-by-default
max_command_timeout=30,
allow_sudo=False, # use with extreme caution
audit_actions=True,
resolve_symlinks=True, # always on for security
use_path_cache=False, # off by default (TOCTOU-safe)
use_shell_exec=False, # off by default
)
controller = SecureUbuntuController(policy)⚙️ Configuration
config.py provides dataclass-based loading/saving (ConfigManager, ServerConfig, SecurityConfig) with a default file at ~/.config/ubuntu-mcp/config.json, created on first run. A ready-to-edit example ships in the repo as config.json.
{
"server": {
"name": "ubuntu-controller",
"version": "1.0.0",
"description": "MCP Server for Ubuntu System Control",
"log_level": "INFO"
},
"security": {
"policy_name": "safe",
"allowed_paths": ["~/", "/tmp", "/var/tmp"],
"forbidden_paths": ["/etc/passwd", "/etc/shadow", "/root", "/boot", "/sys", "/proc"],
"allowed_commands": ["ls", "cat", "echo", "pwd", "whoami", "date", "grep", "find", "which", "file", "head", "tail", "apt", "git", "python3", "pip3"],
"forbidden_commands": ["rm", "rmdir", "dd", "mkfs", "shutdown", "reboot", "mount", "umount", "chmod", "chown"],
"max_command_timeout": 30,
"allow_sudo": false
}
}ℹ️ Runtime policy is chosen via
--policy;config.pyis the programmatic / embedded-config path.
🔍 Available Tools
Tool | Signature | Notes |
📁 |
| Metadata: size, perms |
📄 |
| UTF-8, size-validated, encoding-tolerant |
✍️ |
| Atomic temp+rename, timestamped |
⌨️ |
| Direct exec, sanitized PATH/env, timeout + output caps |
🖥️ |
| OS, memory, disk usage, user, hostname, arch |
🔎 |
|
|
📦 |
|
|
🔒 Security Features
✅ Path traversal — blocked
../../../etc/passwd → SecurityViolation
/etc/passwd → SecurityViolation
/tmp/../etc/passwd → SecurityViolation
symlink_to_/etc/passwd → SecurityViolation (symlinks fully resolved)Every path is canonicalized with symlink resolution, then matched against allowlist + denylist before access. Access to the server's own files and system_critical_paths is always refused.
✅ Command injection — blocked
echo hello; rm -rf / → SecurityViolation
echo `cat /etc/passwd` → SecurityViolation
echo $(whoami) → SecurityViolation
ls | rm -rf / → SecurityViolationParsed with shlex (no shell interpretation), the executable is resolved to a real absolute path (defeats PATH injection), checked against the whitelist/blacklist, then run directly via subprocess.exec with a sanitized environment (LD_PRELOAD, LD_LIBRARY_PATH, IFS stripped).
✅ Resource exhaustion — mitigated
Threat | Defense |
Oversized file reads | Hard size limit before read |
Hanging commands | Per-process-group timeout, |
Output flooding | stdout/stderr capped + truncation marker |
Directory enumeration | Item-count cap with |
📜 Audit trail
Everything lands in /tmp/ubuntu_mcp_audit.log:
COMMAND_ATTEMPT: user=serp3n7 cmd='ls -la' cwd=default
FILE_READ: user=serp3n7 path='/home/serp3n7/foo' status=SUCCESS
SECURITY_VIOLATION: user=serp3n7 violation='COMMAND_BLOCKED' details='Command not in whitelist: nmap'🧪 Testing
./run_tests.sh # full suite: controller, MCP client, policies, files, packages
python main.py --test # functionality tests
python main.py --security-test # attack-surface validation
python test_client.py # end-to-end MCP protocol client
python test_client.py --simple # controller-level smoke testThe --security-test suite validates real vectors — symlink attacks, path traversal, server self-protection, injection patterns, forbidden commands, and size limits — and exits non-zero on any bypass.
📦 Installation Scripts
Script | Use | Notes |
Interactive dev setup | venv → deps → | |
System install (root) | Installs to | |
Claude Desktop launcher | Activates | |
Disk-space demo | Prints a usage bar using |
# systemd service install
sudo python3 install.py
sudo systemctl enable --now ubuntu-mcp🛠️ Development
Add a tool
from main import create_secure_policy, SecureUbuntuController
controller = SecureUbuntuController(create_secure_policy())
@mcp.tool("your_tool_name")
async def your_tool(param: str) -> str:
try:
result = controller.safe_operation(param)
return json.dumps(result, indent=2)
except Exception as e:
return json.dumps({"error": str(e)}, indent=2)Extend security
def create_custom_policy() -> SecurityPolicy:
return SecurityPolicy(
allowed_paths=["/your/paths"],
forbidden_commands=["dangerous", "commands"],
# ...
)Standards
PEP 8 · type hints on all public functions · docstrings on every tool
Tests for new functionality — run
./run_tests.shbefore opening a PRSecurity-first: permission is denied until a policy explicitly grants it
See CONTRIBUTING.md and CHANGELOG.md.
🔧 Troubleshooting
Symptom | Cause & fix |
Server appears to hang | It's not — MCP servers run continuously over stdio and wait for messages |
| Not using the venv; point Claude at |
| Path/command outside policy — review the audit log and widen the policy deliberately |
| The file isn't readable/writable by the server account — check |
Debug mode:
python main.py --log-level DEBUG --policy secure
tail -f /tmp/ubuntu_mcp_audit.log📄 License & Disclosure
License: MIT · Contributing: CONTRIBUTING.md
Found a vulnerability? Email radjackbartok@proton.me — don't open a public issue.
Made for the security-conscious AI community 🚀
💡 Pro tip: start with the
securepolicy and widen it deliberately — it's easier to grant than to recover.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Security gateway for AI agents: policy, approval, and audited execution, no secrets shared.
Runtime permission, approval, and audit layer for AI agent tool execution.
- FullmaktOAuthai.fullmakt
Credential broker for AI agents: scoped, revocable API access with policy enforcement and audit.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA secure protocol server that allows AI assistants to safely interact with Ubuntu systems through controlled file operations, command execution, package management, and system information retrieval.41MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to launch and manage system processes with strict security controls through executable allowlists, resource monitoring, and output capture capabilities.511MIT
- AlicenseBqualityDmaintenanceProvides AI assistants with the ability to control Linux desktop environments through tools for file management, application launching, and system operations like clipboard access. It includes a multi-level security model to manage permissions for safe, elevated, and restricted actions.6MIT
- AlicenseAqualityCmaintenanceEnables AI assistants to perform controlled Linux system administration tasks like reading logs, managing services, cron jobs, WordPress, and executing sandboxed Python code, with strict security constraints.292GPL 2.0
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Serp3n7/secure-ubuntu-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server