Swaps the filesystem and bash providers for a mirage virtual workspace: file tools and shell commands run over mounted resources (RAM, S3, Redis, Slack, Gmail, Notion, Postgres) instead of the host disk, with per-mount read/write/exec modes, per-command sandbox routing (monty, pyodide, quickjs in process; docker, e2b, daytona remote), and installed CLIs (git, gh, slack, linear, ntn, gws, or one you register) as head words in the virtual terminal.
Install
# from npm (prebuilt)
dsh plugin --profile web add @struktoai/mirage-dsh
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:strukto-ai/mirage#path:/typescript/packages/dsh
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Mirage is a Virtual Terminal for AI Agents. The virtual filesystem delivers broad data context, virtualized CLIs give an agent more flexibility on tool use, dynamic runtimes save underlying infrastructure cost and are more token efficient, and fine-grained control over an agent's actions and even over what it can see gives the best security. Together these parts form one virtualized terminal, giving the best agent performance, cost efficiency and security.
Here is an example of launching Mirage inside an application:
ws = Workspace(
{
"/tmp": (RAMVFS(), MountMode.EXEC),
"/redis": (RedisVFS(url=redis_url), MountMode.WRITE),
"/slack": (SlackVFS(SlackConfig(token=slack_bot_token)), MountMode.EXEC),
},
# monty captures python, so scripts run sandboxed inside the workspace
runtimes=[MontyRuntime(captures=["python", "python3"]), "workspace"],
)
# one grep sweeps every source
await ws.shell("grep -rln session /redis /tmp")
# run a script that lives in Slack, file the report into Redis
await ws.shell("python3 /slack/channels/general_.../files/example__F....py > /redis/report.txt")
# install a typed CLI under a head word: dispatched by name, not by path,
# and discoverable through `man`, `type` and `which` like any other program
ws.register_cli("slack", SLACK, {"token": slack_bot_token})
await ws.shell('slack send-message --channel general --text "report is up"')
About
- Unified virtual terminal interface, not N SDKs and M MCPs. Every backend speaks the same filesystem semantics, so pipelines compose across services.
- A virtual filesystem over every source. S3, Google Drive, Slack, Gmail, Redis and the rest mount side by side under one root, so an agent reaches all of them through a unified interface with the unix tools it already knows, like
ls,grep,findandjq. - Virtual command line tools (CLIs).
git,slackandntnare answered by Mirage itself, so an agent drives the service with nothing installed, across different runtimes and machines, and one tool can be virtualized into two or more, each under its own name with its own credentials. - Routed, dynamic runtimes. Python, JavaScript and any other command can be sent to a configured runtime, in process, sandboxed or remote, which decouples computation from storage and lets either change without touching the other.
- The virtualized Mirage shell. It binds the filesystem, the CLIs and the runtimes into one command line, so pipes, redirection, variables, jobs and history work across all three.
- Profiles designed for agents.
allow,askanddenygovern commands and CLIs, whilehideandshowgovern files and folders, so a hidden path is not merely unreadable but absent from the filesystem the agent sees. - A scriptable policy engine. A policy script can prohibit any dangerous action before it runs, and the same stack gates every VFS op and session write, so neither a file nor an environment variable leaks.
- Notifications wired into the VFS and agents. External changes become an event stream on the mount, so a new Slack reply surfaces as a change to the chat file in the virtual filesystem, and the agent reacts to it instead of rescanning the tree.
Virtual Filesystem
Everything Mirage "mounts" as one unified virtual filesystem for AI agents. Each service sits side-by-side under a single root and answers the same POSIX semantics.
| VFS | |
|---|---|
| Object Storage | |
| Files and Documents | |
| Messaging and Work | |
| Databases and Data Platforms | |
| Observability | |
| Local and Remote |
Agents reach it through the Python and TypeScript SDKs, the mirage CLI, or a real
mountpoint over FUSE and FSKit, then work it with the unix tools they already know,
like ls, grep, find and jq.
Virtual Command Line Tool
These command line tools are virtualized: Mirage answers git, slack or ntn
itself, so an agent drives the service without that program being installed on the
machine. Each one mimics the real tool, so an agent that knows the CLI needs nothing
new. Because they are virtual, the same tool can be installed more than once under
different names, each with its own credentials, so every agent gets exactly the
accounts it is given.
| CLIs | |
|---|---|
| Code | |
| Communication | |
| Work and Data |
Virtual Runtime
Runtimes are virtualized the same way, and not only for coding languages. Any
command on the line can be redirected to a configured runtime, so Python might
run in-process with Monty while
another command, say kubectl, is sent to a remote machine over SSH. Which runtime
serves a given line can be decided by a
scripted runtime router.
| Runtimes | |
|---|---|
| Python | |
| JavaScript | |
| Sandboxes |
Security
A profile decides what a session may run and what it may see. Commands are governed
by customizable allow, ask and deny rules, and paths by hide and show, so a
hidden file is not merely unreadable but absent from the filesystem the agent sees.
For anything those rules cannot express, a profile can name a policy script that runs
at the gate on every command and answers allow, deny or ask itself, though like every
rule it can only restrict and never grant. Separately, a host can register its own
policies on the policy engine, an
ordered stack the workspace consults on every command, VFS op and session write. See
the permissions docs.
Authentication
Credentials and authentication integrate with the stores secrets already live in, including AWS Secrets Manager, 1Password, Auth0 and dotenv, so an environment variable in Mirage can resolve straight to a credential held in one of them.
| Sources | |
|---|---|
| Built in | |
| Custom |
Installation
- Python ≥ 3.11 for the
mirage-aipackage and themirageCLI - Node.js ≥ 20 for the TypeScript SDK
Python
uv add mirage-ai # installs the `mirage` library and the `mirage` CLI binary
TypeScript
npm install @struktoai/mirage-node # Node.js servers and CLIs
npm install @struktoai/mirage-browser # browser / edge runtimes
npm install @struktoai/mirage-agents # OpenAI / Vercel AI / LangChain / Mastra adapters
Both runtime packages pull in @struktoai/mirage-core automatically.
CLI
curl -fsSL https://strukto.ai/mirage/install.sh | sh
# or
npm install -g @struktoai/mirage-cli
# or
uvx mirage-ai
# or
npx @struktoai/mirage-cli
Quickstart
Python
from mirage import Workspace
from mirage.vfs.ram import RAMVFS
from mirage.vfs.s3 import S3Config, S3VFS
ws = Workspace({
"/data": RAMVFS(),
"/s3": S3VFS(S3Config(bucket="my-bucket")),
})
await ws.shell("cp /s3/report.csv /data/report.csv")
await ws.shell("grep alert /s3/data/log.jsonl | wc -l")
await ws.snapshot("demo.tar")
TypeScript
import { Workspace, RAMVFS, S3VFS } from '@struktoai/mirage-node'
const ws = new Workspace({
'/data': new RAMVFS(),
'/s3': new S3VFS({ bucket: 'my-bucket' }),
})
await ws.shell('cp /s3/report.csv /data/report.csv')
await ws.shell('grep alert /s3/data/log.jsonl | wc -l')
await ws.snapshot('demo.tar')
CLI
mirage workspace create ws.yaml --id demo
mirage execute --workspace_id demo --command "cp /s3/report.csv /data/report.csv"
mirage provision --workspace_id demo --command "cat /s3/data/large.jsonl"
mirage workspace snapshot demo demo.tar
mirage workspace load demo.tar --id demo-restored
Contributors
Thanks to everyone who has contributed to Mirage.
Links
More in this category
yjh051108/dsh-routing-suite★ 7003
One repository, three parts: a runtime injector for DSH plugin packages (inject, hot-reload, unload, promote a dev staging tool to the front, route self-heal, plus a settings-page plugin manager that lists, unloads and drags folders in to internalize), a task-aware reasoning-mode router agent preset (router-standard / router-spec / router-react), and a graded two-level task protocol whose six tools (commit_star, lock_stage, revise_do, edit_plan, mark_task, redteam_verdict) pin task state to disk. The injector implementation ships in-tree, so the install carries its own behaviour rather than a dependency list.
hust-open-atom-club/oh-dsh★ 325
Community distribution: TUI, desktop, and Web UI as one bundle with layered installation.
weijiafu14/pi2dsh★ 206
Pi Host ABI compatibility engine: after one install, unmodified Pi extensions from npm mount as native DSH plugins with `dsh plugin add <pi-package>`. Verified end to end on stock DSH with pi-mcp-adapter (full MCP manager: OAuth, resources, prompts, MCP Apps, elicitation, sampling), @tintinweb/pi-subagents, pi-code, pi-hermes-memory and pi-background-tasks; `pi2dsh inspect` reports a package's compatibility before installing.
lire1131/dsh-undo-savepoint★ 166
Undo/redo & rollback system for DSH: every config change is auto-snapshotted; undo/redo/restore to any version from the WebUI or the offline CLI/GUI tools (works even when DSH fails to boot).
Fishquito7/dsh-skill-mcp-panel★ 155
Manages DSH skills and MCP servers from the web settings: skill cards with hot enable/disable, workspace scopes, groups, batch migration and drag-and-drop import, plus stdio/HTTP MCP CRUD with connection tests, secret redaction and the unified dsh-panel CLI.
kanneiren/dsh-network-settings★ 107
Visualize the DSH process network path on Windows or WSL with layered DNS/TCP/TLS/HTTP probes, detect stale proxy configuration, and apply snapshot-guarded repairs.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.