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 +111 -6
- package/index.js +172 -193
- package/indexer.js +26 -21
- package/lib/audit.js +22 -14
- package/lib/config.js +312 -0
- package/lib/indexGate.js +49 -0
- package/lib/indexerLock.js +376 -0
- package/lib/indexerRuntime.js +142 -0
- package/lib/lancedbTables.js +307 -0
- package/lib/processMode.js +28 -0
- package/package.json +4 -2
- package/search.js +4 -18
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,
|
|
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
|
-
|
|
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
|
|
254
|
-
|
|
355
|
+
# Run the indexer daemon (owns indexer.lock + vector-index refresh)
|
|
356
|
+
npm run indexer
|
|
255
357
|
|
|
256
|
-
#
|
|
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
|
```
|