vm0-computer

VM0 Computer API for secure sandbox. Use when user mentions "VM0 Computer", "secure sandbox", "browser sandbox", or asks about computer use.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "vm0-computer" with this command: npx skills add vm0-ai/vm0-skills/vm0-ai-vm0-skills-vm0-computer

VM0 Computer Connector

Access the user's local filesystem from a VM0 sandbox over a secure WebDAV tunnel established by the VM0 Computer Connector.


When to Use

Use this skill when you need to:

  • List files and directories on the user's local machine
  • Read files from the user's computer into the sandbox
  • Write or update files on the user's local machine
  • Transfer outputs back to the user's local filesystem

How to Use

Setup

Note on Proxy Persistence: VM0 sandboxes are stateless environments. The proxy process and /tmp/proxy.mjs file will be cleared between sessions. This is expected behavior - you'll need to reinstall ws and recreate the proxy each time you start a new sandbox session.

Write the proxy script to /tmp/proxy.mjs:

import { WebSocket, WebSocketServer } from "ws";
import http from "http";
import https from "https";

const TOKEN = process.env.COMPUTER_CONNECTOR_BRIDGE_TOKEN;
const DOMAIN = process.env.COMPUTER_CONNECTOR_DOMAIN;

// Chrome CDP WebSocket proxy: ws://127.0.0.1:9222 → wss://chrome.{DOMAIN}
const wss = new WebSocketServer({ host: "127.0.0.1", port: 9222 });
wss.on("connection", (local) => {
  const remote = new WebSocket(`wss://chrome.${DOMAIN}`, {
    headers: { "x-vm0-token": TOKEN },
  });
  local.on("message", (msg) => remote.send(msg));
  remote.on("message", (msg) => local.send(msg));
  local.on("close", () => remote.close());
  remote.on("close", () => local.close());
});

// WebDAV HTTP proxy: http://127.0.0.1:8080 → https://webdav.{DOMAIN}
http.createServer((req, res) => {
  const upstream = https.request(
    `https://webdav.${DOMAIN}${req.url}`,
    { method: req.method, headers: { ...req.headers, "x-vm0-token": TOKEN, host: `webdav.${DOMAIN}` } },
    (proxyRes) => { res.writeHead(proxyRes.statusCode, proxyRes.headers); proxyRes.pipe(res); }
  );
  req.pipe(upstream);
}).listen(8080, "127.0.0.1");

console.log("WebDAV proxy: http://127.0.0.1:8080");
console.log("CDP proxy:    ws://127.0.0.1:9222");

Run

cd /tmp && npm install ws && node /tmp/proxy.mjs &

The proxy runs in the background. Tools can now connect to http://127.0.0.1:8080 (WebDAV) and ws://127.0.0.1:9222 (Chrome CDP) without any additional headers.

1. List Files in a Directory

Use PROPFIND to list the contents of a directory (depth 1):

curl -s -X PROPFIND "http://127.0.0.1:8080"

List a subdirectory:

curl -s -X PROPFIND "http://127.0.0.1:8080/reports/" --header "Depth: 1"

2. Download a File from the Local Machine

curl -s -o /tmp/myfile.pdf "http://127.0.0.1:8080/myfile.pdf"

Read a text file directly:

curl -s "http://127.0.0.1:8080/notes.txt"

3. Upload a File to the Local Machine

Write a local sandbox file to remote:

curl -s -X PUT "http://127.0.0.1:8080/output-report.txt" --header "Content-Type: text/plain" --data-binary @/home/user/output-report.txt

Upload from stdin (inline content):

curl -s -X PUT "http://127.0.0.1:8080/result.json" --header "Content-Type: application/json" -d '{"status": "done"}'

4. Delete a File

curl -s -X DELETE "http://127.0.0.1:8080/old-file.txt"

5. Create a Directory

curl -s -X MKCOL "http://127.0.0.1:8080/new-folder/"

6. Move (Rename) a File

curl -s -X MOVE "http://127.0.0.1:8080/old-name.txt" --header "Destination: http://127.0.0.1:8080/new-name.txt"

Move to a subdirectory:

curl -s -X MOVE "http://127.0.0.1:8080/report.pdf" --header "Destination: http://127.0.0.1:8080/archive/report.pdf"

7. Search File Contents

WebDAV does not support full-text search natively. Use PROPFIND with Depth: infinity to list all files recursively, then download and search:

# List all files recursively
curl -s -X PROPFIND "http://127.0.0.1:8080/" --header "Depth: infinity" | grep -o '<D:href>[^<]*</D:href>' | sed 's/<[^>]*>//g'

Search for a keyword across all text files:

for f in $(curl -s -X PROPFIND "http://127.0.0.1:8080/" --header "Depth: infinity" | grep -o '<D:href>[^<]*</D:href>' | sed 's/<[^>]*>//g' | grep '\.txt$'); do
  content=$(curl -s "http://127.0.0.1:8080${f}")
  echo "$content" | grep -q "keyword" && echo "Found in: $f"
done

Troubleshooting

SSL Certificate Error (ERR_TLS_CERT_ALTNAME_INVALID)

Issue: The first connection attempt may fail with ERR_TLS_CERT_ALTNAME_INVALID or similar SSL certificate errors.

Cause: The ngrok tunnel needs a few minutes to provision and propagate SSL certificates after the Computer Connector starts.

Solution:

  1. Wait 2-3 minutes after starting the Computer Connector for SSL certificates to be fully provisioned
  2. The proxy will automatically work once certificates are ready - no code changes needed
  3. Test with a simple curl command: curl -s "http://127.0.0.1:8080/"

Note: Do NOT add rejectUnauthorized: false to the proxy code as a workaround. This weakens security and is unnecessary - simply wait for proper certificate provisioning.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

hackernews

No summary provided by upstream source.

Repository SourceNeeds Review
958-vm0-ai
General

google-sheets

No summary provided by upstream source.

Repository SourceNeeds Review
247-vm0-ai
General

apify

No summary provided by upstream source.

Repository SourceNeeds Review
215-vm0-ai
General

serpapi

No summary provided by upstream source.

Repository SourceNeeds Review
170-vm0-ai