소스 검색

Improve documentation and add skill for plugin marketplace

- Add skill.md for Claude Code plugin marketplace
- Update .mcp.json to use local build path (works when installed from GitHub)
- Expand CLAUDE.md with backslash escaping, ID usage, and more examples
- Add backslash escaping section to README Known Limitations
- Add test count (28 tests) to Development section
Robert Sweet 5 달 전
부모
커밋
1b7fe7cae2
4개의 변경된 파일307개의 추가작업 그리고 55개의 파일을 삭제
  1. 2 2
      .mcp.json
  2. 99 52
      CLAUDE.md
  3. 25 1
      README.md
  4. 181 0
      skills/apple-mail/skill.md

+ 2 - 2
.mcp.json

@@ -1,8 +1,8 @@
 {
   "mcpServers": {
     "apple-mail": {
-      "command": "npx",
-      "args": ["apple-mail-mcp"]
+      "command": "node",
+      "args": ["build/index.js"]
     }
   }
 }

+ 99 - 52
CLAUDE.md

@@ -6,99 +6,138 @@ This file provides guidance for AI agents (Claude, etc.) when using this MCP ser
 
 This MCP server enables AI assistants to interact with Apple Mail on macOS via AppleScript. All operations are local - no data leaves the user's machine.
 
+## Critical: Backslash Escaping
+
+**When sending content with backslashes to any tool, you MUST escape them.**
+
+The MCP protocol uses JSON for parameters. In JSON, `\` is an escape character. To include a literal backslash:
+
+| You want | Send in JSON parameter |
+|----------|------------------------|
+| `\` | `\\` |
+| `\\` | `\\\\` |
+| `C:\Users\` | `C:\\Users\\` |
+
+### Why This Matters
+
+If you send a single backslash without escaping:
+- The JSON parser interprets `\` as an escape sequence
+- Invalid sequences like `\ ` (backslash-space) cause silent failures
+- The email send/draft may fail with no clear error
+
+### Examples
+
+**Correct - Windows path in email:**
+```
+body: "The file is at C:\\Users\\Documents\\report.pdf"
+```
+
+**Incorrect - Will fail:**
+```
+body: "The file is at C:\Users\Documents\report.pdf"
+```
+
 ## Tool Usage Tips
 
-### Message Operations
+### Using Message IDs (Required)
 
-#### search-messages
-- Use `query` for general text search across subject, sender, content
-- Use `from` to filter by sender email address
-- Use `subject` for subject line matching
-- Combine `mailbox` and `account` to narrow search scope
-- Default limit is 50 messages
+All message operations require an `id` parameter. **Always get IDs first** using `list-messages` or `search-messages`:
 
-#### send-email
-- `to` must be an array of email addresses, even for single recipient
-- `body` is plain text by default
-- Specify `account` to send from a specific account
+```
+# List messages returns IDs
+list-messages mailbox="INBOX"
+→ Messages with IDs like "12345", "12346", etc.
+
+# Use ID for all subsequent operations
+get-message id="12345"
+mark-as-read id="12345"
+delete-message id="12345"
+reply-to-message id="12345" body="Thanks!"
+```
 
-#### create-draft
-- Same parameters as `send-email`
-- Saves to Drafts folder without sending
-- User can review and send manually from Mail.app
+### Recipient Arrays
 
-#### reply-to-message
-- Requires message `id` to reply to
-- Set `replyAll: true` to reply to all recipients
-- Set `send: false` to save as draft instead of sending
+The `to`, `cc`, and `bcc` parameters must always be arrays:
 
-#### forward-message
-- Requires message `id` to forward
-- `to` must be an array of recipient addresses
-- Optional `body` to prepend a message
-- Set `send: false` to save as draft instead of sending
+**Correct:**
+```json
+{
+  "to": ["bob@example.com"],
+  "subject": "Hello"
+}
+```
 
-#### mark-as-read / mark-as-unread / flag-message / unflag-message / delete-message
-- All require a message `id`
-- Get message IDs from `search-messages` or `list-messages`
+**Incorrect:**
+```json
+{
+  "to": "bob@example.com",
+  "subject": "Hello"
+}
+```
 
-#### move-message
-- Requires message `id` and destination `mailbox` name
-- Specify `account` if mailbox is in a specific account
+### send-email vs create-draft
 
-### Mailbox Operations
+- Use `send-email` for immediate sending
+- Use `create-draft` when the user should review first
+- **Recommendation**: For important emails, use `create-draft` and tell the user to review in Mail.app
 
-#### list-mailboxes
-- Returns all mailboxes (folders) for an account
-- Common mailboxes: INBOX, Sent, Drafts, Trash, Junk, Archive
+### reply-to-message
 
-#### get-unread-count
-- Omit parameters to get total unread across all accounts
-- Specify `mailbox` for specific folder count
+- Set `replyAll: true` to reply to all recipients
+- Set `send: false` to save as draft instead of sending immediately
+- Default behavior: reply to sender only, send immediately
+
+### forward-message
+
+- Requires message `id` and `to` array
+- Optional `body` to prepend a message
+- Set `send: false` to save as draft
 
 ### Multi-account
 
+- Default account is typically the first configured
 - Use `list-accounts` to see available accounts
 - Pass `account` parameter to target specific account
-- Default account is typically the first configured account
 
 ## Error Handling
 
 | Error | Likely Cause |
 |-------|--------------|
 | "Mail.app not responding" | Mail.app frozen or not running |
-| "Message not found" | Message ID is invalid or message was deleted |
+| "Message not found" | Message ID is invalid or message was deleted/moved |
 | "Permission denied" | macOS automation permission needed |
-| "Account not found" | Account name doesn't match exactly |
+| "Account not found" | Account name doesn't match exactly (case-sensitive) |
 | "Failed to send email" | Network issue or Mail.app configuration problem |
+| Silent failure | Backslash not escaped in content |
 
 ## Security Considerations
 
-- **Sending emails**: Always confirm with user before sending
-- **Deleting messages**: Warn user that deletion may be permanent
-- **Reading emails**: May contain sensitive information
+- **Sending emails**: Always confirm with user before sending. Recommend `create-draft` for review.
+- **Deleting messages**: Warn user that deletion moves to Trash (can be recovered).
+- **Reading emails**: May contain sensitive information - summarize rather than display full content when appropriate.
 
 ## Example Workflows
 
 ### Check for important emails
 ```
 1. list-accounts → get available accounts
-2. search-messages from="boss@company.com" → find emails from boss
+2. search-messages query="boss@company.com" → find emails from boss
 3. get-message id="..." → read the full content
 ```
 
-### Send a reply
+### Send a reply safely
 ```
 1. get-message id="..." → read original message
-2. reply-to-message id="..." body="Thanks for the update!" → reply to sender
-   OR
-   reply-to-message id="..." body="..." replyAll=true → reply to all
+2. reply-to-message id="..." body="..." send=false → save as draft
+3. Tell user to review in Mail.app before sending
 ```
 
-### Create a draft for user review
+### Compose and send
 ```
 1. create-draft to=["recipient@example.com"] subject="..." body="..."
-2. Tell user to review the draft in Mail.app before sending
+2. Tell user: "I've created a draft. Review it in Mail.app and send when ready."
+   OR if user confirms they want to send immediately:
+3. send-email to=["recipient@example.com"] subject="..." body="..."
 ```
 
 ### Forward an email
@@ -109,6 +148,14 @@ This MCP server enables AI assistants to interact with Apple Mail on macOS via A
 
 ### Organize inbox
 ```
-1. search-messages isRead=false → find unread
-2. For each: get-message, then move-message to appropriate folder
+1. search-messages query="newsletter" → find newsletters
+2. For each: move-message id="..." mailbox="Archive"
 ```
+
+## Testing Your Understanding
+
+Before sending emails with paths or special characters, verify escaping:
+
+- `~/path/to/file` - No escaping needed (no backslashes)
+- `C:\Users\` - Needs escaping: `C:\\Users\\`
+- `file\ name.txt` - Needs escaping: `file\\ name.txt`

+ 25 - 1
README.md

@@ -434,6 +434,30 @@ If installed from source, use this configuration:
 | Message ID scope | Message IDs are searched across all mailboxes (may be slow with large mailboxes) |
 | No smart mailboxes | Cannot access Smart Mailboxes via AppleScript |
 
+### Backslash Escaping (Important for AI Agents)
+
+When sending content containing backslashes (`\`) to this MCP server, **you must escape them as `\\`** in the JSON parameters.
+
+**Why:** The MCP protocol uses JSON for parameter passing. In JSON, a single backslash is an escape character. To include a literal backslash in content, it must be escaped as `\\`.
+
+**Example - Email with file path:**
+```json
+{
+  "to": ["colleague@company.com"],
+  "subject": "File Location",
+  "body": "The file is at C:\\\\Users\\\\Documents\\\\report.pdf"
+}
+```
+
+The `\\\\` in JSON becomes `\\` in the actual string, which represents a single `\` in the email.
+
+**Common patterns requiring escaping:**
+- Windows paths: `C:\Users\` → `C:\\\\Users\\\\` in JSON
+- Shell escaped spaces: `Mobile\ Documents` → `Mobile\\\\ Documents` in JSON
+- Regex patterns: `\d+` → `\\\\d+` in JSON
+
+**If you see errors** when sending emails with backslashes, double-check that backslashes are properly escaped in the JSON payload.
+
 ---
 
 ## Troubleshooting
@@ -469,7 +493,7 @@ If installed from source, use this configuration:
 ```bash
 npm install      # Install dependencies
 npm run build    # Compile TypeScript
-npm test         # Run test suite
+npm test         # Run test suite (28 tests)
 npm run lint     # Check code style
 npm run format   # Format code
 ```

+ 181 - 0
skills/apple-mail/skill.md

@@ -0,0 +1,181 @@
+# Apple Mail Skill
+
+This skill enables you to manage Apple Mail on macOS through natural language. Use it whenever the user mentions email, wants to send messages, or needs to read, search, or organize their inbox.
+
+## When to Use This Skill
+
+Use this skill when the user:
+
+- Wants to check their email or inbox
+- Asks to find or search for emails
+- Wants to read a specific email message
+- Needs to send an email or reply to one
+- Wants to create a draft email for review
+- Asks to forward an email to someone
+- Wants to mark emails as read/unread or flag them
+- Asks to delete or move emails
+- Mentions Apple Mail, Mail app, inbox, or "my email"
+
+## Available Tools
+
+### Message Operations
+
+| Tool | Purpose |
+|------|---------|
+| `list-messages` | List messages in a mailbox (default: INBOX) |
+| `search-messages` | Find messages by sender, subject, or content |
+| `get-message` | Read the full content of a message |
+| `send-email` | Send a new email immediately |
+| `create-draft` | Save an email to Drafts for review |
+| `reply-to-message` | Reply to a message (supports reply-all) |
+| `forward-message` | Forward a message to new recipients |
+| `mark-as-read` | Mark a message as read |
+| `mark-as-unread` | Mark a message as unread |
+| `flag-message` | Flag a message for follow-up |
+| `unflag-message` | Remove flag from a message |
+| `delete-message` | Move a message to Trash |
+| `move-message` | Move a message to a different mailbox |
+
+### Mailbox Operations
+
+| Tool | Purpose |
+|------|---------|
+| `list-mailboxes` | List all mailboxes/folders in an account |
+| `get-unread-count` | Get count of unread messages |
+
+### Account Operations
+
+| Tool | Purpose |
+|------|---------|
+| `list-accounts` | List configured email accounts |
+
+### Diagnostics
+
+| Tool | Purpose |
+|------|---------|
+| `health-check` | Verify Mail.app connectivity |
+| `get-mail-stats` | Get message and unread statistics |
+
+## Usage Patterns
+
+### Checking Email
+
+When the user wants to see their inbox:
+
+```
+User: "Check my email"
+Action: Use list-messages with mailbox="INBOX"
+
+User: "Do I have any unread emails?"
+Action: Use get-unread-count, then list-messages if they want details
+```
+
+### Finding Emails
+
+When the user wants to find specific emails:
+
+```
+User: "Find emails from Sarah"
+Action: Use search-messages with query="Sarah"
+
+User: "Search for emails about the project deadline"
+Action: Use search-messages with query="project deadline"
+```
+
+### Reading Emails
+
+When the user wants to see email content:
+
+```
+User: "Show me that email from John"
+Action: First search-messages to find it, then get-message with the ID
+```
+
+### Sending Emails
+
+When the user wants to send an email:
+
+```
+User: "Send an email to bob@example.com about the meeting"
+Action: Use send-email with to=["bob@example.com"], appropriate subject and body
+
+User: "Draft an email to the team" (wants to review first)
+Action: Use create-draft, then tell user to review in Mail.app
+```
+
+### Replying and Forwarding
+
+When the user wants to respond to emails:
+
+```
+User: "Reply to that email"
+Action: Use reply-to-message with the message ID and body
+
+User: "Reply all with my thoughts"
+Action: Use reply-to-message with replyAll=true
+
+User: "Forward this to my colleague"
+Action: Use forward-message with the message ID and recipient
+```
+
+### Organizing Email
+
+When the user wants to organize:
+
+```
+User: "Mark that as read"
+Action: Use mark-as-read with the message ID
+
+User: "Move these newsletters to Archive"
+Action: Use move-message with mailbox="Archive"
+
+User: "Delete that spam"
+Action: Use delete-message with the message ID
+```
+
+## Important Guidelines
+
+1. **Message IDs**: All message operations require an ID. Get IDs from `list-messages` or `search-messages` first.
+2. **Recipient Arrays**: The `to`, `cc`, and `bcc` parameters must be arrays, even for single recipients: `["email@example.com"]`
+3. **Default Account**: Operations default to the first configured account. Use `account` parameter for others.
+4. **Draft vs Send**: Use `create-draft` when the user wants to review before sending. Recommend this for important emails.
+5. **Backslash Escaping**: When email content contains backslashes, escape them as `\\` in the JSON.
+6. **macOS Only**: This skill only works on macOS systems.
+
+## Error Handling
+
+- **"Message not found"**: The message ID may be invalid or the message was deleted. Use search-messages to find it again.
+- **"Permission denied"**: User needs to grant automation permission in System Preferences > Privacy & Security > Automation.
+- **"Account not found"**: Account names are case-sensitive. Use list-accounts to see exact names.
+- **"Failed to send"**: Check network connection and Mail.app configuration.
+
+## Examples
+
+### Quick inbox check
+```
+User: "Any important emails today?"
+→ list-messages to see recent messages
+→ Summarize senders and subjects for user
+```
+
+### Email workflow
+```
+User: "Reply to Sarah's email about the budget"
+→ 1. search-messages query="Sarah budget"
+→ 2. get-message to read content
+→ 3. reply-to-message with user's response
+```
+
+### Safe sending pattern
+```
+User: "Send an email to the client about the delay"
+→ 1. create-draft with the composed email
+→ 2. Tell user: "I've created a draft. Please review it in Mail.app before sending."
+```
+
+### Multi-account usage
+```
+User: "Check my work email"
+→ 1. list-accounts to find work account name
+→ 2. list-messages with account="Work Exchange"
+```