macos-sys-assist
Provides tools to automate macOS system operations including application control, window management, file system access, input simulation, and screenshots via native macOS Accessibility APIs.
Click on "Install 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., "@macos-sys-assistfind my budget spreadsheet and open it"
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.
macos-sys-assist
A secure, constraint-based macOS OS-level automation MCP server for AI assistants.
What Is This?
macos-sys-assist is a Python-based MCP (Model Context Protocol) server that enables AI assistants to safely interact with macOS at the system level. It uses native macOS Accessibility APIs via pyobjc, eliminating the risks associated with shell execution.
Key Features
No Shell Execution — All operations use native macOS APIs, never
os.system()orsubprocessApplication Allow-List — Only pre-approved apps can be interacted with
Multi-Step Task Engine — Parse complex prompts into executable chains of actions
File System — Find, read, and open files safely
Screenshots — Capture full screen, windows, or regions
Clipboard — Read and write clipboard contents
App Lifecycle — Launch, quit, and focus applications
Window Management — Move, resize, snap to halves/quarters
Input Simulation — Click, type, press key combinations
Related MCP server: macos-mcp
Quick Start
Installation
git clone https://github.com/YOUR_USERNAME/macos-sys-assist.git
cd macos-sys-assist
./setup.shGrant Permissions
Accessibility — System Settings → Privacy & Security → Accessibility → Add Terminal/Python
Screen Recording (for screenshots) — System Settings → Privacy & Security → Screen Recording → Add Terminal/Python
Configure Apps
Edit allowed_apps.json to control which apps can be automated.
Usage
Standalone Mode
./run.shOpenCode Integration
Add to opencode.jsonc:
"mcp": {
"macos-sys-assist": {
"type": "local",
"command": ["/path/to/macos-sys-assist/run.sh"],
"enabled": true
}
}Direct Python Usage (via bash)
.venv/bin/python3 -c "
import sys
sys.path.insert(0, '.')
from macos.accessibility import AccessibilityWrapper
a = AccessibilityWrapper()
print(a.get_frontmost_app())
"Complete Tool Reference
App Intelligence (Read-Only)
Tool | Description | Returns |
| Get currently focused application | name, bundle_id, pid |
| List all running apps with windows | name, bundle_id, pid |
| Info about a specific app | name, bundle_id, pid, active |
| Get primary display resolution | width, height |
| Get all connected displays | list of displays |
File System (Read-Only)
Tool | Description | Returns |
| Search files by name/pattern | file list with paths, sizes |
| Read text file contents | content, lines, size |
| List directory contents | files, folders, counts |
| Open file in default app | status, filename |
| Read clipboard text | content, length |
| Check clipboard state | boolean, length |
Input Simulation
Tool | Description | Security |
| Click at screen coordinates | ⚠️ Confirmation |
| Type text character by character | ⚠️ Confirmation |
| Press key combo (e.g., | ⚠️ Blocked combos |
| Write text to clipboard | ⚠️ Confirmation |
Window Management
Tool | Description | Security |
| Move active window to coords | ⚠️ Confirmation |
| Resize active window | ⚠️ Confirmation |
| Get window position/size | Read-only |
App Lifecycle
Tool | Description | Security |
| Launch an application | ⚠️ Allow-list |
| Quit an application | ⚠️ Allow-list |
| Bring app to front | ⚠️ Allow-list |
Screenshots (Requires Screen Recording Permission)
Tool | Description |
| Capture full screen |
| Capture specific window |
| Capture screen region |
Multi-Step Task Engine
How It Works
The task engine decomposes complex natural language prompts into executable steps. Each step's output can be chained into the next step's input.
Supported Prompt Patterns
Pattern | Example |
| "Find readme.md in Downloads and open it" |
| "Open data.csv in downloads folder" |
| "Find and open report.pdf" |
| "Open notes.txt" (auto-searches Downloads) |
| "Launch Safari" |
| "List Downloads" |
| "Find all .pdf files in Documents" |
| "What app is currently focused?" |
Example: Find and Open File
from macos.task_engine import PromptParser, TaskEngine
from macos.filesystem import FileSystemManager
from macos.app_lifecycle import AppLifecycleManager
from macos.window import WindowManager
from macos.input import InputSimulator
from macos.accessibility import AccessibilityWrapper
# Parse the prompt
steps = PromptParser.parse("Find readme.md in Downloads and open it")
# Output:
# Step 1: find_files(directory="~/Downloads", pattern="readme.md")
# Step 2: open_file(filepath=<result_of_step_1>)
# Execute
engine = TaskEngine(
FileSystemManager(),
AppLifecycleManager(),
WindowManager(),
InputSimulator(),
AccessibilityWrapper()
)
result = engine.execute(steps)
print(result.final_output)
# Output:
# ✅ Find 'readme.md' in ~/Downloads: Found 1 items
# ✅ Open the found fileConfiguration
allowed_apps.json
Controls which apps can be automated and what actions are allowed:
{
"allowed_apps": [
{
"bundle_id": "com.apple.Safari",
"name": "Safari",
"allow_actions": true
},
{
"bundle_id": "com.microsoft.VSCode",
"name": "Visual Studio Code",
"allow_actions": true
}
],
"global_settings": {
"require_confirmation_for_click": true,
"require_confirmation_for_type": true,
"require_confirmation_for_key": false,
"max_string_length": 500,
"blocked_key_combinations": [
"cmd+q",
"cmd+delete",
"ctrl+alt+delete"
]
}
}Finding Bundle IDs
osascript -e 'id of app "Safari"'
# Output: com.apple.SafariCommon Bundle IDs
App | Bundle ID |
Safari |
|
Google Chrome |
|
Brave Browser |
|
Visual Studio Code |
|
Terminal |
|
Finder |
|
Security Model
Design Principles
Least Privilege — Only minimum necessary capabilities exposed
No Shell Access — All operations use native macOS APIs
Explicit Allow-List — Only pre-approved apps can be controlled
Human-in-the-Loop — Invasive actions require user confirmation
Input Validation — Text length limits, key combo blocking
6-Layer Security
1. Application Allow-List → Only approved bundle IDs pass
2. Action Permission Check → Per-app allow_actions flag
3. Input Validation → Text length, key combo validation
4. Blocked Operations → Destructive shortcuts rejected
5. Confirmation Prompts → User approval for invasive actions
6. Native API Only → No shell, no AppleScriptWhat's Blocked
Threat | Mitigation |
Arbitrary command execution | No |
Unauthorized app control | Application allow-list |
Destructive key combos | Blocked combinations list |
Excessive text input | Maximum string length (500) |
Unconfirmed actions | Confirmation prompts |
Project Structure
macos-sys-assist/
├── server.py # Main MCP server entry point
├── config.py # Configuration management
├── security.py # Security validation layer
├── allowed_apps.json # Application allow-list
├── requirements.txt # Python dependencies
├── setup.sh # Installation script
├── run.sh # Wrapper script
├── macos/ # Native macOS API wrappers
│ ├── accessibility.py # App queries, screen info
│ ├── window.py # Window move/resize
│ ├── input.py # Mouse/keyboard simulation
│ ├── filesystem.py # File search, read, open
│ ├── app_lifecycle.py # Launch, quit, focus apps
│ ├── screenshot.py # Screen capture
│ ├── clipboard.py # Clipboard read/write
│ └── task_engine.py # Multi-step task execution
└── tools/ # MCP tool definitions
├── information.py # Read-only app/screen tools
├── actions.py # Input/window action tools
├── filesystem.py # File system tools
├── screenshot.py # Screenshot tools
└── clipboard.py # Clipboard toolsRoadmap
Completed ✅
Base MCP server with app intelligence and input simulation
Window management (move, resize, snap)
Application lifecycle (launch, quit, focus)
File system operations (find, read, open, list)
Screenshot capability (full screen, window, region)
Clipboard operations (read, write, check)
Multi-step task engine with prompt parser
Planned 📋
Push to GitHub as public repository
Notification center integration
Volume/brightness control
Multi-monitor window management
Drag and drop simulation
Troubleshooting
"Accessibility permission not granted"
System Settings → Privacy & Security → Accessibility
Add Terminal.app or
.venv/bin/python3Ensure toggle is ON
Restart the server
"Screen Recording permission required"
System Settings → Privacy & Security → Screen Recording
Add Terminal.app or
.venv/bin/python3Ensure toggle is ON
Restart the server
"App not in allow-list"
Find the app's bundle ID:
osascript -e 'id of app "AppName"'Add it to
allowed_apps.jsonRestart the server
MCP tools not appearing in OpenCode UI
Known OpenCode bug. The server loads correctly but tools don't appear in the UI. Use the bash fallback method:
.venv/bin/python3 -c "import sys; sys.path.insert(0, '.'); from macos.accessibility import AccessibilityWrapper; print(AccessibilityWrapper().get_frontmost_app())"License
MIT License — see LICENSE
Acknowledgments
Built for the OpenCode AI assistant framework.
Uses the Model Context Protocol for tool integration.
Powered by pyobjc for native macOS API access.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/kbdiamondes/macos-sys-assist'
If you have feedback or need assistance with the MCP directory API, please join our Discord server