The Mesa SDK implements the IFileSystem interface from Vercel’s just-bash library. This means your agent can execute regular bash commands — using tools like ls, cat, cp, grep, and more — directly against Mesa repositories without cloning or mounting anything, or even needing a sandbox. Both read and write operations are supported.
The integration lives in the @mesadev/sdk package. You create a MesaFS filesystem, call .bash() to get a bash executor, and start executing commands.
How It Works
Under the hood, the Mesa SDK implements just-bash’s virtual filesystem interface by calling into our native NAPI addon. In effect, this is a TypeScript wrapper around the same Rust core that powers MesaFS FUSE.
When you run a command like ls /my-repo/src, just-bash calls into MesaFS which fetches the directory listing from Mesa’s API. Writes work the same way — file changes are persisted back to Mesa automatically. Our just-bash implementation takes advantage of the same caching and prefetching mechanisms as MesaFS FUSE, which means you get the same performance benefits without the need for a sandbox.
When to use MesaFS just-bash
If you have an existing TypeScript-defined agent that runs in your multi-tenant backend, MesaFS just-bash enables you to get the full benefits of a filesystem without needing a sandbox.
For example, agents written using Vercel’s AI SDK, Mastra, or Langchain can now manipulate files using the full power of bash and common Unix tools, rather than just basic readFile/writeFile tools.
When not to use just-bash
If your agent needs to install dependencies or run arbitrary code, you should instead mount MesaFS FUSE in a sandboxed environment like an ECS container or lightweight VM from a provider like Daytona, Vercel, or Modal.
Quick Start
Initialize a Mesa client and a filesystem handle scoped to the repos you want to access. You can create as many filesystem handles as you need.
import { Mesa } from "@mesadev/sdk";
const mesa = new Mesa({ adminApiKey: process.env.MESA_ADMIN_API_KEY });
// Create a MesaFS filesystem scoped to your repos
const fs = await mesa.fs.create({
repos: [{ name: "my-repo", desiredBookmark: "main" }],
mode: "rw", // or "ro" for read-only access
});
// Get a bash shell backed by MesaFS
const bash = fs.bash();
// Run commands
const result = await bash.exec("ls /my-repo/src");
console.log(result.stdout);
Create a tool for your agent to use. Note: The shape of the tool depends on your agent framework. Here we use the ai package from Vercel’s AI SDK.
import { tool } from 'ai';
import { z } from 'zod';
const bashTool = tool({
description: 'Execute bash commands',
inputSchema: z.object({
command: z.string(),
}),
execute: async ({ command }) => {
return await bash.exec(command);
},
});
Configuring the Shell
The .bash() method accepts options to configure the shell environment:
const bash = fs.bash({
env: { NODE_ENV: "production" },
cwd: "/my-repo",
});
// Now commands run relative to /my-repo
await bash.exec("ls src");
Available options:
| Option | Description |
|---|
env | Environment variables available to commands |
cwd | Working directory for command execution |
executionLimits | Resource limits (timeouts, memory) |
fetch | Custom fetch implementation for network access |
network | Network access configuration |
python | Python runtime configuration |
javascript | JavaScript runtime configuration |
commands | Which built-in commands to enable |
customCommands | User-defined custom commands |
logger | Logging interface |
Filesystem Operations
You can also use the MesaFS filesystem directly without going through bash. The filesystem implements the full IFileSystem interface:
// Read a file
const content = await fs.readFile("/my-repo/src/index.ts");
// Write a file
await fs.writeFile("/my-repo/src/new-file.ts", "export const x = 1;");
// Check if a file exists
const exists = await fs.exists("/my-repo/package.json");
// List a directory
const entries = await fs.readdir("/my-repo/src");
// Copy files
await fs.cp("/my-repo/src/a.ts", "/my-repo/src/b.ts");
// Remove files
await fs.rm("/my-repo/src/old-file.ts");
The filesystem supports symlinks, permissions (chmod), timestamps (utimes), and recursive directory operations.
Hard links are not supported and will return ENOTSUP.
Caching
For better performance on repeated reads, configure a disk cache:
const fs = await mesa.fs.create({
repos: [{ name: "my-repo", desiredBookmark: "main" }],
mode: "rw",
cache: {
diskCache: {
path: "/tmp/mesa-cache",
maxSizeBytes: 1024 * 1024 * 1024, // 1 GB
},
},
});
The native MesaFS bindings are available for:
- macOS (ARM64, x64)
- Linux (x64 glibc, x64 musl, ARM64 musl)
The correct native binary is automatically selected at runtime based on your platform.
Limitations
just-bash does not support installing dependencies (ex. running npm install) or executing arbitrary code (ex. running python or node).
- MesaFS just-bash is not currently supported in the browser or browser-like runtimes like Cloudflare Workers or Vercel Edge Functions. NOTE: this limitation is due to the use of NAPI — we will likely support a browser-runtime version in the future via a WASM build.
- Bun support is experimental and may not work in all cases. This is due to Bun’s incomplete support for NAPI.