Skip to main content
Glama

applescript_execute

Execute AppleScript code to automate tasks on macOS, such as managing Notes, Calendar, Contacts, Messages, Mail, Finder, Safari, and system functions. Streamline workflows by retrieving, modifying, or organizing data and executing shell commands with ease.

Instructions

Run AppleScript code to interact with Mac applications and system features. This tool can access and manipulate data in Notes, Calendar, Contacts, Messages, Mail, Finder, Safari, and other Apple applications. Common use cases include but not limited to: - Retrieve or create notes in Apple Notes - Access or add calendar events and appointments - List contacts or modify contact details - Search for and organize files using Spotlight or Finder - Get system information like battery status, disk space, or network details - Read or organize browser bookmarks or history - Access or send emails, messages, or other communications - Read, write, or manage file contents - Execute shell commands and capture the output

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
code_snippetYesMulti-line appleScript code to execute
timeoutNoCommand execution timeout in seconds (default: 60)

Implementation Reference

  • Python handler for the 'applescript_execute' tool. Writes AppleScript to temp file and executes with osascript using subprocess.run, handling timeout and errors.
    @server.call_tool() async def handle_call_tool( name: str, arguments: dict[str, Any] | None ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: """Handle execution of AppleScript to interact with Mac applications and data""" try: if name == "applescript_execute": if not arguments or "code_snippet" not in arguments: raise ValueError("Missing code_snippet argument") # Get timeout parameter or use default timeout = arguments.get("timeout", 60) # Create temp file for the AppleScript with tempfile.NamedTemporaryFile(suffix='.scpt', delete=False) as temp: temp_path = temp.name try: # Write the AppleScript to the temp file temp.write(arguments["code_snippet"].encode('utf-8')) temp.flush() # Execute the AppleScript cmd = ["/usr/bin/osascript", temp_path] result = subprocess.run( cmd, capture_output=True, text=True, timeout=timeout ) if result.returncode != 0: error_message = f"AppleScript execution failed: {result.stderr}" return [types.TextContent(type="text", text=error_message)] return [types.TextContent(type="text", text=result.stdout)] except subprocess.TimeoutExpired: return [types.TextContent(type="text", text=f"AppleScript execution timed out after {timeout} seconds")] except Exception as e: return [types.TextContent(type="text", text=f"Error executing AppleScript: {str(e)}")] finally: # Clean up the temporary file try: os.unlink(temp_path) except: pass else: raise ValueError(f"Unknown tool: {name}") except Exception as e: return [types.TextContent(type="text", text=f"Error: {str(e)}")]
  • JavaScript inline handler for 'applescript_execute' tool, calls executeAppleScript function with optional remote execution support.
    async ({ code_snippet, timeout = 60 }) => { logger.info(`Executing AppleScript with timeout ${timeout}s`); if (!code_snippet) { return { content: [{ type: 'text', text: 'Error: Missing code_snippet argument' }] }; } try { // Inject configuration variables into the AppleScript environment if needed if (code_snippet.includes('{{REMOTE_HOST}}')) { code_snippet = code_snippet.replace(/\{\{REMOTE_HOST\}\}/g, config.remoteHost); } if (code_snippet.includes('{{REMOTE_PASSWORD}}')) { code_snippet = code_snippet.replace(/\{\{REMOTE_PASSWORD\}\}/g, config.remotePassword); } if (code_snippet.includes('{{REMOTE_USER}}')) { code_snippet = code_snippet.replace(/\{\{REMOTE_USER\}\}/g, config.remoteUser); } const result = await executeAppleScript(code_snippet, timeout); return { content: [{ type: 'text', text: result }] }; } catch (error) { return { content: [{ type: 'text', text: `Error: ${error.message}` }] }; } }
  • Python registration of the 'applescript_execute' tool in the list_tools handler, including schema and description.
    @server.list_tools() async def handle_list_tools() -> list[types.Tool]: """List available tools""" return [ types.Tool( name="applescript_execute", description="""Run AppleScript code to interact with Mac applications and system features. This tool can access and manipulate data in Notes, Calendar, Contacts, Messages, Mail, Finder, Safari, and other Apple applications. Common use cases include but not limited to: - Retrieve or create notes in Apple Notes - Access or add calendar events and appointments - List contacts or modify contact details - Search for and organize files using Spotlight or Finder - Get system information like battery status, disk space, or network details - Read or organize browser bookmarks or history - Access or send emails, messages, or other communications - Read, write, or manage file contents - Execute shell commands and capture the output """, inputSchema={ "type": "object", "properties": { "code_snippet": { "type": "string", "description": """Multi-line appleScript code to execute. """ }, "timeout": { "type": "integer", "description": "Command execution timeout in seconds (default: 60)" } }, "required": ["code_snippet"] }, ) ]
  • server.js:200-240 (registration)
    JavaScript registration of the 'applescript_execute' tool using server.tool, with Zod schema and inline handler.
    server.tool( 'applescript_execute', 'Run AppleScript code to interact with Mac applications and system features. This tool can access and manipulate data in Notes, Calendar, Contacts, Messages, Mail, Finder, Safari, and other Apple applications. Common use cases include but not limited to: - Retrieve or create notes in Apple Notes - Access or add calendar events and appointments - List contacts or modify contact details - Search for and organize files using Spotlight or Finder - Get system information like battery status, disk space, or network details - Read or organize browser bookmarks or history - Access or send emails, messages, or other communications - Read, write, or manage file contents - Execute shell commands and capture the output', { code_snippet: z.string().describe('Multi-line appleScript code to execute'), timeout: z.number().optional().describe('Command execution timeout in seconds (default: 60)') }, async ({ code_snippet, timeout = 60 }) => { logger.info(`Executing AppleScript with timeout ${timeout}s`); if (!code_snippet) { return { content: [{ type: 'text', text: 'Error: Missing code_snippet argument' }] }; } try { // Inject configuration variables into the AppleScript environment if needed if (code_snippet.includes('{{REMOTE_HOST}}')) { code_snippet = code_snippet.replace(/\{\{REMOTE_HOST\}\}/g, config.remoteHost); } if (code_snippet.includes('{{REMOTE_PASSWORD}}')) { code_snippet = code_snippet.replace(/\{\{REMOTE_PASSWORD\}\}/g, config.remotePassword); } if (code_snippet.includes('{{REMOTE_USER}}')) { code_snippet = code_snippet.replace(/\{\{REMOTE_USER\}\}/g, config.remoteUser); } const result = await executeAppleScript(code_snippet, timeout); return { content: [{ type: 'text', text: result }] }; } catch (error) { return { content: [{ type: 'text', text: `Error: ${error.message}` }] }; } } );
  • JavaScript helper function that dispatches to local or remote AppleScript execution based on config.
    async function executeAppleScript(code, timeout = 60) { // Check if all remote credentials are available for SSH execution const useRemote = config.remoteHost && config.remoteHost !== 'localhost' && config.remoteUser && config.remotePassword; if (useRemote) { return executeRemoteAppleScript(code, timeout); } else { return executeLocalAppleScript(code, timeout); } } async function executeLocalAppleScript(code, timeout = 60) { // Create a temporary file for the AppleScript const tempPath = path.join(os.tmpdir(), `applescript_${Date.now()}.scpt`); try { // Write the AppleScript to the temporary file fs.writeFileSync(tempPath, code); // Execute the AppleScript return new Promise((resolve, reject) => { exec(`/usr/bin/osascript "${tempPath}"`, { timeout: timeout * 1000 }, (error, stdout, stderr) => { // Clean up the temporary file try { fs.unlinkSync(tempPath); } catch (e) { logger.warn(`Failed to delete temporary file: ${e.message}`); } if (error) { if (error.killed) { resolve(`AppleScript execution timed out after ${timeout} seconds`); } else { resolve(`AppleScript execution failed: ${stderr}`); } } else { resolve(stdout); } }); }); } catch (e) { return `Error executing AppleScript: ${e.message}`; } } async function executeRemoteAppleScript(code, timeout = 60) { logger.info(`Executing AppleScript on remote host: ${config.remoteHost}`); // Create a temporary file for the AppleScript const localTempPath = path.join(os.tmpdir(), `applescript_${Date.now()}.scpt`); const remoteTempPath = `/tmp/applescript_${Date.now()}.scpt`; try { // Write the AppleScript to the temporary file fs.writeFileSync(localTempPath, code); // Initialize SSH client const ssh = new NodeSSH(); // Connect to remote host try { await ssh.connect({ host: config.remoteHost, username: config.remoteUser, password: config.remotePassword, // Useful when password auth fails and you need to try keyboard-interactive tryKeyboard: true, onKeyboardInteractive: (name, instructions, lang, prompts, finish) => { if (prompts.length > 0 && prompts[0].prompt.toLowerCase().includes('password')) { finish([config.remotePassword]); } } }); logger.info('SSH connection established successfully'); // Upload the AppleScript file await ssh.putFile(localTempPath, remoteTempPath); // Execute the AppleScript on the remote machine const result = await ssh.execCommand(`/usr/bin/osascript "${remoteTempPath}"`, { timeout: timeout * 1000 }); // Clean up the remote file await ssh.execCommand(`rm -f "${remoteTempPath}"`); // Clean up the local file try { fs.unlinkSync(localTempPath); } catch (e) { logger.warn(`Failed to delete local temporary file: ${e.message}`); } // Disconnect from the remote host ssh.dispose(); if (result.code !== 0) { return `Remote AppleScript execution failed: ${result.stderr}`; } return result.stdout; } catch (sshError) { // Clean up the local file on error try { fs.unlinkSync(localTempPath); } catch (e) { logger.warn(`Failed to delete local temporary file: ${e.message}`); } return `SSH error: ${sshError.message}`; } } catch (e) { return `Error executing remote AppleScript: ${e.message}`; } }

Other Tools

Related Tools

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/peakmojo/applescript-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server