A fast, OS-sandboxed Model Context Protocol gateway with an embedded Code Mode engine and shell-output token compression — in a single Rust binary.
Cut your agent's API bill while physically stopping it from wiping your disk or exfiltrating your secrets.
Autonomous AI coding agents have three expensive, dangerous habits:
- Token bloat — they pump raw
cargo test/npm installoutput and hundreds of MCP tool schemas straight into the context window. - The MCP scaling wall — attach a few MCP servers and the model now carries the JSON Schemas of every tool on every single turn.
- Remote code execution by design — letting an agent run shell commands or LLM-generated code is RCE on your machine.
Skarn is one binary that fixes all three:
- Aggregates your downstream MCP servers behind a tiny, constant tool surface (
search/read_tool_docs/execute) using Code Mode — the model writes a short script that orchestrates tools in a sandbox, so megabyte intermediate payloads never reach the context window. - Compresses shell output with declarative, per-tool filters — typically 70–90% fewer tokens, while guaranteeing errors and warnings survive.
- Sandboxes everything it executes with OS-native kernel primitives — Seatbelt on macOS, Landlock + seccomp on Linux, AppContainer on Windows — with no Docker, no daemon, no VM.
┌──────────────────────────── Skarn (one binary) ────────────────────────────┐
│ │
AI agent ─┼─▶ search / execute ──▶ Code Mode isolate ──▶ skarn.callTool() ──┐ │
(Claude │ (≈1k tokens, (QuickJS, hermetic, │ │ │
Code, │ not 30k) OS-sandboxed) ▼ │ │
Cursor…) │ ┌────────────┐ ┌────────────┐ │
│ compressed 15-token ◀── return summary ──┤ MCP client │… │ MCP client │ │
│ result, not a 15k (big data stays └─────┬──────┘ └─────┬──────┘ │
│ log dump inside the box) ▼ ▼ │
└────────────────────────────────────────────── Postgres MCP GitHub MCP ──────┘
Skarn is young. The macOS (Seatbelt) and Linux (Landlock + seccomp) sandboxes are runtime-verified in CI on every push; Windows AppContainer is the least exercised backend so far. By design it runs untrusted, model-generated code, so please read SECURITY.md for the threat model and what is explicitly out of scope before you point a real agent at it. The most useful thing you can send right now is a bug report or an attempt to break the sandbox.
# One line (macOS / Linux):
curl -fsSL https://rani367.github.io/Skarn/install.sh | sh
# Or with Cargo:
cargo install skarnThis installs the skarn binary.
# 1. Scaffold a config and see integration snippets
skarn init
# 2. Check which kernel sandbox is active on your machine
skarn doctor
# 3. Point your agent at the gateway (Claude Code / Cursor / Windsurf):
# add to your MCP config:
# { "mcpServers": { "skarn": { "command": "skarn", "args": ["serve"] } } }
# 4. (Optional) try a Code Mode script against your configured servers:
skarn exec --code 'return (await skarn.listTools()).length'
# 5. (Optional) compress + sandbox the agent's shell commands directly:
skarn run --net deny -- cargo test
# 6. (Optional) install shell completion (bash/zsh/fish/powershell):
# skarn completions zsh > ~/.zfunc/_skarn
# Then add `fpath+=~/.zfunc` and `compinit` to your .zshrcDownstream servers can be local (transport = "stdio") or remote
(transport = "http", Streamable HTTP with optional bearer auth) — see
skarn.example.toml.
Instead of injecting every tool's schema, the gateway exposes three meta-tools. The model calls search() to find tools, then writes a short script and hands it to execute():
// The model writes this; Skarn runs it in a hermetic, OS-sandboxed isolate.
const issues = await skarn.server("github").search_issues({ q: "is:open label:bug" });
const stale = issues.filter(i => daysSince(i.updated_at) > 90); // filtering happens HERE
await skarn.server("slack").post_message({ channel: "#triage", text: summarize(stale) });
return { staleCount: stale.length }; // only this returns to the modelThe 1,000-row intermediate result never touches the context window.
| Scenario | Classic MCP (input tokens) | Skarn Code Mode | Reduction |
|---|---|---|---|
| 16 servers / 508 tools, multi-step task | ~150,000 | ~2,000 | ~99% |
| Single 3-tool workflow | ~20,700 | ~1,100 | ~95% |
(Figures from the published Code Mode literature — see docs/adr/0001. Your mileage varies with catalog size.)
skarn run --stats -- cargo test| Command | Raw tokens | Compressed | Reduction |
|---|---|---|---|
cargo test |
~25,000 | ~2,500 | ~90% |
npm install |
~16,000 | ~3,200 | ~80% |
git diff |
~10,000 | ~2,500 | ~75% |
ls / tree |
~2,000 | ~400 | ~80% |
Errors, warnings, and failures are always kept — even rescued out of a truncated middle.
skarn run -- <cmd> confines the command to your project directory and denies network egress, enforced by the kernel:
| Platform | Mechanism | Cold start |
|---|---|---|
| macOS | Seatbelt (sandbox_init) |
< 5 ms |
| Linux | Landlock LSM + seccomp-bpf | < 5 ms |
| Windows | AppContainer + Job Object | < 10 ms |
Compare to Docker's 200 ms+ cold start, root daemon, and per-seat licensing.
Code Mode execute gets the same protection: on macOS and Linux the gateway runs
each script in a dedicated worker process that sandboxes itself (deny network,
no workspace writes) before touching model-generated code, so an isolate escape
still lands in a kernel-confined process. Configure it with isolation in
skarn.toml (auto / worker / in_process).
- Claude Code / Codex CLI — run
skarn hookfor a PreToolUse hook that routes shell commands throughskarn run(sandbox + compression, no prompt changes). See docs/integrations/claude-code.md. - Cursor / Windsurf — set Skarn as an MCP server in the IDE config to get Code Mode + aggregation. See docs/integrations/cursor-windsurf.md.
A Cargo workspace with strictly separated, independently usable crates:
| Crate | Responsibility |
|---|---|
skarn-sandbox |
OS-native sandbox abstraction (Seatbelt / Landlock+seccomp / AppContainer) |
skarn-compress |
YAML-driven shell-output token compression |
skarn-codemode |
Hermetic QuickJS isolate + oxc TS-strip & AST validation + tool bridge |
skarn-gateway |
MCP server/client aggregation on the official rmcp SDK |
skarn |
The skarn CLI tying it all together |
See the Architecture Decision Records for the engineering rationale.
Skarn runs untrusted, model-generated code by design. Read SECURITY.md for the threat model, what is and isn't defended, and how to report vulnerabilities.
git clone https://github.com/Rani367/Skarn
cd Skarn
cargo build --release # binary at target/release/skarn
cargo test --workspace # macOS sandbox is runtime-verified hereRequires Rust 1.95+.
See CONTRIBUTING.md. Issues and PRs welcome.
The landing page lives at rani367.github.io/Skarn — a
single-screen animated overview (a WebGL turbulent-flow hero with the headline numbers and one-line
install). It also serves the installer, so the one-liner above
(curl -fsSL https://rani367.github.io/Skarn/install.sh | sh) pulls from there.
The site source is in website/ (Vite + React) and deploys to GitHub Pages automatically
via .github/workflows/pages.yml on every push that touches it.
Licensed under either of MIT or Apache-2.0 at your option.