Building 100+ macOS Automation Tools in 2 Days: My Vibe Coding Experience
The Challenge
Two days ago, I set out to do something I never thought possible: build a complete suite of macOS automation tools from scratch using Swift.
The result? 5 MCP Servers with over 100 tools, covering:
- Things 3: 37 tools for complete task management control
- Apple Calendar: Full calendar automation via EventKit
- Apple Mail: Email workflow automation
- Logic Pro: Music production control
- Claude Desktop: Using Claude to control Claude
Here’s the catch: I had never written a line of Swift before.
What is Vibe Coding?
Vibe coding is a new development paradigm. You don’t need to master a language before you start building. You just need to know what you want to create, then iterate through conversation with AI.
Traditional development:
graph LR
A[Learn Language] --> B[Understand Framework] --> C[Design] --> D[Implement] --> E[Debug] --> F[Test] --> G[Ship]
style G fill:#FFF7EB,stroke:#D97706,stroke-width:2px
Estimated: 2–3 months
Vibe coding:
graph LR
A[Describe Intent] --> B[AI Generates] --> C[Test] --> D[Find Issues] --> E[Describe Problem] --> F[AI Fixes] --> C
style C fill:#FFF7EB,stroke:#D97706,stroke-width:2px
Actual: 2 days
The Real Journey
Day 1: “This Should Be Simple”
I started with a modest goal: let Claude Code control my Things 3 app. The idea was straightforward—wrap Things 3’s AppleScript API in an MCP server.
The first version worked quickly. Then reality hit.
Problem 1: Internationalization (i18n)
-- English system
tell application "Things3" to get list "Inbox"
-- Chinese system: "Inbox" doesn't exist, need "收件匣"
-- Japanese system: need "インボックス"
Solution: Don’t use names. Use Things 3’s internal source type IDs instead—these are language-independent.
Problem 2: Performance Disaster
The first version made one AppleScript call per property, per todo. One todo has ~10 properties. 100 todos = 1,000 AppleScript calls.
Result: Listing Today’s tasks took 30 seconds.
Solution: Batch fetch all properties in a single AppleScript call. Performance improved 29x.
Problem 3: MCP Connection Timeouts
Random disconnections plagued the server. After hours of debugging, I found the culprit: AppleScript execution is synchronous and blocks MCP’s event loop.
Solution: Move AppleScript execution to a background thread.
// Wrong: blocks main thread
let result = script.executeAndReturnError(&error)
// Right: background execution
DispatchQueue.global().async {
let result = script.executeAndReturnError(&error)
}
Day 2: From 1 to 5
With core problems solved, Day 2 was about replicating the pattern across other apps.
Each app brought its own challenges:
| App | Challenge |
|---|---|
| Calendar | EventKit requires async permission requests |
| AppleScript API is massive (50+ actions) | |
| Logic Pro | Almost no documentation, pure exploration |
| Claude Desktop | Requires Accessibility permissions for UI control |
But having established patterns on Day 1, these problems fell faster. Patterns transfer. Knowledge compounds.
The Numbers
| Metric | Traditional (estimated) | Vibe Coding (actual) |
|---|---|---|
| Time | 2-3 months | 2 days |
| Learning curve | Learn first, build later | Learn while building |
| Code quality | Depends on experience | Depends on conversation quality |
| Debugging | Stack Overflow | Ask the AI |
| Documentation | Write separately | Generated alongside |
Efficiency gain: 30-50x
What This Changes
1. Lowered Barriers
Previously, building a macOS app meant learning Swift, understanding Cocoa frameworks, and navigating Xcode. Now? Start building immediately. Learn when you hit problems.
2. Near-Zero Cost of Experimentation
Wrong approach? Just change it. Takes seconds. This freedom enables bolder experimentation.
3. Expanded Individual Capability
These 5 MCP servers cover the core of macOS productivity apps. That used to be a small company’s product line. Now it’s a weekend project.
Lessons for Those Starting Out
- Don’t wait to be “ready”: Start building. You’ll never feel fully prepared.
- Learn to describe problems well: AI output quality depends on input quality.
- Embrace errors: Every error is a learning opportunity, not a failure.
- Build transferable patterns: When you solve a problem, think about how to reuse that solution.
Conclusion
Two days ago, I didn’t know Swift, didn’t understand MCP protocol, and had never built a native macOS application.
Two days later, I shipped 5 open-source projects with over 100 tools combined.
This isn’t because I’m particularly talented. It’s because the tools have changed.
Vibe coding isn’t replacing programmers. It’s enabling programmers to do what was previously impossible.
Project Links:
- che-things-mcp - Things 3 automation
- che-ical-mcp - Calendar management
- che-apple-mail-mcp - Email automation
- che-claude-desktop-mcp - Claude Desktop control