local-mcp 3.0.88 → 3.0.89
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/package.json +1 -1
- package/setup.js +52 -40
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "local-mcp",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.89",
|
|
4
4
|
"description": "LMCP — connect Claude Desktop, Cursor, Windsurf to Mail, Calendar, Contacts, Teams, OneDrive on macOS. Privacy-first: all data stays on your Mac.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
package/setup.js
CHANGED
|
@@ -304,28 +304,29 @@ async function runSetup(opts = {}) {
|
|
|
304
304
|
// Auto-launch primary configured AI client + show "Try this now" banner
|
|
305
305
|
_autoLaunchClient(configured)
|
|
306
306
|
|
|
307
|
-
//
|
|
307
|
+
// Anon-first cloud relay activation (replaces the interactive email prompt
|
|
308
|
+
// removed 2026-04-19). When no email is set, register an anonymous tunnel
|
|
309
|
+
// token keyed on machine_id so cloud relay comes online immediately. Users
|
|
310
|
+
// can attach an email later via the tray or /settings to unlock cross-Mac
|
|
311
|
+
// sync + paid-license features. Non-fatal on failure — the install still
|
|
312
|
+
// succeeds and the server can retry at startup.
|
|
308
313
|
if (!email) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
} catch { /* config will be created on first server run */ }
|
|
323
|
-
email = prompted
|
|
314
|
+
try {
|
|
315
|
+
const cfg = _readJson(cfgFile)
|
|
316
|
+
const alreadyLinked = (cfg.license_email && cfg.license_email.length > 0)
|
|
317
|
+
const alreadyAnon = (cfg.cloud_token && typeof cfg.cloud_token === 'string' && cfg.cloud_token.startsWith('lmcp-'))
|
|
318
|
+
if (!alreadyLinked && !alreadyAnon) {
|
|
319
|
+
const tok = await _registerAnonToken()
|
|
320
|
+
if (tok) {
|
|
321
|
+
const cfg2 = _readJson(cfgFile)
|
|
322
|
+
cfg2.cloud_token = tok
|
|
323
|
+
_writeJson(cfgFile, cfg2)
|
|
324
|
+
console.log(' ✓ Cloud relay activated (anonymous)')
|
|
325
|
+
}
|
|
324
326
|
}
|
|
325
|
-
}
|
|
327
|
+
} catch { /* non-fatal */ }
|
|
326
328
|
}
|
|
327
329
|
|
|
328
|
-
// Ping de tracking (fire-and-forget, no bloquea)
|
|
329
330
|
_pingInstall(configured, opts.method || 'setup', email)
|
|
330
331
|
}
|
|
331
332
|
|
|
@@ -407,30 +408,41 @@ function _getMachineId() {
|
|
|
407
408
|
return ''
|
|
408
409
|
}
|
|
409
410
|
|
|
410
|
-
///
|
|
411
|
-
///
|
|
412
|
-
///
|
|
413
|
-
|
|
411
|
+
/// Claim an anonymous tunnel token via /tunnel/register-anon so cloud relay
|
|
412
|
+
/// activates without asking for an email (2026-04-19 anon-first rollout). The
|
|
413
|
+
/// token is keyed on the Mac's machine_id (IOPlatformUUID, shared via Keychain
|
|
414
|
+
/// with the Swift daemon). Returns the token string or '' on failure — callers
|
|
415
|
+
/// treat failure as non-fatal and fall through to the email-based path.
|
|
416
|
+
async function _registerAnonToken() {
|
|
414
417
|
return new Promise((resolve) => {
|
|
415
|
-
const
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
418
|
+
const https = require('https')
|
|
419
|
+
const machineId = _getMachineId()
|
|
420
|
+
const payload = JSON.stringify({ machine_id: machineId })
|
|
421
|
+
const req = https.request({
|
|
422
|
+
host: BACKEND_HOST,
|
|
423
|
+
port: 443,
|
|
424
|
+
method: 'POST',
|
|
425
|
+
path: '/tunnel/register-anon',
|
|
426
|
+
headers: {
|
|
427
|
+
'Content-Type': 'application/json',
|
|
428
|
+
'Content-Length': Buffer.byteLength(payload),
|
|
429
|
+
},
|
|
430
|
+
timeout: 8000,
|
|
431
|
+
}, (res) => {
|
|
432
|
+
let buf = ''
|
|
433
|
+
res.on('data', (chunk) => { buf += chunk })
|
|
434
|
+
res.on('end', () => {
|
|
435
|
+
try {
|
|
436
|
+
const obj = JSON.parse(buf)
|
|
437
|
+
const tok = (obj && typeof obj.token === 'string') ? obj.token : ''
|
|
438
|
+
resolve(tok.startsWith('lmcp-') ? tok : '')
|
|
439
|
+
} catch { resolve('') }
|
|
440
|
+
})
|
|
433
441
|
})
|
|
442
|
+
req.on('error', () => resolve(''))
|
|
443
|
+
req.on('timeout', () => { try { req.destroy() } catch {} resolve('') })
|
|
444
|
+
req.write(payload)
|
|
445
|
+
req.end()
|
|
434
446
|
})
|
|
435
447
|
}
|
|
436
448
|
|