local-mcp 1.116.0 → 1.118.0

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.
Files changed (2) hide show
  1. package/index.js +33 -6
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -14,6 +14,7 @@
14
14
  const { spawn } = require('child_process')
15
15
  const path = require('path')
16
16
  const os = require('os')
17
+ const fs = require('fs')
17
18
 
18
19
  // Solo macOS
19
20
  if (process.platform !== 'darwin') {
@@ -85,13 +86,39 @@ async function main() {
85
86
  process.exit(1)
86
87
  }
87
88
 
88
- // Binario PyInstaller standalone — sin Python, sin dependencias externas
89
- // Usar spawn (async) en lugar de spawnSync para que el event loop siga corriendo
90
- // y ensureTray() pueda completar sus operaciones de red en background.
91
89
  const { binPath } = runtime
92
- // slice(3): skip node, index.js, and cmd ('stdio') — 'stdio' ya está hardcodeado abajo
93
- const extraArgs = process.argv.slice(3)
94
- const child = spawn(binPath, ['stdio', ...extraArgs], {
90
+
91
+ // ── Symlink estable + migración de config de Claude Desktop ──────────────────
92
+ // El binario corre como hijo de node → TCC muestra "node" en los diálogos de
93
+ // permisos (Messages, Mail, etc.) en lugar de "local-mcp-server".
94
+ // Solución: crear un symlink estable y apuntar Claude Desktop directamente
95
+ // al binario. En la próxima sesión, Claude Desktop llama al binario sin node
96
+ // como padre → TCC ve "com.local-mcp.server" directamente.
97
+ const { CACHE_DIR } = require('./download')
98
+ const stableLink = path.join(CACHE_DIR, 'local-mcp-server')
99
+ try {
100
+ if (fs.existsSync(stableLink)) fs.unlinkSync(stableLink)
101
+ fs.symlinkSync(binPath, stableLink)
102
+
103
+ // Migrar claude_desktop_config.json si todavía usa npx
104
+ const claudeConfig = path.join(
105
+ os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'
106
+ )
107
+ if (fs.existsSync(claudeConfig)) {
108
+ const cfg = JSON.parse(fs.readFileSync(claudeConfig, 'utf8'))
109
+ const srv = cfg.mcpServers?.['local-mcp']
110
+ if (srv && srv.command === 'npx') {
111
+ cfg.mcpServers['local-mcp'] = { command: stableLink }
112
+ fs.writeFileSync(claudeConfig, JSON.stringify(cfg, null, 2))
113
+ process.stderr.write(`\n✓ Config de Claude Desktop actualizado.\n`)
114
+ process.stderr.write(` Reiniciá Claude Desktop para que Local MCP corra sin node como padre.\n`)
115
+ process.stderr.write(` (Esto elimina los diálogos de permisos repetidos.)\n\n`)
116
+ }
117
+ }
118
+ } catch { /* no crítico — seguimos con spawn normal */ }
119
+
120
+ // Spawn para esta sesión (siguiente sesión ya será binario directo)
121
+ const child = spawn(binPath, [], {
95
122
  stdio: 'inherit',
96
123
  env: process.env,
97
124
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "local-mcp",
3
- "version": "1.116.0",
3
+ "version": "1.118.0",
4
4
  "description": "MCP server for macOS — connect Claude Desktop, Cursor, Windsurf to Mail, Calendar, Contacts, Teams, OneDrive. Privacy-first: all data stays on your Mac.",
5
5
  "main": "index.js",
6
6
  "bin": {