remote-control-mcp

remote-control-mcp

Enables 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.

Category
访问服务器

README

remote-control-mcp

License: MIT Node MCP SDK

An MCP server that gives AI services (Claude, Cursor, etc.) remote control of your Mac — execute shell commands, read/write files, and run AppleScript — secured with OAuth 2.0 + PKCE.

Demo

remote-control-mcp demo

Claude searches for a tteok shop on Naver Maps, gets driving directions, takes a screenshot, and emails the result. All done in the Claude app on iOS.


What it does

  • Exposes your Mac as an MCP server reachable over the internet through a secure tunnel
  • Runs shell commands (zsh) asynchronously and returns stdout, stderr, and exit code
  • Reads and writes files and directories using fs.promises — no shell injection surface
  • Executes AppleScript for UI automation and app control
  • Protects every tool call with OAuth 2.0 + PKCE; token rotation revokes old tokens immediately
  • Optional file server (port 3835) to share files from ~/Public/mcp-files/ via browser or any HTTP client

⚠️ Security Warning

This server provides remote shell execution on your Mac.

  • OAuth 2.0 + PKCE protects the MCP endpoint — valid tokens are required for all tool calls
  • PIN-gated authorization — connecting a new client requires a one-time PIN generated by rcmcp auth on your local machine. The PIN is never written to disk and is only accessible via localhost. Anyone who reaches /authorize without the PIN cannot obtain a token.
  • The network layer is your second line of defense — always terminate TLS before exposing the server. Plain HTTP exposes OAuth tokens in transit regardless of whether you use a domain name or a raw IP.

This server is designed for personal, single-user use behind a private tunnel. Do not expose it to untrusted networks.


Requirements

  • macOS (Linux support planned; AppleScript tools are macOS-only)
  • Node.js >=20.16.0 or >=22.3.0
  • A tunnel to expose the server — Cloudflare Tunnel, ngrok, or Tailscale (see below)
  • Redis (required in production for token persistence; in-memory fallback used without it)

Quick Start

Automated (recommended)

setup.sh handles everything interactively — dependencies, .env, build, tunnel, LaunchAgent, and CLI:

git clone https://github.com/hexpy-games/remote-control-mcp
cd remote-control-mcp
./setup.sh

Manual

git clone https://github.com/hexpy-games/remote-control-mcp
cd remote-control-mcp
npm install
cp .env.example .env
# Edit .env — set BASE_URI to your tunnel URL
npm run build
npm start

Then set up a tunnel (see below) and add the server URL to your AI client.


Tunnel Options (for manual setup)

Never expose the server over plain HTTP. Always terminate TLS — via a tunnel or a reverse proxy:

setup.sh automates Options 1 and 2 (Cloudflare Tunnel and ngrok).

Option 1: Cloudflare Tunnel (recommended — free, stable URL)

brew install cloudflared

# Permanent subdomain (requires free Cloudflare account)
cloudflared tunnel login
cloudflared tunnel create remote-control-mcp
cloudflared tunnel route dns remote-control-mcp your-subdomain.yourdomain.com
# Set BASE_URI=https://your-subdomain.yourdomain.com in .env
cloudflared tunnel run remote-control-mcp

One-shot (URL changes each run, useful for testing):

cloudflared tunnel --url http://localhost:3232

Option 2: ngrok (quick setup, generous free tier)

brew install ngrok
ngrok config add-authtoken <your-token>
ngrok http 3232
# Copy the https URL and set it as BASE_URI in .env

The ngrok free tier assigns a random URL on each restart — update BASE_URI in .env after each restart, then run rcmcp restart server. Paid plans support a fixed static domain.

Option 3: Self-hosted (advanced)

Only use this if you have proper TLS termination in place:

  1. Forward port 3232 on your router to your Mac
  2. Set BASE_URI to your domain or public IP in .env
  3. Terminate TLS at a reverse proxy — plain HTTP exposes OAuth tokens in transit
# Example: Caddy as a TLS-terminating reverse proxy
brew install caddy
# Caddyfile:
# your-domain.com {
#   reverse_proxy localhost:3232
# }
caddy run

Connect to Claude

After the server is running and a tunnel is up:

1. Add the MCP server in Claude

In Claude.ai (desktop or web): go to Settings → Integrations → Add Integration and paste your server URL:

https://your-tunnel-url/mcp

Claude will immediately start an OAuth authorization flow.

2. Authorization

A browser window will open asking you to approve the connection. This is where you enter the Server PIN.

Get your PIN:

rcmcp auth

This generates a fresh one-time PIN, copies it to your clipboard, and waits for you to complete the authorization:

  Authorization PIN
  ────────────────────────────────────────

    9aRs-VhzM   (copied to clipboard)

  → Enter this PIN on the /authorize approval page.

  ⠙  Waiting for authorization...

Paste the PIN into the browser form and click Approve. The terminal will confirm automatically:

  ✓ Authorization complete

3. Start using remote tools

Once authorized, Claude has access to four tools on your Mac:

Tool What it does
shell_exec Run any zsh command
osascript Run AppleScript (UI automation, app control)
file_read Read files or list directories
file_write Write files (creates directories as needed)

Example prompts to try:

  • "Take a screenshot and describe what's on my screen"
  • "What files are in my Downloads folder?"
  • "Search for coffee shops near me on Maps and send me the directions"

Other clients: Any MCP-compatible client (Cursor, Windsurf, etc.) can connect using the same server URL. The OAuth flow is standard.


Configuration

Copy .env.example to .env and edit as needed.

Variable Default Description
PORT 3232 Port the MCP server listens on
BASE_URI http://localhost:3232 Public URL of this server — must match your tunnel URL
NODE_ENV development Set to production when deploying
BLOCKED_COMMANDS (empty) Comma-separated substrings to block in shell_exec
REDIS_URL (unset) Redis connection URL — required in production
REDIS_TLS 0 Set to 1 to enable TLS for the Redis connection

Redis

Redis is required in production for token persistence and expiry. Without it, tokens are stored in memory and lost on restart.

# Docker
docker run -d -p 6379:6379 redis:7-alpine

# Homebrew
brew install redis && brew services start redis

Set REDIS_URL=redis://localhost:6379 in .env.


Available Tools

Tool Description
shell_exec Execute a zsh command on the Mac. Runs asynchronously; supports concurrent commands. Returns stdout, stderr, and exit code.
osascript Execute an AppleScript. Scripts are written to a private temp directory to prevent TOCTOU races. Use for UI automation and app control.
file_read Read file contents or list a directory. Uses fs.promises directly — no shell spawning.
file_write Write content to a file. Creates intermediate directories if needed.

Security notes

  • BLOCKED_COMMANDS is a last-resort safeguard, not a security boundary. Security is enforced at the OAuth + tunnel layer.
  • Refresh token rotation revokes the previous token immediately.
  • A default blocklist prevents the most catastrophic commands (rm -rf /, fork bombs, direct disk writes, etc.).

rcmcp CLI

setup.sh installs rcmcp, a management CLI for day-to-day operations:

rcmcp status                    # server + tunnel + file server status and endpoint URL
rcmcp start [server|tunnel|fileserver|all]
rcmcp stop  [server|tunnel|fileserver|all]
rcmcp restart [server|tunnel|fileserver|all]
rcmcp logs [server|tunnel|fileserver|all] [-f]
rcmcp url                       # print current MCP endpoint URL
rcmcp update                    # git pull → rebuild → restart server
rcmcp uninstall                 # remove LaunchAgents, binary, and PATH entry

Targets can be abbreviated: srv, tun, fs.


File Server (optional)

setup.sh can install an optional lightweight file server (port 3835) that serves files from ~/Public/mcp-files/ over HTTP. Useful for sharing or viewing Mac files from any browser, HTTP client, or AI service.

GET https://your-tunnel-url/files/<filename>

Managed via rcmcp start fileserver / rcmcp stop fileserver.


Development

# Run with live reload
npm run dev

# Type-check without emitting
npm run typecheck

# Lint
npm run lint

# Build
npm run build

Contributing

Reporting issues

  • Bug: Open an issue with the prefix [bug]. Include OS version, Node version, reproduction steps, and expected vs. actual behavior.
  • Feature request: Open an issue with the prefix [feat]. Describe the use case, not just the solution.

Submitting a PR

  1. Fork the repo and create a branch from main
  2. Follow branch naming conventions:
    • feat/ — new feature
    • fix/ — bug fix
    • docs/ — documentation only
    • chore/ — tooling, deps, CI
  3. Run npm run lint and npm run typecheck — both must pass
  4. Open a PR against main with a clear description of what and why

Commit style

Use Conventional Commits:

feat: add Tailscale tunnel option
fix: prevent shell_exec hanging on commands with no output
docs: clarify Redis requirement in README
chore: upgrade MCP SDK to 1.25

What gets accepted

  • Security improvements
  • New MCP tools that fit the "remote Mac control" scope
  • Additional tunnel provider support
  • Bug fixes

What gets rejected

  • Changes that remove the OAuth requirement
  • Features that broaden scope to multi-user or server-side use cases

License

MIT — Copyright (c) 2026 Hexpy Games & remote-control-mcp contributors

See LICENSE for the full text.


Disclaimer

This project is not affiliated with, endorsed by, or sponsored by Anthropic, Claude.ai, or any other AI service provider.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选