Commit f7d4c8b
Performance improvements and benchmark framework (#7)
* docs(CLAUDE.md): clarify MCP integration priority for local tools
Add critical guidance for tool selection priority to prevent duplicate
integrations. Emphasizes local MCP servers (Gmail, Calendar, Reminders)
over Rube/Composio fallbacks.
Key changes:
- Add explicit tool selection priority checklist
- Document when to use local MCP vs Rube/Composio
- Clarify fallback scenarios for external integrations
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* feat(reminders): add timing instrumentation and increase timeouts
Performance and reliability improvements for Reminders MCP server:
- Add timing instrumentation for all API operations
- Increase AppleScript timeout from 10s to 15s
- Increase EventKit fetch timeout from 10s to 15s
- Add [TIMING] markers for benchmark capture
Timing markers enable performance profiling and help identify
bottlenecks in AppleScript and EventKit async operations.
Timeout increases reduce intermittent failures caused by
Reminders.app latency on system load.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* feat(texting): add FDA-free database access with security-scoped bookmarks
Major UX improvement for Messages database access without Full Disk Access:
Core Features:
- Security-scoped bookmark support via file picker
- Lazy contacts sync with tiered approach (daemon → Rust CLI → Python)
- Permission checking and guided setup
- TTL-based sync caching (30min default)
New Files:
- db_access.py: Security-scoped bookmark manager
- file_picker.py: NSOpenPanel integration for bookmark creation
iMessage Client Improvements:
- Auto-detect running contacts daemon
- Prefer Rust CLI sync (~500ms) over Python (~700ms)
- Interactive permission prompts when appropriate
- Graceful fallback to legacy FDA path
Messages Interface Improvements:
- Bookmark-first initialization (use_bookmark=True default)
- Comprehensive permission checking API
- Backward compatibility with explicit path mode
This eliminates the need for users to grant Full Disk Access,
using Apple's security-scoped bookmark API instead. Users pick
the Messages database once via file picker, bookmark is stored,
and future access works without FDA.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* feat(gmail): add batch optimization and CLI with daemon support
Major performance improvements and new CLI interface:
Performance Optimizations (5x speedup):
- Implement BatchHttpRequest for parallel email fetching
- Eliminate N+1 query pattern (was: 1 list + N detail calls)
- Add timing instrumentation for profiling
- OAuth token caching with load/refresh timing
New CLI Interface (gmail_cli.py):
- Standalone CLI for terminal/scripting use
- Daemon mode support (6.2x faster than MCP)
- JSON output for automation
- Operations: unread, list, search, send
- Shares OAuth tokens with MCP server
Performance Benchmarks:
- Unread count: MCP 1,030ms → CLI+daemon 167ms (6.2x)
- List 10 emails: MCP 1,180ms → CLI+daemon 318ms (3.7x)
- Search: MCP 1,160ms → CLI+daemon 287ms (4.1x)
Documentation:
- Add performance comparison table
- Document CLI vs MCP use cases
- Reference google_daemon setup
Use MCP for Claude Code integration, CLI+daemon for
high-frequency operations and scripting.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* feat(calendar): add CLI with daemon support and timing instrumentation
New CLI interface and performance improvements for Google Calendar:
New CLI Interface (calendar_cli.py):
- Standalone CLI for terminal/scripting use
- Daemon mode support for faster operations
- JSON output for automation
- Operations: list, today, week, upcoming, find-free, create
- Shares OAuth tokens with MCP server
Performance Instrumentation:
- Add timing context manager for profiling
- Track OAuth operations (load, refresh, auth)
- Track API calls for performance analysis
- [TIMING] markers for benchmark capture
Documentation Updates:
- Add high-performance CLI section
- Document daemon setup and usage
- Performance comparison guidance
- CLI vs MCP use case matrix
Similar to Gmail integration, provides both MCP server for
Claude Code integration and CLI for high-frequency scripting.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* feat(google-daemon): add shared daemon for Gmail and Calendar services
New daemon infrastructure for high-performance Google API access:
Core Daemon (google_daemon/server.py):
- Shared credential and API client management
- Background refresh for hot startup (<50ms)
- Unix domain socket for IPC
- Process lifecycle management (start/stop/status/restart)
- Automatic OAuth token refresh
- Graceful shutdown and error recovery
Architecture:
- Single daemon serves both Gmail and Calendar CLIs
- Eliminates per-request OAuth overhead
- Maintains warm API connections
- 6.2x faster than MCP for high-frequency operations
Client Integration:
- Unix socket protocol for request/response
- JSON-based command/response format
- Timeout handling and connection retry
- Shared by gmail_cli.py and calendar_cli.py
Lifecycle Commands:
- start: Launch daemon in background
- stop: Graceful shutdown
- status: Check daemon health
- restart: Stop and restart daemon
Testing:
- Integration test suite for daemon lifecycle
- Request/response validation
- Error handling verification
This daemon enables the performance improvements documented
in Gmail and Calendar CLI tools.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* feat(benchmarks): add comprehensive iMessage MCP benchmark framework
New benchmark infrastructure for evaluating MCP server performance:
Normalized Workload Benchmarking (normalized_workload_benchmarks.py):
- Real-world workload simulation (conversation history, search, etc.)
- Multi-server comparison (photon, sameelarif, mcp_imessage, imcp)
- Operation-level timing breakdown (parsing, execution, serialization)
- Headline metrics: overall latency, server processing time
- Validation of results against expected schemas
- Statistical analysis and ranking
Visualization Tools (visualize_benchmark_story*.py):
- Generate performance comparison tables
- Create comprehensive Markdown reports
- Workload ranking and analysis
- Tool mapping and coverage analysis
- Combined result aggregation across test runs
Benchmark Methodology:
- Realistic workloads based on actual usage patterns
- Timing instrumentation via [TIMING] markers
- Client-side and server-side timing capture
- Multiple iterations for statistical validity
- Result validation to ensure correctness
Output Formats:
- JSON: Raw benchmark data with full timing breakdown
- CSV: Tabular data for analysis and graphing
- Markdown: Human-readable reports with tables
- Summary: Aggregated statistics and rankings
This framework enabled the performance optimizations documented
in the iMessage gateway and identified the 19x speedup over
vanilla MCP implementations.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* chore(benchmarks): add iMessage MCP performance benchmark results
Comprehensive benchmark data documenting performance across
multiple MCP server implementations and configurations:
Test Configurations:
- photon (custom MCP server with FastAPI)
- sameelarif (community MCP server)
- mcp_imessage (reference implementation)
- imcp (legacy implementation)
- node22 environment variants
- Various timeout and validation configurations
Result Files:
- JSON: Raw timing data with operation-level breakdown
- CSV: Tabular data (combined, server summary, tool mapping, rankings)
- Markdown: Human-readable performance tables
- Debug payloads: Request/response validation data
Key Findings (from results):
- photon achieves 19x speedup over vanilla MCP (40ms vs 763ms)
- node22 timeout tuning reduces failures
- Validation overhead minimal (<5ms)
- Batch operations show consistent performance
Benchmark Dates: January 7-8, 2026
These results informed the Gateway CLI design decision and
validated the performance gains documented in README.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* docs(plans): add Rust MCP clients handoff documentation
Planning document for implementing high-performance Rust-based
MCP clients for Gmail and Calendar integrations.
Objective:
- Replace Python daemon with native Rust implementation
- Achieve sub-100ms latency for common operations
- Reduce memory footprint and startup time
- Maintain compatibility with existing CLI interfaces
Key Design Points:
- Async Rust with tokio runtime
- Unix domain socket IPC protocol
- Shared OAuth token management
- Hot credential caching
- Graceful degradation to Python fallback
Target Performance:
- Gmail unread count: <80ms (current: 167ms with daemon)
- Calendar list: <90ms (current: ~150ms with daemon)
- Memory: <20MB resident (current: ~80MB Python)
- Startup: <10ms cold, <1ms hot
Next Steps:
- Project structure setup
- OAuth client implementation
- Gmail API client
- Calendar API client
- Integration with existing CLIs
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* feat(imessage): implement Phase 3 - analytics, discovery, and groups commands
Implements complete Phase 3 of Rust CLI migration with 9 new commands:
Analytics commands:
- analytics: Conversation statistics with 6 SQL queries (message counts, busiest hour/day, top contacts, attachments, reactions)
- followup: Detect unanswered questions and stale conversations
- reactions: Query tapback messages (already implemented in reading.rs)
Discovery commands:
- handles: List all unique phone/email handles
- unknown: Find messages from non-contacts
- discover: Frequent texters not in contacts
- scheduled: Scheduled messages stub (not supported by Messages.db)
Groups commands:
- groups: List all group chats with participants
- group-messages: Get messages from specific groups (by group_id or participant)
All commands support both JSON and human-readable output formats.
Development time: ~15 minutes across 3 sprints (3A, 3B, 3C)
Build time: <2s
Test coverage: Manual testing verified all commands working
Phase 3 completes feature parity with Python gateway for analytics, discovery, and groups functionality.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(imessage): add Phase 4 daemon infrastructure and fix PR review comments
Phase 4 Daemon Infrastructure (wolfies-imessage):
- Add daemon module with NDJSON protocol over UNIX socket
- Create wolfies-imessage-daemon binary (start/stop/status commands)
- Create wolfies-imessage-client thin client binary (3.8MB)
- Hot SQLite connection + contact cache for sub-2ms latency
- Health endpoint achieving 1.2ms avg (18x faster than CLI baseline)
- Phase 4A: Contact caching with Arc-based sharing
- Phase 4B: Parallel queries with rayon (followup 7% faster)
PR #7 Review Comment Fixes:
- Add comprehensive docstring to _extract_target_from_response (Gemini HIGH)
- Change broad Exception catch to specific json.JSONDecodeError (Gemini MEDIUM)
- Add daemon support to calendar_cli events/get/create/delete commands (Codex P2)
- Add stale pidfile safety check in google_daemon cmd_stop (Codex P2)
New Dependencies:
- uuid, daemonize, shellexpand, libc (Rust daemon)
- rayon 1.8 (parallel queries)
Performance Results:
- Daemon health: 1.2ms avg (vs 22ms CLI baseline) = 18x faster
- Followup command: 6.2ms (7% improvement with parallel queries)
- Analytics: Hot connection ready for Phase 5 command handlers
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Wolfgang Schoenberger <221313372+wolfiesch@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>1 parent 3705952 commit f7d4c8b
File tree
140 files changed
+48519
-209
lines changed- Plans
- Reminders
- mcp_server
- src
- Texting
- benchmarks
- results
- debug_payloads
- 20260107_202056_node22_validated
- brew_MCP_cardmagic_messages_messages_--mcp
- github_MCP_TextFly_photon-imsg-mcp_node_stdio
- github_MCP_sameelarif_imessage-mcp_node_tsx
- 20260107_205840_node22_publish/brew_MCP_cardmagic_messages_messages_--mcp
- 20260107_210235_node22_publish_validated
- brew_MCP_cardmagic_messages_messages_--mcp
- github_MCP_TextFly_photon-imsg-mcp_node_stdio
- github_MCP_sameelarif_imessage-mcp_node_tsx
- gateway
- wolfies-imessage
- src
- bin
- commands
- contacts
- daemon
- db
- src
- benchmarks
- results
- scripts
- src
- integrations
- gmail
- google_calendar
- google_daemon
- tests/integration
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
140 files changed
+48519
-209
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
185 | 185 | | |
186 | 186 | | |
187 | 187 | | |
188 | | - | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
189 | 201 | | |
190 | 202 | | |
191 | 203 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
11 | 14 | | |
12 | 15 | | |
13 | 16 | | |
14 | 17 | | |
15 | 18 | | |
| 19 | + | |
16 | 20 | | |
17 | | - | |
| 21 | + | |
18 | 22 | | |
19 | 23 | | |
20 | 24 | | |
21 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
22 | 57 | | |
23 | 58 | | |
24 | 59 | | |
| |||
267 | 302 | | |
268 | 303 | | |
269 | 304 | | |
270 | | - | |
271 | | - | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
279 | 315 | | |
280 | 316 | | |
281 | 317 | | |
| |||
297 | 333 | | |
298 | 334 | | |
299 | 335 | | |
300 | | - | |
301 | | - | |
302 | | - | |
303 | | - | |
304 | | - | |
305 | | - | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
306 | 343 | | |
307 | 344 | | |
308 | 345 | | |
| |||
324 | 361 | | |
325 | 362 | | |
326 | 363 | | |
327 | | - | |
| 364 | + | |
| 365 | + | |
328 | 366 | | |
329 | 367 | | |
330 | 368 | | |
| |||
333 | 371 | | |
334 | 372 | | |
335 | 373 | | |
336 | | - | |
| 374 | + | |
| 375 | + | |
337 | 376 | | |
338 | 377 | | |
339 | 378 | | |
| |||
355 | 394 | | |
356 | 395 | | |
357 | 396 | | |
358 | | - | |
| 397 | + | |
| 398 | + | |
359 | 399 | | |
360 | 400 | | |
361 | 401 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
10 | 13 | | |
11 | 14 | | |
12 | 15 | | |
| |||
309 | 312 | | |
310 | 313 | | |
311 | 314 | | |
312 | | - | |
| 315 | + | |
313 | 316 | | |
314 | 317 | | |
315 | 318 | | |
| |||
579 | 582 | | |
580 | 583 | | |
581 | 584 | | |
582 | | - | |
| 585 | + | |
| 586 | + | |
583 | 587 | | |
584 | 588 | | |
585 | 589 | | |
| |||
0 commit comments