SYSTEM
remote mac automation
Control your Mac from anywhere using natural language. Built with Cloudflare Agents SDK for intelligent scheduling, memory, and tool orchestration.
quick start
desktop app (recommended)
The easiest way to get started. Download, install, and the app guides you through everything.
- Download SYSTEM.dmg from releases
- Drag to Applications
- Launch and follow the onboarding wizard
The app lives in your menu bar and handles permissions, configuration, and auto-starts everything.
cli (advanced)
git clone https://github.com/ygwyg/system
cd system && npm install
npm run setup # interactive wizard
npm start # start everything
permissions
SYSTEM requires 3 macOS permissions to control your Mac. The desktop app guides you through granting these.
| permission | why it's needed |
|---|---|
| Accessibility | Keyboard input, mouse control, window management |
| Screen Recording | Screenshots for visual context |
| Automation | Control apps: Finder, Safari, Notes, Calendar, Reminders, Music, Mail, System Events |
System Settings → Privacy & Security → [Permission] → Enable SYSTEM. The desktop app will prompt you and open the right settings pane automatically.
architecture
SYSTEM uses a split architecture for security: the Agent (brain) runs on Cloudflare Workers, while the Bridge (body) runs locally on your Mac.
┌───────────────────────────────────────────────────────┐ │ USER │ │ (phone/browser) │ └─────────────────────┬─────────────────────────────────┘ │ HTTPS ▼ ┌───────────────────────────────────────────────────────┐ │ AGENT (Brain) │ │ Cloudflare Workers │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Claude │ │ State │ │ Schedules │ │ │ │ AI │ │ (D.O.) │ │ (D.O.) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────┬─────────────────────────────────┘ │ Tunnel ▼ ┌───────────────────────────────────────────────────────┐ │ BRIDGE (Body) │ │ Your Mac (local) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ AppleScript │ │ Shell │ │ Raycast │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └───────────────────────────────────────────────────────┘
• Claude for NLP
• State, memory, scheduling
• WebSocket real-time
• AppleScript, shell exec
• Raycast extensions
• Cloudflare Tunnel
authentication
All requests require an API secret via Bearer token or query parameter.
// Header
Authorization: Bearer <api_secret>
// Or query parameter
?token=<api_secret>
The API secret is generated during npm run setup and stored in
bridge.config.json.
chat
Send natural language commands to control your Mac.
Send a message to the agent.
request
{
"message": "Play some jazz music"
}
response
{
"message": "Playing jazz on Apple Music",
"actions": [{
"tool": "music_play",
"args": { "query": "jazz" },
"success": true,
"result": "Now playing: Jazz Vibes"
}]
}
Clear conversation history and state.
schedules
Schedule one-time or recurring tasks using natural language or cron syntax.
List all scheduled tasks.
{
"schedules": [{
"id": "abc123",
"description": "Play closing time",
"scheduledAt": "2026-01-05T17:00:00Z",
"cron": "0 17 * * *"
}]
}
Cancel a scheduled task by ID.
• "Remind me to call mom in 30 minutes"
• "Every day at 5pm, play Closing Time"
• "At 9am tomorrow, open Linear"
state
The agent maintains persistent state including preferences and conversation history.
Get current agent state for debugging.
{
"preferences": { "wife": "Jane" },
"historyLength": 12,
"scheduleCount": 2
}
core tools
Foundational tools for Mac automation.
| tool | description |
|---|---|
open_app |
Open any application |
open_url |
Open URL in browser |
shell |
Run safe shell commands |
shell_list |
List available shell commands |
applescript |
Execute AppleScript |
notify |
Show macOS notification |
say |
Text-to-speech |
clipboard_get |
Get clipboard contents |
clipboard_set |
Set clipboard contents |
screenshot |
Take screenshot |
computer use agent (CUA)
Visual automation tools that let AI see and interact with any application. The CUA takes screenshots, analyzes them with Claude's vision, and executes mouse/keyboard actions.
Use the /computer-use endpoint to run a full agentic loop: screenshot →
analyze → act → verify → repeat until goal is complete.
vision & screenshots
| tool | description |
|---|---|
cua_screenshot |
Take screenshot for visual analysis |
cua_screen_info |
Get display information |
cua_get_windows |
List all visible windows with positions |
cua_mouse_position |
Get current cursor position |
mouse actions
| tool | description |
|---|---|
cua_click |
Click at coordinates (x, y) |
cua_double_click |
Double-click at coordinates |
cua_right_click |
Right-click (context menu) |
cua_drag |
Click and drag from point to point |
cua_scroll |
Scroll up/down/left/right |
keyboard actions
| tool | description |
|---|---|
cua_type |
Type text at cursor |
cua_key |
Press key combo (e.g., "cmd+c", "return") |
cua_select_all |
Cmd+A |
cua_copy |
Cmd+C |
cua_paste |
Cmd+V |
cua_undo |
Cmd+Z |
cua_save |
Cmd+S |
app & window control
| tool | description |
|---|---|
cua_focus_app |
Bring app to front |
cua_launch_app |
Launch application |
cua_window_manage |
Move, resize, minimize, maximize, close |
cua_menu_click |
Click menu item by path (e.g., "File > Save") |
cua_new_tab |
Cmd+T |
cua_switch_tab |
Switch to tab 1-9 |
cua_close_window |
Cmd+W |
utility
| tool | description |
|---|---|
cua_wait |
Wait N seconds |
cua_wait_for |
Wait for UI element to appear/disappear |
cua_open_url |
Open URL in default browser |
accessibility tools
Higher-level tools that find and interact with UI elements by role/title instead of coordinates.
| tool | description |
|---|---|
ax_get_elements |
Get UI tree of frontmost app (roles, positions, titles) |
ax_find |
Find elements by role (AXButton, AXTextField, etc.) |
ax_click_element |
Find button by title and click it |
ax_type_in_field |
Find text field and type into it |
ax_focused_element |
Get currently focused element |
ax_list_apps |
List running applications |
computer-use endpoint
Run a full agentic loop to accomplish a visual task:
{
"goal": "Click the Submit button",
"maxIterations": 10,
"app": "Safari" // optional: focus this app first
}
response
{
"success": true,
"message": "Clicked Submit button",
"iterations": 2,
"actions": [
{ "tool": "cua_click", "args": {"x": 500, "y": 300}, "result": "Clicked" }
]
}
CUA tools need Screen Recording permission to take screenshots. Grant this in System Settings → Privacy & Security → Screen Recording → Enable SYSTEM.
music
Control Apple Music playback.
| tool | description |
|---|---|
music_play |
Play/search music |
music_pause |
Pause playback |
music_next |
Skip to next track |
music_previous |
Previous track |
music_current |
Get current track info |
volume_get |
Get volume level |
volume_set |
Set volume (0-100) |
volume_up |
Increase volume 10% |
volume_down |
Decrease volume 10% |
volume_mute |
Toggle mute |
system
Control system settings, get status, manage files and apps.
calendar & reminders
| tool | description |
|---|---|
calendar_today |
Today's events |
calendar_upcoming |
Upcoming events |
calendar_next |
Next event |
calendar_create |
Create event |
reminders_list |
List reminders |
reminders_create |
Create reminder |
reminders_complete |
Complete reminder |
display & focus
| tool | description |
|---|---|
brightness_set |
Set brightness |
dark_mode_toggle |
Toggle dark mode |
dark_mode_status |
Get dark mode status |
dnd_toggle |
Toggle Do Not Disturb |
lock_screen |
Lock Mac |
sleep_display |
Sleep display |
sleep_mac |
Sleep Mac |
system status
| tool | description |
|---|---|
battery_status |
Battery level & charging |
wifi_status |
WiFi network info |
storage_status |
Disk space |
running_apps |
List running apps |
front_app |
Get frontmost app |
notes
Read and write Apple Notes.
| tool | description |
|---|---|
notes_list |
List recent notes |
notes_search |
Search notes by keyword |
notes_create |
Create a new note |
notes_read |
Read note content |
notes_append |
Append to existing note |
files
Search and manage files via Finder.
| tool | description |
|---|---|
finder_search |
Search files by name |
finder_downloads |
List recent downloads |
finder_desktop |
List desktop files |
finder_reveal |
Reveal file in Finder |
finder_trash |
Move file to trash |
shortcuts
Run Apple Shortcuts.
| tool | description |
|---|---|
shortcut_run |
Run a shortcut by name |
shortcut_list |
List available shortcuts |
Create powerful automations in Shortcuts.app, then trigger them via SYSTEM. Example: "Run my Morning Routine shortcut"
browser
Get info from Safari, Chrome, Arc, or other browsers.
| tool | description |
|---|---|
browser_url |
Get current tab URL |
browser_tabs |
List open tabs |
raycast extensions
Execute Raycast extensions for powerful integrations. SYSTEM scans your installed extensions and makes them available as tools.
how it works
During npm run setup, SYSTEM scans your Raycast extensions folder and
presents compatible commands for you to enable. Each enabled command becomes a dedicated
tool.
Raycast Extension SYSTEM Tool ───────────────── ─────────── spotify-player/play → spotify_play linear/create-issue → linear_create_issue slack/send-message → slack_send_message
extension discovery
SYSTEM looks in ~/.config/raycast/extensions/ and reads each extension's
package.json to find commands. Only commands with
mode: "no-view" or mode: "view" are compatible.
compatible extension types
| type | works? | notes |
|---|---|---|
| No-view commands | ✅ Best | Execute silently, return result |
| View commands | ⚠️ Partial | Opens Raycast UI briefly |
| Form commands | ❌ No | Requires user input in Raycast |
| Menu bar commands | ❌ No | Background only |
popular extensions that work well
| extension | commands | use case |
|---|---|---|
spotify-player |
play, pause, next, like | Music control |
linear |
create-issue, search | Issue tracking |
slack |
send-message, set-status | Team communication |
todoist |
create-task, today | Task management |
github |
create-issue, search | Code management |
notion |
create-page, search | Notes & docs |
tool naming
Tools are named as {extension}_{command} with hyphens replaced by
underscores:
// Extension: linear, Command: create-issue-for-myself
Tool name: linear_create_issue_for_myself
// Extension: spotify-player, Command: play
Tool name: spotify_player_play
using raycast tools
Once enabled, just ask naturally:
- "Create a Linear issue for fixing the login bug"
- "Send a Slack message to #general saying hello"
- "Play Daft Punk on Spotify"
- "Add 'buy groceries' to my Todoist"
generic raycast tool
For extensions not in your enabled list, use the generic raycast tool:
{
"extension": "spotify-player",
"command": "play",
"arguments": { "query": "jazz" }
}
deep link format
Under the hood, SYSTEM uses Raycast deep links:
raycast://extensions/{author}/{extension}/{command}?arguments={json}
troubleshooting
If an extension isn't showing in setup, make sure it's installed via Raycast Store,
not manually. Check ~/.config/raycast/extensions/.
This usually means the command requires UI interaction (forms, selections). These commands aren't fully compatible. Try a different command from the same extension.
Many extensions require you to authenticate in Raycast first. Open Raycast and run the command manually once to complete OAuth/login flows.
re-scanning extensions
If you install new Raycast extensions, run setup again to add them:
npm run setup
Your existing configuration will be preserved—you'll just see new extensions to enable.
bridge api
Direct API to the local bridge. Used by the agent, but also available for custom integrations.
List all available tools on the bridge.
Execute a specific tool.
{
"tool": "open_app",
"args": { "app": "Safari" }
}
Check bridge status.
websocket
Real-time updates for scheduled tasks and notifications.
// Connect to WebSocket
const ws = new WebSocket('wss://your-agent.workers.dev/ws?token=...');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
// Types: scheduled_result, notification, bridge_status
console.log(data.type, data.payload);
};
| event type | description |
|---|---|
scheduled_result |
Result of a scheduled task |
notification |
System notification |
bridge_status |
Bridge online/offline |
security
SYSTEM is designed with security as a priority.
🔐 authentication
Bearer token required for all requests. Tokens are generated during setup and stored locally.
🛡️ shell safety
Only allowlisted commands can run. Dangerous patterns (rm -rf, sudo, etc.) are blocked.
🚇 tunnel security
Quick Tunnels are ephemeral — new URL each session. Bridge binds to 0.0.0.0 only when tunnel is active.
🖥️ local execution
All commands run locally on your Mac. The bridge never exposes your system to the internet without the tunnel.
cloudflare access (recommended)
If you deploy to Cloudflare Workers, add Cloudflare Access for Zero Trust authentication at the edge — before requests even reach your agent.
While the API secret provides application-level auth, Cloudflare Access adds network-level protection. Only authenticated users can reach your agent at all.
setup via dashboard
- Go to Cloudflare Zero Trust Dashboard
- Navigate to Access → Applications → Add an application
- Select Self-hosted and enter your worker URL
- Create an access policy (e.g., email =
you@example.com) - Save — users must now authenticate before accessing SYSTEM
automation (terraform)
# Note: wrangler doesn't support Access config directly
# Use Terraform for infrastructure-as-code
resource "cloudflare_access_application" "system" {
zone_id = var.zone_id
name = "SYSTEM"
domain = "your-agent.workers.dev"
session_duration = "24h"
}
resource "cloudflare_access_policy" "allow_me" {
application_id = cloudflare_access_application.system.id
zone_id = var.zone_id
name = "Allow specific emails"
precedence = 1
decision = "allow"
include {
email = ["you@example.com"]
}
}
Cloudflare Access is configured separately from Workers deployment. The
wrangler CLI doesn't manage Access policies — use the dashboard or
Terraform.