mac-bridge-mcp
An MCP server that runs on a Mac and exposes a small, sharp set of tools (shell, file transfer, binary execution, screenshots) over a token-protected network port.
README
๐ mac-bridge-mcp
Let an AI securely drive a macOS machine, from anywhere.
An MCP server that runs on a Mac and exposes a small, sharp set of tools (shell, file transfer, binary execution, screenshots) over a token-protected network port. Point your AI client at it and it can build, test, and automate on macOS, even when your AI is running on Windows or Linux.
your machine (Windows / Linux / Mac) the Mac you want to control
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ AI client (MCP host) โ HTTP + โ mac-bridge-mcp โ
โ e.g. Claude Desktop, an agent โ โโโโโโโโบ โ โโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ bearer โ โ IP allowlist โ token โ โ
โ "build & test my binary on macOS" โ token โ โโโโโโโโโโโโฌโโโโโโโโโโโโ โ
โ โ โโโโโโโโ โ shell ยท files ยท exec โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ results โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๏ธ Warning - this is remote code execution on the host Mac, by design. Anyone who can reach the port and has the token gets the equivalent of a shell. Run it only on machines you own, keep the port off the public internet, and read the Security model before exposing it anywhere. The token is as sensitive as an SSH key.
Table of contents
- Why
- Features
- Quickstart
- Installation
- Configuration
- Connecting your AI client
- Tools
- Example: cross-platform binary test loop
- Security model
- macOS permissions
- License
Why
If you ship software that has to run on both Windows and macOS, you constantly
need "the other OS" in the loop, to compile a native binary, run the test
suite, reproduce a platform-specific bug, or grab a screenshot of how something
renders. mac-bridge-mcp puts a Mac one tool-call away from whatever AI you're
already working with, so a single conversation can drive both platforms.
The original motivation was cross-platform security research. When an AI
reviews source code that compiles on Windows, Linux, and macOS, it will sometimes
surface a vulnerability that only manifests on macOS, and then have no way to
confirm it. Lacking access to a macOS system, it can't compile the affected code,
run a proof-of-concept, and check whether the finding is genuine or a false
positive. mac-bridge-mcp closes that gap: it gives the AI a real Mac to
compile, test, and verify on, so macOS-specific findings can be triaged on
the actual operating system instead of guessed at.
It speaks MCP's Streamable HTTP transport, so any MCP-capable client can use it, locally or across the network.
Features
- Real macOS control - shell commands, direct binary execution, file read/write, directory listing, and screen capture.
- Two security gates - an optional source-IP allowlist (with CIDR support) in front of a constant-time bearer-token check.
- Built-in TLS - serve HTTPS directly from a cert + key, or rely on an SSH tunnel / VPN. No reverse proxy required.
- Optional filesystem jail - confine every operation under one directory.
- Works across machines - drive a Mac from Windows or Linux over an SSH tunnel or a private VPN.
- Tiny and readable - one dependency-light Python module, easy to audit and extend.
- Client-agnostic - works with any MCP host, with a drop-in
mcp-remoteconfig for stdio-only clients.
Quickstart
On the Mac (the machine you want to control):
# 1. Get the code and install the two dependencies
git clone https://github.com/YOUR_USERNAME/mac-bridge-mcp
cd mac-bridge-mcp
pip install fastmcp uvicorn # or: pip install -r requirements.txt
# 2. Generate a token and run the server
export MCP_BRIDGE_TOKEN="$(python3 -c 'import secrets;print(secrets.token_urlsafe(32))')"
echo "Token: $MCP_BRIDGE_TOKEN" # copy this
python3 src/mac_bridge_mcp/server.py
With the default MCP_BRIDGE_HOST=127.0.0.1, the server is reachable only from
the Mac itself. To connect from another machine, open an SSH tunnel and point
your client at the local end of it:
ssh -L 8765:127.0.0.1:8765 you@your-mac # then connect to http://127.0.0.1:8765/mcp
If you bind to an address your other machine can already reach, for example
the Mac's Tailscale or LAN IP via MCP_BRIDGE_HOST, you don't need the
tunnel. Just connect straight to http://<that-ip>:8765/mcp. In that case
encrypt the connection by enabling TLS / HTTPS (or keep it on a
trusted private network/VPN), and never bind to a public address (see the
Security model).
Installation
From source:
git clone https://github.com/YOUR_USERNAME/mac-bridge-mcp
cd mac-bridge-mcp
pip install -e .
Requires Python 3.10+ on macOS.
Configuration
Everything is configured through environment variables (or a local .env, see
.env.example).
| Variable | Default | Purpose |
|---|---|---|
MCP_BRIDGE_TOKEN |
random | Shared secret ("password"). Set it to keep it stable across restarts. |
MCP_BRIDGE_HOST |
127.0.0.1 |
Bind address. Do not use 0.0.0.0 on an untrusted network. |
MCP_BRIDGE_PORT |
8765 |
Listen port. |
MCP_BRIDGE_PATH |
/mcp |
URL path for the MCP endpoint. |
MCP_BRIDGE_SHELL |
/bin/zsh |
Shell used by run_command. |
MCP_BRIDGE_ALLOW_IPS |
unset | Comma-separated IPs/CIDRs allowed to connect. Unset = any IP (token still required). |
MCP_BRIDGE_ROOT |
unset | Confine all file/binary operations under this directory. |
MCP_BRIDGE_TLS_CERT |
unset | Path to a PEM certificate. Set with MCP_BRIDGE_TLS_KEY to serve HTTPS. |
MCP_BRIDGE_TLS_KEY |
unset | Path to the certificate's private key (PEM). |
MCP_BRIDGE_TLS_KEY_PASSWORD |
unset | Password for the private key, if it is encrypted. |
MCP_BRIDGE_TRUST_FORWARDED |
unset | Read client IP from X-Forwarded-For. ONLY behind a proxy you control. |
Connecting your AI client
The server and your AI usually run on different machines. Two cases:
Your client supports remote / HTTP MCP servers directly - point it at
http://<host>:8765/mcp and add the header Authorization: Bearer <token>.
Your client only launches local stdio servers (the classic Claude Desktop
pattern), use the mcp-remote
bridge, which runs locally and forwards to the remote server. See
examples/claude_desktop_config.json:
{
"mcpServers": {
"mac-bridge": {
"command": "npx",
"args": [
"mcp-remote",
"http://MAC_IP_OR_HOST:8765/mcp",
"--header", "Authorization: Bearer YOUR_TOKEN_HERE"
]
}
}
}
Test before wiring up an AI with the MCP Inspector (no model required):
npx @modelcontextprotocol/inspector
# URL: http://127.0.0.1:8765/mcp (transport: Streamable HTTP)
# Header: Authorization: Bearer <token>
...or run the included smoke test:
TOKEN=your-token ./examples/smoke_test.sh
Tools
| Tool | Description |
|---|---|
system_info |
macOS version, CPU architecture (arm64 / x86_64), hostname, user. Call first. |
run_command |
Run a shell command; returns stdout, stderr, exit code, timeout flag. |
run_binary |
Execute a binary directly with verbatim args (no shell parsing). |
list_dir |
List a directory with type, size, and mode for each entry. |
read_file |
Read a file as text, or base64 for binaries. |
write_file |
Write a file; base64_encoded + make_executable for pushing binaries. |
screenshot |
Capture the screen as a base64 PNG (needs Screen Recording permission). |
Every tool returns a structured result and handles its own errors, so the AI gets a clean signal instead of a stack trace.
Example: cross-platform binary test loop
A typical "I built it on Windows, does it work on macOS?" round-trip:
system_info- confirmarchisarm64vsx86_64.write_file- push your built artifact (base64,make_executable=true).run_binary- run it with test arguments; inspectstdout/exit_code.read_file- pull back any output files it produced.
Because the AI sees the architecture first, it can pick the right build and even
recompile via run_command (clang, cargo build, go build, ...) before
testing.
๐ Security model
Requests pass through two gates, in order, on every request:
- IP allowlist (
MCP_BRIDGE_ALLOW_IPS) - a peer outside the list is rejected with 403 before the token is even compared. Supports single addresses and CIDR ranges, IPv4 and IPv6. - Bearer token - checked with a constant-time comparison; missing/wrong gives 401.
An optional filesystem jail (MCP_BRIDGE_ROOT) then confines every path
argument to a chosen directory.
What IP does the server actually see?
-
SSH tunnel - traffic arrives from
127.0.0.1(the tunnel exit on the Mac), so include127.0.0.1/::1in the allowlist; your real gate there is the SSH login itself. -
Tailscale / WireGuard / LAN - the server sees the client's real address, so the allowlist is meaningful. Pin it to your client's VPN IP or LAN subnet:
export MCP_BRIDGE_ALLOW_IPS="127.0.0.1,::1,100.64.0.0/10,192.168.1.0/24"
Operating rules of thumb
- Keep
MCP_BRIDGE_HOST=127.0.0.1; reach the server via SSH tunnel or a private VPN. Never put it on the public internet. - Use a long random token; rotate it if it leaks; never commit
.env. - Run as a normal user, not root.
- Encrypt the connection. The server can serve HTTPS itself (see
TLS / HTTPS), or you can rely on an SSH tunnel / VPN for
encryption. Don't send the token over plain HTTP across a network. Leave
MCP_BRIDGE_TRUST_FORWARDEDoff unless a reverse proxy you control sets it.
TLS / HTTPS
The server has built-in TLS, point it at a certificate and key and it serves
https:// directly, no reverse proxy required:
export MCP_BRIDGE_TLS_CERT="/path/to/server.crt"
export MCP_BRIDGE_TLS_KEY="/path/to/server.key"
python3 src/mac_bridge_mcp/server.py # now on https://...
Three easy ways to get a certificate, best first:
-
Tailscale (recommended): if you reach the Mac over Tailscale, run
tailscale cert <machine>.<tailnet>.ts.net. You get a real, trusted certificate with no client-side configuration, clients verify it normally. -
mkcert (LAN):
mkcertinstalls a local CA and issues certs your machines trust. Good for a home/office LAN. -
Self-signed: run
examples/gen_self_signed_cert.sh. The traffic is encrypted, but clients don't trust a self-signed cert by default and will refuse to connect until told to trust it. For themcp-remotebridge that means pointing Node at your cert:NODE_EXTRA_CA_CERTS=/path/to/server.crt npx mcp-remote https://<host>:8765/mcp \ --header "Authorization: Bearer <token>"
When TLS is on, use https:// in every client URL. The MCP_BRIDGE_ALLOW_IPS
and token gates apply exactly the same over HTTPS.
macOS permissions
- Shell and file tools need no special permission.
screenshotneeds Screen Recording for whatever process runs the server (Terminal / iTerm /python): System Settings -> Privacy & Security -> Screen Recording, then restart that app.- Future mouse/keyboard control will need Accessibility permission in the same place.
License
MIT ยฉ IamLeandrooooo
Built on the Model Context Protocol and FastMCP.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.