μish
the llm-native shell

Five MCP tools that give your agent structured output, error diagnostics, and process control. One binary. No dependencies.

$ curl -fsSL https://ohitsmish.com/install.sh | sh $ claude mcp add mish -- mish serve
01 GET STARTED

Two commands to five tools

Install the binary, register it as an MCP server, restart your client. That's it.

install
# macOS (Apple Silicon + Intel) and Linux $ curl -fsSL https://ohitsmish.com/install.sh | sh # or from source $ cargo install --git https://github.com/aetherwing-io/mish
connect as MCP server
# Claude Code $ claude mcp add mish -- mish serve # or any MCP client — add to your config: "mish": { "command": "mish", "args": ["serve"] }

Restart your client. Five tools appear:

ToolWhat it does
sh_run Run a command. Output is squashed, categorized, and enriched with diagnostics on failure.
sh_spawn Start a background process. Wait-for-ready patterns, aliases, output spools.
sh_interact Send input, read tail, signal, or kill a running process.
sh_session Named PTY sessions with full lifecycle control.
sh_help Self-documenting reference card. Your agent reads it, never needs a manual.

macOS + Linux · Works with Claude Code, Cursor, Windsurf, or any MCP-compatible client

02 CAPABILITIES

What one binary gives your agent

Metadata

Structured on every response

Exit code, timing, and command category. Your agent never parses raw text to know what happened.

Compression

Output squashing

ANSI stripping, progress removal, dedup, Oreo truncation. The noisy middle disappears. Head and tail survive.

Diagnostics

Error enrichment

When commands fail, mish pre-walks paths, checks permissions, and lists nearby files — before your agent has to ask.

Filtering

Watch patterns

Regex filters at the source, not in the context window. A full test suite returns only the lines that match.

Lifecycle

Process supervision

Named handles, output spools, wait-for-ready. The process table rides along on every response for free.

Routing

6-category classification

condense, narrate, passthrough, structured, interactive, dangerous. Every command gets the handler it deserves.

03 THE RECEIPTS

Measured, not promised

Same commands. Same machine. Same session. mish vs bare shell on a real Rust codebase.

ScenarioReductionHow
Full test suite 6.6× Dedup + Oreo truncation — head and tail kept, repetitive middle dropped
Test suite + watch 440× Only regex-matched lines return
Failed command 5→1 round trips Path walks, permissions, nearest dirs — pre-fetched on failure
sh_run — cargo build
{ "exit_code": 0, "duration_ms": 1183, "category": "condense", "output": "Compiling mish v0.1.0 warning: field is never read (×3) --> src/mcp/server.rs:71:5 --> src/session/shell.rs:89:5 --> src/tools/sh_spawn.rs:371:4 Finished `dev` profile in 0.98s", "recommendations": [ { "flag": "--message-format=json", "reason": "quieter output" } ] }

Three identical warning structures collapsed to one. Next-run flag suggested.

sh_run — cargo test --lib
{ "exit_code": 0, "duration_ms": 22263, "category": "condense", "lines": { "total": 1319, "shown": 201 }, "output": "running 1289 tests test audit::logger::tests::command_record ... ok (×2) test audit::logger::tests::serialization ... ok (×3) ... ··· [594 lines truncated — 0 errors in hidden region] ··· ... test yield_engine::detector::tests::yield_state ... ok test result: ok. 1289 passed; 0 failed; finished in 21.97s" }

Head and tail preserved. Hidden region scanned for errors. Repeated patterns collapsed.

sh_run — cargo test --lib — watch="warning"
{ "exit_code": 0, "duration_ms": 22316, "lines": { "total": 1319, "shown": 3 }, "matched_lines": [ "warning: field `config` is never read", "warning: field `shell_path` is never read", "warning: `mish` (lib test) generated 2 warnings" ] }

Same test suite. Same 1,319 lines executed. Three returned.

sh_run — cp /tmp/missing.txt /var/log/dest/
{ "exit_code": 1, "category": "narrate", "output": "cp: /var/log/dest does not exist", "enrichment": [ { "kind": "source", "message": "missing.txt ✗ not found" }, { "kind": "path", "message": "/var/log /var/log/dest " }, { "kind": "parent", "message": "rwxr-xr-x " }, { "kind": "nearest", "message": "apache2/, asl/, cups/, ..." } ] }

One call. Source checked, path walked, permissions verified, nearby dirs listed.

Full benchmark data →