@danainnovations/cortex-mcp 1.0.83 → 1.0.85

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
@@ -339,7 +339,13 @@ function getWizardHtml() {
339
339
  color: #8f999f;
340
340
  text-transform: uppercase;
341
341
  letter-spacing: 0.08em;
342
- margin-bottom: 8px;
342
+ margin-bottom: 4px;
343
+ }
344
+ .mcp-section-subtitle {
345
+ font-size: 12px;
346
+ color: #6b7780;
347
+ font-weight: 400;
348
+ margin-bottom: 12px;
343
349
  }
344
350
 
345
351
  /* \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 */
@@ -665,6 +671,27 @@ function getWizardHtml() {
665
671
  .text-muted { color: #6b7780; }
666
672
  .hidden { display: none !important; }
667
673
 
674
+ /* \u2500\u2500 Client Section Divider \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
675
+ .client-section-divider {
676
+ margin: 24px 0 16px;
677
+ padding-top: 20px;
678
+ border-top: 1px solid rgba(255, 255, 255, 0.08);
679
+ }
680
+ .client-section-title {
681
+ font-size: 11px;
682
+ font-weight: 500;
683
+ color: #8f999f;
684
+ text-transform: uppercase;
685
+ letter-spacing: 0.08em;
686
+ margin-bottom: 4px;
687
+ }
688
+ .client-section-subtitle {
689
+ font-size: 12px;
690
+ color: #6b7780;
691
+ font-weight: 400;
692
+ margin-bottom: 12px;
693
+ }
694
+
668
695
  /* \u2500\u2500 Stdio Snippet \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
669
696
  .stdio-snippet {
670
697
  background: rgba(0, 0, 0, 0.3);
@@ -1041,50 +1068,39 @@ function getWizardHtml() {
1041
1068
  databricks: 'Query data warehouses, explore Unity Catalog, and manage jobs',
1042
1069
  };
1043
1070
 
1044
- async function renderMcps() {
1045
- var container = document.getElementById('mcp-list-container');
1046
-
1047
- // Fetch per-user available MCPs (uses API key from login)
1048
- try {
1049
- var userResp = await fetch('/api/user-mcps');
1050
- var userData = await userResp.json();
1051
- if (userData.mcps && userData.mcps.length > 0) {
1052
- state.enabledMcps = userData.mcps.map(function(m) { return m.name; });
1053
- state.selectedMcps = state.enabledMcps.slice();
1054
- }
1055
- } catch (e) {
1056
- // Fall back to global enabledMcps from initial state
1057
- }
1058
-
1059
- // Fetch existing OAuth connections to show connected status
1060
- try {
1061
- var resp = await fetch('/api/connections');
1062
- var data = await resp.json();
1063
- state.connections = data.connections || [];
1064
- } catch (e) {
1065
- state.connections = state.connections || [];
1066
- }
1067
-
1071
+ function renderMcpList(container) {
1068
1072
  var enabledList = (state.enabledMcps && state.enabledMcps.length > 0)
1069
1073
  ? state.enabledMcps : ['m365'];
1070
1074
  var enabledMcps = state.availableMcps.filter(function(m) { return enabledList.indexOf(m.name) !== -1; });
1071
1075
  var disabledMcps = state.availableMcps.filter(function(m) { return enabledList.indexOf(m.name) === -1; });
1072
1076
 
1077
+ // Split enabled into company vs personal
1078
+ var companyMcps = enabledMcps.filter(function(m) { return m.authMode === 'company'; });
1079
+ var personalMcps = enabledMcps.filter(function(m) { return m.authMode === 'personal'; });
1080
+
1073
1081
  var html = '';
1074
1082
 
1075
- // Enabled section
1076
- if (enabledMcps.length > 0) {
1083
+ if (companyMcps.length > 0) {
1077
1084
  html += '<div class="mcp-section">';
1078
- html += '<div class="mcp-section-title">Available integrations</div>';
1085
+ html += '<div class="mcp-section-title">Company Integrations</div>';
1086
+ html += '<div class="mcp-section-subtitle">Ready to use \\u2014 no account connection needed</div>';
1079
1087
  html += '<div class="mcp-list">';
1080
- html += enabledMcps.map(function(mcp) { return renderMcpItem(mcp, false, false); }).join('');
1088
+ html += companyMcps.map(function(mcp) { return renderMcpItem(mcp, false, false); }).join('');
1089
+ html += '</div></div>';
1090
+ }
1091
+
1092
+ if (personalMcps.length > 0) {
1093
+ html += '<div class="mcp-section">';
1094
+ html += '<div class="mcp-section-title">Personal Integrations</div>';
1095
+ html += '<div class="mcp-section-subtitle">Connect your personal account to use these</div>';
1096
+ html += '<div class="mcp-list">';
1097
+ html += personalMcps.map(function(mcp) { return renderMcpItem(mcp, false, false); }).join('');
1081
1098
  html += '</div></div>';
1082
1099
  }
1083
1100
 
1084
- // Disabled (coming soon) section
1085
1101
  if (disabledMcps.length > 0) {
1086
1102
  html += '<div class="mcp-section">';
1087
- html += '<div class="mcp-section-title">Coming soon</div>';
1103
+ html += '<div class="mcp-section-title">Coming Soon</div>';
1088
1104
  html += '<div class="mcp-list">';
1089
1105
  html += disabledMcps.map(function(mcp) { return renderMcpItem(mcp, false, true); }).join('');
1090
1106
  html += '</div></div>';
@@ -1103,6 +1119,34 @@ function getWizardHtml() {
1103
1119
  });
1104
1120
  }
1105
1121
 
1122
+ async function renderMcps() {
1123
+ var container = document.getElementById('mcp-list-container');
1124
+
1125
+ // Render immediately with data from init() \u2014 no loading delay
1126
+ renderMcpList(container);
1127
+
1128
+ // Fetch updated user MCPs and connections in parallel
1129
+ try {
1130
+ var results = await Promise.all([
1131
+ fetch('/api/user-mcps'),
1132
+ fetch('/api/connections')
1133
+ ]);
1134
+ var userData = await results[0].json();
1135
+ var connData = await results[1].json();
1136
+
1137
+ if (userData.mcps && userData.mcps.length > 0) {
1138
+ state.enabledMcps = userData.mcps.map(function(m) { return m.name; });
1139
+ state.selectedMcps = state.enabledMcps.slice();
1140
+ }
1141
+ state.connections = connData.connections || [];
1142
+
1143
+ // Re-render with fresh data (connection badges, updated enabled list)
1144
+ renderMcpList(container);
1145
+ } catch (e) {
1146
+ // Already rendered with init() data \u2014 no action needed
1147
+ }
1148
+ }
1149
+
1106
1150
  function renderMcpItem(mcp, isRequired, isDisabled) {
1107
1151
  var icon = MCP_ICONS[mcp.name] || '';
1108
1152
  var conn = (state.connections || []).find(function(c) { return c.mcp_name === mcp.name; });
@@ -1138,6 +1182,22 @@ function getWizardHtml() {
1138
1182
  }
1139
1183
 
1140
1184
  // \u2500\u2500 Step 4: Configure Clients \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
1185
+ function renderClientItem(client) {
1186
+ var detected = client.detected;
1187
+ var icon = CLIENT_ICONS[client.type] || '';
1188
+ var alreadyConfigured = state.configuredClients.indexOf(client.type) !== -1;
1189
+ var statusText = alreadyConfigured ? 'Configured' : (detected ? 'Detected' : 'Not found');
1190
+ return (
1191
+ '<label class="client-item' + (detected ? '' : ' disabled') +
1192
+ (alreadyConfigured ? ' checked already-configured' : '') + '" data-client="' + client.type + '">' +
1193
+ (icon ? '<div class="client-icon">' + icon + '</div>' : '') +
1194
+ '<div class="mcp-check"><span class="mcp-check-icon">&#10003;</span></div>' +
1195
+ '<span class="client-name">' + escapeHtml(client.name) + '</span>' +
1196
+ '<span class="client-status">' + statusText + '</span>' +
1197
+ '</label>'
1198
+ );
1199
+ }
1200
+
1141
1201
  function renderClients() {
1142
1202
  var el = document.getElementById('client-list');
1143
1203
  document.getElementById('client-result').className = 'hidden';
@@ -1147,21 +1207,25 @@ function getWizardHtml() {
1147
1207
  // Pre-select already-configured clients
1148
1208
  state.selectedClients = state.configuredClients.slice();
1149
1209
 
1150
- el.innerHTML = state.detectedClients.map(function(client) {
1151
- var detected = client.detected;
1152
- var icon = CLIENT_ICONS[client.type] || '';
1153
- var alreadyConfigured = state.configuredClients.indexOf(client.type) !== -1;
1154
- var statusText = alreadyConfigured ? 'Configured' : (detected ? 'Detected' : 'Not found');
1155
- return (
1156
- '<label class="client-item' + (detected ? '' : ' disabled') +
1157
- (alreadyConfigured ? ' checked already-configured' : '') + '" data-client="' + client.type + '">' +
1158
- (icon ? '<div class="client-icon">' + icon + '</div>' : '') +
1159
- '<div class="mcp-check"><span class="mcp-check-icon">&#10003;</span></div>' +
1160
- '<span class="client-name">' + escapeHtml(client.name) + '</span>' +
1161
- '<span class="client-status">' + statusText + '</span>' +
1162
- '</label>'
1163
- );
1164
- }).join('');
1210
+ // Split into auto-configured and manual-setup clients
1211
+ var autoClients = state.detectedClients.filter(function(c) {
1212
+ return c.type !== 'perplexity' && c.type !== 'stdio';
1213
+ });
1214
+ var manualClients = state.detectedClients.filter(function(c) {
1215
+ return c.type === 'perplexity' || c.type === 'stdio';
1216
+ });
1217
+
1218
+ var html = autoClients.map(renderClientItem).join('');
1219
+
1220
+ if (manualClients.length > 0) {
1221
+ html += '<div class="client-section-divider">' +
1222
+ '<div class="client-section-title">Additional Clients</div>' +
1223
+ '<div class="client-section-subtitle">These require a few extra manual steps after setup</div>' +
1224
+ '</div>';
1225
+ html += manualClients.map(renderClientItem).join('');
1226
+ }
1227
+
1228
+ el.innerHTML = html;
1165
1229
 
1166
1230
  el.querySelectorAll('.client-item:not(.disabled):not(.already-configured)').forEach(function(item) {
1167
1231
  item.addEventListener('click', function(e) {
@@ -1546,7 +1610,7 @@ function detectClients() {
1546
1610
  });
1547
1611
  clients.push({
1548
1612
  type: "stdio",
1549
- name: "OpenClaw (stdio)",
1613
+ name: "OpenClaw",
1550
1614
  configPath: null,
1551
1615
  detected: true
1552
1616
  });
@@ -2527,7 +2591,7 @@ var CortexHttpClient = class {
2527
2591
  humanReadableError(status, body) {
2528
2592
  switch (status) {
2529
2593
  case 401:
2530
- return "Invalid API key. Check your key at https://aidentity.app/settings/keys";
2594
+ return "Invalid API key. Run 'npx @danainnovations/cortex-mcp login' to get a new key.";
2531
2595
  case 403:
2532
2596
  return "API key lacks MCP permissions. Create a new key with MCP access.";
2533
2597
  case 404: