host-shell-mcp
Provides host shell access on macOS, allowing an AI agent to run commands with the user's tools and credentials while enforcing filesystem read/write permissions through the macOS sandbox.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@host-shell-mcpcommit and push the changes in ~/dev/my-app"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
host-shell-mcp
An MCP server that lets an AI agent working in a sandbox or VM, like Claude in Cowork, run shell commands on your real computer. You decide which folders it can change.
Commands run on your Mac, with your tools and credentials:
git push,gh,brew, your.zshrcPATH. That's the reason to use it.Commands can change files only in the folders you allow. They can read everywhere else, and macOS enforces the rules on everything a command starts, whether it's a shell, Python or Node script.
Access is granted when it's needed. When Claude needs a new folder, a dialog on your Mac asks you: Deny / Allow this session / Always allow.
Claude can't change its own permissions. Commands can't touch the settings file, the log, or the dialog.
Everything is logged to a file you can read.
Install in Cowork
Cowork's Add connector box only takes URLs, and Anthropic's cloud (not your computer) connects to those URLs, so a local server can't go there. Install it as a plugin instead. Claude Desktop starts a plugin's local MCP servers on your computer.
npm install
npm run cowork-pluginThis writes dist/host-shell-mcp-cowork-plugin.zip. In Claude, open Customize → Plugins, choose the upload option, and select the zip. To check it's running on your Mac and not in the VM, ask Claude to run uname -a with it: Darwin means your Mac.
The plugin's launcher finds Node.js on its own (Homebrew, nvm, Volta, fnm, mise, asdf), because apps opened from the Dock don't see your shell's PATH. If it picks the wrong one, set HOST_SHELL_MCP_NODE to the path of the node you want.
Plugin MCP servers only run in local Cowork sessions, not cloud ones.
Related MCP server: SSH MCP Server
Use with other MCP clients
Run npm install, then add it to the client's config:
{ "mcpServers": { "host-shell": { "command": "node", "args": ["/absolute/path/to/host-shell-mcp/server.js"] } } }Settings
On first run, the server creates ~/.config/host-shell-mcp/config.toml. It's commented, so you can read it and edit it by hand. Changes apply to the next command, with no restart needed.
mode = "sandboxed" # or "unrestricted"
write = [ # folders commands may create, edit, rename and delete in
"~/Development",
]
write_caches = [ # temp and cache folders tools like npm, pip and git need
"$TMPDIR", "/private/tmp", "~/Library/Caches", "~/.npm", "~/.cache",
]
deny_read = [] # folders commands may not read at all
shell = "" # empty = your login shell
default_cwd = "~"
timeout_seconds = 600 # commands running longer are stopped
log_file = "~/Library/Logs/host-shell-mcp/commands.jsonl"You don't need to set anything up first. The defaults let commands read everywhere and write only to temp and cache folders. The first time Claude needs to change files somewhere, it calls request_write_access with the folder and a reason, and this appears on your Mac:
Claude wants to create, change and delete files in:
~/Development/my-app
Claude's reason: "Run npm install and commit the lockfile."
[Deny] [Allow this session] [Always allow]
Always allow adds the folder to write and keeps your comments. Broad locations like ~ or / come with a warning. If nobody answers within two minutes, the request counts as denied.
A broken settings file stops all commands until you fix it. The server never falls back to looser rules.
How the sandbox works
Commands run under macOS's Seatbelt sandbox (sandbox-exec), the same mechanism Chrome, Claude Code and Codex use. The rules:
sandboxed | unrestricted | |
Read files | everywhere except | everywhere except |
Create, edit, rename, delete |
| anywhere |
Settings file and command log | never writable | never writable |
Launch apps ( | blocked | allowed |
Nothing reads the command text. macOS enforces the rules on every process a command starts, so tricks like
$(…),sh -cor writing a script and running it make no difference. Filters based on the command text are what most other shell MCP servers use, and nearly all of them have published ways around them.Writing includes renaming and deleting. macOS treats a rename as a delete, and git and most editors save by renaming, so "can write but not delete" would break them.
It's a guardrail, not a guarantee. A command can still ask something outside the sandbox to act for it:
sshto your own Mac, Docker, or a launchd job. AppleScript and app launching are blocked because they're the easy routes to an unsandboxed Terminal.It's macOS only. On other systems, set
mode = "unrestricted". Commands then run without a sandbox.
Tools
Tool | What it does |
| Runs a command. Returns the exit code, stdout and stderr, or a |
| Waits for a running command (up to |
| Stops a running command and everything it started. |
| Shows the permission dialog on your Mac. |
When the sandbox blocks something, the result says so and tells Claude about request_write_access.
Behavior
Commands run as you. The tool description tells the agent to treat this as the real machine: nothing is undoable. It should use its own sandboxed shell for ordinary file work, and this tool for what needs the host (credentials, git remotes, installed tools, host-only files).
run_commandis marked destructive (destructiveHint), so clients ask before running it.Command log. Each command gets a
startline (time, mode, cwd, command) and anendline (exit code, signal, timeout or cancel, duration), matched byidandpid. Access requests are logged with the answer given. The file is readable only by you, since commands can contain secrets. Watch it withtail -f ~/Library/Logs/host-shell-mcp/commands.jsonl.Fresh shell per call.
cdandexportdon't carry over. It's an interactive login shell ($SHELL -ilc), so your.zprofileand.zshrcload andPATHmatches your terminal. That adds about 0.4 s per command with nvm.Bash-style globbing under zsh. A glob that matches nothing is passed through as-is instead of aborting with "no matches found".
No TTY, and stdin is closed. Commands that prompt (sudo, ssh passwords) get EOF and fail instead of hanging. Use the
stdinargument to feed input.Long commands don't block.
run_commandwaits 30 seconds by default, under the roughly 60-second limit many MCP clients put on one call. A command still running after that becomes a job: Claude gets the output so far and ajob_id, and follows up withread_outputorstop_command. The command keeps running until it finishes or reachestimeout_seconds. While a call waits, the server sends progress notifications, so clients that support them can keep it alive.Timeouts,
stop_commandand cancellation kill the whole process tree: SIGTERM, then SIGKILL 2 seconds later. Cancelling a call that's waiting on a command (for example, pressing stop in the app) stops that command too.Long output keeps its start and end. Each stream shows its first 20 KB and last 20 KB, where errors usually are. Anything in between is saved to a file next to the log (
~/Library/Logs/host-shell-mcp/output/), and the result gives its path. Output files are deleted after a day.git and gh never prompt or page. Commands get
GIT_TERMINAL_PROMPT=0,GCM_INTERACTIVE=never,GIT_PAGER=cat,PAGER=catandGH_PROMPT_DISABLED=1, so a missing credential fails right away instead of hanging.VM paths are translated when it's safe. Cowork shows your shared folders inside its VM as
/sessions/<id>/mnt/<folder>, and Claude sometimes passes those ascwd. The server translates such a path when exactly one host folder with that name exists, looking in your allowed folders and the usual places like~/Developmentand~/Desktop, and says so in the result. If there's no match or more than one, Claude gets an error asking for the host path instead of a guess.Background jobs don't block.
cmd &returns as soon as the shell exits, and the job keeps running. Redirect its output (nohup cmd > /tmp/cmd.log 2>&1 &).Client disconnect. When stdin closes, stdout breaks, or the server gets a signal, it stops running commands and exits.
stdout is protocol only. All logging goes to stderr.
Development
npm test # against server.js
npm run cowork-plugin && npm run test:plugin # against the packaged pluginThe tests start the real server over stdio with throwaway settings. They cover the sandbox, including scripts in other languages and attempts to edit the settings. A test hook stands in for the dialog.
This server cannot be deployed
Maintenance
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
The trust harness for AI agents. Set what an agent can do before it acts.
Runtime permission, approval, and audit layer for AI agent tool execution.
Security gateway for AI agents: policy, approval, and audited execution, no secrets shared.
Related MCP Servers
- AlicenseAqualityFmaintenanceAllows AI assistants to safely execute common Unix/macOS terminal commands through a controlled interface with comprehensive security features.810MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to securely execute shell commands on local machines through an SSH interface with session management, command execution, and sudo support.1-
- AlicenseAqualityFmaintenanceEnables AI assistants to execute terminal commands on a host machine with configurable, granular permission controls and safety protections. It features multiple security modes, including allowlists and manual approval, to ensure safe command execution within specified directories.6Apache 2.0
- AlicenseNot gradedqualityDmaintenanceEnables AI services like Claude and Cursor to remotely control a Mac by executing shell commands, managing files, and running AppleScript for UI automation. Access is secured through OAuth 2.0 authentication and encrypted tunnels to protect remote interactions.2MIT