@magpiecloud/mags
v1.9.0
Published
Mags CLI & SDK - Execute commands and scripts on Mags Sandboxes
Maintainers
Readme
Mags - Instant VM Execution
Execute scripts instantly on Magpie's microVM infrastructure. VMs boot in <100ms from a warm pool, giving you instant access to isolated compute environments.
What is Mags?
Mags is a CLI and SDK for running scripts on ephemeral microVMs. Each execution gets its own isolated VM that:
- Boots in ~300ms (from warm pool)
- Supports optional S3-backed persistent workspaces (with
-pflag) - Syncs /root directory automatically when persistence is enabled
- Can expose public URLs for web services
- Provides SSH access through secure proxy
- Auto-sleeps when idle and wakes on request
Installation
npm install -g @magpiecloud/magsAuthentication
Interactive Login (Recommended)
mags loginThis opens your browser to the Magpie dashboard where you can create an API token. Paste the token when prompted, and it will be saved to ~/.mags/config.json for all future commands.
Auth Commands
mags login # Authenticate with Magpie
mags whoami # Check current authentication status
mags logout # Remove saved credentialsEnvironment Variable (Alternative)
export MAGS_API_TOKEN="your-token-here"Quick Start
Run a simple command
mags run 'echo Hello World'Create a sandbox
# Create a new VM (local disk only)
mags new myproject
# Create with S3 data persistence
mags new myproject -p
# SSH into it
mags ssh myprojectRun with a persistent workspace
Workspaces persist data between runs using S3 sync:
# First run - install dependencies
mags run -w myproject 'apk add python3 py3-pip && pip install requests'
# Second run - dependencies are still there
mags run -w myproject 'python3 -c "import requests; print(requests.__version__)"'Deploy a web service with public URL
mags run -p --url 'python3 -m http.server 8080'
# Returns: https://abc123.apps.magpiecloud.comCLI Reference
Commands
| Command | Description |
|---------|-------------|
| mags login | Authenticate with Magpie (saves token locally) |
| mags logout | Remove saved credentials |
| mags whoami | Show current authentication status |
| mags new <workspace> [-p] | Create a VM sandbox (add -p for S3 persistence) |
| mags run [options] <script> | Execute a script on a microVM |
| mags ssh <workspace> | Open interactive SSH session to a VM |
| mags status <job-id> | Get job status |
| mags logs <job-id> | Get job logs |
| mags list | List recent jobs |
| mags url <job-id> [port] | Enable URL access for a job |
| mags stop <job-id> | Stop a running job |
| mags set <name\|id> [options] | Update VM settings (--no-sleep, --sleep) |
Run Options
| Flag | Description | Default |
|------|-------------|---------|
| -w, --workspace <id> | Use persistent workspace (S3 sync) | auto-generated |
| -p, --persistent | Keep VM alive after script completes | false |
| --url | Enable public URL access (requires -p) | false |
| --port <port> | Port to expose for URL access | 8080 |
| --no-sleep | Keep VM always running, never auto-sleep (requires -p) | false |
| --startup-command <cmd> | Command to run when VM wakes from sleep | none |
SSH Access
Connect to any running VM via SSH:
mags ssh myprojectSSH Features
- Secure proxy: Connect via
api.magpiecloud.com:PORT(agent IPs are hidden) - PTY support: Full interactive terminal with colors and editors
- Key-based auth: Automatic SSH key management
- Hostname: VMs use
mags-vmas hostname
SSH Session Example
$ mags ssh myproject
Connecting to api.magpiecloud.com:40006...
(Use Ctrl+D or 'exit' to disconnect)
mags-vm:~# ls
index.html test.txt
mags-vm:~# python3 --version
Python 3.11.6
mags-vm:~# exitWorkspaces & Persistence
How It Works
When you use a workspace, Mags:
- Mounts a JuiceFS filesystem backed by S3
- Creates an OverlayFS to capture all filesystem changes
- Syncs your
/rootdirectory to S3 every 30 seconds - Restores your files when you reconnect
What Gets Persisted
/root- Your home directory (synced every 30 seconds)/jfs- Direct JuiceFS mount (instant S3 sync)- Installed packages and dependencies
- Configuration files and dotfiles
Sync Behavior
| Event | Behavior | |-------|----------| | While running | Auto-sync every 30 seconds | | On stop | Full sync before VM terminates | | On wake | Previous state restored instantly |
Usage Examples
Basic Execution
# Simple command
mags run 'echo Hello World'
# Multi-line script
mags run 'apk add curl && curl -s https://api.github.com/users/octocat | head -5'
# With environment info
mags run 'uname -a && cat /etc/os-release'Persistent Workspaces
# Create a workspace with dependencies
mags run -w ml-project 'apk add python3 py3-pip && pip install numpy pandas scikit-learn'
# Run scripts using the workspace
mags run -w ml-project 'python3 train.py'
# All files in /root are persisted
mags run -w ml-project 'ls -la /root'Web Services
# Simple static server
mags run -p --url 'python3 -m http.server 8080'
# Node.js app
mags run -w myapp -p --url --port 3000 'npm install && npm start'
# Flask app
mags run -w flask-app -p --url 'pip install flask && python app.py'
# Custom startup command for auto-wake
mags run -w api -p --url --startup-command 'python server.py' 'pip install -r requirements.txt && python server.py'Always-On VMs
By default, persistent VMs auto-sleep after 10 minutes of inactivity and wake on the next request. Use --no-sleep to keep a VM running 24/7:
# Always-on API server (never auto-sleeps)
mags run -w my-api -p --no-sleep --url --port 3000 'npm start'
# Always-on background worker
mags run -w worker -p --no-sleep 'python worker.py'If an always-on VM's host becomes unhealthy, the orchestrator automatically re-provisions it on a healthy agent within ~60 seconds.
Interactive Development
# Create a dev environment (local disk)
mags new dev-env
# SSH in and work
mags ssh dev-env
# Inside the VM:
mags-vm:~# apk add git nodejs npm
mags-vm:~# git clone https://github.com/user/repo
mags-vm:~# cd repo && npm install
mags-vm:~# npm run devNode.js SDK
For programmatic access, use the SDK:
const Mags = require('@magpiecloud/mags');
const mags = new Mags({
apiToken: process.env.MAGS_API_TOKEN
});SDK Methods
Jobs
| Method | Description |
|--------|-------------|
| run(script, options) | Submit a job. Options: name, workspaceId, baseWorkspaceId, persistent, noSleep, ephemeral, startupCommand, environment, fileIds, diskGb |
| runAndWait(script, options) | Submit and block until done. Extra options: timeout, pollInterval |
| new(name, options) | Create a VM sandbox and wait until running. Options: persistent, baseWorkspaceId, diskGb, timeout |
| status(requestId) | Get job status |
| logs(requestId) | Get job logs |
| list({page, pageSize}) | List recent jobs (paginated) |
| findJob(nameOrId) | Find job by name, workspace ID, or request ID |
| updateJob(requestId, {startupCommand, noSleep}) | Update job settings |
| stop(nameOrId) | Stop a job (accepts name, workspace ID, or request ID) |
| exec(nameOrId, command, {timeout}) | Execute a command on a running/sleeping VM via SSH |
| sync(requestId) | Sync workspace to S3 without stopping |
| resize(workspace, diskGb) | Resize workspace disk (stops VM, creates new one) |
| usage({windowDays}) | Get aggregated usage summary |
URL & Access
| Method | Description |
|--------|-------------|
| enableAccess(requestId, port) | Enable SSH (port 22) or HTTP access (default 8080) |
| url(nameOrId, port) | Enable public URL and return the full URL |
| urlAliasCreate(subdomain, workspaceId, domain) | Create a stable URL alias for a workspace |
| urlAliasList() | List all URL aliases |
| urlAliasDelete(subdomain) | Delete a URL alias |
Workspaces
| Method | Description |
|--------|-------------|
| listWorkspaces() | List all workspaces |
| deleteWorkspace(workspaceId) | Delete a workspace and its S3 data |
Files
| Method | Description |
|--------|-------------|
| uploadFiles(filePaths) | Upload local files, returns array of file IDs |
Cron Jobs
| Method | Description |
|--------|-------------|
| cronCreate({name, cronExpression, script, workspaceId, environment, persistent}) | Create a scheduled job |
| cronList() | List all cron jobs |
| cronGet(id) | Get a cron job |
| cronUpdate(id, updates) | Update a cron job |
| cronDelete(id) | Delete a cron job |
SDK Examples
// Run and wait for completion
const result = await mags.runAndWait('echo Hello World');
console.log(result.logs);
// Create a sandbox (local disk)
await mags.new('myproject');
// Create a sandbox with S3 persistence
await mags.new('myproject', { persistent: true });
// Execute command on existing VM
const { output } = await mags.exec('myproject', 'ls -la /root');
console.log(output);
// Run with workspace and options
const job = await mags.run('python script.py', {
workspaceId: 'myproject',
persistent: true,
diskGb: 5,
startupCommand: 'python server.py'
});
// Always-on VM (never auto-sleeps)
await mags.run('node server.js', {
workspaceId: 'my-api',
persistent: true,
noSleep: true
});
// Enable public URL
const { url } = await mags.url('my-api', 3000);
console.log(url); // https://abc123.apps.magpiecloud.com
// Create stable URL alias
await mags.urlAliasCreate('my-app', 'my-api');
// Resize workspace disk
await mags.resize('myproject', 10); // 10GB
// Stop a job by name
await mags.stop('myproject');API Endpoints
For direct API access:
| Endpoint | Method | Description |
|----------|--------|-------------|
| /api/v1/mags-jobs | POST | Submit a new job |
| /api/v1/mags-jobs | GET | List jobs (paginated) |
| /api/v1/mags-jobs/{id}/status | GET | Get job status |
| /api/v1/mags-jobs/{id}/logs | GET | Get job logs |
| /api/v1/mags-jobs/{id}/access | POST | Enable SSH/URL access |
| /api/v1/mags-jobs/{id} | PATCH | Update job settings |
Example API Request
curl -X POST https://api.magpiecloud.com/api/v1/mags-jobs \
-H "Authorization: Bearer $MAGS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"script": "echo Hello World",
"type": "inline",
"workspace_id": "myproject",
"persistent": true,
"no_sleep": true
}'Job Status Values
| Status | Description |
|--------|-------------|
| pending | Job queued, waiting for VM |
| running | Script executing |
| sleeping | Persistent VM idle (wakes on request) |
| completed | Script finished successfully |
| error | Script failed |
VM Environment
Each VM runs Alpine Linux with hostname mags-vm and includes:
/root- Persistent home directory (synced to S3)/jfs- Direct JuiceFS mount- Common tools: curl, wget, git, python3, nodejs
- Package manager:
apk add <package>
Installing Packages
# Python packages
mags run 'apk add python3 py3-pip && pip install requests flask pandas'
# Node.js packages
mags run 'apk add nodejs npm && npm install -g express'
# System packages
mags run 'apk add ffmpeg imagemagick'Performance
| Metric | Value | |--------|-------| | Warm start | ~300ms | | Cold start | ~4 seconds | | Script overhead | ~50ms | | Workspace sync | Every 30 seconds |
Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| MAGS_API_TOKEN | Your API token (required) | - |
| MAGS_API_URL | API endpoint | https://api.magpiecloud.com |
Troubleshooting
"API token required"
Set your API token:
mags login
# or
export MAGS_API_TOKEN="your-token-here""Job timed out"
Increase the timeout or check if your script is hanging:
mags run --timeout 600 'long-running-script.sh'"Workspace not found"
Workspace IDs are case-sensitive. Check with:
mags listURL not accessible
Make sure you're using both -p (persistent) and --url flags, and your app is listening on the correct port:
mags run -p --url --port 3000 'node server.js'SSH connection issues
SSH connects through our proxy. If you have issues:
- Ensure the job is running:
mags status <id> - Try reconnecting:
mags ssh <workspace>
Support
- Documentation: https://mags.run
- API Reference: https://mags.run/api.html
- Dashboard: https://mags.run/tokens.html
License
MIT
