Z-Agent Remote Control is designed to let an AI agent perform useful tasks on your computer (file operations, running commands, checking system info) while preventing destructive actions.
┌───────────────────────────────────────────────────────┐
│ Untrusted Network (Internet) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ AI Agent (could be any LLM service) │ │
│ │ - Has the tunnel URL and API key │ │
│ │ - Can send any JSON-RPC request │ │
│ └──────────────┬──────────────────────────────────┘ │
│ │ HTTPS (Cloudflare TLS) │
│ ┌──────────────▼──────────────────────────────────┐ │
│ │ Cloudflare Tunnel Edge │ │
│ │ - TLS termination │ │
│ │ - No access to request content │ │
│ └──────────────┬──────────────────────────────────┘ │
│ │ HTTP (localhost only) │
│ ┌──────────────▼──────────────────────────────────┐ │
│ │ MCP Server (trusted boundary) │ │
│ │ Layer 1: Bearer token auth │ │
│ │ Layer 2: Command blocklist │ │
│ │ Layer 3: Path allowlist (file ops) │ │
│ │ Layer 4: Subprocess timeout │ │
│ │ Layer 5: Audit logging │ │
└──────────────┬──────────────────────────────────┘ │
│ │ │
│ ┌──────────────▼──────────────────────────────────┐ │
│ │ Local Filesystem (restricted to allowed dirs) │ │
│ └─────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────┘
Every request must include a valid Bearer token in the Authorization header.
Authorization: Bearer <api-key>
- Keys are checked as constant-time string comparison
- Missing or invalid keys return HTTP 401 with a JSON-RPC error
- Default key is a placeholder — users must generate their own
- Key generation uses
secrets.choice()(crypto-secure RNG)
The run_command tool blocks any command containing these substrings:
| Blocked | Why |
|---|---|
rm |
File deletion (even rm -rf /) |
sudo |
Privilege escalation |
shutdown |
System shutdown |
reboot |
System reboot |
halt |
System halt |
mkfs |
Filesystem formatting |
dd |
Disk destruction (dd if=/dev/zero) |
chmod |
Permission changes |
chown |
Ownership changes |
kill |
Process termination |
killall |
Mass process termination |
pkill |
Pattern process termination |
Implementation: Substring matching — any command string containing these patterns is rejected. This catches variations like sudo rm -rf / or /usr/bin/kill -9 1.
Known limitations:
- Advanced attackers could potentially encode commands to bypass substring checks (e.g., base64 encoding)
- The blocklist is a first line of defense, not a security boundary
- For stronger isolation, consider running in a container or VM
File operations (read_file, write_file, delete_file, list_directory, search_files) are restricted to configured allowed directories.
Implementation:
- User-provided paths are expanded (
~→ home dir) - Resolved to absolute paths (
Path.resolve()) - Checked against all allowed directory prefixes
- If the resolved path doesn't start with any allowed directory, the operation is rejected
Default allowed directory: ~/projects
Users can add more via the Security tab in Z Control.
All run_command executions have a configurable timeout (default: 25 seconds). This prevents:
- Long-running processes from hanging the server
- Fork bombs and resource exhaustion
- Network-bound commands from blocking indefinitely
Every tool call is logged with:
- Timestamp (ISO 8601)
- Tool name
- Arguments (truncated for large content)
- Client IP
- Result status
Log location: ~/.local/share/mimocode/mcp-audit.log
Review the audit log regularly from the Settings tab in Z Control.
- All traffic between the AI agent and Cloudflare uses TLS 1.3
- Cloudflare forwards to localhost over plain HTTP (loopback interface only)
- The MCP server binds to
127.0.0.1— not accessible from other machines on the LAN - No inbound firewall ports need to be opened
- Tunnel URLs are ephemeral (change on every cloudflared restart)
- Only someone with both the URL AND the API key can access the server
- The URL alone is useless without the API key
-
Always generate a strong API key — use the Generate New button in the Security tab. Aim for 16+ characters with mixed case, numbers, and symbols.
-
Minimize allowed directories — only add directories that the AI agent needs to access.
~/projectsis a good default sandbox. -
Kill services when not in use — click "Kill All & Lock Down" in the Control tab when you're done. This stops both the MCP server and tunnel.
-
Review the audit log — periodically check the audit log in the Settings tab to see what commands have been executed.
-
Never share your tunnel URL and API key — these are equivalent to full access to your allowed directories.
-
Use auto-start wisely — only enable auto-start if you need the tunnel available immediately on login.
-
Keep the app updated — check the GitHub repo for security updates.
- Run the MCP server in a Docker container or VM for stronger isolation
- Use a firewall to block all inbound connections except from the cloudflared process
- Set up Cloudflare named tunnels (instead of quick tunnels) for persistent URLs with access policies
- Consider fail2ban or similar to block repeated auth failures (the MCP server doesn't implement this)
- No rate limiting — the MCP server doesn't limit request frequency
- No user management — single API key, no multi-user support
- Substring blocklist can be bypassed — determined attackers could encode commands (e.g., Python one-liners with
exec) - File content is logged — the audit log may contain file contents for write operations
- No encryption at rest — the API key is stored in plaintext in settings.json
- No revocation — changing the key requires restarting the MCP server
If you find a security vulnerability, please open a GitHub Issue with the [Security] tag. Do not publicly disclose the issue until a fix is available.