Mac Shell MCP Server
Exposes a macOS shell command execution tool plus a self-service whitelist/approval management workflow.
execute_command: run a shell command on macOS with optional arguments.get_whitelist: list whitelisted commands and their security levels.add_to_whitelist: add a command with a security level (safe,requires_approval,forbidden).update_security_level: change the security level of a whitelisted command.remove_from_whitelist: remove a command from the whitelist.get_pending_commands: list commands pending approval.approve_command: approve a pending command by ID.deny_command: deny a pending command by ID, optionally with a reason.
Caveat: this schema matches the 1.x API; the README says these whitelist-editing and approval tools were removed in 2.0.0.
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., "@Mac Shell MCP Server list all files in my Downloads folder"
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.
Mac Shell MCP Server
An MCP server that lets an AI client run a small, fixed set of read-only shell commands, confined to directories you nominate.
It is built around one idea: the agent cannot widen its own authority. There is no tool that edits the policy, no approval queue the agent can drain, and no shell to interpret its arguments.
Upgrading from 1.x? 2.0.0 is a breaking change. Seven tools were removed and the authorization model was replaced. See Migrating from 1.x. 1.x contained two vulnerabilities reported by four independent researchers; see the security advisories.
What it does
Tool | What it is for |
| Run a permitted command inside your configured directories |
| Run one outside them — requires a client that can ask a human |
| Chain read-only commands, stdout to stdin, without a shell |
| Ask what is permitted, rather than guessing and being refused |
| Turn observed usage into config you apply |
Related MCP server: Terminal MCP Server
Default commands
ls pwd echo cat head tail wc grep
Each is restricted to an allowlist of flags. None of them can write a file, execute another program, or read configuration from the environment.
find, git, rm and every interpreter are absent by default. You can add any of them, and should know why they are not there:
find -fprintfwrites attacker-chosen content to an attacker-chosen path, whilefindis naturally classified read-onlygitexecutes commands from a repository's own.git/config, and no environment variable disables thatinterpreters (
python,perl,awk,node,osascript, …) take inline code as an argument
Install
npm install -g @the_cfdude/mac-shell-mcpThen create a policy:
mkdir -p ~/.mac-shell-mcp
cp .mac-shell-mcp.sample.json ~/.mac-shell-mcp/config.json
$EDITOR ~/.mac-shell-mcp/config.json # set allowedRoots to your project
chmod 444 ~/.mac-shell-mcp/config.json # defence in depth; see SecurityAdd to your MCP client:
{
"mcpServers": {
"mac-shell": { "command": "npx", "args": ["-y", "@the_cfdude/mac-shell-mcp"] }
}
}A fresh install with no roots configured refuses everything — deliberately. Each refusal names the permitted commands and where configuration lives, so the first failure tells you what to do.
Configuration
Policy is found in this order, first match wins, never merged:
$MAC_SHELL_MCP_CONFIG— an explicit path~/.mac-shell-mcp/config.jsonHost environment (
MAC_SHELL_ROOTS,MAC_SHELL_COMMANDS)Built-in defaults
Policy is never read from the working directory. A cloned repository must not be able to supply the policy governing the agent that opens it.
{
"allowedRoots": ["/Users/you/Projects/my-project"],
"programDirectories": ["/usr/bin", "/bin", "/usr/sbin", "/sbin"],
"commands": {
"grep": {
"program": "/usr/bin/grep",
"effect": "read",
"allowedArgs": ["-i", "-n", "-r", "-l", "-E", "-F"],
"permission": "allow",
},
},
}permission is allow, ask, or deny. ask requires a client offering MCP elicitation — the only capability that means a human can be asked. Where it is absent, ask becomes deny, never allow.
How it decides
Authorization is effect × scope, computed per call. grep inside your project is free; the same grep against ~/.aws is not. The command name alone never decides.
No shell.
execFileis never given ashelloption, so arguments reach the OS uninterpreted. Nothing evaluates;,$(), or backticks — which is also why filenames with spaces, parentheses and brackets work normally.The program is authorized, not just the arguments. Commands resolve to an absolute path from your program directories, are matched by that resolved path rather than by basename, and are refused if they resolve inside one of your roots. Roots hold data, never code.
The environment is constructed, not inherited, so a variable like
RIPGREP_CONFIG_PATHcannot smuggle in a helper program that never appears in the argument list.Allowlists, never denylists. A denylist is a list of the flags somebody thought of.
Scope includes the working directory, so a command with no path argument is judged by where it runs rather than passing because it named nothing.
Security
The policy file, its parent directories, your program directories, and the whole audit log directory are protected locations. The default command set contains nothing that writes, so none of them is reachable out of the box. If you add a command that writes (cp, mv, rm, tee, ln, chmod, and a few others, by name), the server refuses any call whose path arguments land on a protected location, matched by filesystem identity as well as by path. That check is keyed on the command's name, not on what an arbitrary program might do: a writing command outside that list is not covered, so add one only if you trust what it can write.
chmod 444 on your config is worth doing as a second, independent layer. It is not the mechanism: replacing a file needs write permission on its directory, not the file.
Every request, permitted or refused, is recorded to an append-only audit log.
Known limits, stated rather than implied — see SECURITY.md:
Path detection is heuristic, and fails closed
Everything inside a root is freely readable by one recursive search
askis only as strong as the host's approval promptFlag meanings vary between implementations of the same command name
Report vulnerabilities via private advisory or security@onvex.ai.
Migrating from 1.x
Removed: add_to_whitelist, update_security_level, remove_from_whitelist, approve_command, deny_command, get_pending_commands, get_whitelist.
The first three let any client promote a forbidden command to safe. The next three formed an approval workflow the requesting agent could drain by itself. get_whitelist is replaced by get_policy.
Runtime whitelist edits become a config file you edit and the server reads at startup. rm was FORBIDDEN in 1.x and remains unavailable, so nothing that worked before stops working.
Development
npm install && npm run build
npm test # run it twice; a suite that only passes once is not passing
npm run lint && npm run format:checkDesign and specifications: openspec/changes/mac-shell-mcp-2-security-redesign/.
License
MIT — see LICENSE.
Available Tools
8 toolsadd_to_whitelistC
Add a command to the whitelist
Inputs: command (required), securityLevel (required), description.
approve_commandC
Approve a pending command
Inputs: commandId (required).
deny_commandC
Deny a pending command
Inputs: commandId (required), reason.
execute_commandC
Execute a shell command on macOS
Inputs: command (required), args.
get_pending_commandsB
Get the list of commands pending approval
Inputs: no named parameters.
get_whitelistB
Get the list of whitelisted commands
Inputs: no named parameters.
remove_from_whitelistC
Remove a command from the whitelist
Inputs: command (required).
update_security_levelC
Update the security level of a whitelisted command
Inputs: command (required), securityLevel (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Each tool has a clearly distinct purpose with no ambiguity. The tools cover separate aspects of command management: whitelist operations (add/remove/get), approval workflow (approve/deny/get_pending), execution (execute_command), and security configuration (update_security_level). There is no overlap in functionality.
All tools follow a consistent verb_noun pattern with snake_case throughout. The naming is predictable and readable, using clear action verbs like 'add_to', 'remove_from', 'get', 'execute', 'approve', 'deny', and 'update' paired with appropriate nouns.
With 8 tools, this server is well-scoped for its macOS shell security management purpose. Each tool earns its place by covering essential operations for command whitelisting, approval workflows, execution, and security configuration without being excessive or insufficient.
The tool set provides complete coverage for the macOS shell security domain. It includes full CRUD operations for the whitelist (add, remove, get), comprehensive approval workflow management (approve, deny, get_pending), command execution, and security level updates, leaving no obvious gaps for agents to work with.
Maintenance
Related MCP Connectors
Connect ChatGPT and Claude to your Mac, Windows or Linux with secure MCP remote access.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server that lets your AI assistant build and deploy apps, hosting each one at a live URL.
Remote MCP server exposing your Node Command fleet (files, shell, processes, browser) to AI hosts.
Related MCP Servers
- AlicenseBqualityFmaintenanceA Model Context Protocol server that provides secure command-line access to Windows systems, allowing MCP clients like Claude Desktop to safely execute commands in PowerShell, CMD, and Git Bash shells with configurable security controls.9374 npm266MIT
- FlicenseNot gradedqualityDmaintenanceAn MCP server that allows AI assistants like Claude to execute terminal commands on the user's computer and return the output, functioning like a terminal through AI.91-
- AlicenseAqualityDmaintenanceAn MCP server that enables secure execution of shell commands across Windows, macOS, and Linux with built-in whitelisting and approval mechanisms for enhanced security.9104 npm23MIT
- AlicenseNot gradedqualityDmaintenanceAn enhanced MCP server that grants AI assistants the ability to execute terminal commands on a user's system with improved security controls, designed for use in controlled environments.2MIT