cd /news/ai-agents/zero-tax-virtualization-running-ai-a… Β· home β€Ί topics β€Ί ai-agents β€Ί article
[ARTICLE Β· art-131777] src=dev.to β†— pub= topic=ai-agents verified=true sentiment=Β· neutral

Zero-Tax Virtualization: Running AI Agents Safely in Velo Workspaces

A developer has outlined a method for running autonomous AI coding agents safely on Apple Silicon Macs by isolating agent execution inside a Linux VM while keeping model inference on the macOS host, working around Virtualization.framework's lack of Metal GPU passthrough to Linux guests. The setup, built around Velo Workspaces, bridges the guest VM to a host-side inference server (MLX or Ollama) over a VirtIO-vsock channel, with the guide providing RAM-based model recommendations from 16 GB to 128 GB+ configurations.

by read8 min views1 publishedSep 16, 2026

Running autonomous AI coding agents natively on your primary macOS machine introduces severe security liabilities. Modern agents execute terminal commands, install unverified dependencies via pip and npm, modify arbitrary files, and can be coerced through prompt injection attacks into exfiltrating environment variables, dotfiles, or macOS Keychain secrets.

The standard industry remedy is sandboxing agents inside a Linux virtual machine or container. On Apple Silicon, however, this immediately collides with a hypervisor-level barrier:

Virtualization.framework does not expose the host Metal GPU to Linux guests. Linux VMs receive only a 2D paravirtualized framebuffer (virtio-gpu). Velo Workspaces resolves this trade-off by separating the agent execution environment from the model inference engine:

This guide covers both engines side by side. Pick one in Section 5 β€” everything downstream (VM setup, the vsock bridge, agent configuration) works identically either way, substituting the port your chosen engine listens on.

MLX Ollama
Default port 8080 11434
Model source huggingface.co/models?library=mlx-lm ollama.com/library
Best for Apple Silicon-native performance, the widest current selection of day-one MLX-quantized releases The simplest one-command setup and model management ( ollama pull ,ollama run )

*Note: Inside the VM, the agent's traffic is forwarded over a VirtIO-vsock channel to the AI Bridge on the macOS host, which relays it to the host's inference server (Ollama or MLX). A separate Caddy port forward lets an external LAN client reach the VM's optional web UI.

127.0.0.1:<PORT> inside the VM β€” 8080 for MLX, 11434 for Ollama. The local socat proxy routes this payload across vsock to the host. The Swift AI Bridge receives the connection and relays it to whichever engine you selected as the workspace's Host Provider.http://<VM_IP>:4096 over the standard hypervisor bridge.8081) to the guest's Web UI port ( 4096). Port Both engines use macOS Unified Memory dynamically. Because the OS, display compositor, and the model's KV cache share this pool, reserve at least 20–25% of total host RAM for operating overhead.

Model identifiers below are verified as of this writing β€” always confirm current availability and exact tags at huggingface.co/models?library=mlx-lm (MLX) or ollama.com/library (Ollama) before pulling, since libraries change.

Mac Unified RAM MLX (Hugging Face) Ollama ( ollama pull ... ) Quantization Use Case
16 GB mlx-community/Qwen2.5-Coder-7B-Instruct-4bit qwen2.5-coder:7b 4-bit Fast code completion, lightweight script generation, single-file edits.
24 GB / 32 GB mlx-community/Qwen2.5-Coder-32B-Instruct-4bit`` mlx-community/Mistral-Small-24B-Instruct-4bit qwen2.5-coder:32b`` mistral-small 4-bit Multi-file reasoning, refactoring, and debugging complex logic.
36 GB / 48 GB mlx-community/Qwen3.8-27B-4bit * qwen3.8:27b * 4-bit Advanced agentic tasks, architectural design, repository-wide indexing.
64 GB / 96 GB mlx-community/Llama-3.3-70B-Instruct-4bit llama3.3:70b 4-bit Deep reasoning, zero-shot full repository synthesis, complex planning.
128 GB+ mlx-community/Qwen3.8-2.4T-A95B-*bit deepseek-ai/DeepSeek-V3 deepseek-v3 * 1-bit to 4-bit Full-scale autonomous pipelines, heavy concurrent agent swarms.
  • These are very recent (2026) or very large releases β€” check the library link for the exact current tag/quantization before pulling; MLX and Ollama conversions can lag a new release by days to weeks.

Because the heavy LLM weights and KV caches stay in macOS unified memory, the Linux VM only needs enough resources to execute the code generated by the agent.

Important (Session Longevity): Long-running autonomous sessions gradually leak resources. Agents continuously generate temporary files, compile dependencies, bloat pip/ npm caches, and retain execution logs. Allocate extra memory buffers for long-lived environments to keep the Linux Out-Of-Memory (OOM) killer from terminating tasks.

Scenario vCPUs Memory Storage Primary Workloads & Rationale
Ephemeral / Light Automation 2 vCPUs 2 GB – 3 GB 15 GB – 20 GB CLI automation and simple scripts. Ideal for short-lived, disposable tasks.
Full-Stack Web Development 4 vCPUs 4 GB – 6 GB 30 GB – 40 GB Node.js, Django, SQLite, Vite. Accommodates build tools and background servers.
Long-Running Agent Sessions 4 – 6 vCPUs 8 GB – 12 GB 50 GB – 60 GB Continuous autonomous loops. Buffers memory against cached artifacts and logs.
System Programming & Docker 6 – 8 vCPUs 12 GB – 16 GB 60 GB – 80 GB Rust/Go/C++ compilation, Docker-in-VM services. Prevents compilation lockups.

Pick one engine. All steps in this section run in the macOS Terminal on the host.

Install the official Apple MLX language model package using Python (3.10+):

python3 -m venv ~/.mlx-env
source ~/.mlx-env/bin/activate

pip install --upgrade mlx-lm

Launch the server bound to loopback (127.0.0.1) on port 8080. It downloads the model from Hugging Face automatically on first run. mlx-community/Qwen2.5-Coder-7B-Instruct-4bit below is just an example β€” swap in whichever tag you picked for your RAM tier in Section 3:

mlx_lm.server \
  --model mlx-community/Qwen2.5-Coder-7B-Instruct-4bit \
  --host 127.0.0.1 \
  --port 8080

In a second macOS terminal, verify it's responding to OpenAI-compatible requests:

curl -s http://127.0.0.1:8080/v1/models | grep "id"

Install Ollama from ollama.com (or brew install ollama). qwen2.5-coder:7b below is just an example β€” pull whichever tag you picked for your RAM tier in Section 3 instead:

brew install ollama
ollama serve &          # or just launch the Ollama app β€” it runs this for you
ollama pull qwen2.5-coder:7b

Ollama listens on 127.0.0.1:11434 by default. Verify it's responding:

curl -s http://127.0.0.1:11434/v1/models | grep "id"

Example: AI Sandbox profile with AI Bridge enabled and Host Provider set to MLX. Pick Ollama here instead if that's what you started in Section 5.

All steps in this section run in the Ubuntu Linux Terminal inside the VM. Throughout, <PORT> is 8080 for MLX or 11434 for Ollama β€” whichever you picked in Section 5.

Rather than typing this by hand, open the running workspace's AI Bridge tab in Velo Workspaces β€” it shows your exact port already filled in, with a Copy button on each command block. Run step 1, then either step 2 (forwards for the life of this terminal session β€” simplest, good for a quick test) or step 3 (installs it as a systemd service that survives reboots β€” better for anything you'll come back to):

sudo apt-get install -y socat

socat -d -d TCP-LISTEN:<PORT>,fork,reuseaddr,bind=127.0.0.1,nodelay VSOCK-CONNECT:2:<PORT>

β€” or, to keep it running across reboots β€”

sudo tee /etc/systemd/system/velo-ai-bridge.service >/dev/null <<'EOF'
[Unit]
Description=Velo Workspaces AI Bridge (127.0.0.1:<PORT> to the host over the high speed channel)
After=network.target

[Service]
ExecStart=/usr/bin/socat TCP-LISTEN:<PORT>,fork,reuseaddr,bind=127.0.0.1,nodelay VSOCK-CONNECT:2:<PORT>
Restart=always
RestartSec=2

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable velo-ai-bridge
sudo systemctl restart velo-ai-bridge

Then, either way, verify guest-to-host connectivity across the vsock boundary:

curl -sS http://127.0.0.1:<PORT>/v1/models

If that returns your model's info, the bridge is live β€” every agent below points at http://127.0.0.1:<PORT>/v1, and each one configures that itself in the next section, so there's no separate global environment-variable setup needed here.

OpenCode provides both an automated CLI agent and an interactive web workspace.

   sudo apt install -y curl git build-essential
   curl -fsSL https://opencode.ai/install | bash
   source ~/.bashrc

~/.config/opencode/opencode.json:

   mkdir -p ~/.config/opencode
   nano ~/.config/opencode/opencode.json

Paste this, substituting <PORT> and the model name for your chosen engine (from Section 3):

   {
     "$schema": "https://opencode.ai/config.json",
     "provider": {
       "local": {
         "npm": "@ai-sdk/openai-compatible",
         "name": "Local Server",
         "options": {
           "baseURL": "http://127.0.0.1:<PORT>/v1"
         },
         "models": {
           "<model-name>": {
             "name": "<Display Name>"
           }
         }
       }
     },
     "model": "local/<model-name>"
   }

--auto auto-approves tool execution inside the sandbox:

   opencode run --auto "Write a python script to benchmark disk I/O, execute it, and print the results."
opencode

Inside the TUI, type /connect, select Local Server, and when prompted for an API key, type anything (e.g. local) β€” the local server doesn't check it.

0.0.0.0 so it's reachable across the hypervisor network:

   opencode web --port 4096 --hostname 0.0.0.0

From your Mac's browser: http://<VM_IP>:4096.

Accessing the Web UI from another PC on your LAN: external machines can't route directly into the VM's private subnet, so forward a port on the host. On the macOS host:

   brew install caddy
   caddy reverse-proxy --from :8081 --to <VM_IP>:4096

Any machine on the LAN can then navigate to http://<HOST_IP>:8081.

Open Interpreter provides a direct terminal agent loop designed for code execution.

   pip install open-interpreter

-y auto-approves code execution without a confirmation prompt each time:

   interpreter \
     --api_base http://127.0.0.1:<PORT>/v1 \
     --model <model-name> \
     --api_key local \
     -y

Aider is designed specifically for Git-integrated pair programming and repository modifications. It reads the endpoint from environment variables rather than dedicated CLI flags, and needs the openai/ prefix on the model name so it routes through its OpenAI-compatible path:

   python3 -m pip install aider-chat
cd /path/to/project
   export OPENAI_API_BASE=http://127.0.0.1:<PORT>/v1
   export OPENAI_API_KEY=local
   aider --model openai/<model-name>

Goose is an extensible open-source autonomous agent developed by Block.

   curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash
   export PATH="$HOME/.local/bin:$PATH"
goose configure
bash
   goose run --text "Audit this directory, find security misconfigurations in JSON files, and correct them."
── more in #ai-agents 4 stories Β· sorted by recency
── more on @velo workspaces 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/zero-tax-virtualizat…] indexed:0 read:8min 2026-09-16 Β· β€”