@danainnovations/cortex-mcp 1.0.109 → 1.0.112

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/dist/cli.js CHANGED
@@ -87,7 +87,7 @@ function getWizardHtml() {
87
87
 
88
88
  #app {
89
89
  width: 100%;
90
- max-width: 900px;
90
+ max-width: 1100px;
91
91
  padding: 24px;
92
92
  position: relative;
93
93
  z-index: 1;
@@ -159,7 +159,7 @@ function getWizardHtml() {
159
159
  -webkit-backdrop-filter: blur(20px);
160
160
  border: 1px solid rgba(255, 255, 255, 0.08);
161
161
  border-radius: 20px;
162
- padding: 40px;
162
+ padding: 32px;
163
163
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
164
164
  }
165
165
 
@@ -344,13 +344,13 @@ function getWizardHtml() {
344
344
  font-size: 12px;
345
345
  color: #6b7780;
346
346
  font-weight: 400;
347
- margin-bottom: 12px;
347
+ margin-bottom: 8px;
348
348
  }
349
349
 
350
350
  /* \u2500\u2500 MCP List \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
351
351
  .mcp-list {
352
352
  display: grid;
353
- grid-template-columns: repeat(2, 1fr);
353
+ grid-template-columns: repeat(3, 1fr);
354
354
  gap: 6px;
355
355
  margin-bottom: 8px;
356
356
  }
@@ -358,8 +358,8 @@ function getWizardHtml() {
358
358
  .mcp-item {
359
359
  display: flex;
360
360
  align-items: center;
361
- gap: 10px;
362
- padding: 11px 14px;
361
+ gap: 8px;
362
+ padding: 8px 10px;
363
363
  border-radius: 12px;
364
364
  border: 1px solid rgba(255, 255, 255, 0.06);
365
365
  cursor: pointer;
@@ -450,12 +450,12 @@ function getWizardHtml() {
450
450
  }
451
451
 
452
452
  .mcp-icon {
453
- width: 28px;
454
- height: 28px;
453
+ width: 22px;
454
+ height: 22px;
455
455
  display: flex;
456
456
  align-items: center;
457
457
  justify-content: center;
458
- border-radius: 7px;
458
+ border-radius: 6px;
459
459
  background: rgba(255, 255, 255, 0.04);
460
460
  flex-shrink: 0;
461
461
  }
@@ -512,11 +512,18 @@ function getWizardHtml() {
512
512
  gap: 8px;
513
513
  margin-bottom: 8px;
514
514
  }
515
+ .client-grid {
516
+ display: grid;
517
+ grid-template-columns: repeat(2, 1fr);
518
+ gap: 6px;
519
+ margin-bottom: 8px;
520
+ }
521
+ @media (max-width: 640px) { .client-grid { grid-template-columns: 1fr; } }
515
522
  .client-item {
516
523
  display: flex;
517
524
  align-items: center;
518
- gap: 12px;
519
- padding: 14px 16px;
525
+ gap: 10px;
526
+ padding: 10px 14px;
520
527
  border-radius: 12px;
521
528
  border: 1px solid rgba(255, 255, 255, 0.06);
522
529
  cursor: pointer;
@@ -539,16 +546,16 @@ function getWizardHtml() {
539
546
  .client-item.already-configured .client-status { color: #4CAF50; }
540
547
 
541
548
  .client-icon {
542
- width: 28px;
543
- height: 28px;
549
+ width: 24px;
550
+ height: 24px;
544
551
  display: flex;
545
552
  align-items: center;
546
553
  justify-content: center;
547
- border-radius: 7px;
554
+ border-radius: 6px;
548
555
  background: rgba(255, 255, 255, 0.04);
549
556
  flex-shrink: 0;
550
557
  }
551
- .client-icon svg { width: 16px; height: 16px; fill: #8f999f; }
558
+ .client-icon svg { width: 14px; height: 14px; fill: #8f999f; }
552
559
  .client-item.checked .client-icon svg { fill: #00A3E1; }
553
560
 
554
561
  .client-name { font-size: 13px; font-weight: 500; color: #fff; }
@@ -561,6 +568,71 @@ function getWizardHtml() {
561
568
  letter-spacing: 0.05em;
562
569
  }
563
570
 
571
+ /* \u2500\u2500 Manual Client Cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
572
+ .manual-client-card {
573
+ border: 1px solid rgba(255, 255, 255, 0.08);
574
+ border-radius: 12px;
575
+ padding: 16px;
576
+ margin-bottom: 8px;
577
+ background: rgba(255, 255, 255, 0.02);
578
+ }
579
+ .manual-client-header {
580
+ display: flex;
581
+ align-items: center;
582
+ gap: 10px;
583
+ margin-bottom: 12px;
584
+ }
585
+ .manual-client-header .client-name { font-size: 14px; }
586
+ .manual-client-badge {
587
+ font-size: 9px;
588
+ font-weight: 600;
589
+ text-transform: uppercase;
590
+ letter-spacing: 0.5px;
591
+ color: #00A3E1;
592
+ background: rgba(0, 163, 225, 0.1);
593
+ padding: 2px 8px;
594
+ border-radius: 4px;
595
+ margin-left: auto;
596
+ }
597
+ .manual-client-steps {
598
+ margin: 0;
599
+ padding-left: 18px;
600
+ font-size: 13px;
601
+ line-height: 1.8;
602
+ color: #b0b8c0;
603
+ }
604
+ .manual-client-steps li { margin-bottom: 2px; }
605
+ .manual-client-steps strong { color: #fff; font-weight: 500; }
606
+ .manual-client-steps a { color: #00A3E1; text-decoration: none; }
607
+ .manual-client-steps a:hover { text-decoration: underline; }
608
+ .manual-url-box {
609
+ display: flex;
610
+ align-items: center;
611
+ gap: 8px;
612
+ background: rgba(0, 163, 225, 0.06);
613
+ border: 1px solid rgba(0, 163, 225, 0.15);
614
+ border-radius: 8px;
615
+ padding: 8px 12px;
616
+ margin-top: 10px;
617
+ }
618
+ .manual-url-box code {
619
+ flex: 1;
620
+ font-size: 12px;
621
+ color: #b0b8c0;
622
+ word-break: break-all;
623
+ }
624
+ .manual-url-box .copy-btn {
625
+ background: rgba(0, 163, 225, 0.15);
626
+ border: 1px solid rgba(0, 163, 225, 0.3);
627
+ color: #00A3E1;
628
+ padding: 4px 12px;
629
+ border-radius: 6px;
630
+ cursor: pointer;
631
+ font-size: 11px;
632
+ font-weight: 500;
633
+ white-space: nowrap;
634
+ }
635
+
564
636
  /* \u2500\u2500 Connection List \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
565
637
  .conn-list {
566
638
  display: flex;
@@ -735,6 +807,11 @@ function getWizardHtml() {
735
807
  background: rgba(0, 163, 225, 0.25);
736
808
  }
737
809
 
810
+ /* \u2500\u2500 Tablet / narrow \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
811
+ @media (max-width: 900px) {
812
+ .mcp-list { grid-template-columns: repeat(2, 1fr); }
813
+ }
814
+
738
815
  /* \u2500\u2500 Mobile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
739
816
  @media (max-width: 640px) {
740
817
  #app { padding: 16px; }
@@ -1255,46 +1332,115 @@ function getWizardHtml() {
1255
1332
  document.getElementById('btn-configure').textContent = 'Configure';
1256
1333
 
1257
1334
  // Pre-select already-configured clients (exclude manual/additional ones)
1258
- var nonAutoTypes = ['perplexity', 'stdio', 'claude-ai'];
1335
+ var manualTypes = ['perplexity', 'stdio', 'claude-ai', 'claude-cowork'];
1259
1336
  state.selectedClients = state.configuredClients.filter(function(c) {
1260
- return nonAutoTypes.indexOf(c) === -1;
1337
+ return manualTypes.indexOf(c) === -1;
1261
1338
  });
1262
1339
 
1263
- // Split into auto-configured, web/mobile/cowork, and manual-setup clients
1264
- var autoClients = state.detectedClients.filter(function(c) {
1265
- return c.type !== 'perplexity' && c.type !== 'stdio' && c.type !== 'claude-ai';
1340
+ // Split clients into groups by setup method
1341
+ var autoClientTypes = ['claude-desktop', 'claude-code', 'cursor', 'vscode', 'antigravity', 'codex'];
1342
+ var manualClientTypes = ['claude-cowork', 'claude-ai'];
1343
+ var additionalTypes = ['perplexity', 'stdio'];
1344
+
1345
+ var autoDetected = state.detectedClients.filter(function(c) {
1346
+ return autoClientTypes.indexOf(c.type) !== -1 && c.detected;
1266
1347
  });
1267
- var webClients = state.detectedClients.filter(function(c) {
1268
- return c.type === 'claude-ai';
1348
+ var autoNotFound = state.detectedClients.filter(function(c) {
1349
+ return autoClientTypes.indexOf(c.type) !== -1 && !c.detected;
1269
1350
  });
1270
1351
  var manualClients = state.detectedClients.filter(function(c) {
1271
- return c.type === 'perplexity' || c.type === 'stdio';
1352
+ return manualClientTypes.indexOf(c.type) !== -1;
1353
+ });
1354
+ var additionalClients = state.detectedClients.filter(function(c) {
1355
+ return additionalTypes.indexOf(c.type) !== -1;
1272
1356
  });
1273
1357
 
1274
- var html = autoClients.map(renderClientItem).join('');
1358
+ var mcpUrl = (state.serverUrl || 'https://cortex-bice.vercel.app') + '/mcp/cortex';
1359
+ var html = '';
1275
1360
 
1276
- if (webClients.length > 0) {
1277
- html += '<div class="client-section-divider">' +
1278
- '<div class="client-section-title">Web & Mobile</div>' +
1279
- '<div class="client-section-subtitle">Use Cortex tools on claude.ai and the Claude mobile app</div>' +
1361
+ // \u2500\u2500 Section 1: Auto-configured (2-column grid) \u2500\u2500
1362
+ if (autoDetected.length > 0) {
1363
+ html += '<div class="client-section-divider" style="margin-top:0;padding-top:0;border:none;">' +
1364
+ '<div class="client-section-title">Auto-configured</div>' +
1365
+ '<div class="client-section-subtitle">Select the apps you use \\u2014 we\\u2019ll configure them automatically</div>' +
1280
1366
  '</div>';
1281
- html += webClients.map(renderClientItem).join('');
1367
+ html += '<div class="client-grid">';
1368
+ html += autoDetected.map(renderClientItem).join('');
1369
+ html += '</div>';
1370
+ }
1371
+
1372
+ // Show not-found auto clients dimmed
1373
+ if (autoNotFound.length > 0) {
1374
+ html += '<div class="client-grid" style="margin-top:4px;">';
1375
+ html += autoNotFound.map(renderClientItem).join('');
1376
+ html += '</div>';
1282
1377
  }
1283
1378
 
1379
+ // \u2500\u2500 Section 2: Manual setup with inline instructions \u2500\u2500
1284
1380
  if (manualClients.length > 0) {
1381
+ html += '<div class="client-section-divider">' +
1382
+ '<div class="client-section-title">Connect manually</div>' +
1383
+ '<div class="client-section-subtitle">These need one extra step in the app</div>' +
1384
+ '</div>';
1385
+
1386
+ manualClients.forEach(function(client) {
1387
+ var icon = CLIENT_ICONS[client.type] || '';
1388
+ if (client.type === 'claude-cowork') {
1389
+ html += '<div class="manual-client-card" data-client="claude-cowork">' +
1390
+ '<div class="manual-client-header">' +
1391
+ (icon ? '<div class="client-icon">' + icon + '</div>' : '') +
1392
+ '<span class="client-name">Claude CoWork</span>' +
1393
+ '<span class="manual-client-badge">1 step</span>' +
1394
+ '</div>' +
1395
+ '<ol class="manual-client-steps">' +
1396
+ '<li>Open <strong>Claude Desktop</strong> \\u2192 <strong>Settings</strong> \\u2192 <strong>Connectors</strong></li>' +
1397
+ '<li>Find <strong>Cortex MCP Enterprise</strong> at the bottom</li>' +
1398
+ '<li>Click <strong>Connect</strong> \\u2192 sign in via Okta when prompted</li>' +
1399
+ '</ol>' +
1400
+ '<div class="manual-url-box">' +
1401
+ '<code>' + escapeHtml(mcpUrl) + '</code>' +
1402
+ '<button class="copy-btn" onclick="copySnippet(this)">Copy</button>' +
1403
+ '</div>' +
1404
+ '</div>';
1405
+ }
1406
+ if (client.type === 'claude-ai') {
1407
+ html += '<div class="manual-client-card" data-client="claude-ai">' +
1408
+ '<div class="manual-client-header">' +
1409
+ (icon ? '<div class="client-icon">' + icon + '</div>' : '') +
1410
+ '<span class="client-name">Claude.ai & Mobile</span>' +
1411
+ '<span class="manual-client-badge">1 step</span>' +
1412
+ '</div>' +
1413
+ '<ol class="manual-client-steps">' +
1414
+ '<li>Open <a href="https://claude.ai/settings/integrations" target="_blank">claude.ai/settings/integrations</a></li>' +
1415
+ '<li>Click <strong>Add custom integration</strong></li>' +
1416
+ '<li>Paste the URL below and click <strong>Add</strong></li>' +
1417
+ '</ol>' +
1418
+ '<div class="manual-url-box">' +
1419
+ '<code>' + escapeHtml(mcpUrl) + '</code>' +
1420
+ '<button class="copy-btn" onclick="copySnippet(this)">Copy</button>' +
1421
+ '</div>' +
1422
+ '</div>';
1423
+ }
1424
+ });
1425
+ }
1426
+
1427
+ // \u2500\u2500 Section 3: Additional clients (collapsed) \u2500\u2500
1428
+ if (additionalClients.length > 0) {
1285
1429
  html += '<div class="client-section-divider">' +
1286
1430
  '<div class="client-section-title">Additional Clients</div>' +
1287
- '<div class="client-section-subtitle">These require a few extra manual steps after setup</div>' +
1431
+ '<div class="client-section-subtitle">Perplexity, OpenClaw, and other stdio clients</div>' +
1288
1432
  '</div>';
1289
- html += manualClients.map(renderClientItem).join('');
1433
+ html += '<div class="client-grid">';
1434
+ html += additionalClients.map(renderClientItem).join('');
1435
+ html += '</div>';
1290
1436
  }
1291
1437
 
1292
1438
  el.innerHTML = html;
1293
1439
 
1294
- var manualTypes = ['perplexity', 'stdio', 'claude-ai'];
1440
+ // Attach click handlers to auto-configured items
1295
1441
  el.querySelectorAll('.client-item:not(.disabled):not(.already-configured)').forEach(function(item) {
1296
- // Auto-select detected clients, but NOT manual/additional/web ones
1297
- if (manualTypes.indexOf(item.dataset.client) === -1) {
1442
+ // Auto-select detected auto clients
1443
+ if (manualTypes.indexOf(item.dataset.client) === -1 && !item.classList.contains('disabled')) {
1298
1444
  item.classList.add('checked');
1299
1445
  }
1300
1446
  item.addEventListener('click', function(e) {
@@ -1305,9 +1451,17 @@ function getWizardHtml() {
1305
1451
  });
1306
1452
  });
1307
1453
 
1308
- // Sync selectedClients with all checked items (auto-selected + previously configured)
1309
- state.selectedClients = Array.from(el.querySelectorAll('.client-item.checked'))
1454
+ // Include manual clients in selectedClients so they get configured too
1455
+ manualClients.forEach(function(c) {
1456
+ if (state.selectedClients.indexOf(c.type) === -1) {
1457
+ state.selectedClients.push(c.type);
1458
+ }
1459
+ });
1460
+
1461
+ // Sync selectedClients with all checked items
1462
+ var checkedAuto = Array.from(el.querySelectorAll('.client-item.checked'))
1310
1463
  .map(function(i) { return i.dataset.client; });
1464
+ state.selectedClients = checkedAuto.concat(manualClients.map(function(c) { return c.type; }));
1311
1465
  }
1312
1466
 
1313
1467
  async function configureClients() {
@@ -3677,30 +3831,34 @@ async function startStdioServer(options) {
3677
3831
  capabilities: { tools: { listChanged: false } },
3678
3832
  instructions: [
3679
3833
  "You have access to Cortex, a multi-MCP gateway for building and deploying apps.",
3834
+ "When a user asks to build, create, or make an app, call the build_app tool to get the deployment workflow.",
3680
3835
  "",
3681
3836
  "## Vibe Coding Workflow \u2014 Building New Apps",
3682
3837
  "",
3838
+ "**CRITICAL: You MUST create a branded HTML POC and get user approval BEFORE creating any infrastructure.**",
3839
+ "",
3683
3840
  "When a user asks you to build a NEW app, follow this pipeline:",
3684
3841
  "",
3685
3842
  "1. FIRST call sonance_brand__design_app to get the branded starter blueprint",
3686
- "2. Create a branded HTML proof-of-concept file and ask the user to review it before proceeding",
3687
- "3. After user approves, validate requirements:",
3843
+ "2. Create a branded HTML proof-of-concept file (via filesystem__write_file) and ask the user to review it in their browser",
3844
+ "3. **STOP and WAIT for explicit user approval before proceeding**",
3845
+ "4. After user approves, validate requirements:",
3688
3846
  " - Does it need a database? Only create a Supabase project if the app needs persistent user data",
3689
3847
  " - Does it need user auth? If yes, call supabase__setup_cortex_auth to set up Sign in with Cortex",
3690
- "4. Write Next.js code using Sonance Brand components (sonance_brand__get_components_by_category), not custom UI",
3691
- "5. Create a private GitHub repo (github__create_repository) and push code (github__push_files)",
3848
+ "5. Write Next.js code using Sonance Brand components (sonance_brand__get_components_by_category), not custom UI",
3849
+ "6. Create a private GitHub repo (github__create_repository) and push code (github__push_files)",
3692
3850
  " - Never push .env files or secrets \u2014 include .gitignore and .env.example",
3693
3851
  " - Keep code modular: components in /components, utilities in /lib, no file over 300 lines",
3694
- "6. Set ALL environment variables on Vercel (vercel__set_env_vars_batch) BEFORE deploying:",
3852
+ "7. Set ALL environment variables on Vercel (vercel__set_env_vars_batch) BEFORE deploying:",
3695
3853
  " - Supabase: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY",
3696
3854
  " - Auth (if set up): NEXT_PUBLIC_CORTEX_URL, NEXT_PUBLIC_CORTEX_CLIENT_ID, CORTEX_CLIENT_ID, CORTEX_CLIENT_SECRET",
3697
3855
  " - Extract all values from tool responses \u2014 never ask the user to provide or copy keys",
3698
- "7. Deploy to Vercel (vercel__deploy) and verify deployment succeeds (vercel__get_deployment)",
3856
+ "8. Deploy to Vercel (vercel__deploy) and verify deployment succeeds (vercel__get_deployment)",
3699
3857
  " - If deployment fails, check logs (vercel__get_deployment_logs), fix code, push fix, and retry",
3700
3858
  " - Never tell the user the app is live without confirming READY status",
3701
- "8. After deployment is READY and auth is set up, register the redirect URI (supabase__add_redirect_uri)",
3702
- "9. Run quality checks: security_scan__scan_code_security, code_analysis__lint_directory, code_review__review_directory",
3703
- "10. Call sonance_brand__evaluate_design to verify brand compliance (must score Tier 3+ / >= 60)",
3859
+ "9. After deployment is READY and auth is set up, register the redirect URI (supabase__add_redirect_uri)",
3860
+ "10. Run quality checks: security_scan__scan_code_security, code_analysis__lint_directory, code_review__review_directory",
3861
+ "11. Call sonance_brand__evaluate_design to verify brand compliance (must score Tier 3+ / >= 60)",
3704
3862
  "",
3705
3863
  "## Existing Projects",
3706
3864
  "",
@@ -3748,14 +3906,16 @@ async function startStdioServer(options) {
3748
3906
  "",
3749
3907
  "Follow this pipeline when building apps with Cortex MCP tools.",
3750
3908
  "",
3909
+ "**CRITICAL: For new apps, you MUST create a branded HTML POC and get user approval BEFORE creating any infrastructure (GitHub repo, Vercel project, Supabase project). Do not skip the POC gate.**",
3910
+ "",
3751
3911
  "## New App (Greenfield)",
3752
3912
  "",
3753
3913
  "### Phase 1: Design & Approve",
3754
3914
  "1. Call `sonance_brand__design_app` with the app description to get the branded starter blueprint (CSS, components, layout)",
3755
3915
  "2. Call `sonance_brand__get_css_theme` for the full CSS variables and Tailwind config",
3756
- "3. Create a single branded HTML proof-of-concept file and show the user",
3916
+ "3. Create a single branded HTML proof-of-concept file (via `filesystem__write_file`) and tell the user to open it in their browser",
3757
3917
  "4. Ask the user: 'Does this look right? Ready to build the full app?'",
3758
- "5. Do NOT proceed until the user approves",
3918
+ "5. **STOP and WAIT** \u2014 Do NOT proceed until the user explicitly approves",
3759
3919
  "",
3760
3920
  "### Phase 2: Plan Infrastructure",
3761
3921
  "6. Determine if the app needs a database (user accounts, persistent data \u2192 yes; static content \u2192 no)",