Blaxel logo

Blaxel

0

Blaxel agent skills for building and deploying AI workloads. Includes the Blaxel SDK skill for creating cloud sandboxes and deploying agents, and the Blaxel CLI skill for managing Blaxel resources from the command line.

2 skills

blaxel-cli

Manage Blaxel resources from the command line using the bl CLI. Deploy agents, sandboxes, jobs, and MCP servers. Also installs the Blaxel CLI if not present.

# Blaxel CLI A CLI to manage Blaxel cloud resources from the command line: agents, sandboxes, jobs, MCP servers, drives, and more. ## Prerequisites The `bl` command must be available on PATH. To check: ```bash bl version ``` If not installed, install via the official install script: ```bash curl -fsSL https://raw.githubusercontent.com/blaxel-ai/toolkit/main/install.sh | sh ``` Or via Homebrew: ```bash brew tap blaxel-ai/blaxel && brew install blaxel ``` After installation, log in to your workspace: ```bash bl login my-workspace ``` ## Global Flags All commands support these flags: | Flag | Description | | ------------------------ | ---------------------------------------- | | `-o, --output <format>` | Output format: pretty, yaml, json, table | | `-w, --workspace <name>` | Override workspace for this command | | `-v, --verbose` | Enable verbose output | | `-u, --utc` | Enable UTC timezone | | `--skip-version-warning` | Skip version warning | ## Non-Interactive Mode For commands that prompt for input (confirmations, selections), add `-y` or `--yes` to auto-confirm. This is required when running in non-interactive / no-TTY environments (scripts, CI, agents). ## Available Commands ``` bl apply # Apply configuration changes to resources declaratively using YAML files. bl chat # Start an interactive chat session with a deployed agent. bl connect # Open an interactive terminal session to a sandbox bl delete # Delete Blaxel resources from your workspace. bl deploy # Deploy your Blaxel project to the cloud. bl get # Retrieve information about Blaxel resources in your workspace. bl login # Authenticate with Blaxel to access your workspace. bl logout # Remove stored credentials for a workspace. bl logs # View logs for Blaxel resources. bl new # Create a new Blaxel resource from templates. bl push # Build and push a container image to the Blaxel registry without creating a deployment. bl run # Execute a Blaxel resource with custom input data. bl serve # Start a local development server for your Blaxel project. bl share # Share Blaxel resources with other workspaces in your account. bl token # Retrieve the authentication token for the specified workspace. bl unshare # Remove shared Blaxel resources from other workspaces. bl upgrade # Upgrade the Blaxel CLI to the latest version. bl version # Print the version number bl workspaces # List and manage Blaxel workspaces. ``` ## Reference Documentation - [apply](references/apply.md) - Apply configuration changes to resources declaratively using YAML files. - [chat](references/chat.md) - Start an interactive chat session with a deployed agent. - [connect](references/connect.md) - Open an interactive terminal session to a sandbox - [delete](references/delete.md) - Delete Blaxel resources from your workspace. - [deploy](references/deploy.md) - Deploy your Blaxel project to the cloud. - [get](references/get.md) - Retrieve information about Blaxel resources in your workspace. - [login](references/login.md) - Authenticate with Blaxel to access your workspace. - [logout](references/logout.md) - Remove stored credentials for a workspace. - [logs](references/logs.md) - View logs for Blaxel resources. - [new](references/new.md) - Create a new Blaxel resource from templates. - [push](references/push.md) - Build and push a container image to the Blaxel registry without creating a deployment. - [run](references/run.md) - Execute a Blaxel resource with custom input data. - [serve](references/serve.md) - Start a local development server for your Blaxel project. - [share](references/share.md) - Share Blaxel resources with other workspaces in your account. - [token](references/token.md) - Retrieve the authentication token for the specified workspace. - [unshare](references/unshare.md) - Remove shared Blaxel resources from other workspaces. - [upgrade](references/upgrade.md) - Upgrade the Blaxel CLI to the latest version. - [version](references/version.md) - Print the version number - [workspaces](references/workspaces.md) - List and manage Blaxel workspaces. ## Discovering Options To see available subcommands and flags, run `--help` on any command: ```bash bl --help bl deploy --help bl get --help bl get agents --help ``` ## Common Workflows ### Create a sandbox, run a command, and get its logs ```bash # 1. Create a sandbox with bl apply bl apply -f - <<EOF apiVersion: blaxel.ai/v1alpha1 kind: Sandbox metadata: name: my-sandbox spec: runtime: image: blaxel/base-image:latest memory: 2048 lifecycle: expirationPolicies: - type: ttl-idle value: 1h # Delete after 1 hour of inactivity. Units: h, d, w action: delete EOF # 2. Retrieve sandbox configuration bl get sandbox my-sandbox # 3. Execute a command in the sandbox and get stdout of the command bl run sandbox my-sandbox --path /process --data '{"command": "echo hello world", "name": "my-cmd", "waitForCompletion": true}' # 4. Retrieve the logs for that command in case stdout was not sufficient bl logs sandbox my-sandbox my-cmd ``` ### Run a complex command in a sandbox (agent guideline) `bl run sandbox ... --path /process --data '<json>'` requires the JSON payload to survive **shell quoting**. As soon as the command embeds nested quotes, backslashes, multiple lines, or interpreters like `sh -lc` / `python3 -c`, inline `--data` becomes brittle and the API rejects the request with `400 Bad Request: invalid character ... in string escape code`. **Decision rule for an agent:** 1. Command has **no single quotes, no backslashes, no newlines** → use `--data '{"command": "...", "waitForCompletion": true}'` directly. 2. Anything more complex (nested quotes, escapes, multiline, scripts) → **write the JSON payload to a file** with your Write/file-creation tool (this bypasses the shell entirely), then run with `--file`. ```bash # Step 1 — agent writes /tmp/process.json with content like: # { # "command": "sh -lc 'python3 -c \"print(\\\"hello\\\")\"'", # "name": "cve-check", # "waitForCompletion": true # } # # Step 2 — execute it bl run sandbox my-sandbox --path /process --file /tmp/process.json ``` ### Deploy an agent ```bash bl new agent my-agent cd my-agent bl serve --hotreload # Test locally bl deploy # Deploy to cloud bl chat my-agent # Chat with it ``` ### Manage sandboxes ```bash bl get sandboxes # List all bl get sandbox my-sandbox --watch # Watch status bl connect sandbox my-sandbox # Interactive terminal bl logs sandbox my-sandbox --follow # Stream logs bl delete sandbox my-sandbox # Clean up ``` ### Multi-workspace deployment ```bash bl workspaces dev # Switch to dev bl deploy # Deploy to dev bl workspaces prod # Switch to prod bl deploy # Deploy to prod ```

blaxel-sdk

Use when creating cloud sandboxes (microVMs) to run code, start dev servers, and generate live preview URLs. Also covers deploying AI agents, MCP servers, batch jobs, and Agent Drives (shared filesystems) on Blaxel's serverless infrastructure. Reach for this skill when you need isolated compute environments, real-time app previews, shared file storage across sandboxes, or to deploy agentic workloads.

# Blaxel Skill Reference ## What is Blaxel Blaxel (https://blaxel.ai) is a cloud platform that gives AI agents their own compute environments. Its flagship product is perpetual sandboxes: instant-launching microVMs that resume from standby in under 25ms and scale to zero after a few seconds of inactivity. You use Blaxel primarily to: - Spin up a sandbox, install dependencies, run a dev server, and expose a live preview URL - Build and deploy sandbox templates (custom Docker images) for reusable environments - Deploy AI agents, MCP servers, and batch jobs as serverless endpoints SDKs: TypeScript (`@blaxel/core`) and Python (`blaxel`) CLI: `bl` (install from https://docs.blaxel.ai/cli-reference/introduction) Docs: https://docs.blaxel.ai ## Authentication The SDK authenticates using these sources in priority order: 1. Blaxel CLI, when logged in 2. Environment variables in `.env` file (`BL_WORKSPACE`, `BL_API_KEY`) 3. System environment variables 4. Blaxel configuration file (`~/.blaxel/config.yaml`) Log in locally (recommended for development): ```shell bl login YOUR-WORKSPACE ``` Or set environment variables (for remote/CI environments): ```shell export BL_WORKSPACE=your-workspace export BL_API_KEY=your-api-key ``` When running on Blaxel itself, authentication is automatic. ## Sandbox workflow (primary use case) This is the most common workflow: create a sandbox, run commands in it, and get a preview URL. ### Step 1: Create a sandbox Use a public image from the Blaxel Hub (https://github.com/blaxel-ai/sandbox/tree/main/hub): - `blaxel/base-image:latest` — minimal Linux - `blaxel/node:latest` — Node.js - `blaxel/nextjs:latest` — Next.js - `blaxel/vite:latest` — Vite - `blaxel/expo:latest` — Expo (React Native) - `blaxel/py-app:latest` — Python Or use a custom template image you deployed yourself. Declare the ports you need at creation time. Ports cannot be added after creation. Ports 80, 443, and 8080 are reserved. ```typescript import { SandboxInstance } from "@blaxel/core"; const sandbox = await SandboxInstance.createIfNotExists({ name: "my-sandbox", image: "blaxel/base-image:latest", memory: 4096, ports: [{ target: 3000, protocol: "HTTP" }], }); ``` ```python from blaxel.core import SandboxInstance sandbox = await SandboxInstance.create_if_not_exists({ "name": "my-sandbox", "image": "blaxel/base-image:latest", "memory": 4096, "ports": [{"target": 3000, "protocol": "HTTP"}], }) ``` Use `createIfNotExists` / `create_if_not_exists` to reuse an existing sandbox by name or create a new one. ### Step 2: Write files and run commands ```typescript // Write files await sandbox.fs.write("/app/package.json", JSON.stringify({ name: "my-app", scripts: { dev: "astro dev --host 0.0.0.0 --port 3000" }, dependencies: { "astro": "latest" } })); // Or write multiple files at once await sandbox.fs.writeTree([ { path: "src/pages/index.astro", content: "<h1>Hello</h1>" }, { path: "astro.config.mjs", content: "import { defineConfig } from 'astro/config';\nexport default defineConfig({});" }, ], "/app"); // Execute a command and wait for it to finish const install = await sandbox.process.exec({ name: "install", command: "npm install", workingDir: "/app", waitForCompletion: true, timeout: 60000, }); // Start a long-running dev server (don't wait for completion) const devServer = await sandbox.process.exec({ name: "dev-server", command: "npm run dev", workingDir: "/app", waitForPorts: [3000], // returns once port 3000 is open }); ``` ```python await sandbox.fs.write("/app/package.json", '{"name":"my-app","scripts":{"dev":"astro dev --host 0.0.0.0 --port 3000"},"dependencies":{"astro":"latest"}}') await sandbox.fs.write_tree([ {"path": "src/pages/index.astro", "content": "<h1>Hello</h1>"}, {"path": "astro.config.mjs", "content": "import { defineConfig } from 'astro/config';\nexport default defineConfig({});"}, ], "/app") install = await sandbox.process.exec({ "name": "install", "command": "npm install", "working_dir": "/app", "wait_for_completion": True, "timeout": 60000, }) dev_server = await sandbox.process.exec({ "name": "dev-server", "command": "npm run dev", "working_dir": "/app", "wait_for_ports": [3000], }) ``` IMPORTANT: Dev servers must bind to `0.0.0.0` (not `localhost`) to be reachable through preview URLs. Use `--host 0.0.0.0` or the `HOST` env variable. ### Step 3: Create a preview URL ```typescript const preview = await sandbox.previews.createIfNotExists({ metadata: { name: "app-preview" }, spec: { port: 3000, public: true }, }); const url = preview.spec?.url; // url => https://xxxx.us-pdx-1.preview.bl.run ``` ```python preview = await sandbox.previews.create_if_not_exists({ "metadata": {"name": "app-preview"}, "spec": {"port": 3000, "public": True}, }) url = preview.spec.url ``` For private previews, set `public: false` and create a token: ```typescript const preview = await sandbox.previews.createIfNotExists({ metadata: { name: "private-preview" }, spec: { port: 3000, public: false }, }); const token = await preview.tokens.create(new Date(Date.now() + 10 * 60 * 1000)); // Access: preview.spec?.url + "?bl_preview_token=" + token.value ``` ### Step 4: Manage the sandbox ```typescript // Reconnect to an existing sandbox const sandbox = await SandboxInstance.get("my-sandbox"); // List files const { subdirectories, files } = await sandbox.fs.ls("/app"); // Read a file const content = await sandbox.fs.read("/app/src/pages/index.astro"); // Get process info / logs const proc = await sandbox.process.get("dev-server"); const logs = proc.logs; // available if waitForCompletion was true // Kill a process await sandbox.process.kill("dev-server"); // Delete the sandbox (all data is erased) await sandbox.delete(); ``` ```python sandbox = await SandboxInstance.get("my-sandbox") result = await sandbox.fs.ls("/app") content = await sandbox.fs.read("/app/src/pages/index.astro") proc = await sandbox.process.get("dev-server") # proc.logs available if wait_for_completion was True await sandbox.process.kill("dev-server") await sandbox.delete() ``` ## Sandbox templates (custom images) When you need a reusable environment (e.g. an Astro project with all deps pre-installed), create a template: ```shell bl new sandbox my-astro-template cd my-astro-template ``` This creates: `blaxel.toml`, `Dockerfile`, `entrypoint.sh`, `Makefile`. Customize the Dockerfile. Always include the sandbox-api binary: ```dockerfile FROM node:22-alpine WORKDIR /app COPY --from=ghcr.io/blaxel-ai/sandbox:latest /sandbox-api /usr/local/bin/sandbox-api RUN npm install -g astro COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] ``` The entrypoint.sh must start the sandbox-api: ```bash #!/bin/sh /usr/local/bin/sandbox-api & while ! nc -z 127.0.0.1 8080; do sleep 0.1; done echo "Sandbox API ready" # Optionally start a process via the sandbox API: # curl http://127.0.0.1:8080/process -X POST -d '{"workingDir":"/app","command":"npm run dev","waitForCompletion":false}' -H "Content-Type: application/json" wait ``` Deploy the template: ```shell bl deploy ``` Then retrieve the IMAGE_ID and use it to create sandboxes: ```shell bl get sandboxes my-astro-template -ojson | jq -r '.[0].spec.runtime.image' ``` ```typescript const sandbox = await SandboxInstance.createIfNotExists({ name: "project-sandbox", image: "IMAGE_ID", memory: 4096, ports: [{ target: 3000, protocol: "HTTP" }], }); ``` ## Tutorials and Examples ### Sandboxes Astro: https://docs.blaxel.ai/Tutorials/Astro Expo: https://docs.blaxel.ai/Tutorials/Expo Next.js: https://docs.blaxel.ai/Tutorials/Nextjs ### Agents Overview: https://docs.blaxel.ai/Tutorials/Agents-Overview ## Core CLI commands For CLI commands that may prompt for input (like confirmations), add `-y` to auto-confirm when running in non-interactive / no-TTY environments (e.g. scripts, CI, agents). | Command | Purpose | |---------|---------| | `bl login` | Authenticate to workspace | | `bl new sandbox\|agent\|job\|mcp NAME` | Initialize new resource from template | | `bl deploy` | Build and deploy resource to Blaxel | | `bl deploy -d DIR` | Deploy from a specific directory | | `bl serve` | Run resource locally for testing | | `bl serve --hotreload` | Run locally with hot reload | | `bl get sandboxes\|agents\|jobs\|functions` | List resources | | `bl get sandbox NAME --watch` | Watch a sandbox deployment status | | `bl delete sandbox\|agent\|job\|function NAME` | Remove resource | | `bl connect sandbox NAME` | Open interactive terminal in sandbox | | `bl chat AGENT-NAME` | Interactive chat with deployed agent | | `bl run job NAME --data JSON` | Execute a deployed batch job | ## blaxel.toml structure ```toml name = "my-resource" type = "sandbox" # sandbox, agent, function, job, volume-template [env] NODE_ENV = "development" # NOT for secrets — use Variables-and-secrets [runtime] memory = 4096 # MB generation = "mk3" # timeout = 900 # seconds (agents max 900, jobs max 86400) # Ports (sandbox only) [[runtime.ports]] name = "dev-server" target = 3000 protocol = "tcp" ``` ## Important gotchas - Ports must be declared at sandbox creation time — they cannot be added later - Ports 80, 443, 8080 are reserved by Blaxel - Dev servers must bind to `0.0.0.0`, not `localhost`, for preview URLs to work - ~50% of sandbox memory is reserved for the in-memory filesystem (tmpfs). Use volumes for extra storage - Sandboxes auto-scale to zero after ~5s of inactivity. State is preserved in standby and resumes in <25ms - `waitForCompletion` has a max timeout of 60 seconds. For longer processes, use `process.wait()` with `maxWait` - Secrets should never go in `[env]` — use the Variables-and-secrets page in the Console ## Agent Drive (shared filesystem) Agent Drive is a distributed filesystem backed by SeaweedFS that can be mounted to multiple sandboxes or agents at any time, including while they are already running. Unlike volumes (block storage attached only at sandbox creation), drives support concurrent read-write access from multiple sandboxes and can be attached/detached dynamically. > This feature is currently in private preview. During the preview, Agent Drive is only available in the `us-was-1` region. Both drive and sandbox must be in this region. Use cases: - Passing data between sandboxes without intermediary services - Storing tool outputs and context histories for other agents - Sharing datasets across multiple agents - Creating a shared filesystem cache of package dependencies ### Create a drive ```typescript import { DriveInstance } from "@blaxel/core"; const drive = await DriveInstance.createIfNotExists({ name: "my-drive", region: "us-was-1", displayName: "My Project Drive", // optional; defaults to name labels: { env: "dev", project: "x" }, // optional }); ``` ```python from blaxel.core.drive import DriveInstance drive = await DriveInstance.create_if_not_exists( { "name": "my-drive", "region": "us-was-1", "display_name": "My Project Drive", "labels": {"env": "dev", "project": "x"}, } ) ``` ### Mount a drive to a sandbox ```typescript import { SandboxInstance } from "@blaxel/core"; const sandbox = await SandboxInstance.get("my-sandbox"); await sandbox.drives.mount({ driveName: "my-drive", mountPath: "/mnt/data", drivePath: "/", // optional; defaults to root of the drive }); ``` ```python from blaxel.core import SandboxInstance sandbox = await SandboxInstance.get("my-sandbox") await sandbox.drives.mount( drive_name="my-drive", mount_path="/mnt/data", drive_path="/", ) ``` Once mounted, any file written to the mount path inside the sandbox is stored on the drive and persists even after the sandbox is deleted. ### Mount a subdirectory ```typescript await sandbox.drives.mount({ driveName: "my-drive", mountPath: "/app/project", drivePath: "/projects/alpha", }); ``` ```python await sandbox.drives.mount( drive_name="my-drive", mount_path="/app/project", drive_path="/projects/alpha", ) ``` ### List, unmount, and delete drives ```typescript // List mounted drives on a sandbox const mounts = await sandbox.drives.list(); // List all drives const drives = await DriveInstance.list(); // Unmount await sandbox.drives.unmount("/mnt/data"); // Delete a drive await DriveInstance.delete("my-drive"); // or instance-level: const drive = await DriveInstance.get("my-drive"); await drive.delete(); ``` ```python mounts = await sandbox.drives.list() drives = await DriveInstance.list() await sandbox.drives.unmount("/mnt/data") await DriveInstance.delete("my-drive") # or instance-level: drive = await DriveInstance.get("my-drive") await drive.delete() ``` CLI: `bl get drives` ### Full Agent Drive example ```typescript import { SandboxInstance, DriveInstance } from "@blaxel/core"; // 1. Create a drive const drive = await DriveInstance.createIfNotExists({ name: "agent-storage", region: "us-was-1", }); // 2. Create a sandbox (use image ID from custom template) const sandbox = await SandboxInstance.createIfNotExists({ name: "my-agent-sandbox", image: "my-sandbox-image-id", memory: 2048, region: "us-was-1", }); // 3. Mount the drive await sandbox.drives.mount({ driveName: "agent-storage", mountPath: "/mnt/storage", drivePath: "/", }); // 4. Write a file to the mounted drive await sandbox.fs.write("/mnt/storage/hello.txt", "Hello from the drive!"); // 5. Read it back const content = await sandbox.fs.read("/mnt/storage/hello.txt"); console.log(content); // "Hello from the drive!" // 6. List mounted drives const mounts = await sandbox.drives.list(); console.log(mounts); ``` ```python import asyncio from blaxel.core.drive import DriveInstance from blaxel.core import SandboxInstance async def main(): drive = await DriveInstance.create_if_not_exists( {"name": "agent-storage", "region": "us-was-1"} ) sandbox = await SandboxInstance.create_if_not_exists( { "name": "my-agent-sandbox", "image": "my-sandbox-image-id", "memory": 2048, "region": "us-was-1", } ) await sandbox.drives.mount( drive_name="agent-storage", mount_path="/mnt/storage", drive_path="/", ) await sandbox.fs.write("/mnt/storage/hello.txt", "Hello from the drive!") content = await sandbox.fs.read("/mnt/storage/hello.txt") print(content) mounts = await sandbox.drives.list() print(mounts) asyncio.run(main()) ``` Docs: https://docs.blaxel.ai/Agent-drive/Overview ## Other Blaxel resources ### Agents Hosting Deploy AI agents as serverless auto-scaling HTTP endpoints. Framework-agnostic (LangChain, CrewAI, Claude SDK, etc.). ```shell bl new agent # develop in src/agent.ts or src/agent.py bl serve # test locally bl deploy # deploy bl chat AGENT-NAME # query ``` Sync endpoint handles requests up to 100s, async endpoint up to 10 minutes. Docs: https://docs.blaxel.ai/Agents/Overview ### MCP Servers Hosting Deploy custom tool servers following the MCP protocol. ```shell bl new mcp # implement in src/server.ts or src/server.py bl serve --hotreload # test locally bl deploy ``` Agents connect to deployed MCP servers via SDK: ```typescript const tools = await blTools(["functions/my-mcp-server"]); ``` Every sandbox also exposes its own built-in MCP server at `https://<SANDBOX_URL>/mcp` with tools for process management, filesystem, and code generation. Docs: https://docs.blaxel.ai/Functions/Overview ### Batch Jobs Scalable compute for parallel background tasks (minutes to hours). ```shell bl new job # implement in src/index.ts or src/index.py bl deploy bl run job NAME --data '{"tasks": [...]}' ``` Max 24h per task. Set `maxConcurrentTasks` in blaxel.toml. Docs: https://docs.blaxel.ai/Jobs/Overview ## Resources - Deployment configuration reference: https://docs.blaxel.ai/deployment-reference - CLI command reference: https://docs.blaxel.ai/cli-reference/introduction Read individual SDK files for detailed explanations and code examples: - ./references/sdk-python.md - ./references/sdk-typescript.md Each SDK README contains: - An overview of the SDK - Requirements - Code examples for working with sandboxes, volumes, agents, batch jobs, MCP - Additional useful information For additional documentation, see: https://docs.blaxel.ai/llms.txt