groove-dev 0.17.2 → 0.17.4
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/node_modules/@groove-dev/daemon/integrations-registry.json +23 -33
- package/node_modules/@groove-dev/daemon/src/api.js +45 -43
- package/node_modules/@groove-dev/gui/dist/assets/{index-CEf7nLM2.js → index-DXy6tMX5.js} +11 -11
- package/node_modules/@groove-dev/gui/dist/index.html +1 -1
- package/node_modules/@groove-dev/gui/src/views/IntegrationsStore.jsx +61 -70
- package/package.json +1 -1
- package/packages/daemon/integrations-registry.json +23 -33
- package/packages/daemon/src/api.js +45 -43
- package/packages/gui/dist/assets/{index-CEf7nLM2.js → index-DXy6tMX5.js} +11 -11
- package/packages/gui/dist/index.html +1 -1
- package/packages/gui/src/views/IntegrationsStore.jsx +61 -70
|
@@ -95,21 +95,16 @@
|
|
|
95
95
|
"icon": "calendar",
|
|
96
96
|
"tags": ["calendar", "scheduling", "events", "meetings"],
|
|
97
97
|
"roles": ["ea", "cmo"],
|
|
98
|
-
"npmPackage": "@
|
|
98
|
+
"npmPackage": "@gongrzhe/server-calendar-autoauth-mcp",
|
|
99
99
|
"transport": "stdio",
|
|
100
100
|
"command": "npx",
|
|
101
|
-
"args": ["-y", "@
|
|
102
|
-
"authType": "
|
|
103
|
-
"
|
|
104
|
-
"envKeys": [
|
|
105
|
-
{ "key": "GOOGLE_CLIENT_ID", "label": "OAuth Client ID", "required": true, "hidden": true },
|
|
106
|
-
{ "key": "GOOGLE_CLIENT_SECRET", "label": "OAuth Client Secret", "required": true, "hidden": true },
|
|
107
|
-
{ "key": "GOOGLE_REFRESH_TOKEN", "label": "Refresh Token", "required": true, "hidden": true }
|
|
108
|
-
],
|
|
101
|
+
"args": ["-y", "@gongrzhe/server-calendar-autoauth-mcp"],
|
|
102
|
+
"authType": "none",
|
|
103
|
+
"envKeys": [],
|
|
109
104
|
"setupSteps": [
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"That's it —
|
|
105
|
+
"Just install — the server handles Google sign-in automatically",
|
|
106
|
+
"On first use, a browser window will open for you to authorize",
|
|
107
|
+
"That's it — no API keys or tokens needed"
|
|
113
108
|
],
|
|
114
109
|
"featured": false,
|
|
115
110
|
"downloads": 0,
|
|
@@ -125,21 +120,16 @@
|
|
|
125
120
|
"icon": "email",
|
|
126
121
|
"tags": ["email", "inbox", "messaging", "notifications"],
|
|
127
122
|
"roles": ["ea", "cmo", "support"],
|
|
128
|
-
"npmPackage": "@
|
|
123
|
+
"npmPackage": "@gongrzhe/server-gmail-autoauth-mcp",
|
|
129
124
|
"transport": "stdio",
|
|
130
125
|
"command": "npx",
|
|
131
|
-
"args": ["-y", "@
|
|
132
|
-
"authType": "
|
|
133
|
-
"
|
|
134
|
-
"envKeys": [
|
|
135
|
-
{ "key": "GOOGLE_CLIENT_ID", "label": "OAuth Client ID", "required": true, "hidden": true },
|
|
136
|
-
{ "key": "GOOGLE_CLIENT_SECRET", "label": "OAuth Client Secret", "required": true, "hidden": true },
|
|
137
|
-
{ "key": "GOOGLE_REFRESH_TOKEN", "label": "Refresh Token", "required": true, "hidden": true }
|
|
138
|
-
],
|
|
126
|
+
"args": ["-y", "@gongrzhe/server-gmail-autoauth-mcp"],
|
|
127
|
+
"authType": "none",
|
|
128
|
+
"envKeys": [],
|
|
139
129
|
"setupSteps": [
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"That's it —
|
|
130
|
+
"Just install — the server handles Google sign-in automatically",
|
|
131
|
+
"On first use, a browser window will open for you to authorize",
|
|
132
|
+
"That's it — no API keys or tokens needed"
|
|
143
133
|
],
|
|
144
134
|
"featured": false,
|
|
145
135
|
"downloads": 0,
|
|
@@ -221,9 +211,9 @@
|
|
|
221
211
|
{ "key": "GOOGLE_REFRESH_TOKEN", "label": "Refresh Token", "required": true, "hidden": true }
|
|
222
212
|
],
|
|
223
213
|
"setupSteps": [
|
|
224
|
-
"Click 'Connect with Google' below",
|
|
225
|
-
"
|
|
226
|
-
"
|
|
214
|
+
"Click 'Connect with Google' below to sign in",
|
|
215
|
+
"Authorize Groove to access your Drive",
|
|
216
|
+
"Done — credentials are encrypted and stored locally"
|
|
227
217
|
],
|
|
228
218
|
"featured": false,
|
|
229
219
|
"downloads": 0,
|
|
@@ -239,10 +229,10 @@
|
|
|
239
229
|
"icon": "linear",
|
|
240
230
|
"tags": ["issues", "project-management", "tickets", "sprints"],
|
|
241
231
|
"roles": ["fullstack", "backend", "devops"],
|
|
242
|
-
"npmPackage": "
|
|
232
|
+
"npmPackage": "mcp-linear",
|
|
243
233
|
"transport": "stdio",
|
|
244
234
|
"command": "npx",
|
|
245
|
-
"args": ["-y", "
|
|
235
|
+
"args": ["-y", "mcp-linear"],
|
|
246
236
|
"authType": "api-key",
|
|
247
237
|
"envKeys": [
|
|
248
238
|
{ "key": "LINEAR_API_KEY", "label": "API Key", "required": true }
|
|
@@ -326,10 +316,10 @@
|
|
|
326
316
|
"icon": "home",
|
|
327
317
|
"tags": ["iot", "smart-home", "automation", "devices"],
|
|
328
318
|
"roles": ["home"],
|
|
329
|
-
"npmPackage": "mcp
|
|
319
|
+
"npmPackage": "hass-mcp",
|
|
330
320
|
"transport": "stdio",
|
|
331
321
|
"command": "npx",
|
|
332
|
-
"args": ["-y", "mcp
|
|
322
|
+
"args": ["-y", "hass-mcp"],
|
|
333
323
|
"authType": "api-key",
|
|
334
324
|
"envKeys": [
|
|
335
325
|
{ "key": "HOME_ASSISTANT_URL", "label": "HA URL", "placeholder": "http://homeassistant.local:8123", "required": true },
|
|
@@ -402,10 +392,10 @@
|
|
|
402
392
|
"icon": "database",
|
|
403
393
|
"tags": ["sql", "database", "local", "lightweight"],
|
|
404
394
|
"roles": ["analyst", "backend"],
|
|
405
|
-
"npmPackage": "
|
|
395
|
+
"npmPackage": "mcp-sqlite",
|
|
406
396
|
"transport": "stdio",
|
|
407
397
|
"command": "npx",
|
|
408
|
-
"args": ["-y", "
|
|
398
|
+
"args": ["-y", "mcp-sqlite"],
|
|
409
399
|
"authType": "none",
|
|
410
400
|
"envKeys": [],
|
|
411
401
|
"featured": false,
|
|
@@ -446,6 +446,9 @@ export function createApi(app, daemon) {
|
|
|
446
446
|
|
|
447
447
|
// --- Integrations ---
|
|
448
448
|
|
|
449
|
+
// Google OAuth routes MUST come before parameterized :id routes
|
|
450
|
+
// (Express matches in order — :id would swallow 'google-oauth')
|
|
451
|
+
|
|
449
452
|
app.get('/api/integrations/registry', async (req, res) => {
|
|
450
453
|
const integrations = await daemon.integrations.getRegistry({
|
|
451
454
|
search: req.query.search || '',
|
|
@@ -461,6 +464,48 @@ export function createApi(app, daemon) {
|
|
|
461
464
|
res.json(daemon.integrations.getInstalled());
|
|
462
465
|
});
|
|
463
466
|
|
|
467
|
+
app.get('/api/integrations/google-oauth/status', (req, res) => {
|
|
468
|
+
res.json({ configured: daemon.integrations.isGoogleOAuthConfigured() });
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
app.post('/api/integrations/google-oauth/setup', (req, res) => {
|
|
472
|
+
try {
|
|
473
|
+
const { clientId, clientSecret } = req.body || {};
|
|
474
|
+
if (!clientId || !clientSecret) return res.status(400).json({ error: 'clientId and clientSecret are required' });
|
|
475
|
+
daemon.integrations.setCredential('google-oauth', 'GOOGLE_CLIENT_ID', clientId);
|
|
476
|
+
daemon.integrations.setCredential('google-oauth', 'GOOGLE_CLIENT_SECRET', clientSecret);
|
|
477
|
+
res.json({ ok: true });
|
|
478
|
+
} catch (err) {
|
|
479
|
+
res.status(400).json({ error: err.message });
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
app.get('/api/integrations/oauth/callback', async (req, res) => {
|
|
484
|
+
try {
|
|
485
|
+
const { code, state } = req.query;
|
|
486
|
+
if (!code || !state) return res.status(400).send('Missing code or state parameter');
|
|
487
|
+
await daemon.integrations.handleOAuthCallback(code, state);
|
|
488
|
+
res.send(`<!DOCTYPE html><html><body style="font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#1e2127;color:#e6e6e6">
|
|
489
|
+
<div style="text-align:center">
|
|
490
|
+
<div style="font-size:48px;margin-bottom:16px">✓</div>
|
|
491
|
+
<h2>Connected!</h2>
|
|
492
|
+
<p style="color:#7a8394">You can close this tab and return to Groove.</p>
|
|
493
|
+
<script>setTimeout(()=>window.close(),2000)</script>
|
|
494
|
+
</div>
|
|
495
|
+
</body></html>`);
|
|
496
|
+
} catch (err) {
|
|
497
|
+
res.status(400).send(`<!DOCTYPE html><html><body style="font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#1e2127;color:#e06c75">
|
|
498
|
+
<div style="text-align:center">
|
|
499
|
+
<h2>Connection Failed</h2>
|
|
500
|
+
<p>${err.message}</p>
|
|
501
|
+
<p style="color:#7a8394">Close this tab and try again in Groove.</p>
|
|
502
|
+
</div>
|
|
503
|
+
</body></html>`);
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
// Parameterized :id routes (after specific routes above)
|
|
508
|
+
|
|
464
509
|
app.post('/api/integrations/:id/install', async (req, res) => {
|
|
465
510
|
try {
|
|
466
511
|
const result = await daemon.integrations.install(req.params.id);
|
|
@@ -505,24 +550,6 @@ export function createApi(app, daemon) {
|
|
|
505
550
|
}
|
|
506
551
|
});
|
|
507
552
|
|
|
508
|
-
// --- Google OAuth flow ---
|
|
509
|
-
|
|
510
|
-
app.get('/api/integrations/google-oauth/status', (req, res) => {
|
|
511
|
-
res.json({ configured: daemon.integrations.isGoogleOAuthConfigured() });
|
|
512
|
-
});
|
|
513
|
-
|
|
514
|
-
app.post('/api/integrations/google-oauth/setup', (req, res) => {
|
|
515
|
-
try {
|
|
516
|
-
const { clientId, clientSecret } = req.body || {};
|
|
517
|
-
if (!clientId || !clientSecret) return res.status(400).json({ error: 'clientId and clientSecret are required' });
|
|
518
|
-
daemon.integrations.setCredential('google-oauth', 'GOOGLE_CLIENT_ID', clientId);
|
|
519
|
-
daemon.integrations.setCredential('google-oauth', 'GOOGLE_CLIENT_SECRET', clientSecret);
|
|
520
|
-
res.json({ ok: true });
|
|
521
|
-
} catch (err) {
|
|
522
|
-
res.status(400).json({ error: err.message });
|
|
523
|
-
}
|
|
524
|
-
});
|
|
525
|
-
|
|
526
553
|
app.post('/api/integrations/:id/oauth/start', (req, res) => {
|
|
527
554
|
try {
|
|
528
555
|
const url = daemon.integrations.getOAuthUrl(req.params.id);
|
|
@@ -532,31 +559,6 @@ export function createApi(app, daemon) {
|
|
|
532
559
|
}
|
|
533
560
|
});
|
|
534
561
|
|
|
535
|
-
app.get('/api/integrations/oauth/callback', async (req, res) => {
|
|
536
|
-
try {
|
|
537
|
-
const { code, state } = req.query;
|
|
538
|
-
if (!code || !state) return res.status(400).send('Missing code or state parameter');
|
|
539
|
-
await daemon.integrations.handleOAuthCallback(code, state);
|
|
540
|
-
// Return a nice HTML page that auto-closes
|
|
541
|
-
res.send(`<!DOCTYPE html><html><body style="font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#1e2127;color:#e6e6e6">
|
|
542
|
-
<div style="text-align:center">
|
|
543
|
-
<div style="font-size:48px;margin-bottom:16px">✓</div>
|
|
544
|
-
<h2>Connected!</h2>
|
|
545
|
-
<p style="color:#7a8394">You can close this tab and return to Groove.</p>
|
|
546
|
-
<script>setTimeout(()=>window.close(),2000)</script>
|
|
547
|
-
</div>
|
|
548
|
-
</body></html>`);
|
|
549
|
-
} catch (err) {
|
|
550
|
-
res.status(400).send(`<!DOCTYPE html><html><body style="font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#1e2127;color:#e06c75">
|
|
551
|
-
<div style="text-align:center">
|
|
552
|
-
<h2>Connection Failed</h2>
|
|
553
|
-
<p>${err.message}</p>
|
|
554
|
-
<p style="color:#7a8394">Close this tab and try again in Groove.</p>
|
|
555
|
-
</div>
|
|
556
|
-
</body></html>`);
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
|
|
560
562
|
// --- Agent Integrations (attach/detach) ---
|
|
561
563
|
|
|
562
564
|
app.post('/api/agents/:agentId/integrations/:integrationId', (req, res) => {
|