Skip to main content
Glama
mggrim

apple-reminders-mcp-server

by mggrim
README.md
# Apple Reminders MCP Server

A Model Context Protocol (MCP) server that provides comprehensive integration with Apple Reminders. Built for use with Claude Desktop, Claude Code, and Claude.ai.

## Features

- āœ… **18 Comprehensive Tools** - Full CRUD operations for reminders and lists
- šŸ—£ļø **Natural Language Dates** - Use "tomorrow at 3pm", "next Monday", "in 3 days"
- šŸ” **Advanced Search** - Filter by completion, priority, flags, text, and more
- šŸ“Š **Statistics & Insights** - Get overdue reminders, today's tasks, and analytics
- šŸŽØ **List Customization** - Set colors and emblems for reminder lists
- šŸ”Œ **Dual Transport** - Works with both stdio (local) and HTTP (remote) connections
- ⚔ **Real-time** - Direct integration with your macOS Reminders app

## Installation

### Prerequisites

- macOS (Apple Reminders is macOS-only)
- Node.js 18.0.0 or higher
- npm or yarn

### Quick Install

```bash
# Clone the repository
git clone https://github.com/yourusername/apple-reminders-mcp-server
cd apple-reminders-mcp-server

# Install dependencies
npm install

# Start the server
npm start
```

The server will start on `http://localhost:3001` by default.

## Configuration

### For Claude Desktop/Code (stdio mode)

Add to your Claude Desktop or Claude Code configuration file:

**Location**: `~/Library/Application Support/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "apple-reminders": {
      "command": "npx",
      "args": ["tsx", "/Users/yourusername/Projects/mcp/apple-reminders-mcp-server/src/index.ts"],
      "env": {
        "TRANSPORT": "stdio"
      }
    }
  }
}
```

### For Claude.ai (HTTP mode)

1. Start the server:
   ```bash
   npm start
   ```

2. In Claude.ai settings, add a new MCP connector:
   - URL: `http://localhost:3001/mcp`
   - The server includes a health check at `http://localhost:3001/health`

## Available Tools

### Reminder Operations

| Tool | Description |
|------|-------------|
| `apple_reminders_create` | Create a new reminder with natural language dates |
| `apple_reminders_get` | Get reminder details by ID |
| `apple_reminders_update` | Update reminder properties |
| `apple_reminders_delete` | Delete a reminder |
| `apple_reminders_complete` | Mark reminder as complete/incomplete |
| `apple_reminders_move` | Move reminder to a different list |

### Search & Query

| Tool | Description |
|------|-------------|
| `apple_reminders_list` | List reminders with filters (completion, priority, etc.) |
| `apple_reminders_search` | Search reminders by text |
| `apple_reminders_overdue` | Get all overdue reminders |
| `apple_reminders_today` | Get reminders due today |

### List Management

| Tool | Description |
|------|-------------|
| `apple_reminders_list_lists` | Get all reminder lists |
| `apple_reminders_get_list` | Get specific list details |
| `apple_reminders_create_list` | Create a new list with color/emblem |
| `apple_reminders_update_list` | Update list properties |
| `apple_reminders_delete_list` | Delete a list |

### Utility

| Tool | Description |
|------|-------------|
| `apple_reminders_accounts` | List all accounts (typically iCloud) |
| `apple_reminders_stats` | Get statistics and analytics |
| `apple_reminders_show` | Open a reminder in the Reminders app |

## Usage Examples

### Creating Reminders

```javascript
// Simple reminder
{
  "name": "Call mom"
}

// With natural language due date
{
  "name": "Submit report",
  "dueDate": "tomorrow at 5pm",
  "priority": "high",
  "listName": "Work"
}

// With all details
{
  "name": "Doctor appointment",
  "body": "Annual checkup at Main Street clinic",
  "dueDate": "next Monday at 2pm",
  "remindMeDate": "Monday at 1:30pm",
  "priority": "high",
  "flagged": true,
  "listName": "Personal"
}
```

### Searching Reminders

```javascript
// Find all incomplete tasks
{
  "completed": false
}

// Search for specific text
{
  "query": "meeting",
  "listName": "Work"
}

// Filter by priority
{
  "priority": 1,  // High priority
  "flagged": true
}
```

### Managing Lists

```javascript
// Create a new list with styling
{
  "name": "Q1 Goals",
  "color": "#30D33B",
  "emblem": "education1"
}
```

## Natural Language Date Examples

The server supports natural language date parsing via `chrono-node`:

- "tomorrow" → Tomorrow at 00:00
- "tomorrow at 3pm" → Tomorrow at 15:00
- "next Monday" → Next Monday at 00:00
- "in 3 days" → 3 days from now
- "January 15" → January 15 of current/next year
- "2025-01-15" → ISO date format also supported

## Known Limitations

Due to AppleScript API limitations, the following features are **not supported**:

- āŒ **Subtasks** - Nested/indented reminders are not accessible via AppleScript
- āŒ **Tags** - Hashtags/tags are not accessible via AppleScript
- āŒ **Attachments** - Images and file attachments are not accessible
- āŒ **Nested Lists** - All lists are flat (no folders)

## Development

### Running in Development Mode

```bash
npm run dev
```

### Watch Mode (auto-reload on changes)

```bash
npm run watch
```

### Environment Variables

- `TRANSPORT` - Set to `stdio` or `http` (default: `http`)
- `PORT` - HTTP server port (default: `3001`)
- `DEBUG` - Enable debug logging
- `VERBOSE` - Enable verbose logging

## Technical Details

### Architecture

- **Language**: TypeScript (run via tsx)
- **MCP SDK**: @modelcontextprotocol/sdk v1.0.0
- **Date Parsing**: chrono-node v2.7.0
- **Validation**: Zod v3.25.0
- **HTTP Server**: Express v4.18.2

### Why tsx instead of compiled JavaScript?

This project uses `tsx` to run TypeScript directly rather than pre-compiling to JavaScript. This approach:

- Avoids memory issues with complex Zod schema types during TypeScript compilation
- Provides faster development iteration
- Maintains full TypeScript type safety
- Simplifies the build process

### File Structure

```
apple-reminders-mcp-server/
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ index.ts              # Server entry point
│   ā”œā”€ā”€ types.ts              # TypeScript interfaces
│   ā”œā”€ā”€ services/
│   │   ā”œā”€ā”€ applescript.ts    # AppleScript execution
│   │   ā”œā”€ā”€ dateUtils.ts      # Date parsing utilities
│   │   └── reminders.ts      # Reminders business logic
│   ā”œā”€ā”€ schemas/
│   │   └── index.ts          # Zod validation schemas
│   └── tools/
│       └── index.ts          # MCP tool registrations
ā”œā”€ā”€ package.json
ā”œā”€ā”€ tsconfig.json
└── README.md
```

## Troubleshooting

### Server won't start

- Ensure Node.js 18+ is installed: `node --version`
- Check if port 3001 is available: `lsof -i :3001`
- Verify dependencies are installed: `npm install`

### Reminders app not responding

- Ensure Reminders app has necessary permissions in System Settings > Privacy & Security
- Try manually opening Reminders app first
- Check Console.app for AppleScript errors

### Natural language dates not working

- Ensure `chrono-node` is installed: `npm list chrono-node`
- Check the date format - some complex natural language may not parse
- Fall back to ISO format if needed: `"2025-01-15T15:00:00"`

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

MIT

## Author

Matthew Grimes

## Acknowledgments

- Built on the [Model Context Protocol](https://modelcontextprotocol.io)
- Inspired by the Apple Mail MCP Server
- Uses [chrono-node](https://github.com/wanasit/chrono) for natural language date parsing