cowork-os 0.3.21 → 0.3.23

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 (170) hide show
  1. package/README.md +293 -6
  2. package/connectors/README.md +20 -0
  3. package/connectors/asana-mcp/README.md +24 -0
  4. package/connectors/asana-mcp/dist/index.js +427 -0
  5. package/connectors/asana-mcp/package.json +15 -0
  6. package/connectors/asana-mcp/src/index.ts +553 -0
  7. package/connectors/asana-mcp/tsconfig.json +13 -0
  8. package/connectors/hubspot-mcp/README.md +35 -0
  9. package/connectors/hubspot-mcp/dist/index.js +454 -0
  10. package/connectors/hubspot-mcp/package.json +15 -0
  11. package/connectors/hubspot-mcp/src/index.ts +562 -0
  12. package/connectors/hubspot-mcp/tsconfig.json +13 -0
  13. package/connectors/jira-mcp/README.md +49 -0
  14. package/connectors/jira-mcp/dist/index.js +588 -0
  15. package/connectors/jira-mcp/package.json +15 -0
  16. package/connectors/jira-mcp/src/index.ts +711 -0
  17. package/connectors/jira-mcp/tsconfig.json +13 -0
  18. package/connectors/linear-mcp/README.md +22 -0
  19. package/connectors/linear-mcp/dist/index.js +402 -0
  20. package/connectors/linear-mcp/package.json +15 -0
  21. package/connectors/linear-mcp/src/index.ts +522 -0
  22. package/connectors/linear-mcp/tsconfig.json +13 -0
  23. package/connectors/okta-mcp/README.md +24 -0
  24. package/connectors/okta-mcp/dist/index.js +411 -0
  25. package/connectors/okta-mcp/package.json +15 -0
  26. package/connectors/okta-mcp/src/index.ts +520 -0
  27. package/connectors/okta-mcp/tsconfig.json +13 -0
  28. package/connectors/salesforce-mcp/README.md +47 -0
  29. package/connectors/salesforce-mcp/dist/index.js +584 -0
  30. package/connectors/salesforce-mcp/package.json +15 -0
  31. package/connectors/salesforce-mcp/src/index.ts +722 -0
  32. package/connectors/salesforce-mcp/tsconfig.json +13 -0
  33. package/connectors/servicenow-mcp/README.md +26 -0
  34. package/connectors/servicenow-mcp/dist/index.js +400 -0
  35. package/connectors/servicenow-mcp/package.json +15 -0
  36. package/connectors/servicenow-mcp/src/index.ts +500 -0
  37. package/connectors/servicenow-mcp/tsconfig.json +13 -0
  38. package/connectors/templates/mcp-connector/README.md +31 -0
  39. package/connectors/templates/mcp-connector/package.json +15 -0
  40. package/connectors/templates/mcp-connector/src/index.ts +330 -0
  41. package/connectors/templates/mcp-connector/tsconfig.json +13 -0
  42. package/connectors/zendesk-mcp/README.md +40 -0
  43. package/connectors/zendesk-mcp/dist/index.js +431 -0
  44. package/connectors/zendesk-mcp/package.json +15 -0
  45. package/connectors/zendesk-mcp/src/index.ts +543 -0
  46. package/connectors/zendesk-mcp/tsconfig.json +13 -0
  47. package/dist/electron/electron/agent/daemon.js +25 -0
  48. package/dist/electron/electron/agent/executor.js +181 -26
  49. package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
  50. package/dist/electron/electron/agent/llm/github-copilot-provider.js +97 -0
  51. package/dist/electron/electron/agent/llm/groq-provider.js +33 -0
  52. package/dist/electron/electron/agent/llm/index.js +11 -1
  53. package/dist/electron/electron/agent/llm/kimi-provider.js +33 -0
  54. package/dist/electron/electron/agent/llm/openai-compatible-provider.js +116 -0
  55. package/dist/electron/electron/agent/llm/openai-compatible.js +111 -0
  56. package/dist/electron/electron/agent/llm/openai-oauth.js +2 -1
  57. package/dist/electron/electron/agent/llm/openrouter-provider.js +1 -1
  58. package/dist/electron/electron/agent/llm/provider-factory.js +318 -4
  59. package/dist/electron/electron/agent/llm/types.js +66 -1
  60. package/dist/electron/electron/agent/llm/xai-provider.js +33 -0
  61. package/dist/electron/electron/agent/tools/box-tools.js +231 -0
  62. package/dist/electron/electron/agent/tools/builtin-settings.js +28 -0
  63. package/dist/electron/electron/agent/tools/dropbox-tools.js +237 -0
  64. package/dist/electron/electron/agent/tools/google-drive-tools.js +227 -0
  65. package/dist/electron/electron/agent/tools/notion-tools.js +312 -0
  66. package/dist/electron/electron/agent/tools/onedrive-tools.js +217 -0
  67. package/dist/electron/electron/agent/tools/registry.js +541 -0
  68. package/dist/electron/electron/agent/tools/sharepoint-tools.js +243 -0
  69. package/dist/electron/electron/agent/tools/shell-tools.js +12 -3
  70. package/dist/electron/electron/agent/tools/x-tools.js +1 -1
  71. package/dist/electron/electron/gateway/index.js +1 -0
  72. package/dist/electron/electron/gateway/router.js +123 -143
  73. package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
  74. package/dist/electron/electron/ipc/handlers.js +627 -158
  75. package/dist/electron/electron/main.js +63 -0
  76. package/dist/electron/electron/mcp/oauth/connector-oauth.js +333 -0
  77. package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +503 -154
  78. package/dist/electron/electron/memory/MemoryService.js +1 -1
  79. package/dist/electron/electron/preload.js +74 -1
  80. package/dist/electron/electron/settings/box-manager.js +54 -0
  81. package/dist/electron/electron/settings/dropbox-manager.js +54 -0
  82. package/dist/electron/electron/settings/google-drive-manager.js +54 -0
  83. package/dist/electron/electron/settings/notion-manager.js +56 -0
  84. package/dist/electron/electron/settings/onedrive-manager.js +54 -0
  85. package/dist/electron/electron/settings/sharepoint-manager.js +54 -0
  86. package/dist/electron/electron/utils/box-api.js +153 -0
  87. package/dist/electron/electron/utils/dropbox-api.js +144 -0
  88. package/dist/electron/electron/utils/env-migration.js +19 -0
  89. package/dist/electron/electron/utils/google-drive-api.js +152 -0
  90. package/dist/electron/electron/utils/notion-api.js +103 -0
  91. package/dist/electron/electron/utils/onedrive-api.js +113 -0
  92. package/dist/electron/electron/utils/sharepoint-api.js +109 -0
  93. package/dist/electron/electron/utils/validation.js +82 -3
  94. package/dist/electron/electron/utils/x-cli.js +1 -1
  95. package/dist/electron/shared/channelMessages.js +284 -3
  96. package/dist/electron/shared/llm-provider-catalog.js +198 -0
  97. package/dist/electron/shared/types.js +88 -1
  98. package/package.json +12 -2
  99. package/src/electron/agent/executor.ts +205 -28
  100. package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
  101. package/src/electron/agent/llm/github-copilot-provider.ts +117 -0
  102. package/src/electron/agent/llm/groq-provider.ts +39 -0
  103. package/src/electron/agent/llm/index.ts +5 -0
  104. package/src/electron/agent/llm/kimi-provider.ts +39 -0
  105. package/src/electron/agent/llm/openai-compatible-provider.ts +153 -0
  106. package/src/electron/agent/llm/openai-compatible.ts +133 -0
  107. package/src/electron/agent/llm/openai-oauth.ts +2 -1
  108. package/src/electron/agent/llm/openrouter-provider.ts +2 -1
  109. package/src/electron/agent/llm/provider-factory.ts +414 -6
  110. package/src/electron/agent/llm/types.ts +90 -1
  111. package/src/electron/agent/llm/xai-provider.ts +39 -0
  112. package/src/electron/agent/tools/box-tools.ts +239 -0
  113. package/src/electron/agent/tools/builtin-settings.ts +34 -0
  114. package/src/electron/agent/tools/dropbox-tools.ts +237 -0
  115. package/src/electron/agent/tools/google-drive-tools.ts +228 -0
  116. package/src/electron/agent/tools/notion-tools.ts +330 -0
  117. package/src/electron/agent/tools/onedrive-tools.ts +217 -0
  118. package/src/electron/agent/tools/registry.ts +565 -0
  119. package/src/electron/agent/tools/sharepoint-tools.ts +247 -0
  120. package/src/electron/agent/tools/shell-tools.ts +11 -3
  121. package/src/electron/agent/tools/x-tools.ts +1 -1
  122. package/src/electron/database/SecureSettingsRepository.ts +7 -1
  123. package/src/electron/gateway/index.ts +1 -0
  124. package/src/electron/gateway/router.ts +134 -149
  125. package/src/electron/ipc/canvas-handlers.ts +10 -0
  126. package/src/electron/ipc/handlers.ts +673 -153
  127. package/src/electron/main.ts +35 -0
  128. package/src/electron/mcp/oauth/connector-oauth.ts +448 -0
  129. package/src/electron/mcp/registry/MCPRegistryManager.ts +343 -12
  130. package/src/electron/memory/MemoryService.ts +5 -1
  131. package/src/electron/preload.ts +167 -4
  132. package/src/electron/settings/box-manager.ts +58 -0
  133. package/src/electron/settings/dropbox-manager.ts +58 -0
  134. package/src/electron/settings/google-drive-manager.ts +58 -0
  135. package/src/electron/settings/notion-manager.ts +60 -0
  136. package/src/electron/settings/onedrive-manager.ts +58 -0
  137. package/src/electron/settings/sharepoint-manager.ts +58 -0
  138. package/src/electron/utils/box-api.ts +184 -0
  139. package/src/electron/utils/dropbox-api.ts +171 -0
  140. package/src/electron/utils/env-migration.ts +22 -0
  141. package/src/electron/utils/google-drive-api.ts +183 -0
  142. package/src/electron/utils/notion-api.ts +126 -0
  143. package/src/electron/utils/onedrive-api.ts +137 -0
  144. package/src/electron/utils/sharepoint-api.ts +132 -0
  145. package/src/electron/utils/validation.ts +102 -1
  146. package/src/electron/utils/x-cli.ts +1 -1
  147. package/src/renderer/App.tsx +20 -2
  148. package/src/renderer/components/BoxSettings.tsx +203 -0
  149. package/src/renderer/components/BrowserView.tsx +101 -0
  150. package/src/renderer/components/BuiltinToolsSettings.tsx +105 -0
  151. package/src/renderer/components/CanvasPreview.tsx +68 -1
  152. package/src/renderer/components/ConnectorEnvModal.tsx +116 -0
  153. package/src/renderer/components/ConnectorSetupModal.tsx +566 -0
  154. package/src/renderer/components/ConnectorsSettings.tsx +397 -0
  155. package/src/renderer/components/DropboxSettings.tsx +202 -0
  156. package/src/renderer/components/GoogleDriveSettings.tsx +201 -0
  157. package/src/renderer/components/MCPSettings.tsx +56 -0
  158. package/src/renderer/components/MainContent.tsx +270 -34
  159. package/src/renderer/components/NotionSettings.tsx +231 -0
  160. package/src/renderer/components/Onboarding/Onboarding.tsx +13 -1
  161. package/src/renderer/components/OnboardingModal.tsx +70 -1
  162. package/src/renderer/components/OneDriveSettings.tsx +212 -0
  163. package/src/renderer/components/Settings.tsx +611 -8
  164. package/src/renderer/components/SharePointSettings.tsx +224 -0
  165. package/src/renderer/components/Sidebar.tsx +25 -9
  166. package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
  167. package/src/renderer/styles/index.css +438 -25
  168. package/src/shared/channelMessages.ts +367 -4
  169. package/src/shared/llm-provider-catalog.ts +217 -0
  170. package/src/shared/types.ts +226 -1
@@ -11,6 +11,9 @@
11
11
  import { v4 as uuidv4 } from 'uuid';
12
12
  import { exec } from 'child_process';
13
13
  import { promisify } from 'util';
14
+ import { app } from 'electron';
15
+ import * as path from 'path';
16
+ import * as fs from 'fs';
14
17
  import {
15
18
  MCPRegistry,
16
19
  MCPRegistryEntry,
@@ -28,10 +31,7 @@ const REGISTRY_CACHE_DURATION = 15 * 60 * 1000;
28
31
  // Built-in registry of common MCP servers
29
32
  // This is used as a fallback when the remote registry is unavailable
30
33
  // Package versions verified against npm registry as of 2026-01
31
- const BUILTIN_REGISTRY: MCPRegistry = {
32
- version: '1.1.0',
33
- lastUpdated: new Date().toISOString(),
34
- servers: [
34
+ const BASE_BUILTIN_SERVERS: MCPRegistryEntry[] = [
35
35
  {
36
36
  id: 'filesystem',
37
37
  name: 'Filesystem',
@@ -229,8 +229,333 @@ const BUILTIN_REGISTRY: MCPRegistry = {
229
229
  category: 'testing',
230
230
  verified: true,
231
231
  },
232
- ],
233
- };
232
+ ];
233
+
234
+ const LOCAL_CONNECTOR_VERSION = '0.1.0';
235
+
236
+ function getConnectorScriptPath(connectorName: string): string {
237
+ const baseDir = app.isPackaged
238
+ ? path.join(process.resourcesPath, 'connectors')
239
+ : path.join(process.cwd(), 'connectors');
240
+ return path.join(baseDir, connectorName, 'dist', 'index.js');
241
+ }
242
+
243
+ function getConnectorCommandArgs(connectorName: string): { command: string; args: string[] } {
244
+ const scriptPath = getConnectorScriptPath(connectorName);
245
+ return {
246
+ // Use Electron's bundled Node runtime when possible
247
+ command: process.execPath,
248
+ args: ['--runAsNode', scriptPath],
249
+ };
250
+ }
251
+
252
+ function getConnectorEntries(): MCPRegistryEntry[] {
253
+ const salesforceCommand = getConnectorCommandArgs('salesforce-mcp');
254
+ const jiraCommand = getConnectorCommandArgs('jira-mcp');
255
+ const hubspotCommand = getConnectorCommandArgs('hubspot-mcp');
256
+ const zendeskCommand = getConnectorCommandArgs('zendesk-mcp');
257
+ const servicenowCommand = getConnectorCommandArgs('servicenow-mcp');
258
+ const linearCommand = getConnectorCommandArgs('linear-mcp');
259
+ const asanaCommand = getConnectorCommandArgs('asana-mcp');
260
+ const oktaCommand = getConnectorCommandArgs('okta-mcp');
261
+
262
+ return [
263
+ {
264
+ id: 'salesforce',
265
+ name: 'Salesforce',
266
+ description: 'Salesforce CRM connector for CoWork OS. Requires SALESFORCE_INSTANCE_URL and an access token.',
267
+ version: LOCAL_CONNECTOR_VERSION,
268
+ author: 'CoWork OS',
269
+ homepage: 'https://github.com/CoWork-OS/CoWork-OS',
270
+ repository: 'https://github.com/CoWork-OS/CoWork-OS',
271
+ license: 'MIT',
272
+ installMethod: 'manual',
273
+ transport: 'stdio',
274
+ defaultCommand: salesforceCommand.command,
275
+ defaultArgs: salesforceCommand.args,
276
+ defaultEnv: {
277
+ SALESFORCE_INSTANCE_URL: '',
278
+ SALESFORCE_ACCESS_TOKEN: '',
279
+ SALESFORCE_CLIENT_ID: '',
280
+ SALESFORCE_CLIENT_SECRET: '',
281
+ SALESFORCE_REFRESH_TOKEN: '',
282
+ SALESFORCE_LOGIN_URL: 'https://login.salesforce.com',
283
+ SALESFORCE_API_VERSION: '60.0',
284
+ },
285
+ tools: [
286
+ { name: 'salesforce.health', description: 'Check connector health and auth status' },
287
+ { name: 'salesforce.list_objects', description: 'List available Salesforce objects' },
288
+ { name: 'salesforce.describe_object', description: 'Describe an object and its fields' },
289
+ { name: 'salesforce.get_record', description: 'Fetch a record by id' },
290
+ { name: 'salesforce.search_records', description: 'Run a SOQL query' },
291
+ { name: 'salesforce.create_record', description: 'Create a record' },
292
+ { name: 'salesforce.update_record', description: 'Update a record' },
293
+ ],
294
+ tags: ['salesforce', 'crm', 'enterprise', 'connector'],
295
+ category: 'enterprise',
296
+ verified: true,
297
+ featured: true,
298
+ },
299
+ {
300
+ id: 'jira',
301
+ name: 'Jira',
302
+ description: 'Jira Cloud connector for CoWork OS. Requires JIRA_BASE_URL and auth (token or API token).',
303
+ version: LOCAL_CONNECTOR_VERSION,
304
+ author: 'CoWork OS',
305
+ homepage: 'https://github.com/CoWork-OS/CoWork-OS',
306
+ repository: 'https://github.com/CoWork-OS/CoWork-OS',
307
+ license: 'MIT',
308
+ installMethod: 'manual',
309
+ transport: 'stdio',
310
+ defaultCommand: jiraCommand.command,
311
+ defaultArgs: jiraCommand.args,
312
+ defaultEnv: {
313
+ JIRA_BASE_URL: '',
314
+ JIRA_ACCESS_TOKEN: '',
315
+ JIRA_EMAIL: '',
316
+ JIRA_API_TOKEN: '',
317
+ JIRA_CLIENT_ID: '',
318
+ JIRA_CLIENT_SECRET: '',
319
+ JIRA_REFRESH_TOKEN: '',
320
+ JIRA_API_VERSION: '3',
321
+ },
322
+ tools: [
323
+ { name: 'jira.health', description: 'Check connector health and auth status' },
324
+ { name: 'jira.list_projects', description: 'List Jira projects' },
325
+ { name: 'jira.get_issue', description: 'Fetch an issue by id or key' },
326
+ { name: 'jira.search_issues', description: 'Run a JQL query' },
327
+ { name: 'jira.create_issue', description: 'Create an issue' },
328
+ { name: 'jira.update_issue', description: 'Update an issue' },
329
+ ],
330
+ tags: ['jira', 'issue-tracking', 'enterprise', 'connector'],
331
+ category: 'enterprise',
332
+ verified: true,
333
+ featured: true,
334
+ },
335
+ {
336
+ id: 'hubspot',
337
+ name: 'HubSpot',
338
+ description: 'HubSpot CRM connector for CoWork OS. Requires HUBSPOT_ACCESS_TOKEN.',
339
+ version: LOCAL_CONNECTOR_VERSION,
340
+ author: 'CoWork OS',
341
+ homepage: 'https://github.com/CoWork-OS/CoWork-OS',
342
+ repository: 'https://github.com/CoWork-OS/CoWork-OS',
343
+ license: 'MIT',
344
+ installMethod: 'manual',
345
+ transport: 'stdio',
346
+ defaultCommand: hubspotCommand.command,
347
+ defaultArgs: hubspotCommand.args,
348
+ defaultEnv: {
349
+ HUBSPOT_ACCESS_TOKEN: '',
350
+ HUBSPOT_CLIENT_ID: '',
351
+ HUBSPOT_CLIENT_SECRET: '',
352
+ HUBSPOT_REFRESH_TOKEN: '',
353
+ HUBSPOT_BASE_URL: 'https://api.hubapi.com',
354
+ },
355
+ tools: [
356
+ { name: 'hubspot.health', description: 'Check connector health and auth status' },
357
+ { name: 'hubspot.search_objects', description: 'Search CRM objects' },
358
+ { name: 'hubspot.get_object', description: 'Fetch a CRM object by id' },
359
+ { name: 'hubspot.create_object', description: 'Create a CRM object' },
360
+ { name: 'hubspot.update_object', description: 'Update a CRM object' },
361
+ ],
362
+ tags: ['hubspot', 'crm', 'enterprise', 'connector'],
363
+ category: 'enterprise',
364
+ verified: true,
365
+ },
366
+ {
367
+ id: 'zendesk',
368
+ name: 'Zendesk',
369
+ description: 'Zendesk Support connector for CoWork OS. Requires ZENDESK credentials.',
370
+ version: LOCAL_CONNECTOR_VERSION,
371
+ author: 'CoWork OS',
372
+ homepage: 'https://github.com/CoWork-OS/CoWork-OS',
373
+ repository: 'https://github.com/CoWork-OS/CoWork-OS',
374
+ license: 'MIT',
375
+ installMethod: 'manual',
376
+ transport: 'stdio',
377
+ defaultCommand: zendeskCommand.command,
378
+ defaultArgs: zendeskCommand.args,
379
+ defaultEnv: {
380
+ ZENDESK_SUBDOMAIN: '',
381
+ ZENDESK_EMAIL: '',
382
+ ZENDESK_API_TOKEN: '',
383
+ ZENDESK_ACCESS_TOKEN: '',
384
+ ZENDESK_CLIENT_ID: '',
385
+ ZENDESK_CLIENT_SECRET: '',
386
+ ZENDESK_REFRESH_TOKEN: '',
387
+ },
388
+ tools: [
389
+ { name: 'zendesk.health', description: 'Check connector health and auth status' },
390
+ { name: 'zendesk.search_tickets', description: 'Search Zendesk tickets' },
391
+ { name: 'zendesk.get_ticket', description: 'Fetch a ticket by id' },
392
+ { name: 'zendesk.create_ticket', description: 'Create a ticket' },
393
+ { name: 'zendesk.update_ticket', description: 'Update a ticket' },
394
+ ],
395
+ tags: ['zendesk', 'support', 'enterprise', 'connector'],
396
+ category: 'enterprise',
397
+ verified: true,
398
+ },
399
+ {
400
+ id: 'servicenow',
401
+ name: 'ServiceNow',
402
+ description: 'ServiceNow connector for CoWork OS. Requires instance URL and credentials.',
403
+ version: LOCAL_CONNECTOR_VERSION,
404
+ author: 'CoWork OS',
405
+ homepage: 'https://github.com/CoWork-OS/CoWork-OS',
406
+ repository: 'https://github.com/CoWork-OS/CoWork-OS',
407
+ license: 'MIT',
408
+ installMethod: 'manual',
409
+ transport: 'stdio',
410
+ defaultCommand: servicenowCommand.command,
411
+ defaultArgs: servicenowCommand.args,
412
+ defaultEnv: {
413
+ SERVICENOW_INSTANCE_URL: '',
414
+ SERVICENOW_INSTANCE: '',
415
+ SERVICENOW_USERNAME: '',
416
+ SERVICENOW_PASSWORD: '',
417
+ SERVICENOW_ACCESS_TOKEN: '',
418
+ },
419
+ tools: [
420
+ { name: 'servicenow.health', description: 'Check connector health and auth status' },
421
+ { name: 'servicenow.list_records', description: 'List records from a table' },
422
+ { name: 'servicenow.get_record', description: 'Fetch a record by sys_id' },
423
+ { name: 'servicenow.create_record', description: 'Create a record in a table' },
424
+ { name: 'servicenow.update_record', description: 'Update a record in a table' },
425
+ ],
426
+ tags: ['servicenow', 'itsm', 'enterprise', 'connector'],
427
+ category: 'enterprise',
428
+ verified: true,
429
+ },
430
+ {
431
+ id: 'linear',
432
+ name: 'Linear',
433
+ description: 'Linear GraphQL connector for CoWork OS. Requires LINEAR_API_KEY.',
434
+ version: LOCAL_CONNECTOR_VERSION,
435
+ author: 'CoWork OS',
436
+ homepage: 'https://github.com/CoWork-OS/CoWork-OS',
437
+ repository: 'https://github.com/CoWork-OS/CoWork-OS',
438
+ license: 'MIT',
439
+ installMethod: 'manual',
440
+ transport: 'stdio',
441
+ defaultCommand: linearCommand.command,
442
+ defaultArgs: linearCommand.args,
443
+ defaultEnv: {
444
+ LINEAR_API_KEY: '',
445
+ },
446
+ tools: [
447
+ { name: 'linear.health', description: 'Check connector health and auth status' },
448
+ { name: 'linear.list_projects', description: 'List Linear projects' },
449
+ { name: 'linear.search_issues', description: 'Search issues by title' },
450
+ { name: 'linear.get_issue', description: 'Fetch an issue by id' },
451
+ ],
452
+ tags: ['linear', 'project', 'enterprise', 'connector'],
453
+ category: 'enterprise',
454
+ verified: true,
455
+ },
456
+ {
457
+ id: 'asana',
458
+ name: 'Asana',
459
+ description: 'Asana connector for CoWork OS. Requires ASANA_ACCESS_TOKEN.',
460
+ version: LOCAL_CONNECTOR_VERSION,
461
+ author: 'CoWork OS',
462
+ homepage: 'https://github.com/CoWork-OS/CoWork-OS',
463
+ repository: 'https://github.com/CoWork-OS/CoWork-OS',
464
+ license: 'MIT',
465
+ installMethod: 'manual',
466
+ transport: 'stdio',
467
+ defaultCommand: asanaCommand.command,
468
+ defaultArgs: asanaCommand.args,
469
+ defaultEnv: {
470
+ ASANA_ACCESS_TOKEN: '',
471
+ },
472
+ tools: [
473
+ { name: 'asana.health', description: 'Check connector health and auth status' },
474
+ { name: 'asana.list_projects', description: 'List projects in a workspace' },
475
+ { name: 'asana.get_task', description: 'Fetch a task by id' },
476
+ { name: 'asana.search_tasks', description: 'Search tasks in a workspace' },
477
+ { name: 'asana.create_task', description: 'Create a task' },
478
+ { name: 'asana.update_task', description: 'Update a task' },
479
+ ],
480
+ tags: ['asana', 'project', 'enterprise', 'connector'],
481
+ category: 'enterprise',
482
+ verified: true,
483
+ },
484
+ {
485
+ id: 'okta',
486
+ name: 'Okta',
487
+ description: 'Okta connector for CoWork OS. Requires OKTA_BASE_URL and OKTA_API_TOKEN.',
488
+ version: LOCAL_CONNECTOR_VERSION,
489
+ author: 'CoWork OS',
490
+ homepage: 'https://github.com/CoWork-OS/CoWork-OS',
491
+ repository: 'https://github.com/CoWork-OS/CoWork-OS',
492
+ license: 'MIT',
493
+ installMethod: 'manual',
494
+ transport: 'stdio',
495
+ defaultCommand: oktaCommand.command,
496
+ defaultArgs: oktaCommand.args,
497
+ defaultEnv: {
498
+ OKTA_BASE_URL: '',
499
+ OKTA_API_TOKEN: '',
500
+ },
501
+ tools: [
502
+ { name: 'okta.health', description: 'Check connector health and auth status' },
503
+ { name: 'okta.list_users', description: 'List users' },
504
+ { name: 'okta.get_user', description: 'Fetch a user by id' },
505
+ { name: 'okta.create_user', description: 'Create a user' },
506
+ { name: 'okta.update_user', description: 'Update a user' },
507
+ ],
508
+ tags: ['okta', 'identity', 'enterprise', 'connector'],
509
+ category: 'enterprise',
510
+ verified: true,
511
+ },
512
+ ];
513
+ }
514
+
515
+ function getBuiltinRegistry(): MCPRegistry {
516
+ return {
517
+ version: '1.1.0',
518
+ lastUpdated: new Date().toISOString(),
519
+ servers: [...BASE_BUILTIN_SERVERS, ...getConnectorEntries()],
520
+ };
521
+ }
522
+
523
+ function mergeLocalConnectors(registry: MCPRegistry): MCPRegistry {
524
+ const localConnectors = getConnectorEntries();
525
+ const existingIds = new Set(registry.servers.map((s) => s.id));
526
+ const existingNames = new Set(registry.servers.map((s) => s.name.toLowerCase()));
527
+ const mergedServers = [...registry.servers];
528
+
529
+ for (const connector of localConnectors) {
530
+ if (existingIds.has(connector.id) || existingNames.has(connector.name.toLowerCase())) {
531
+ continue;
532
+ }
533
+ mergedServers.push(connector);
534
+ }
535
+
536
+ return {
537
+ ...registry,
538
+ servers: mergedServers,
539
+ };
540
+ }
541
+
542
+ function validateManualEntry(entry: MCPRegistryEntry): void {
543
+ if (entry.installMethod !== 'manual') return;
544
+
545
+ const command = entry.defaultCommand || entry.installCommand;
546
+ if (!command) {
547
+ throw new Error(`Manual server ${entry.name} is missing a command`);
548
+ }
549
+
550
+ const args = entry.defaultArgs || [];
551
+ const scriptPath = args.find((arg) => /\.(c|m)?js$/i.test(arg));
552
+ if (scriptPath && !fs.existsSync(scriptPath)) {
553
+ throw new Error(
554
+ `Connector script not found at ${scriptPath}. ` +
555
+ `Build connectors first (npm run build:connectors) or reinstall.`
556
+ );
557
+ }
558
+ }
234
559
 
235
560
  export class MCPRegistryManager {
236
561
  private static registryCache: MCPRegistry | null = null;
@@ -249,7 +574,7 @@ export class MCPRegistryManager {
249
574
 
250
575
  if (!settings.registryEnabled) {
251
576
  console.log('[MCPRegistryManager] Registry disabled, using built-in registry');
252
- return BUILTIN_REGISTRY;
577
+ return getBuiltinRegistry();
253
578
  }
254
579
 
255
580
  try {
@@ -273,21 +598,24 @@ export class MCPRegistryManager {
273
598
  throw new Error('Invalid registry format');
274
599
  }
275
600
 
601
+ // Merge local connectors into remote registry
602
+ const mergedRegistry = mergeLocalConnectors(registry);
603
+
276
604
  // Update cache
277
- this.registryCache = registry;
605
+ this.registryCache = mergedRegistry;
278
606
  this.cacheTimestamp = Date.now();
279
607
 
280
- console.log(`[MCPRegistryManager] Fetched ${registry.servers.length} servers from registry`);
281
- return registry;
608
+ console.log(`[MCPRegistryManager] Fetched ${mergedRegistry.servers.length} servers from registry (with local connectors)`);
609
+ return mergedRegistry;
282
610
  } catch (error: any) {
283
611
  // Only log on first failure or after cache expires
284
612
  if (!this.registryCache) {
285
613
  console.warn('[MCPRegistryManager] Failed to fetch registry, using built-in:', error.message);
286
614
  }
287
615
  // Cache the built-in registry to prevent repeated fetch attempts
288
- this.registryCache = BUILTIN_REGISTRY;
616
+ this.registryCache = getBuiltinRegistry();
289
617
  this.cacheTimestamp = Date.now();
290
- return BUILTIN_REGISTRY;
618
+ return this.registryCache;
291
619
  }
292
620
  }
293
621
 
@@ -391,6 +719,9 @@ export class MCPRegistryManager {
391
719
  throw new Error(`Server ${entry.name} is already installed`);
392
720
  }
393
721
 
722
+ // Validate manual entries (local connectors)
723
+ validateManualEntry(entry);
724
+
394
725
  // Verify the npm package exists before installing
395
726
  if (entry.packageName && entry.installMethod === 'npm') {
396
727
  const verification = await this.verifyNpmPackage(entry.packageName);
@@ -354,7 +354,11 @@ export class MemoryService {
354
354
  settings.ollama?.model,
355
355
  settings.gemini?.model,
356
356
  settings.openrouter?.model,
357
- settings.openai?.model
357
+ settings.openai?.model,
358
+ settings.groq?.model,
359
+ settings.xai?.model,
360
+ settings.kimi?.model,
361
+ settings.customProviders
358
362
  );
359
363
 
360
364
  const response = await provider.createMessage({