A secure MCP bridge for AI agents and native commands.
WASM isolation for agents. OS-level restrictions for everything else.
Almide + Wasmtime · No Docker required
Porta controls what programs can access — filesystem, network, commands — using capability-based security.
Two execution modes:
- WASM sandbox — Almide/Rust/C agents compiled to WASM run inside wasmtime with mathematical isolation
- Native restrictions — Any command (Claude Code, Python, Node.js) runs with OS-level filesystem and network restrictions (macOS sandbox-exec)
porta run claude --allow-net '*:443' -v . -e "HOME=$HOME" -- --print "Fix the bug"Or declaratively:
porta init native claude
porta up -- --print "Fix the bug in main.rs"# Network open by default (like Docker)
porta run curl -- https://example.com
# → works
# Restrict to HTTPS only
porta run curl --allow-net '*:443' -- https://example.com
# → works
# Restrict to port 80 — HTTPS blocked
porta run curl --allow-net '*:80' -- https://example.com
# → exit status: 7 (port 443 not allowed)porta run agent.wasm --profile full -v ./workspace
porta serve agent.wasm # Start as MCP serverporta run auto-detects mode: .wasm files run in WASM sandbox, everything else runs as a native command with OS-level restrictions.
Declarative configuration for restricted execution.
[runtime]
type = "native" # "native" or "wasm"
command = "claude" # Command to run (native mode)
# wasm = "agent.wasm" # WASM binary (wasm mode)
[sandbox]
mounts = ["."] # Directories the command can write to
# mounts = [".:ro"] # Read-only mount
network = ["*:443"] # Restrict to these ports (empty = all open)
[env]
NODE_ENV = "production"
[secrets]
API_KEY = "sk-..."
# Or read from host environment:
# API_KEY = { from-env = true }porta init native claude # Generate porta.toml
porta up # Run from porta.toml
porta up -- --print "hi" # Pass arguments to the command| Command | Description |
|---|---|
porta init [native|wasm] [cmd] |
Create porta.toml |
porta up [-- args...] |
Run from porta.toml |
| Command | Description |
|---|---|
porta run <target> |
Execute WASM (.wasm) or native command |
porta run -d <agent.wasm> |
Run WASM as background daemon |
porta serve <agent.wasm> |
Start MCP server on stdio |
| Command | Description |
|---|---|
porta build <agent.wasm> |
Generate manifest.json |
porta inspect <agent.wasm> |
Show module info |
porta validate <agent.wasm> |
Check WASI imports against profile |
| Command | Description |
|---|---|
porta ps |
List instances |
porta stop <id> |
Stop instance (SIGTERM) |
porta kill <id> |
Kill instance (SIGKILL) |
porta logs <id> |
View instance logs |
porta rm <id> |
Remove stopped instance |
| Flag | Description |
|---|---|
-e, --env <KEY=VALUE> |
Set environment variable |
--env-file <path> |
Load env vars from file |
--secret <KEY=VALUE> |
Inject secret as env var |
-v <path> |
Mount directory (writable) |
-v <path>:ro |
Mount directory (read-only) |
--allow-net <host:port> |
Allow outbound network (repeatable) |
--allow-exec <cmd,...> |
Allow specific commands (comma-separated) |
--profile <name> |
Capability profile: ai-agent, worker, full |
--step-limit <n> |
Max WASM instructions |
--max-memory <pages> |
Max WASM memory pages |
--restart <policy> |
no, on-failure, always |
-d, --detach |
Run as background daemon |
--help, -h |
Show help for any command |
Porta enforces restrictions at two levels:
- OS layer (sandbox-exec) — Process-level port-based network control and filesystem restrictions. Cannot be bypassed by the child process.
- MCP layer — Application-level host+port URL filtering and capability checks on
porta.execandporta.httpbuiltin tools.
Uses sandbox-exec to enforce:
| Control | Behavior |
|---|---|
| FS write | Denied everywhere except -v mounted dirs and /tmp |
| FS read | ~/.ssh and ~/.gnupg denied (cryptographic keys). Everything else user-configurable via -v |
| Network | Open by default. --allow-net "*:443" restricts to HTTPS only |
| Read-only | -v ./data:ro → read OK, write denied |
Note: macOS sandbox-exec supports port-based filtering only. Host-based filtering (
api.example.com:443) is enforced at the MCP layer for builtin tools.
Deny-by-default capability system. Every WASI import is validated against the capability set before execution.
| Capability | Controls |
|---|---|
io |
stdin/stdout/stderr |
fs |
File read (path_open, stat, readdir) |
fs.write |
File write (create, rename, delete) |
process |
Process lifecycle, args |
env |
Environment variables |
clock |
Time/clock |
random |
Random bytes |
net |
Network access |
exec |
Command execution |
Built-in profiles: ai-agent (IO + Process), worker (+Clock +Random), full (all).
Manifest capabilities are respected in both serve and run modes.
porta serve agent.wasm --profile full| Tool | Requires | Description |
|---|---|---|
porta.exec |
CapExec + --allow-exec |
Execute a command with filesystem and network restrictions |
porta.http |
CapNet + --allow-net |
Make HTTP requests to allowed hosts |
| Agent tools | — | Dispatched to WASM agent |
initialize, tools/list, tools/call, resources/list, resources/read, prompts/list, prompts/get, ping
{
"mcpServers": {
"agent": {
"type": "stdio",
"command": "porta",
"args": ["serve", "agent.wasm", "--profile", "full", "--allow-net", "*:443"]
}
}
}porta
├── cli.almd — Options, arg parsing, help
├── mod.almd — Command dispatch (entry point)
│
├── engine.almd — serve, run, validate, inspect
├── dispatch.almd — WASM instance lifecycle & tool dispatch
├── mcp.almd — MCP protocol (JSON-RPC 2.0 / stdio)
├── jsonrpc.almd — Content-Length framed JSON-RPC
├── sandbox.almd — Capability-based security
│
├── ops.almd — Daemon management (ps/stop/kill/logs/rm)
├── build.almd — Manifest generation
├── project.almd — porta.toml (up/init)
│
├── wasm_rt.almd — Wasmtime bridge + runtime functions
├── config.almd — porta.toml parser
├── manifest.almd — manifest.json parser
├── observability.almd — Execution metrics
├── util.almd — CLI utilities
│
└── wasm/
├── binary.almd — WASM binary parser
└── wasi.almd — WASI Preview 1 host functions
# From source (requires Almide >= 0.12.0)
almide build src/mod.almd -o porta
cp porta ~/.local/bin/| Runtime | Status | Example |
|---|---|---|
| Almide → WASM | Full support | porta run agent.wasm |
| Python 3.14 | Runs in WASM | porta run python.wasm -- script.py |
| Native commands | OS restrictions | porta run claude -- --print "hi" |
Apache-2.0
