groove-dev 0.17.6 → 0.17.7

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.
@@ -458,9 +458,9 @@ export class IntegrationStore {
458
458
  }
459
459
 
460
460
  /**
461
- * Pre-authenticate an auto-auth integration by running its MCP server briefly.
462
- * The server will open a browser for OAuth. Once auth completes, the server
463
- * stores tokens locally so future agent spawns work without prompting.
461
+ * Pre-authenticate an auto-auth integration by running its MCP server
462
+ * and sending the MCP handshake (initialize + tools/list). This triggers
463
+ * the server's built-in OAuth flow which opens a browser for sign-in.
464
464
  * Returns a handle to track the auth process.
465
465
  */
466
466
  authenticate(integrationId) {
@@ -477,13 +477,45 @@ export class IntegrationStore {
477
477
  if (val) env[ek.key] = val;
478
478
  }
479
479
 
480
- // Spawn the MCP server it will trigger OAuth on startup
480
+ // Spawn the MCP server with stdin/stdout for JSON-RPC,
481
+ // stderr inherited so it can open browsers and show auth prompts
481
482
  const proc = cpSpawn(command, args, {
482
483
  env: { ...process.env, ...env },
483
- stdio: ['pipe', 'pipe', 'pipe'],
484
+ stdio: ['pipe', 'pipe', 'inherit'],
484
485
  detached: false,
485
486
  });
486
487
 
488
+ // Send MCP handshake to initialize the server — this triggers auth
489
+ const initMsg = JSON.stringify({
490
+ jsonrpc: '2.0', id: 1, method: 'initialize',
491
+ params: {
492
+ protocolVersion: '2024-11-05',
493
+ capabilities: {},
494
+ clientInfo: { name: 'groove', version: '1.0.0' },
495
+ },
496
+ });
497
+ const listToolsMsg = JSON.stringify({
498
+ jsonrpc: '2.0', id: 2, method: 'tools/list', params: {},
499
+ });
500
+ const initializedNotif = JSON.stringify({
501
+ jsonrpc: '2.0', method: 'notifications/initialized',
502
+ });
503
+
504
+ // Wait a moment for npx to download + start, then send handshake
505
+ proc.stdout.on('data', (chunk) => {
506
+ const text = chunk.toString();
507
+ // After initialize response, send initialized notification + tools/list
508
+ if (text.includes('"id":1') || text.includes('"id": 1')) {
509
+ proc.stdin.write(initializedNotif + '\n');
510
+ setTimeout(() => proc.stdin.write(listToolsMsg + '\n'), 500);
511
+ }
512
+ });
513
+
514
+ // Send initialize after a brief delay for npx startup
515
+ setTimeout(() => {
516
+ try { proc.stdin.write(initMsg + '\n'); } catch { /* process may have exited */ }
517
+ }, 3000);
518
+
487
519
  // Auto-kill after 2 minutes (auth should complete well before that)
488
520
  const timeout = setTimeout(() => {
489
521
  try { proc.kill('SIGTERM'); } catch { /* ignore */ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "groove-dev",
3
- "version": "0.17.6",
3
+ "version": "0.17.7",
4
4
  "description": "Open-source agent orchestration layer — the AI company OS. MCP integrations (Slack, Gmail, Stripe, 15+), agent scheduling (cron), business roles (CMO, CFO, EA). GUI dashboard, multi-agent coordination, zero cold-start, infinite sessions. Works with Claude Code, Codex, Gemini CLI, Ollama.",
5
5
  "license": "FSL-1.1-Apache-2.0",
6
6
  "author": "Groove Dev <hello@groovedev.ai> (https://groovedev.ai)",
@@ -458,9 +458,9 @@ export class IntegrationStore {
458
458
  }
459
459
 
460
460
  /**
461
- * Pre-authenticate an auto-auth integration by running its MCP server briefly.
462
- * The server will open a browser for OAuth. Once auth completes, the server
463
- * stores tokens locally so future agent spawns work without prompting.
461
+ * Pre-authenticate an auto-auth integration by running its MCP server
462
+ * and sending the MCP handshake (initialize + tools/list). This triggers
463
+ * the server's built-in OAuth flow which opens a browser for sign-in.
464
464
  * Returns a handle to track the auth process.
465
465
  */
466
466
  authenticate(integrationId) {
@@ -477,13 +477,45 @@ export class IntegrationStore {
477
477
  if (val) env[ek.key] = val;
478
478
  }
479
479
 
480
- // Spawn the MCP server it will trigger OAuth on startup
480
+ // Spawn the MCP server with stdin/stdout for JSON-RPC,
481
+ // stderr inherited so it can open browsers and show auth prompts
481
482
  const proc = cpSpawn(command, args, {
482
483
  env: { ...process.env, ...env },
483
- stdio: ['pipe', 'pipe', 'pipe'],
484
+ stdio: ['pipe', 'pipe', 'inherit'],
484
485
  detached: false,
485
486
  });
486
487
 
488
+ // Send MCP handshake to initialize the server — this triggers auth
489
+ const initMsg = JSON.stringify({
490
+ jsonrpc: '2.0', id: 1, method: 'initialize',
491
+ params: {
492
+ protocolVersion: '2024-11-05',
493
+ capabilities: {},
494
+ clientInfo: { name: 'groove', version: '1.0.0' },
495
+ },
496
+ });
497
+ const listToolsMsg = JSON.stringify({
498
+ jsonrpc: '2.0', id: 2, method: 'tools/list', params: {},
499
+ });
500
+ const initializedNotif = JSON.stringify({
501
+ jsonrpc: '2.0', method: 'notifications/initialized',
502
+ });
503
+
504
+ // Wait a moment for npx to download + start, then send handshake
505
+ proc.stdout.on('data', (chunk) => {
506
+ const text = chunk.toString();
507
+ // After initialize response, send initialized notification + tools/list
508
+ if (text.includes('"id":1') || text.includes('"id": 1')) {
509
+ proc.stdin.write(initializedNotif + '\n');
510
+ setTimeout(() => proc.stdin.write(listToolsMsg + '\n'), 500);
511
+ }
512
+ });
513
+
514
+ // Send initialize after a brief delay for npx startup
515
+ setTimeout(() => {
516
+ try { proc.stdin.write(initMsg + '\n'); } catch { /* process may have exited */ }
517
+ }, 3000);
518
+
487
519
  // Auto-kill after 2 minutes (auth should complete well before that)
488
520
  const timeout = setTimeout(() => {
489
521
  try { proc.kill('SIGTERM'); } catch { /* ignore */ }