Smartsh
Safe, token-efficient command execution for AI coding agents via an MCP server and local daemon (smartshd) that runs shell commands with safety checks and returns compact JSON.
Installation
npx smartshAsk AI about Smartsh
Powered by Claude Β· Grounded in docs
I know everything about Smartsh. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
>smartsh_
Safe, compact command execution for AI coding agents.
MCP server + local daemon that gives Cursor and Claude Code a safe, token-efficient way to run shell commands.
Why smartsh?
When AI agents run terminal commands, they dump huge raw logs into context β burning tokens and confusing the model.
smartsh fixes this:
- Runs commands through a local daemon (
smartshd) - Returns compact structured JSON instead of raw output
- Uses Ollama for intelligent summaries of command results
- Applies safety checks before execution (blocks dangerous commands)
- Supports risk approval workflows for destructive operations
- Truncates output automatically for massive token savings
Install (3 steps)
Step 1: Install Ollama (required)
smartsh uses Ollama for intelligent command output summaries. Install it first.
macOS / Linux:
curl -fsSL https://ollama.com/install.sh | sh
ollama serve
ollama pull llama3.2:3b
Windows:
- Download and install from https://ollama.com/download
- Then in PowerShell:
ollama serve
ollama pull llama3.2:3b
Step 2: Install smartsh
If Ollama is already installed, this is the only terminal command users need to run for smartsh installation.
macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/BegaDeveloper/smartsh/main/scripts/install.sh | sh
Windows (PowerShell):
powershell -NoProfile -ExecutionPolicy Bypass -Command "iwr -useb https://raw.githubusercontent.com/BegaDeveloper/smartsh/main/scripts/install.ps1 | iex"
Install via Go:
go install github.com/BegaDeveloper/smartsh/cmd/smartsh@latest
go install github.com/BegaDeveloper/smartsh/cmd/smartshd@latest
smartsh setup-agent
The installer runs setup-agent automatically. After setup completes, you get these files in ~/.smartsh/:
| File | Use with |
|---|---|
cursor-mcp.json | Cursor |
claude-code-mcp.json | Claude Code |
agent-instructions.txt | Paste into Cursor/Claude rules |
Step 3: Connect to Cursor or Claude Code
For Cursor:
Copy cursor-mcp.json into your project:
# macOS / Linux
cp ~/.smartsh/cursor-mcp.json /path/to/your/project/.cursor/mcp.json
# Windows
copy %USERPROFILE%\.smartsh\cursor-mcp.json C:\path\to\your\project\.cursor\mcp.json
Then paste ~/.smartsh/agent-instructions.txt into Cursor β Settings β Rules.
For Claude Code:
Copy claude-code-mcp.json as your Claude desktop config:
# macOS / Linux
cp ~/.smartsh/claude-code-mcp.json ~/.claude/claude_desktop_config.json
# Windows
copy %USERPROFILE%\.smartsh\claude-code-mcp.json %USERPROFILE%\.claude\claude_desktop_config.json
Verify
smartsh doctor
Generated MCP JSON (reference)
If you prefer to set up manually, here's what the generated cursor-mcp.json / claude-code-mcp.json looks like:
If you are writing JSON manually, use your own absolute
smartshbinary path forcommand(it differs per user and OS).
{
"mcpServers": {
"smartsh": {
"command": "/ABSOLUTE/PATH/TO/smartsh",
"args": ["mcp"],
"env": {
"SMARTSH_DAEMON_URL": "http://127.0.0.1:8787",
"SMARTSH_DAEMON_TOKEN": "<auto-generated-token>",
"SMARTSH_SUMMARY_PROVIDER": "ollama",
"SMARTSH_OLLAMA_REQUIRED": "true",
"SMARTSH_OLLAMA_ALWAYS": "true",
"SMARTSH_OLLAMA_URL": "http://127.0.0.1:11434",
"SMARTSH_OLLAMA_MODEL": "llama3.2:3b",
"SMARTSH_MCP_HTTP_TIMEOUT_SEC": "900",
"SMARTSH_MCP_DEFAULT_UNSAFE": "true",
"SMARTSH_MCP_DEFAULT_REQUIRE_APPROVAL": "false",
"SMARTSH_MCP_DEFAULT_ALLOWLIST_MODE": "off"
}
}
}
}
The token is generated automatically by
smartsh setup-agentand stored in~/.smartsh/config.
Rule snippet (paste into Cursor/Claude rules)
For command execution, always use the smartsh MCP tool (smartsh_run).
In some clients it appears as smartsh-local_smartsh_run.
Never use direct shell execution unless explicitly requested by the user.
Do not use run_terminal_cmd when the smartsh MCP tool is available.
Prefer summarized tool output and avoid dumping full terminal logs.
How It Works
βββββββββββββββ MCP JSON-RPC βββββββββββ HTTP ββββββββββββ
β Cursor / β βββββββββββββββββββΆ β smartsh β βββββββββββΆ β smartshd β
β Claude Code β βββββββββββββββββββ β mcp β βββββββββββ β daemon β
βββββββββββββββ compact summary βββββββββββ execute ββββββββββββ
- Agent sends command via MCP tool (
smartsh_run) smartsh mcpforwards to local daemonsmartshdvalidates safety β executes β summarizes via Ollama- Compact JSON returned to agent (not raw logs)
Example response
{
"status": "failed",
"exit_code": 1,
"summary": "command failed (exit code 1): Cannot find module '@app/auth'",
"error_type": "compile",
"primary_error": "Cannot find module '@app/auth'",
"next_action": "Fix TypeScript compiler errors and rerun build/test.",
"failed_files": ["src/app/auth/auth.service.ts"],
"top_issues": ["TS2307: Cannot find module '@app/auth'"]
}
Compare that to 500+ lines of raw tsc output the agent would normally dump.
Features
Safety & Policy
- Blocks dangerous commands (
rm -rf /, privilege escalation, pipe-to-shell) - Risk approval workflow β agent must confirm before running destructive ops
- Command allowlist mode (
off/warn/enforce) - Project-level policy via
.smartsh-policy.yaml
Token Savings
- Success runs return only summary (no output tail)
- Failed runs return truncated tail + structured error info
- MCP compact mode enabled by default
- Configurable tail size via
SMARTSH_MCP_MAX_OUTPUT_TAIL_CHARS
Ollama Summaries
- Ollama is the default summary provider
- Sends only truncated, redacted output to local Ollama
- Strict JSON response schema enforced
- Falls back to deterministic parsing if Ollama is unavailable
Daemon Capabilities
- Persistent jobs in BoltDB (survive restarts)
- Async execution with
job_idpolling - SSE status streaming
- PTY interactive sessions
- Execution isolation (timeout, memory, CPU, env allowlist)
- Token auth required by default
- Prometheus metrics at
/metrics
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
SMARTSH_DAEMON_URL | http://127.0.0.1:8787 | Daemon address |
SMARTSH_DAEMON_TOKEN | (auto-generated) | Auth token (required) |
SMARTSH_DAEMON_DISABLE_AUTH | false | Disable auth (not recommended) |
SMARTSH_SUMMARY_PROVIDER | ollama | deterministic, ollama, or hybrid |
SMARTSH_OLLAMA_URL | http://127.0.0.1:11434 | Ollama endpoint |
SMARTSH_OLLAMA_MODEL | llama3.2:3b | Ollama model |
SMARTSH_OLLAMA_REQUIRED | true | Fail if Ollama unavailable |
SMARTSH_OLLAMA_ALWAYS | false | Use Ollama summaries for successful runs too |
SMARTSH_OLLAMA_TIMEOUT_SEC | 8 | Ollama request timeout |
SMARTSH_MCP_COMPACT_OUTPUT | true | Enable compact responses |
SMARTSH_MCP_MAX_OUTPUT_TAIL_CHARS | 600 | Max output tail chars |
SMARTSH_MCP_HTTP_TIMEOUT_SEC | 300 | MCPβdaemon HTTP timeout (seconds) |
SMARTSH_MCP_DEFAULT_UNSAFE | false | Default unsafe for MCP tool calls |
SMARTSH_MCP_DEFAULT_REQUIRE_APPROVAL | true | Default risk approval requirement for MCP tool calls |
SMARTSH_MCP_DEFAULT_ALLOWLIST_MODE | warn | Default allowlist mode for MCP tool calls (off/warn/enforce) |
SMARTSH_DAEMON_ADDR | 127.0.0.1:8787 | Daemon listen address |
Risky Commands
When an agent tries to run a destructive command (e.g. rm -rf), smartsh returns status=needs_approval with an approval_id. The agent then calls smartsh_approve with decision=yes or decision=no.
Use unsafe=true in the tool call only when you want to bypass the approval step entirely.
Manual Download
| Platform | File |
|---|---|
| macOS Apple Silicon (M1/M2/M3) | smartsh_darwin_arm64.tar.gz |
| macOS Intel | smartsh_darwin_amd64.tar.gz |
| Linux x64 | smartsh_linux_amd64.tar.gz |
| Linux arm64 | smartsh_linux_arm64.tar.gz |
| Windows x64 | smartsh_windows_amd64.zip |
Download from Releases.
Building from Source
go build -o smartsh ./cmd/smartsh
go build -o smartshd ./cmd/smartshd
# Cross-platform release archives
./scripts/build.sh # macOS/Linux
.\scripts\build.ps1 # Windows
Release Flow (Maintainers)
git checkout main && git pull
go test ./...
./scripts/build.sh
git add . && git commit -m "release: vX.Y.Z"
git push origin main
git tag vX.Y.Z
git push origin vX.Y.Z
If auto-release does not trigger:
gh release create vX.Y.Z \
dist/release/smartsh_darwin_amd64.tar.gz \
dist/release/smartsh_darwin_arm64.tar.gz \
dist/release/smartsh_linux_amd64.tar.gz \
dist/release/smartsh_linux_arm64.tar.gz \
dist/release/smartsh_windows_amd64.zip \
dist/release/checksums.txt \
--title vX.Y.Z --generate-notes
