apple-tools-mcp 1.1.4 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -39,6 +39,8 @@ If you installed from source, point your MCP client at the local `index.js` inst
39
39
  "args": ["/absolute/path/to/Apple-Tools-MCP/index.js"]
40
40
  ```
41
41
 
42
+ **Mac Mini** stays on a **global npm** install (`npm install -g apple-tools-mcp`) — no git clone on Mini. **MacBook / development** uses the clone above.
43
+
42
44
  ### 2. Grant Full Disk Access
43
45
 
44
46
  The MCP server needs access to read your Mail, Messages, and Calendar databases.
@@ -89,15 +91,22 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
89
91
 
90
92
  Other clients use their own settings UI or config file. Use the same `command` and `args`; only the file path or UI differs.
91
93
 
94
+ MCP clients are **short-lived stdio** processes: they exit when the client closes stdin. Always-on indexing belongs on the **indexer daemon**, not a sleep-pipe wrapper around this binary.
95
+
92
96
  ### 4. Restart your MCP client
93
97
 
94
98
  Quit and reopen the client so it loads the server. For Claude Desktop, fully quit (Cmd+Q) and reopen.
95
99
 
96
100
  ## Building the Index
97
101
 
98
- On first use, the server will automatically build a vector index of your emails, messages, and calendar events. Email history is unlimited by default. This may take a while depending on the volume of data.
102
+ On first use, a vector index of your emails, messages, and calendar events is built automatically. Email history is unlimited by default. This may take a while depending on the volume of data.
103
+
104
+ **Who indexes**
99
105
 
100
- You can manually rebuild the index:
106
+ - **Indexer daemon running** (recommended on Mac Mini): the daemon owns `~/.apple-tools-mcp/indexer.lock` and refreshes `~/.apple-tools-mcp/vector-index/`. MCP stdio clients only search; they do not start background refresh.
107
+ - **No daemon** (default MacBook / Claude Desktop / Cursor): the MCP stdio process indexes **locally on startup**, same as previous versions, then exits when the client disconnects.
108
+
109
+ You can manually rebuild the index (stop the indexer daemon first if it is running, so it is not writing at the same time):
101
110
 
102
111
  ```bash
103
112
  # Index all email history (default)
@@ -109,6 +118,96 @@ APPLE_TOOLS_INDEX_DAYS_BACK=30 npm run build-index
109
118
 
110
119
  The index is stored in `~/.apple-tools-mcp/vector-index/`.
111
120
 
121
+ ## Index refresh interval
122
+
123
+ Resolved **once at process start**. Precedence (highest wins):
124
+
125
+ 1. `INDEX_INTERVAL_MS` environment variable (milliseconds or human form: `30s`, `1m`, `5m`, `1h`)
126
+ 2. `~/.apple-tools-mcp/config.json` keys `indexInterval` or `indexIntervalMs`
127
+ 3. Product default: **5 minutes** (`300000` ms) — typical MacBook / MCP local-fallback
128
+
129
+ Values are **clamped** to **15 seconds** minimum and **6 hours** maximum. Invalid JSON, unknown keys, and unparseable intervals are logged and ignored (the process does not crash). The effective interval is logged at start, for example:
130
+
131
+ ```text
132
+ Effective index refresh interval: 1m (60000 ms) [source=config]
133
+ ```
134
+
135
+ A warn line is also logged when clamping occurs.
136
+
137
+ ### Example `~/.apple-tools-mcp/config.json` (Mac Mini)
138
+
139
+ Recommended Mini always-on interval is **1 minute**. 30 seconds is allowed (at or above the 15s floor).
140
+
141
+ ```json
142
+ {
143
+ "indexInterval": "1m"
144
+ }
145
+ ```
146
+
147
+ Equivalent: `"indexIntervalMs": 60000`, or `INDEX_INTERVAL_MS=60000` (env overrides the file).
148
+
149
+ Missing `config.json` is fine — env then the 5-minute default apply.
150
+
151
+ ## Always-on indexer (Mac Mini LaunchAgent)
152
+
153
+ On Mini, run the **indexer daemon**, not a sleep-pipe wrapper around `apple-tools-mcp`. Grok Bot, Claude Desktop, and other clients still attach via short-lived stdio MCP (`npx -y apple-tools-mcp` or the global `apple-tools-mcp` bin).
154
+
155
+ **Entrypoint:** `node index.js --mode=indexer`
156
+ **Convenience bin:** `apple-tools-indexer` (same file; npm global install provides it)
157
+ **npm script (clone only):** `npm run indexer`
158
+ **One-shot rebuild:** `npm run build-index` (stop the indexer daemon first)
159
+
160
+ LaunchAgent should invoke **node + `--mode=indexer`** on the **global** package (Mini has no git clone). LaunchAgent does not inherit your shell `PATH`, so use absolute paths from `which node` and `npm root -g`.
161
+
162
+ ```bash
163
+ which node
164
+ # Apple Silicon Homebrew example: /opt/homebrew/bin/node
165
+ # Intel Homebrew / usr/local example: /usr/local/bin/node
166
+
167
+ npm root -g
168
+ # Example: /opt/homebrew/lib/node_modules
169
+ ```
170
+
171
+ Example `~/Library/LaunchAgents/com.apple-tools-mcp.indexer.plist`:
172
+
173
+ ```xml
174
+ <?xml version="1.0" encoding="UTF-8"?>
175
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
176
+ <plist version="1.0">
177
+ <dict>
178
+ <key>Label</key>
179
+ <string>com.apple-tools-mcp.indexer</string>
180
+ <key>ProgramArguments</key>
181
+ <array>
182
+ <string>/opt/homebrew/bin/node</string>
183
+ <string>/opt/homebrew/lib/node_modules/apple-tools-mcp/index.js</string>
184
+ <string>--mode=indexer</string>
185
+ </array>
186
+ <key>RunAtLoad</key>
187
+ <true/>
188
+ <key>KeepAlive</key>
189
+ <true/>
190
+ <key>EnvironmentVariables</key>
191
+ <dict>
192
+ <key>PATH</key>
193
+ <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
194
+ </dict>
195
+ <key>StandardOutPath</key>
196
+ <string>/tmp/apple-tools-indexer.out.log</string>
197
+ <key>StandardErrorPath</key>
198
+ <string>/tmp/apple-tools-indexer.err.log</string>
199
+ </dict>
200
+ </plist>
201
+ ```
202
+
203
+ Replace the node and `node_modules` paths with the values from `which node` and `npm root -g`. Load it with:
204
+
205
+ ```bash
206
+ launchctl load ~/Library/LaunchAgents/com.apple-tools-mcp.indexer.plist
207
+ ```
208
+
209
+ KeepAlive belongs on this indexer job only — not on the MCP stdio process.
210
+
112
211
  ## Available Tools
113
212
 
114
213
  Once configured, your MCP client can use these tools:
@@ -206,12 +305,15 @@ Ensure Node.js has Full Disk Access (see Installation step 2).
206
305
  If the index becomes corrupted or out of sync:
207
306
 
208
307
  ```bash
308
+ # If the Mini indexer LaunchAgent is running, unload it first
309
+ # launchctl unload ~/Library/LaunchAgents/com.apple-tools-mcp.indexer.plist
310
+
209
311
  # Remove existing index files
210
312
  rm -rf ~/.apple-tools-mcp/vector-index
211
313
  rm -f ~/.apple-tools-mcp/index-meta.json
212
314
  rm -f ~/.apple-tools-mcp/indexer.lock
213
315
 
214
- # Restart your MCP client to trigger a fresh rebuild
316
+ # Restart the indexer daemon or your MCP client to trigger a fresh rebuild
215
317
  ```
216
318
 
217
319
  ### Monitor indexing progress
@@ -250,12 +352,15 @@ npm install -D vitest @vitest/coverage-v8 fast-check
250
352
  # Run tests
251
353
  npm test
252
354
 
253
- # Run tests with verbose coverage report
254
- npx vitest run --coverage --reporter=verbose
355
+ # Run the indexer daemon (owns indexer.lock + vector-index refresh)
356
+ npm run indexer
255
357
 
256
- # Build index with debug output
358
+ # One-shot rebuild (stop the indexer daemon first)
257
359
  npm run build-index
258
360
 
361
+ # Run tests with verbose coverage report
362
+ npx vitest run --coverage --reporter=verbose
363
+
259
364
  # Run audit to check index health
260
365
  npm run audit
261
366
  ```