Back to skills directory
more-io/claude-apple-bridges

more-io/claude-apple-bridges

@more-io 24

Give Claude Code native access to Apple Reminders, Calendar, Contacts, Notes, Mail, and tmux.

applemacosclaude-codereminderscalendarcontactsnotestmuxautomation

Install

$ npx skills add more-io/claude-apple-bridges

README

# GitHub Repository: more-io/claude-apple-bridges

**URL:** https://github.com/more-io/claude-apple-bridges
**Author:** more-io
**Description:** Swift CLI bridges giving Claude Code native access to Apple Reminders, Calendar, Contacts, Notes, Mail and tmux — includes Claude Code skill with full command reference
**Homepage:** https://github.com/more-io/claude-apple-bridges
**Language:** Swift

## Stats
- Stars: 24
- Forks: 2
- Open Issues: 0
- Commits: 53
- Created: 2026-02-22T14:17:20Z
- Updated: 2026-06-10T21:35:32Z
- Pushed: 2026-05-27T07:46:31Z

## README
# Claude Apple Bridges

![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)
![Platform: macOS 13+](https://img.shields.io/badge/Platform-macOS%2013%2B-lightgrey.svg)
![Swift](https://img.shields.io/badge/Swift-5.9%2B-orange.svg)

Swift CLI tools that give [Claude Code](https://claude.ai/claude-code) native access to Apple apps — Reminders, Calendar, Contacts, Notes, Mail, and tmux. Includes a [Claude Code skill](#skills) (`/apple-bridges`) with complete command reference for all bridges.

## Usage Examples with Claude Code

Once set up, you can ask Claude naturally in any Claude Code session. Here are real-world examples:

---

### Task & Project Management

> *"What's on my todo list for today?"*

Claude checks your Reminders and summarizes open items with due dates and priorities.

> *"I just finished the login bug fix — mark the GitHub issue and the reminder as done."*

Claude closes the GitHub issue and calls `reminders-bridge complete` in one step.

> *"Add a reminder to my 'Work' list to review the PR tomorrow morning."*

Claude creates the reminder with a due date set to tomorrow at 9:00.

---

### Calendar-Aware Scheduling

> *"I want to work on the Android release tomorrow — find a free slot and set a reminder."*

Claude checks `calendar-bridge tomorrow`, finds a free window, and sets the reminder due date accordingly — no double-booking.

> *"What do I have going on this week? Block some time for code review."*

Claude reads your calendar for each day, spots gaps, and adds events or reminders where they fit.

> *"Schedule our next planning session for next Monday at 10am in my Work calendar."*

Claude calls `calendar-bridge add` directly without you having to open Calendar.

---

### Contacts Lookup

> *"What's Rob's phone number?"*

Claude searches your Contacts and returns the number directly — no need to open the Contacts app.

> *"Add Alex to my contacts: +49 123 456789, [email protected]"*

Claude calls `contacts-bridge add` and confirms once saved.

> *"Show me all details for my contact Thomas."*

Claude returns name, phone, email, address and birthday in one view.

---

### Development Workflow Integration

> *"Start working on issue #42 — create a reminder to track it and add the 'in progress' label."*

Claude adds a GitHub label, creates a Reminders entry with the issue number in the notes, and sets a due date.

> *"We finished the feature — close the issue, complete the reminder, and write the release note."*

Claude handles all three in one go.

> *"What are my open todos related to this project?"*

Claude reads your Reminders list and cross-references with open GitHub issues for a full picture.

---

### End-of-Day / Planning

> *"Summarize what we did today and create reminders for anything we didn't finish."*

Claude reviews the session, identifies incomplete work, and adds follow-up reminders with appropriate due dates.

> *"Set reminders for all open todos so they show up in my Calendar tomorrow after my meetings."*

Claude reads tomorrow's calendar first to avoid conflicts, then sets due times in the free slots.

---

## Bridges

### reminders-bridge
Access and manage Apple Reminders from Claude Code.

```
reminders-bridge lists                                   List all reminder lists
reminders-bridge create-list <name>                      Create a new list
reminders-bridge rename-list <old> <new>                 Rename an existing list
reminders-bridge delete-list <name>                      Delete a list (and all its reminders)
reminders-bridge items <list>                            Show all reminders in a list
reminders-bridge incomplete <list>                       Show only incomplete reminders
reminders-bridge today                                   Show reminders due today (all lists)
reminders-bridge overdue                                 Show all overdue reminders (all lists)
reminders-bridge search <query>                          Search by title/notes across all lists
reminders-bridge add <list> <title> [notes]              Add a new reminder
reminders-bridge set-due <list> <title> <datetime>       Set due date (YYYY-MM-DD HH:mm)
reminders-bridge set-notes <list> <title> <notes>        Set or update notes
reminders-bridge rename <list> <oldTitle> <newTitle>     Rename a reminder (title only, preserves notes/due)
reminders-bridge complete <list> <title>                 Mark a reminder as complete
reminders-bridge delete <list> <title> [--force]         Delete a reminder (dry-run without --force)
```

### calendar-bridge
Read and write Apple Calendar events from Claude Code.

```
calendar-bridge calendars                                     List all calendars
calendar-bridge today                                         Show today's events
calendar-bridge tomorrow                                      Show tomorrow's events
calendar-bridge week                                          Show this week's events
calendar-bridge events <YYYY-MM-DD>                           Show events for a date
calendar-bridge free-slots <YYYY-MM-DD>                       Show free time slots (08:00–20:00)
calendar-bridge search <query>                                Search events by title (next 365 days)
calendar-bridge add <cal> <title> <start> <end>               Add event (YYYY-MM-DD HH:mm)
calendar-bridge add-all-day <cal> <title> <YYYY-MM-DD>        Add all-day event
calendar-bridge delete <cal> <title> <YYYY-MM-DD> [--force]   Delete event (dry-run without --force)
```

### contacts-bridge
Search and manage Apple Contacts from Claude Code.

```
contacts-bridge search <query>                                Search by name, email or phone
contacts-bridge show <name>                                   Show full details for a contact
contacts-bridge add <firstName> <lastName> [phone] [email]    Add a new contact
contacts-bridge update <name> phone <value>                   Update phone number
contacts-bridge update <name> email <value>                   Update email address
contacts-bridge delete <name> [--force]                       Delete a contact (dry-run without --force)
contacts-bridge birthdays-today                               Contacts with birthday today
contacts-bridge birthdays-upcoming <days>                     Upcoming birthdays in next N days
```

### notes-bridge
Read and write Apple Notes from Claude Code.

```
notes-bridge accounts                                         List all accounts
notes-bridge folders [account]                                List folders (default: iCloud)
notes-bridge list [folder] [account]                          List notes with modification date
notes-bridge search <query>                                   Search by title and content across all accounts
notes-bridge read <title> [account]                           Read note content as plain text
notes-bridge add <folder> <title> <body> [account]            Create a new note
notes-bridge append <title> <text> [account]                  Append text to an existing note
notes-bridge delete <title> [--force] [account]               Delete a note (dry-run without --force)
```

**Formatting:** The `body` and `text` parameters support HTML — Notes.app renders it natively.

```bash
# Plain text note
notes-bridge add "Ideas" "Shopping" "Milk, Bread, Eggs"

# Rich note with HTML formatting
notes-bridge add "Work" "Meeting Notes" "<b>Attendees:</b> Tobias, Heiko<br><br><ul><li>Discussed Q1 roadmap</li><li>Next steps: review PR</li></ul>"

# Append a formatted section
notes-bridge append "Meeting Notes" "<br><b>Follow-up:</b><br><ul><li>Send report by Friday</li></ul>"
```

Supported HTML tags: `<b>`, `<i>`, `<u>`, `<br>`, `<ul>`, `<ol>`, `<li>`, `<h1>`–`<h3>`, `<a href="...">`, `<p>`

### mail-bridge
Read and send Apple Mail messages from Claude Code.

```
mail-bridge accounts                                                           List all email accounts
mail-bridge mailboxes [account]                                                List mailboxes (default: first account)
mail-bridge list [mailbox|account] [account] [count]                           List recent messages (auto-detects account names)
mail-bridge unread [mailbox|account] [account] [--all] [--max N] [--since X]   List unread — fast (server-side filter); --all = every account
mail-bridge search <query> [max_results] [account] [--unread] [--since X]      Search subject/sender — output includes <mid:...> for each hit
mail-bridge read <index> [mailbox] [account]                                   Read message (unread status preserved)
mail-bridge read <index> [mailbox] [account] --mark-read                       Read message and mark as read
mail-bridge read <index> [mailbox] [account] --raw                             Read raw RFC822 source (HTML + MIME attachments)
mail-bridge read --mid <message-id> [account] [--mark-read] [--raw]            Read by RFC822 message-id (no listing needed) — fetches full body
mail-bridge send <to> <subject> <body> [/attachment] [--from <email>]          Opens compose window — user reviews and sends manually
mail-bridge send <to> <subject> <body> [/attachment] [--from <email>] --force  Sends directly without UI
mail-bridge delete <index> [mailbox] [account] [--force]                       Move to Trash (dry-run without --force)
```

**`--since` accepts** `Nd` / `Nw` / `Nm` (days/weeks/months), a bare integer (days), or `YYYY-MM-DD`.

**Unread / search performance:** both commands push the filter into Mail.app via a `whose` clause, so Mail scans the mailbox internally instead of the bridge fetching every message's properties over IPC. On a 50k-message INBOX the old behaviour took minutes; the filtered variant returns in ~1s per account. Use `--since 7d` to narrow further on servers that index slowly.

```bash
# All unread across every account, last 7 days, cap at 20
mail-bridge unread --all --since 7d --max 20

# Only unread results when searching
mail-bridge search "invoice" --unread --since 30d
```

**`--mid` example — fetch a specific message without knowing its INBOX index:**

`search` now prints an `<mid:...>` token for every hit (RFC822 Message-ID).
Pass it to `read --mid` to fetch the full message directly — no expensive
`list` walk required, and Mail.app downloads the body if it was only
partially cached.

```bash
mail-bridge search "invoice" 50 [email protected] --since 90d
# Found 7 message(s) (last 90d):
#   <mid:[email protected]> Invoice #4711 — [email protected] (3/15)
#   ...

mail-bridge read --mid "[email protected]" [email protected] --raw > /tmp/mail.eml
```

**`--raw` example — extract PDF attachments from invoice emails:**

```bash
# Dump the raw message source (RFC822, includes HTML body + MIME attachments)
mail-bridge read 42 INBOX [email protected] --raw > /tmp/mail.eml

# Then parse with Python to save any PDF attachment
python3 <<'EOF'
import email
raw = open('/tmp/mail.eml').read().split('\n---\n', 1)[1]
msg = email.message_from_string(raw)
for part in msg.walk():
    fn = part.get_filename() or ''
    if fn.endswith('.pdf'):
        open(f'/tmp/{fn}', 'wb').write(part.get_payload(decode=True))
        print('Saved', fn)
EOF
```

Use `--raw` when the default plain-text body strips URLs, images, or attachments you need (e.g. Stripe invoice links, PDF receipts, ticket attachments).

**Send examples:**

```bash
# Ask Claude to draft a reply → compose window opens in Mail.app for review:
mail-bridge send [email protected] "Betreff" "Hallo Heiko, ..."

# Claude sends automatically without user interaction (explicit intent required):
mail-bridge send [email protected] "Betreff" "Hallo Heiko, ..." --force

# With attachment and explicit sender:
mail-bridge send [email protected] "Report" "See attached." /tmp/report.pdf --from [email protected] --force
```

### tmux-bridge
Read and write tmux session contents from Claude Code — great for end-of-day summaries and interactive terminal control.

```
tmux-bridge sessions                              List all running sessions
tmux-bridge windows [session]                     List windows in a session
tmux-bridge panes [session]                       List all panes with path and command
tmux-bridge read <target> [lines]                 Read pane content (e.g. main:1.1, default: 1000 lines)
tmux-bridge write <target> <text> [--no-enter]    Send keystrokes to a pane
tmux-bridge snapshot [session] [lines]            Capture all panes at once (default: 5000 lines)
```

**Write examples:**

```bash
# Send a command (text + Enter)
tmux-bridge write main:0.0 "ls -la"

# Send text without pressing Enter
tmux-bridge write main:0.0 "partial input" --no-enter
```

Typical workflow: run your work in named tmux sessions, then ask Claude at the end of the day:
> *"Read tmux-bridge snapshot and summarize what I worked on today."*

---

## Setup

### 1. Compile

```bash
# Install all bridges at once (recommended)
git clone https://github.com/more-io/claude-apple-bridges.git
cd claude-apple-bridges
make install
```

**Optional: Persistent TCC permissions with a Developer certificate**

By default, bridges are ad-hoc signed. macOS TCC may re-prompt for permissions in new terminal sessions (especially remote/SSH). If you have an Apple Developer certificate, pass `CODESIGN_IDENTITY` for persistent grants:

```bash
make install CODESIGN_IDENTITY="Apple Development: Your Name (TEAMID)"
```

Or install individually:

```bash
make install-reminders
make install-calendar
make install-contacts
make install-notes
make install-mail
```

<details>
<summary>Manual compile (without make)</summary>

```bash
# reminders-bridge
cat > /tmp/reminders-info.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSRemindersUsageDescription</key>
    <string>Claude Code needs access to Reminders to manage tasks.</string>
</dict>
</plist>
EOF
swiftc reminders-bridge.swift -o ~/.claude/reminders-bridge \
  -framework EventKit \
  -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __info_plist -Xlinker /tmp/reminders-info.plist
codesign --force --sign - --identifier com.claude.reminders-bridge ~/.claude/reminders-bridge

# contacts-bridge
cat > /tmp/contacts-info.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSContactsUsageDescription</key>
    <string>Claude Code needs access to Contacts to look up and manage contacts.</string>
</dict>
</plist>
EOF
swiftc contacts-bridge.swift -o ~/.claude/contacts-bridge \
  -framework Contacts \
  -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __info_plist -Xlinker /tmp/contacts-info.plist
codesign --force --sign - --identifier com.claude.contacts-bridge ~/.claude/contacts-bridge

# calendar-bridge
cat > /tmp/calendar-info.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSCalendarsFullAccessUsageDescription</key>
    <string>Claude Code needs access to Calendar to schedule and view events.</string>
</dict>
</plist>
EOF
swiftc calendar-bridge.swift -o ~/.claude/calendar-bridge \
  -framework EventKit \
  -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __info_plist -Xlinker /tmp/calendar-info.plist
codesign --force --sign - --identifier com.claude.calendar-bridge ~/.claude/calendar-bridge

# notes-bridge
swiftc notes-bridge.swift -o ~/.claude/notes-bridge
codesign --force --sign - --identifier com.claude.notes-bridge ~/.claude/notes-bridge

# mail-bridge
swiftc mail-bridge.swift -o ~/.claude/mail-bridge
codesign --force --sign - --identifier com.claude.mail-bridge ~/.claude/mail-bridge
```

</details>

### 2. Grant permissions

Run each binary once from Terminal to trigger the macOS permission dialog:

```bash
~/.claude/reminders-bridge lists
~/.claude/calendar-bridge today
~/.claude/contacts-bridge search "test"
~/.claude/notes-bridge accounts
~/.claude/mail-bridge accounts
```

Then approve in **System Settings → Privacy & Security → Reminders / Calendars / Contacts / Automation**. Notes and Mail access is granted automatically via AppleScript on first use.

### 3. Add to Claude Code allowed tools

Add the bridges to your **global** `~/.claude/settings.json` so they work across all projects without confirmation prompts:

```json
{
  "permissions": {
    "allow": [
      "Bash(~/.claude/reminders-bridge*)",
      "Bash(~/.claude/calendar-bridge*)",
      "Bash(~/.claude/contacts-bridge*)",
      "Bash(~/.claude/notes-bridge*)",
      "Bash(~/.claude/mail-bridge*)",
      "Bash(~/.claude/tmux-bridge*)"
    ]
  }
}
```

---

## Requirements

- macOS 13+
- Swift (comes with Xcode or `xcode-select --install`)
- Claude Code

---

## Testing

After installing, run the integration test suite to verify everything works:

```bash
make test
```

35 tests cover all commands across all three bridges — exit codes, output validation, and argument handling. No data is modified during tests.

---

## Skills

Skills are structured prompt templates that Claude Code can load automatically when a bridge topic comes up. Instead of relying solely on CLAUDE.md for bridge documentation, the skill provides complete command syntax, parameters, and usage examples on demand.

### What Skills Do

When you type `/apple-bridges` in Claude Code (or when Claude detects you're asking about Reminders, Calendar, Contacts, Notes, Mail, or tmux), the skill loads:

1. **SKILL.md** — Overview of all bridges with a quick reference table
2. **Detail files** — Full documentation per bridge, loaded only when needed

This keeps context usage minimal while giving Claude complete knowledge of every command.

### Install Skills

Skills are included with `make install`:

```bash
make install          # Installs bridges AND skills
make install-skills   # Install skills only
```

This copies the skill files to `~/.claude/skills/apple-bridges/`.

### Manual Install

```bash
cp -r skills/apple-bridges ~/.claude/skills/
```

### Verify

Start a new Claude Code session and type `/apple-bridges` — it should be available as a slash command.

---

## Contributing

Pull requests are welcome! When adding a new bridge:

1. Create `<name>-bridge.swift` in the repo root
2. Add compile instructions to `README.md` and `CLAUDE.md`
3. Add the permission grant step to `README.md`
4. Add usage examples to `README.md`

See `CLAUDE.md` for developer notes and the branching workflow.

---

## License

MIT — see [LICENSE](LICENSE) for details.

Information

Language
Swift
Created
2026/6/18
Updated
2026/6/18