bb-applescript-mcp-server

Beyond-Better/bb-applescript-mcp-server

3.2

If you are the rightful owner of bb-applescript-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The AppleScript MCP Server allows LLM clients to interact with macOS applications using AppleScript, providing a safe and controlled environment for script execution.

Tools
5
Resources
0
Prompts
0

AppleScript MCP Server

A Model Context Protocol (MCP) server that enables LLM clients to interact with macOS applications through AppleScript. Built using the @beyondbetter/bb-mcp-server library, this server provides safe, controlled execution of predefined scripts with optional support for arbitrary script execution.

Features

  • šŸ”’ Safe by Default: Arbitrary script execution disabled by default
  • šŸ“¦ Plugin Architecture: Modular design with task-focused plugins
  • šŸ› ļø Standard Tools: Read dictionaries, check permissions, Finder operations
  • šŸ“ BBEdit Integration: Create notebooks and projects
  • ā±ļø Timeout Protection: Configurable timeouts with hard limits
  • šŸ“„ Structured Errors: Consistent error handling with LLM-friendly hints
  • šŸ“Š Performance: Support for both compiled and template-based scripts

Prerequisites

  • Deno: Version 2.5.0 or later
  • macOS: Required for AppleScript execution
  • Applications: Any macOS application that supports AppleEvents (scriptable applications)
    • Examples: Finder (built-in), BBEdit, Mail, Safari, etc.
    • This server includes plugins for Finder and BBEdit by default
    • You can create plugins for any scriptable application

Quick Start

Option 1: Run Directly from JSR (Recommended)

No installation required! Just Deno and a config file.

1. Install Deno (if needed)
curl -fsSL https://deno.land/install.sh | sh
2. Configure in Beyond Better

Global Configuration (applies to all projects):

  1. Open BB Settings
  2. Go to "MCP Servers" tab
  3. Click "Configure Servers"
  4. Add new server with:
    • Server ID: applescript
    • Display Name: AppleScript Tools
    • Transport Type: STDIO (Local Process)
    • Command: deno
    • Arguments:
      run
      --allow-all
      --unstable-kv
      jsr:@beyondbetter/bb-applescript-mcp-server
      

Project-Level Configuration (specific project only):

  1. Open your project in BB
  2. Go to Project Settings → "MCP Servers"
  3. Enable server for AppleScript Tools
3. Start Using

That's it! The server runs directly from JSR with no download or installation needed.

Alternative: Claude Desktop Configuration

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
	"mcpServers": {
		"applescript": {
			"command": "deno",
			"args": [
				"run",
				"--allow-all",
				"--unstable-kv",
				"jsr:@beyondbetter/bb-applescript-mcp-server"
			]
		}
	}
}

Restart Claude Desktop.

4. Optional: Configuration

By default, the server runs with safe defaults:

  • Arbitrary script execution: disabled
  • All standard plugins: enabled
  • Default timeouts: 30s default, 5min max

To customize, add environment variables in BB's MCP server configuration:

In BB Settings → MCP Servers → Edit Server → Environment Variables:

KeyValueDescription
LOG_LEVELinfoSet to debug for detailed logs
ENABLE_ARBITRARY_SCRIPTSfalseSet to true to enable run_script tool
PLUGINS_ALLOWED_LIST(empty)Comma-separated list to load specific plugins
PLUGINS_BLOCKED_LIST(empty)Comma-separated list to block plugins

Option 2: Run from Local Repository

For development or customization:

1. Clone and Setup
# Clone the repository
git clone https://github.com/your-username/bb-mcp-applescript.git
cd bb-mcp-applescript/server

# Copy environment template
cp .env.example .env
2. Configure Environment

Edit .env to customize:

# Basic Configuration
MCP_TRANSPORT=stdio
LOG_LEVEL=info

# Plugin Control
PLUGINS_ALLOWED_LIST=        # Empty = load all plugins
PLUGINS_BLOCKED_LIST=        # Block specific plugins

# Safety (IMPORTANT)
ENABLE_ARBITRARY_SCRIPTS=false  # Set to true to enable run_script tool

# Timeouts
APPLESCRIPT_TIMEOUT_DEFAULT=30000   # 30 seconds
APPLESCRIPT_TIMEOUT_MAX=300000      # 5 minutes
3. Run the Server
# Development mode (with auto-reload)
deno task dev

# Production mode
deno task start
4. Configure in Beyond Better

Global Configuration:

  1. Open BB Settings (or Project Settings)
  2. Go to "MCP Servers" tab
  3. Add new server:
    • Server ID: applescript
    • Display Name: AppleScript Tools (Local Dev)
    • Transport Type: STDIO (Local Process)
    • Command: deno
    • Arguments:
      run
      --allow-all
      --unstable-kv
      /absolute/path/to/bb-mcp-applescript/server/main.ts
      
    • Environment Variables (optional):
      • LOG_LEVEL: debug
      • ENABLE_ARBITRARY_SCRIPTS: false
Alternative: Claude Desktop Configuration

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
	"mcpServers": {
		"applescript": {
			"command": "deno",
			"args": [
				"run",
				"--allow-all",
				"--unstable-kv",
				"/absolute/path/to/bb-mcp-applescript/server/main.ts"
			]
		}
	}
}

Restart Claude Desktop.

Project Structure

server/
ā”œā”€ā”€ main.ts                          # Server entry point
ā”œā”€ā”€ deno.jsonc                       # Deno configuration
ā”œā”€ā”€ .env.example                     # Environment template
ā”œā”€ā”€ mcp_server_instructions.md       # LLM context/instructions
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ plugins/
│   │   ā”œā”€ā”€ standard.plugin/         # Standard tools plugin
│   │   │   ā”œā”€ā”€ plugin.ts            # Plugin implementation
│   │   │   └── scripts/             # AppleScript files
│   │   │       ā”œā”€ā”€ read_dictionary.applescript
│   │   │       ā”œā”€ā”€ check_permissions.applescript
│   │   │       └── finder/
│   │   │           ā”œā”€ā”€ set_file_label.applescript
│   │   │           ā”œā”€ā”€ get_file_label.applescript
│   │   │           ā”œā”€ā”€ get_file_info_extended.applescript
│   │   │           ā”œā”€ā”€ reveal_in_finder.applescript
│   │   │           └── get_selection.applescript
│   │   └── bbedit.plugin/           # BBEdit tools plugin
│   │       ā”œā”€ā”€ plugin.ts
│   │       └── scripts/
│   │           ā”œā”€ā”€ create_notebook.applescript
│   │           └── create_project.applescript
│   └── utils/
│       ā”œā”€ā”€ scriptLoader.ts          # Script loading/discovery
│       ā”œā”€ā”€ scriptRunner.ts          # Script execution
│       ā”œā”€ā”€ templateRenderer.ts      # Template interpolation
│       └── errorHandler.ts          # Error standardization
└── tests/

Available Tools

AppleScript Tools (Standard Plugin)

šŸ”§ run_script

Status: šŸ”’ Disabled by default

Execute arbitrary AppleScript code.

Enable: Set ENABLE_ARBITRARY_SCRIPTS=true in .env

Parameters:

  • script: AppleScript code to execute
  • timeout: Optional timeout in milliseconds

Example:

{
  script: 'tell application "Finder" to get name of startup disk',
  timeout: 5000
}
šŸ“– read_dictionary

Read an application's AppleScript dictionary to understand its scriptable interface.

Parameters:

  • application: Application name (e.g., "BBEdit", "Finder")
  • filter: Optional filter criteria
    • include.types: Array of types to include
    • include.names: Specific names to include
    • searchTerms: Terms for fuzzy matching
    • format: "full" or "summary" (default: "summary")
  • timeout: Optional timeout

Example:

{
  application: "BBEdit",
  filter: {
    include: { names: ["project", "notebook"] },
    searchTerms: ["create"],
    format: "summary"
  }
}
āœ… check_applescript_permissions

Check automation permissions for applications.

Parameters:

  • applications: Optional array of app names (default: ["Finder", "BBEdit", "Terminal"])
  • timeout: Optional timeout

Returns: Permission status for each application with instructions if needed.

Finder Tools (Standard Plugin)

šŸ·ļø set_file_label

Set Finder label colors for files/folders.

Parameters:

  • paths: Array of file/folder paths
  • labelIndex: 0=None, 1=Red, 2=Orange, 3=Yellow, 4=Green, 5=Blue, 6=Purple, 7=Gray
  • timeout: Optional timeout
šŸ·ļø get_file_label

Get Finder label colors for files/folders.

Parameters:

  • paths: Array of file/folder paths
  • timeout: Optional timeout
šŸ“Š get_file_info_extended

Get detailed file information including Spotlight comments, tags, labels, etc.

Parameters:

  • path: File or folder path
  • timeout: Optional timeout
šŸ” reveal_in_finder

Reveal and select files/folders in Finder.

Parameters:

  • paths: Array of paths to reveal
  • timeout: Optional timeout
šŸ“‹ get_finder_selection

Get currently selected items in Finder.

Parameters:

  • timeout: Optional timeout

BBEdit Tools (BBEdit Plugin)

šŸ““ create_bbedit_notebook

Create a new BBEdit notebook.

Parameters:

  • name: Notebook name (required)
  • location: Optional save location (default: ~/Documents/BBEdit Notebooks/)
  • content: Optional array of content items
    • type: "text" or "file"
    • data: Text content or file path
  • open: Whether to open after creation (default: true)
  • timeout: Optional timeout

Example:

{
  name: "Project Notes",
  content: [
    { type: "text", data: "Meeting notes..." },
    { type: "file", data: "/path/to/notes.txt" }
  ],
  open: true
}
šŸ“ create_bbedit_project

Create a new BBEdit project.

Parameters:

  • name: Project name (required)
  • location: Optional save location (default: ~/Documents/BBEdit Projects/)
  • items: Optional array of file/folder paths to add
  • settings: Optional project settings (reserved for future)
  • open: Whether to open after creation (default: true)
  • timeout: Optional timeout

Example:

{
  name: "Website Project",
  items: [
    "/Users/username/Projects/website/src",
    "/Users/username/Projects/website/docs"
  ],
  open: true
}

Plugin Management

Loading Plugins

Plugins are auto-discovered from src/plugins/ directory.

Load all plugins (default):

PLUGINS_ALLOWED_LIST=
PLUGINS_BLOCKED_LIST=

Load specific plugins only:

PLUGINS_ALLOWED_LIST=standard,bbedit
PLUGINS_BLOCKED_LIST=

Load all except specific plugins:

PLUGINS_ALLOWED_LIST=
PLUGINS_BLOCKED_LIST=experimental

Creating Custom Plugins

Plugins allow you to add tools for any scriptable macOS application. See the complete guide:

šŸ“

Quick example for a Mail.app plugin:

// src/plugins/mail.plugin/plugin.ts
import { AppPlugin, ToolRegistry, z } from 'jsr:@beyondbetter/bb-mcp-server';
import { findAndExecuteScript } from '../../utils/scriptLoader.ts';

export default {
	name: 'mail',
	version: '1.0.0',
	description: 'Tools for Mail.app',
	workflows: [],
	tools: [],

	async initialize(dependencies, toolRegistry, workflowRegistry) {
		const pluginDir = getPluginDir();
		
		toolRegistry.registerTool(
			'send_email',
			{
				title: 'Send Email',
				description: 'Create an email in Mail.app',
				category: 'Mail',
				inputSchema: {
					to: z.string().email().describe('Recipient'),
					subject: z.string().describe('Subject'),
					body: z.string().describe('Body'),
				},
			},
			async (args) => {
				// Runs scripts/send_email.applescript with template variables
				return await findAndExecuteScript(
					pluginDir,
					'send_email',
					{ to: args.to, subject: args.subject, body: args.body }
				);
			},
		);
	},
} as AppPlugin;

The guide covers:

  • Plugin structure and file naming
  • AppleScript template variables
  • Multiple tools per plugin
  • Error handling and debugging
  • Complete working examples

Script Development

Template Scripts

Use template variables in .applescript files:

-- my_script.applescript
tell application "Finder"
    set file label of (POSIX file ${filePath} as alias) to ${labelIndex}
end tell

Variables are automatically escaped and type-converted:

  • Strings: Wrapped in quotes, escaped
  • Arrays: Converted to AppleScript lists: {"item1", "item2"}
  • Objects: Converted to AppleScript records: {key:"value"}
  • null/undefined: Converted to missing value

Compiled Scripts

For better performance, use compiled scripts:

# Compile an AppleScript
osacompile -o my_script.scpt my_script.applescript

Compiled scripts run directly without compilation overhead.

Error Handling

All tools return consistent error structures:

{
	"success": false,
	"error": {
		"type": "permission|timeout|script_error|system_error|disabled",
		"message": "Human-readable error",
		"code": "ERR_CODE",
		"hint": "LLM-friendly suggestion",
		"details": "Technical details"
	},
	"metadata": {
		"executionTime": 123,
		"scriptPath": "/path/to/script",
		"timeoutUsed": 30000
	}
}

Common Issues

Permission Denied

Solution: Grant automation permissions

  1. Use check_applescript_permissions to identify which apps need permissions
  2. Go to System Settings > Privacy & Security > Automation
  3. Enable automation for the MCP server process
Script Timeouts

Solution: Increase timeout or optimize script

  • Set higher timeout parameter
  • Check APPLESCRIPT_TIMEOUT_MAX configuration
  • Break complex operations into smaller scripts
run_script Disabled

Solution: Enable in configuration

  • Set ENABLE_ARBITRARY_SCRIPTS=true in .env
  • Restart server
  • Be aware of security implications

Security Considerations

  1. šŸ”’ Arbitrary Scripts: Disabled by default. Only enable if you trust the LLM client.
  2. šŸ“ File System: Scripts run with server process permissions.
  3. šŸŽÆ Application Control: Can control any app with granted automation permissions.
  4. ā±ļø Timeout Limits: Always enforced to prevent runaway scripts.
  5. šŸ“ Error Details: May contain system information. Review error output.

Performance Tips

  • Use compiled scripts (.scpt) for frequently-used operations
  • Set appropriate timeouts based on operation complexity
  • Batch operations when possible (e.g., multiple files at once)
  • Cache results for read-only operations (e.g., dictionary reads)

Testing

# Run tests
deno task test

# Run specific test file
deno test tests/scriptRunner.test.ts

Contributing

This is a showcase example for the @beyondbetter/bb-mcp-server library.

Contributions welcome:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Submit a pull request

License

MIT License - see LICENSE file for details

Related Projects

Support


Built with @beyondbetter/bb-mcp-server - A powerful framework for building MCP servers with plugins, workflows, and OAuth support.