AppleScript

by joshrutkowski

134 stars
Not rated
GitHub

About

Integrates AppleScript to enable natural language control of macOS applications and system functions.

Details

Author
joshrutkowski
Repository
joshrutkowski/applescript-mcp
GitHub stars
134
License
MIT License
Categories
Developer Tools, Other, Productivity, Design, AI
Tags
#integration

- 🗓️ Calendar management (events, reminders)
- 📋 Clipboard operations
- 🔍 Finder integration
- 🔔 System notifications
- ⚙️ System controls (volume, dark mode, apps)
- 📟 iTerm terminal integration
- 📬 Mail (create new email, list emails, get email)
- 🔄 Shortcuts automation
- 💬 Messages (list chats, get messages, search messages, send a message)
- 🗒️ Notes (create formatted notes, list notes, search notes)
- 📄 Pages (create documents)

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name AppleScript
    Command (node, npx, python, etc.) node
    Arguments
    • Argument 1 /path/to/applescript-mcp/dist/index.js

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository


npm install

After running npm run build add the following to your mcp.json file:

json
{
"mcpServers": {
"applescript-mcp-server": {
"command": "node",
"args": ["/path/to/applescript-mcp/dist/index.js"]
}
}
}
```

add

Create calendar event. Parameters: title (string), startDate (date), endDate (date), calendar (optional string)

list

List today's events. Parameters: None

set_clipboard

Copy to clipboard. Parameters: content (string)

get_clipboard

Get clipboard contents. Parameters: None

clear_clipboard

Clear clipboard. Parameters: None

get_selected_files

Get selected files. Parameters: None

search_files

Search for files. Parameters: query (string), location (optional string)

quick_look

Preview file. Parameters: path (string)

send_notification

Show notification. Parameters: title (string), message (string), sound (optional string)

toggle_do_not_disturb

Toggle DND mode. Parameters: None

volume

Set system volume. Parameters: level (integer 0-100)

get_frontmost_app

Get active app. Parameters: None

launch_app

Open application. Parameters: name (string)

quit_app

Close application. Parameters: name (string), force (optional boolean)

toggle_dark_mode

Toggle dark mode. Parameters: None

paste_clipboard

Paste to iTerm. Parameters: None

run

Execute command in iTerm. Parameters: command (string), newWindow (optional boolean)

run_shortcut

Run a shortcut. Parameters: name (string), input (optional string)

list_shortcuts

List all available shortcuts. Parameters: limit (optional integer)

create_email

Create a new email in Mail.app. Parameters: recipient (string), subject (string), body (string)

list_emails

List emails from a mailbox. Parameters: mailbox (optional string), count (optional integer), unreadOnly (optional boolean)

get_email

Get a specific email by search. Parameters: subject (optional string), sender (optional string), dateReceived (optional date), mailbox (optional string), account (optional string), unreadOnly (optional boolean), includeBody (optional boolean)

list_chats

List available iMessage and SMS chats. Parameters: includeParticipantDetails (optional boolean, default: false)

get_messages

Get messages from the Messages app. Parameters: limit (optional integer, default: 100)

search_messages

Search for messages containing specific text. Parameters: searchText (string), sender (optional string), chatId (optional string), limit (optional integer, default: 50), daysBack (optional integer, default: 30)

compose_message

Open Messages app with pre-filled message or auto-send. Parameters: recipient (string), body (optional string), auto (optional boolean, default: false)

create

Create a note with markdown-like formatting. Parameters: title (string), content (string), format (optional string)

createRawHtml

Create a note with direct HTML content. Parameters: title (string), html (string)

list

List notes, optionally from a specific folder. Parameters: folder (optional string)

get

Get a specific note by title. Parameters: title (string), folder (optional string)

search

Search for notes containing specific text. Parameters: query (string), folder (optional string), limit (optional integer, default: 5), includeBody (optional boolean, default: true)

create_document

Create a new Pages document with plain text. Parameters: content (string)

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "applescript": {
            "cwd": "string (optional)",
            "env": {},
            "args": [
                "/path/to/applescript-mcp/dist/index.js"
            ],
            "shell": false,
            "command": "node"
        }
    }
}

Linux

{
    "cwd": "string (optional)",
    "env": [],
    "args": [
        "/path/to/applescript-mcp/dist/index.js"
    ],
    "shell": false,
    "command": "node"
}

Macos

{
    "cwd": "string (optional)",
    "env": [],
    "args": [
        "/path/to/applescript-mcp/dist/index.js"
    ],
    "shell": false,
    "command": "node"
}

Windows

{
    "cwd": "string (optional)",
    "env": [],
    "args": [
        "/c",
        "node",
        "/path/to/applescript-mcp/dist/index.js"
    ],
    "shell": false,
    "command": "cmd"
}
# applescript-mcp MCP Server A Model Context Protocol server that enables LLM applications to interact with macOS through AppleScript. This server provides a standardized interface for AI applications to control system functions, manage files, handle notifications, and more. [![Node.js CI](https://github.com/joshrutkowski/applescript-mcp/actions/workflows/node.js.yml/badge.svg)](https://github.com/joshrutkowski/applescript-mcp/actions/workflows/node.js.yml) <a href="https://glama.ai/mcp/servers/0t5gydjcqw"><img width="380" height="200" src="https://glama.ai/mcp/servers/0t5gydjcqw/badge" alt="applescript-mcp MCP server" /></a> ## Features - 🗓️ Calendar management (events, reminders) - 📋 Clipboard operations - 🔍 Finder integration - 🔔 System notifications - ⚙️ System controls (volume, dark mode, apps) - 📟 iTerm terminal integration - 📬 Mail (create new email, list emails, get email) - 🔄 Shortcuts automation - 💬 Messages (list chats, get messages, search messages, send a message) - 🗒️ Notes (create formatted notes, list notes, search notes) - 📄 Pages (create documents) ### Planned Features - 🧭 Safari (open in Safari, save page content, get selected page/tab) - ✅ Reminders (create, get) ## Prerequisites - macOS 10.15 or later - Node.js 18 or later ## Available Categories ### Calendar | Command | Description | Parameters | | ------- | --------------------- | --------------------------------------------------- | | `add` | Create calendar event | `title`, `startDate`, `endDate`, `calendar` (optional) | | `list` | List today's events | None | #### Examples ``` // Create a new calendar event Create a calendar event titled "Team Meeting" starting tomorrow at 2pm for 1 hour // List today's events What events do I have scheduled for today? ``` ### Clipboard | Command | Description | Parameters | | ----------------- | ---------------------- | ---------- | | `set_clipboard` | Copy to clipboard | `content` | | `get_clipboard` | Get clipboard contents | None | | `clear_clipboard` | Clear clipboard | None | #### Examples ``` // Copy text to clipboard Copy "Remember to buy groceries" to my clipboard // Get clipboard contents What's currently in my clipboard? // Clear clipboard Clear my clipboard ``` ### Finder | Command | Description | Parameters | | -------------------- | ------------------ | ------------------------------ | | `get_selected_files` | Get selected files | None | | `search_files` | Search for files | `query`, `location` (optional) | | `quick_look` | Preview file | `path` | #### Examples ``` // Get selected files in Finder What files do I currently have selected in Finder? // Search for files Find all PDF files in my Documents folder // Preview a file Show me a preview of ~/Documents/report.pdf ``` ### Notifications > Note: Sending notification requires that you enable notifications in System Settings > Notifications > Script Editor. | Command | Description | Parameters | | ----------------------- | ----------------- | -------------------------------------- | | `send_notification` | Show notification | `title`, `message`, `sound` (optional) | | `toggle_do_not_disturb` | Toggle DND mode | None | #### Examples ``` // Send a notification Send me a notification with the title "Reminder" and message "Time to take a break" // Toggle Do Not Disturb Turn on Do Not Disturb mode ``` ### System | Command | Description | Parameters | | ------------------- | ----------------- | -------------------------- | | `volume` | Set system volume | `level` (0-100) | | `get_frontmost_app` | Get active app | None | | `launch_app` | Open application | `name` | | `quit_app` | Close application | `name`, `force` (optional) | | `toggle_dark_mode` | Toggle dark mode | None | #### Examples ``` // Set system volume Set my Mac's volume to 50% // Get active application What app am I currently using? // Launch an application Open Safari // Quit an application Close Spotify // Toggle dark mode Switch to dark mode ``` ### iTerm | Command | Description | Parameters | | ----------------- | --------------- | --------------------------------- | | `paste_clipboard` | Paste to iTerm | None | | `run` | Execute command | `command`, `newWindow` (optional) | #### Examples ``` // Paste clipboard to iTerm Paste my clipboard contents into iTerm // Run a command in iTerm Run "ls -la" in iTerm // Run a command in a new iTerm window Run "top" in a new iTerm window ``` ### Shortcuts | Command | Description | Parameters | | ---------------- | ------------------------------------------ | ---------------------------------------------------- | | `run_shortcut` | Run a shortcut | `name`, `input` (optional) | | `list_shortcuts` | List all available shortcuts | `limit` (optional) | #### Examples ``` // List available shortcuts List all my available shortcuts // List with limit Show me my top 5 shortcuts // Run a shortcut Run my "Daily Note in Bear" shortcut // Run a shortcut with input Run my "Add to-do" shortcut with input "Buy groceries" ``` ### Mail | Command | Description | Parameters | | ------------- | -------------------------------- | --------------------------------------------------------- | | `create_email`| Create a new email in Mail.app | `recipient`, `subject`, `body` | | `list_emails` | List emails from a mailbox | `mailbox` (optional), `count` (optional), `unreadOnly` (optional) | | `get_email` | Get a specific email by search | `subject` (optional), `sender` (optional), `dateReceived` (optional), `mailbox` (optional), `account` (optional), `unreadOnly` (optional), `includeBody` (optional) | #### Examples ``` // Create a new email Compose an email to john@example.com with subject "Meeting Tomorrow" and body "Hi John, Can we meet tomorrow at 2pm?" // List emails Show me my 10 most recent unread emails // Get a specific email Find the email from sarah@example.com about "Project Update" ``` ### Messages | Command | Description | Parameters | | ----------------- | -------------------------------------------- | --------------------------------------------------------- | | `list_chats` | List available iMessage and SMS chats | `includeParticipantDetails` (optional, default: false) | | `get_messages` | Get messages from the Messages app | `limit` (optional, default: 100) | | `search_messages` | Search for messages containing specific text | `searchText`, `sender` (optional), `chatId` (optional), `limit` (optional, default: 50), `daysBack` (optional, default: 30) | | `compose_message` | Open Messages app with pre-filled message or auto-send | `recipient` (required), `body` (optional), `auto` (optional, default: false) | #### Examples ``` // List available chats Show me my recent message conversations // Get recent messages Show me my last 20 messages // Search messages Find messages containing "dinner plans" from John in the last week // Compose a message Send a message to 555-123-4567 saying "I'll be there in 10 minutes" ``` ### Notes | Command | Description | Parameters | | ----------------- | -------------------------------------------- | --------------------------------------------------------- | | `create` | Create a note with markdown-like formatting | `title`, `content`, `format` (optional with formatting options) | | `createRawHtml` | Create a note with direct HTML content | `title`, `html` | | `list` | List notes, optionally from a specific folder| `folder` (optional) | | `get` | Get a specific note by title | `title`, `folder` (optional) | | `search` | Search for notes containing specific text | `query`, `folder` (optional), `limit` (optional, default: 5), `includeBody` (optional, default: true) | #### Examples ``` // Create a new note with markdown formatting Create a note titled "Meeting Minutes" with content "# Discussion Points\n- Project timeline\n- Budget review\n- Next steps" and format headings and lists // Create a note with HTML Create a note titled "Formatted Report" with HTML content "<h1>Quarterly Report</h1><p>Sales increased by <strong>15%</strong></p>" // List notes Show me all my notes in the "Work" folder // Get a specific note Show me my note titled "Shopping List" // Search notes Find notes containing "recipe" in my "Cooking" folder ``` ### Pages | Command | Description | Parameters | | ----------------- | -------------------------------------------- | --------------------------------------------------------- | | `create_document` | Create a new Pages document with plain text | `content` | #### Examples ``` // Create a new Pages document Create a Pages document with the content "Project Proposal\n\nThis document outlines the scope and timeline for the upcoming project." ``` ## Architecture The applescript-mcp server is built using TypeScript and follows a modular architecture: ### Core Components 1. **AppleScriptFramework** (`framework.ts`): The main server class that: - Manages MCP protocol communication - Handles tool registration and execution - Provides logging functionality - Executes AppleScript commands 2. **Categories** (`src/categories/*.ts`): Modular script collections organized by functionality: - Each category contains related scripts (e.g., calendar, system, notes) - Categories are registered with the framework in `index.ts` 3. **Types** (`src/types/index.ts`): TypeScript interfaces defining: - `ScriptDefinition`: Structure for individual scripts - `ScriptCategory`: Collection of related scripts - `LogLevel`: Standard logging levels - `FrameworkOptions`: Configuration options ### Execution Flow 1. Client sends a tool request via MCP protocol 2. Server identifies the appropriate category and script 3. Script content is generated (static or dynamically via function) 4. AppleScript is executed via macOS `osascript` command 5. Results are returned to the client ### Logging System The framework includes a comprehensive logging system that: - Logs to both stderr and MCP logging protocol - Supports multiple severity levels (debug, info, warning, error, etc.) - Provides detailed execution information for troubleshooting ## Development ### Setup ```bash # Install dependencies npm install # Build the server npm run build # Launch MCP Inspector # See: https://modelcontextprotocol.io/docs/tools/inspector npx @modelcontextprotocol/inspector node path/to/server/index.js args... ``` ### Adding New Functionality #### 1. Create Category File Create `src/categories/newcategory.ts`: ```typescript import { ScriptCategory } from "../types/index.js"; export const newCategory: ScriptCategory = { name: "category_name", description: "Category description", scripts: [ // Scripts will go here ], }; ``` #### 2. Add Scripts ```typescript { name: "script_name", description: "What the script does", schema: { type: "object", properties: { paramName: { type: "string", description: "Parameter description" } }, required: ["paramName"] }, script: (args) => ` tell application "App" // AppleScript code using ${args.paramName} end tell ` } ``` #### 3. Register Category Update `src/index.ts`: ```typescript import { newCategory } from "./categories/newcategory.js"; // ... server.addCategory(newCategory); ``` ### Advanced Script Development For more complex scripts, you can: 1. **Use dynamic script generation**: ```typescript script: (args) => { // Process arguments and build script dynamically let scriptContent = `tell application "App"\n`; if (args.condition) { scriptContent += ` // Conditional logic\n`; } scriptContent += `end tell`; return scriptContent; } ``` 2. **Process complex data**: ```typescript // Example from Notes category function generateNoteHtml(args: any): string { // Process markdown-like syntax into HTML let processedContent = content; if (format.headings) { processedContent = processedContent.replace(/^# (.+)$/gm, '<h1>$1</h1>'); // ... } return processedContent; } ``` ## Debugging ### Using MCP Inspector The MCP Inspector provides a web interface for testing and debugging your server: ```bash npm run inspector ``` ### Logging Enable debug logging by setting the environment variable: ```bash DEBUG=applescript-mcp* npm start ``` ### Example configuration After running `npm run build` add the following to your `mcp.json` file: ```json { "mcpServers": { "applescript-mcp-server": { "command": "node", "args": ["/path/to/applescript-mcp/dist/index.js"] } } } ``` ### Common Issues - **Permission Errors**: Check System Preferences > Security & Privacy > Privacy > Automation - **Script Failures**: Test scripts directly in Script Editor.app before integration - **Communication Issues**: Check stdio streams aren't being redirected - **Database Access**: Some features (like Messages) require Full Disk Access permission ## Resources - [AppleScript Language Guide](https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html) - [MCP Protocol Documentation](https://modelcontextprotocol.io) - [Issue Tracker](https://github.com/joshrutkowski/applescript-mcp/issues) ## Contributing 1. Fork the repository 2. Create a feature branch 3. Commit your changes 4. Push to the branch 5. Create a Pull Request ## License MIT License - see [LICENSE](LICENSE) for details
No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.