Building a Shortcuts MCP Server
This approach integrates Claude's chat interface with macOS's automation capabilities, opening up entirely new workflows.
This approach integrates Claude's chat interface with macOS's automation capabilities, opening up entirely new workflows.
I recently released something that I'm genuinely excited about: a Shortcuts MCP server. I'm not only excited about the functionality it provides and how well it works, but also the workflow and documentation I put in place for it.
A TypeScript MCP server that connects Claude to your macOS Shortcuts library. Interactive workflows with file pickers, dialogs, and prompts work through AppleScript integration, while CLI handles discovery and management.
From the GitHub README
This summary captures what I wanted to achieve, but if you know shortcuts, you know this opens a whole world of automation. You get system integration, various Apple app integration, and third-party app support as well.
For example, I use BetterTouchTool for window snapping and controlling my Stream Deck. BTT comes with quite a few shortcuts of its own: "Custom Move Resize," window management actions, and more. You can build Shortcuts with these actions, and now Claude has access to these features. I might use this to set up a particular window layout - perhaps Claude next to iA Writer, my markdown editor of choice.
Speaking of iA Writer, it also comes with a host of Shortcuts actions. A use case I started implementing a few months ago was loading prompts and context documents into the clipboard, then pasting them into Claude. Now I simply say "Run my 'Get Writing Guidance' shortcut" and all the information Claude needs to effectively edit my communications is available.
These actions also give me the ability to have Claude create markdown documents and add them directly to my iA Writer library.
The framework I used is called FastMCP. This made it extremely easy to get up and running, and by all accounts has been rock solid for me. I use Pino for logging and debugging. FastMCP provides logging, but it's available in tool context and not easily used in business logic files. The logs naturally end up where you'd expect to find them (~/Library/Logs/Claude/
).
The codebase is relatively small, focusing on a few core tools and resources:
Tools:
run_shortcut
- AppleScript execution with comprehensive logginguser_context
- Read and update local preferences and usage trackingview_shortcut
- CLI editor opening with fallback guidanceResources (automatically embedded):
shortcuts://available
- Current shortcuts listexecution://runs/recent
- Recent execution history (local only)context://system/current
- System state for time-based suggestionscontext://user/profile
- Local user preferences and patternsThese resources are automatically embedded because when each tool is called (excluding view_shortcut
), these resources are returned. This allows Claude to know what shortcuts you have, your execution history (including successes and failures), date and time information, and your favorite shortcuts and workflows.
The MCP standard includes descriptions and schema with each tool to help AI assistants understand how to use them, what parameters they need, what to expect back, and what effect the tool might have. Here's how the run_shortcut
tool and user profile resource are defined:
server.addTool({
annotations: {
openWorldHint: true, // Indicates tool can handle varied inputs
readOnlyHint: false, // Tool can modify system state
title: "Run Shortcut",
},
description:
"Execute a macOS Shortcut by name with optional input. Use when users want to run any shortcut including interactive workflows with file pickers, dialogs, location services, and system permissions. All shortcut types are supported through AppleScript integration.",
async execute(args, { log }) {
// AppleScript execution logic
// Error handling and logging
// Return shortcut output + embedded resources
},
name: "run_shortcut",
parameters: z.object({
input: z
.string()
.optional()
.describe("Optional input to pass to the shortcut"),
name: z.string().describe("The name of the Shortcut to run"),
}),
});
server.addResource({
description:
"User preferences including favorite shortcuts, workflow patterns, current projects, and focus areas. Contains stored user preferences and contextual information for personalized recommendations.",
async load() {
// Load user preference file
// Parse and format for Claude context
// Return structured preference data
},
mimeType: "text/plain", // Content type for the resource
name: "User preferences & usage patterns",
uri: "context://user/profile", // Unique identifier for the resource
});
The description
and name
properties are crucial - they provide valuable information for assistants to understand what's available and how to use it effectively. The parameters
schema uses Zod validation to ensure type safety and provide clear parameter descriptions.
Worth noting: these resources, though primarily accessed by Claude via tool calls, are also available in the Claude Desktop UI. Users can click the plus button in the lower left corner of the chat interface and see an entry for resources provided by installed MCP servers.
Also available in Claude's interface are prompts that MCP servers might provide. The Shortcuts server includes one prompt that analyzes available shortcuts and recommends the best option for specific tasks:
Analyze the available shortcuts and user context from the embedded resources to recommend the best shortcut for this task.
Then analyze which shortcut(s) would best accomplish this task:
1. Look for exact matches first
2. Consider shortcuts that could be adapted
3. If no perfect match exists, suggest the closest alternatives
4. Explain why you're recommending specific shortcuts
5. Provide usage guidance for the recommended shortcut(s)
IMPORTANT: When recommending shortcuts:
- Use the EXACT name from the shortcuts list (case-sensitive)
- AppleScript execution (run_shortcut) is more forgiving than CLI commands (view_shortcut)
Be specific about which shortcut to use and how to use it effectively.
Also, I should mention .dxt
support! This is not only a more dependable way to install MCP servers, but I was able to provide this through as automated releases using Github workflows. Give it try if you're into Claude and Shortcuts.
This approach integrates Claude's chat interface with macOS's automation capabilities, opening up entirely new workflows.
This has sparked new ideas for me regarding my Shortcuts - how best to build them and what I can achieve with them, especially when I'm in a development workflow. I'm particularly excited about the implications with the next version of macOS. The "Use Model" action allows you to query the on-device model, private cloud compute model, and ChatGPT, which opens even more workflow possibilities.
This has been an enjoyable process for me - from first planning around prototypes mostly generated by Claude Code to getting my own hands in the code, so to speak. And as impressive as Claude Code is, I definitely enjoyed writing this myself.
Why? I love to code. I love to learn, and I wanted to understand more about the MCP protocol and how to get the most out of it. Even though I believe I've established a way of collaborating with AI systems, there's still a difference between getting into the technology you're working with and producing something yourself.
This isn't to say it was all or nothing. Claude Code wrote my tests and helped with documentation - ironically, testing and documentation are chores many developers cite as things they don't like (I actually do enjoy them). But using Claude for these tasks was far more efficient than doing them myself.
The same goes for writing PR summaries, choosing keywords for the package.json and repository, and a chore I truly do not enjoy: naming functions. When it came to research and planning, collaborating with Claude made deciding on frameworks far faster and easier.
For building something for myself, for learning and understanding how to best use AI, this was the right mix for me. If I was building a product, maybe the balance would be different. Maybe more, maybe less, depending on the feature. I've thought about this quite a bit. As the quality of these tools evolves, I'm sure my approach will too.
Enjoyed this article? I share thoughts on component architecture, and AI-enhanced workflows, regularly.